@@ -88,6 +88,7 @@ var DashTx = ("object" === typeof module && exports) || {};
88
88
let TxUtils = { } ;
89
89
90
90
const CURRENT_VERSION = 3 ;
91
+ const TYPE_VERSION = 0 ;
91
92
const SATOSHIS = 100000000 ;
92
93
93
94
const MAX_U8 = Math . pow ( 2 , 8 ) - 1 ;
@@ -142,11 +143,13 @@ var DashTx = ("object" === typeof module && exports) || {};
142
143
Tx . LEGACY_DUST = 2000 ;
143
144
144
145
Tx . _HEADER_ONLY_SIZE =
145
- 4 + // version
146
+ 2 + // version
147
+ 2 + // type
146
148
4 ; // locktime
147
149
148
150
Tx . HEADER_SIZE =
149
- 4 + // version
151
+ 2 + // version
152
+ 2 + // type
150
153
1 + // input count
151
154
1 + // output count
152
155
4 ; // locktime
@@ -303,11 +306,13 @@ var DashTx = ("object" === typeof module && exports) || {};
303
306
304
307
/** @type {TxInfoSigned } */
305
308
let txInfoSigned = {
309
+ version : txInfo . version || CURRENT_VERSION ,
310
+ type : txInfo . type || TYPE_VERSION ,
306
311
/** @type {Array<TxInputSigned> } */
307
312
inputs : [ ] ,
308
313
outputs : txInfo . outputs ,
309
- version : txInfo . version || CURRENT_VERSION ,
310
314
locktime : txInfo . locktime || 0x00 ,
315
+ extraPayload : "" ,
311
316
transaction : "" ,
312
317
} ;
313
318
@@ -687,9 +692,10 @@ var DashTx = ("object" === typeof module && exports) || {};
687
692
* or the largest available coins until that total is met.
688
693
*/
689
694
//@ts -ignore - TODO update typedefs
690
- Tx . createLegacyTx = function ( coins , outputs , changeOutput ) {
695
+ Tx . createLegacyTx = function ( coins , outputs , changeOutput , extraPayload ) {
691
696
// TODO bump to 4 for DIP: enforce tx hygiene
692
697
let version = CURRENT_VERSION ;
698
+ let type = TYPE_VERSION ;
693
699
694
700
coins = coins . slice ( 0 ) ;
695
701
outputs = outputs . slice ( 0 ) ;
@@ -773,10 +779,12 @@ var DashTx = ("object" === typeof module && exports) || {};
773
779
774
780
let txInfo = {
775
781
version,
782
+ type,
776
783
inputs,
777
784
outputs,
778
785
changeIndex,
779
786
locktime,
787
+ extraPayload,
780
788
} ;
781
789
// let change = txInfo.outputs[txInfo.changeIndex];
782
790
@@ -1120,9 +1128,11 @@ var DashTx = ("object" === typeof module && exports) || {};
1120
1128
Tx . serialize = function (
1121
1129
{
1122
1130
version = CURRENT_VERSION ,
1131
+ type = TYPE_VERSION ,
1123
1132
inputs,
1124
- locktime = 0x0 ,
1125
1133
outputs,
1134
+ locktime = 0x0 ,
1135
+ extraPayload = "" ,
1126
1136
/* maxFee = 10000, */
1127
1137
_debug = false ,
1128
1138
} ,
@@ -1135,15 +1145,23 @@ var DashTx = ("object" === typeof module && exports) || {};
1135
1145
1136
1146
/** @type Array<String> */
1137
1147
let tx = [ ] ;
1138
- let v = TxUtils . _toUint32LE ( version ) ;
1148
+ let v = TxUtils . _toUint16LE ( version ) ;
1139
1149
tx . push ( v ) ;
1150
+ let t = TxUtils . _toUint16LE ( type ) ;
1151
+ tx . push ( t ) ;
1140
1152
1141
1153
void Tx . serializeInputs ( inputs , { _tx : tx , _sep : _sep } ) ;
1142
1154
void Tx . serializeOutputs ( outputs , { _tx : tx , _sep : _sep } ) ;
1143
1155
1144
1156
let locktimeHex = TxUtils . _toUint32LE ( locktime ) ;
1145
1157
tx . push ( locktimeHex ) ;
1146
1158
1159
+ if ( extraPayload ) {
1160
+ let nTrailer = Tx . utils . toVarInt ( extraPayload . length / 2 ) ;
1161
+ tx . push ( nTrailer ) ;
1162
+ tx . push ( extraPayload ) ;
1163
+ }
1164
+
1147
1165
let txHex = tx . join ( _sep ) ;
1148
1166
1149
1167
if ( sigHashType ) {
@@ -1459,10 +1477,15 @@ var DashTx = ("object" === typeof module && exports) || {};
1459
1477
1460
1478
tx . offset = 0 ;
1461
1479
1462
- tx . versionHex = hex . substr ( tx . offset , 8 ) ;
1480
+ tx . versionHex = hex . substr ( tx . offset , 4 ) ;
1463
1481
let versionHexRev = Tx . utils . reverseHex ( tx . versionHex ) ;
1464
1482
tx . version = parseInt ( versionHexRev , 16 ) ;
1465
- tx . offset += 8 ;
1483
+ tx . offset += 4 ;
1484
+
1485
+ tx . typeHex = hex . substr ( tx . offset , 4 ) ;
1486
+ let typeHexRev = Tx . utils . reverseHex ( tx . typeHex ) ;
1487
+ tx . type = parseInt ( typeHexRev , 16 ) ;
1488
+ tx . offset += 4 ;
1466
1489
1467
1490
let [ numInputs , numInputsSize ] = TxUtils . _parseVarIntHex ( hex , tx . offset ) ;
1468
1491
tx . offset += numInputsSize ;
@@ -1631,10 +1654,26 @@ var DashTx = ("object" === typeof module && exports) || {};
1631
1654
tx . locktime = parseInt ( locktimeHexRev , 16 ) ;
1632
1655
tx . offset += 8 ;
1633
1656
1657
+ tx . extraPayloadSizeHex = "" ;
1658
+ /** @type {Uint8? } */
1659
+ tx . extraPayloadSize = null ;
1660
+ tx . extraPayloadHex = "" ;
1661
+ if ( tx . type > 0 ) {
1662
+ // TODO varint
1663
+ tx . extraPayloadSizeHex = hex . substr ( tx . offset , 2 ) ;
1664
+ tx . extraPayloadSize = parseInt ( tx . extraPayloadSizeHex , 16 ) ;
1665
+ tx . offset += 2 ;
1666
+
1667
+ tx . extraPayloadHex = hex . substr ( tx . offset , 2 * tx . extraPayloadSize ) ;
1668
+ tx . offset += 2 * tx . extraPayloadSize ;
1669
+ }
1670
+
1634
1671
tx . sigHashTypeHex = hex . substr ( tx . offset ) ;
1635
1672
if ( tx . sigHashTypeHex ) {
1636
- tx . sigHashType = parseInt ( tx . sigHashTypeHex . slice ( 0 , 2 ) ) ;
1637
- hex = hex . slice ( 0 , - 8 ) ;
1673
+ let firstLEIntByte = tx . sigHashTypeHex . slice ( 0 , 2 ) ;
1674
+ tx . sigHashType = parseInt ( firstLEIntByte ) ;
1675
+ let fullLEIntHexSize = 8 ;
1676
+ hex = hex . slice ( 0 , - fullLEIntHexSize ) ; // but the size is actually 4 bytes
1638
1677
}
1639
1678
1640
1679
tx . size = hex . length / 2 ;
@@ -1806,6 +1845,18 @@ var DashTx = ("object" === typeof module && exports) || {};
1806
1845
throw err ;
1807
1846
} ;
1808
1847
1848
+ /**
1849
+ * Just assumes that all target CPUs are Little-Endian,
1850
+ * which is true in practice, and much simpler.
1851
+ * @param {BigInt|Number } n - 16-bit positive int to encode
1852
+ */
1853
+ TxUtils . _toUint16LE = function ( n ) {
1854
+ let hexLE = TxUtils . _toUint32LE ( n ) ;
1855
+ // ex: 03000800 => 0300
1856
+ hexLE = hexLE . slice ( 0 , 4 ) ;
1857
+ return hexLE ;
1858
+ } ;
1859
+
1809
1860
/**
1810
1861
* Just assumes that all target CPUs are Little-Endian,
1811
1862
* which is true in practice, and much simpler.
@@ -1916,6 +1967,7 @@ if ("object" === typeof module) {
1916
1967
1917
1968
/** @typedef {Number } Float64 */
1918
1969
/** @typedef {Number } Uint8 */
1970
+ /** @typedef {Number } Uint16 */
1919
1971
/** @typedef {Number } Uint32 */
1920
1972
/** @typedef {Number } Uint53 */
1921
1973
/** @typedef {String } Hex */
@@ -1952,11 +2004,13 @@ if ("object" === typeof module) {
1952
2004
1953
2005
/**
1954
2006
* @typedef TxInfo
2007
+ * @prop {Uint16 } [version]
2008
+ * @prop {Uint16 } [type]
1955
2009
* @prop {Array<TxInputForSig> } inputs
1956
- * @prop {Uint32 } [locktime] - 0 by default
1957
2010
* @prop {Array<TxOutput> } outputs
1958
- * @prop {Uint32 } [version]
1959
- * @prop {String } [transaction] - signed transaction hex
2011
+ * @prop {Uint32 } [locktime] - 0 by default
2012
+ * @prop {Hex } [extraPayload] - extra payload bytes
2013
+ * @prop {Hex } [transaction] - signed transaction hex
1960
2014
* @prop {Boolean } [_debug] - bespoke debug output
1961
2015
*/
1962
2016
@@ -1970,10 +2024,12 @@ if ("object" === typeof module) {
1970
2024
1971
2025
/**
1972
2026
* @typedef TxInfoSigned
2027
+ * @prop {Uint16 } version
2028
+ * @prop {Uint16 } type
1973
2029
* @prop {Array<TxInputSigned> } inputs
1974
- * @prop {Uint32 } locktime - 0 by default
1975
2030
* @prop {Array<TxOutput> } outputs
1976
- * @prop {Uint32 } version
2031
+ * @prop {Uint32 } locktime - 0 by default
2032
+ * @prop {Hex } extraPayload - extra payload bytes
1977
2033
* @prop {String } transaction - signed transaction hex
1978
2034
* @prop {Boolean } [_debug] - bespoke debug output
1979
2035
*/
@@ -2126,9 +2182,12 @@ if ("object" === typeof module) {
2126
2182
/**
2127
2183
* @callback TxCreateRaw
2128
2184
* @param {Object } opts
2185
+ * @param {Uint16 } [opts.version]
2186
+ * @param {Uint16 } [opts.type]
2129
2187
* @param {Array<TxInputRaw> } opts.inputs
2130
2188
* @param {Array<TxOutput> } opts.outputs
2131
- * @param {Uint32 } [opts.version]
2189
+ * @param {Uint32 } [opts.locktime]
2190
+ * @param {Hex } [opts.extraPayload]
2132
2191
* @param {Boolean } [opts._debug] - bespoke debug output
2133
2192
*/
2134
2193
@@ -2141,9 +2200,12 @@ if ("object" === typeof module) {
2141
2200
/**
2142
2201
* @callback TxCreateSigned
2143
2202
* @param {Object } opts
2203
+ * @param {Uint16 } [opts.version]
2204
+ * @param {Uint16 } [opts.type]
2144
2205
* @param {Array<TxInputSigned> } opts.inputs
2145
2206
* @param {Array<TxOutput> } opts.outputs
2146
- * @param {Uint32 } [opts.version]
2207
+ * @param {Uint32 } [opts.locktime]
2208
+ * @param {Hex } [opts.extraPayload]
2147
2209
* @param {Boolean } [opts._debug] - bespoke debug output
2148
2210
* xparam {String} [opts.sigHashType] - hex, typically 01 (ALL)
2149
2211
*/
@@ -2251,21 +2313,25 @@ if ("object" === typeof module) {
2251
2313
/**
2252
2314
* @callback TxSerialize
2253
2315
* @param {Object } txInfo
2316
+ * @param {Uint16 } [txInfo.version]
2317
+ * @param {Uint16 } [txInfo.type]
2254
2318
* @param {Array<TxInputRaw|TxInputForSig|TxInputSigned> } txInfo.inputs
2255
- * @param {Uint32 } [txInfo.locktime]
2256
2319
* @param {Array<TxOutput> } txInfo.outputs
2257
- * @param {Uint32 } [txInfo.version]
2320
+ * @param {Uint32 } [txInfo.locktime]
2321
+ * @param {Hex? } [txInfo.extraPayload] - extra payload
2258
2322
* @param {Boolean } [txInfo._debug] - bespoke debug output
2259
2323
* @param {Uint32 } [sigHashType]
2260
2324
*/
2261
2325
2262
2326
/**
2263
2327
* @callback TxSerializeForSig
2264
2328
* @param {Object } txInfo
2329
+ * @param {Uint16 } [txInfo.version]
2330
+ * @param {Uint16 } [txInfo.type]
2265
2331
* @param {Array<TxInputRaw|TxInputForSig> } txInfo.inputs
2266
2332
* @param {Uint32 } [txInfo.locktime]
2267
2333
* @param {Array<TxOutput> } txInfo.outputs
2268
- * @param {Uint32 } [txInfo.version]
2334
+ * @param {Hex? } [txInfo.extraPayload] - extra payload
2269
2335
* @param {Boolean } [txInfo._debug] - bespoke debug output
2270
2336
* @param {Uint32 } sigHashType
2271
2337
*/
0 commit comments