@@ -89,6 +89,7 @@ var DashTx = ("object" === typeof module && exports) || {};
89
89
let TxUtils = { } ;
90
90
91
91
const CURRENT_VERSION = 3 ;
92
+ const TYPE_VERSION = 0 ;
92
93
const SATOSHIS = 100000000 ;
93
94
94
95
const MAX_U8 = Math . pow ( 2 , 8 ) - 1 ;
@@ -143,11 +144,13 @@ var DashTx = ("object" === typeof module && exports) || {};
143
144
Tx . LEGACY_DUST = 2000 ;
144
145
145
146
Tx . _HEADER_ONLY_SIZE =
146
- 4 + // version
147
+ 2 + // version
148
+ 2 + // type
147
149
4 ; // locktime
148
150
149
151
Tx . HEADER_SIZE =
150
- 4 + // version
152
+ 2 + // version
153
+ 2 + // type
151
154
1 + // input count
152
155
1 + // output count
153
156
4 ; // locktime
@@ -307,11 +310,13 @@ var DashTx = ("object" === typeof module && exports) || {};
307
310
308
311
/** @type {TxInfoSigned } */
309
312
let txInfoSigned = {
313
+ version : txInfo . version || CURRENT_VERSION ,
314
+ type : txInfo . type || TYPE_VERSION ,
310
315
/** @type {Array<TxInputSigned> } */
311
316
inputs : [ ] ,
312
317
outputs : txInfo . outputs ,
313
- version : txInfo . version || CURRENT_VERSION ,
314
318
locktime : txInfo . locktime || 0x00 ,
319
+ extraPayload : txInfo . extraPayload || "" ,
315
320
transaction : "" ,
316
321
} ;
317
322
@@ -694,9 +699,10 @@ var DashTx = ("object" === typeof module && exports) || {};
694
699
* or the largest available coins until that total is met.
695
700
*/
696
701
//@ts -ignore - TODO update typedefs
697
- Tx . createLegacyTx = function ( coins , outputs , changeOutput ) {
702
+ Tx . createLegacyTx = function ( coins , outputs , changeOutput , extraPayload ) {
698
703
// TODO bump to 4 for DIP: enforce tx hygiene
699
704
let version = CURRENT_VERSION ;
705
+ let type = TYPE_VERSION ;
700
706
701
707
coins = coins . slice ( 0 ) ;
702
708
outputs = outputs . slice ( 0 ) ;
@@ -780,10 +786,12 @@ var DashTx = ("object" === typeof module && exports) || {};
780
786
781
787
let txInfo = {
782
788
version,
789
+ type,
783
790
inputs,
784
791
outputs,
785
792
changeIndex,
786
793
locktime,
794
+ extraPayload,
787
795
} ;
788
796
// let change = txInfo.outputs[txInfo.changeIndex];
789
797
@@ -1127,9 +1135,11 @@ var DashTx = ("object" === typeof module && exports) || {};
1127
1135
Tx . serialize = function (
1128
1136
{
1129
1137
version = CURRENT_VERSION ,
1138
+ type = TYPE_VERSION ,
1130
1139
inputs,
1131
- locktime = 0x0 ,
1132
1140
outputs,
1141
+ locktime = 0x0 ,
1142
+ extraPayload = "" ,
1133
1143
/* maxFee = 10000, */
1134
1144
_debug = false ,
1135
1145
} ,
@@ -1142,22 +1152,29 @@ var DashTx = ("object" === typeof module && exports) || {};
1142
1152
1143
1153
/** @type Array<String> */
1144
1154
let tx = [ ] ;
1145
- let v = TxUtils . _toUint32LE ( version ) ;
1155
+ let v = TxUtils . _toUint16LE ( version ) ;
1146
1156
tx . push ( v ) ;
1157
+ let t = TxUtils . _toUint16LE ( type ) ;
1158
+ tx . push ( t ) ;
1147
1159
1148
1160
void Tx . serializeInputs ( inputs , { _tx : tx , _sep : _sep } ) ;
1149
1161
void Tx . serializeOutputs ( outputs , { _tx : tx , _sep : _sep } ) ;
1150
1162
1151
1163
let locktimeHex = TxUtils . _toUint32LE ( locktime ) ;
1152
1164
tx . push ( locktimeHex ) ;
1153
1165
1154
- let txHex = tx . join ( _sep ) ;
1166
+ if ( extraPayload ) {
1167
+ let nExtraPayload = Tx . utils . toVarInt ( extraPayload . length / 2 ) ;
1168
+ tx . push ( nExtraPayload ) ;
1169
+ tx . push ( extraPayload ) ;
1170
+ }
1155
1171
1156
1172
if ( sigHashType ) {
1157
1173
let sigHashTypeHex = TxUtils . _toUint32LE ( sigHashType ) ;
1158
- txHex = ` ${ txHex } ${ sigHashTypeHex } ` ;
1174
+ tx . push ( sigHashTypeHex ) ;
1159
1175
}
1160
1176
1177
+ let txHex = tx . join ( _sep ) ;
1161
1178
return txHex ;
1162
1179
} ;
1163
1180
//@ts -ignore - same function, but typed and documented separately for clarity
@@ -1466,10 +1483,15 @@ var DashTx = ("object" === typeof module && exports) || {};
1466
1483
1467
1484
tx . offset = 0 ;
1468
1485
1469
- tx . versionHex = hex . substr ( tx . offset , 8 ) ;
1486
+ tx . versionHex = hex . substr ( tx . offset , 4 ) ;
1470
1487
let versionHexRev = Tx . utils . reverseHex ( tx . versionHex ) ;
1471
1488
tx . version = parseInt ( versionHexRev , 16 ) ;
1472
- tx . offset += 8 ;
1489
+ tx . offset += 4 ;
1490
+
1491
+ tx . typeHex = hex . substr ( tx . offset , 4 ) ;
1492
+ let typeHexRev = Tx . utils . reverseHex ( tx . typeHex ) ;
1493
+ tx . type = parseInt ( typeHexRev , 16 ) ;
1494
+ tx . offset += 4 ;
1473
1495
1474
1496
let [ numInputs , numInputsSize ] = TxUtils . _parseVarIntHex ( hex , tx . offset ) ;
1475
1497
tx . offset += numInputsSize ;
@@ -1638,10 +1660,26 @@ var DashTx = ("object" === typeof module && exports) || {};
1638
1660
tx . locktime = parseInt ( locktimeHexRev , 16 ) ;
1639
1661
tx . offset += 8 ;
1640
1662
1663
+ tx . extraPayloadSizeHex = "" ;
1664
+ /** @type {Uint8? } */
1665
+ tx . extraPayloadSize = null ;
1666
+ tx . extraPayloadHex = "" ;
1667
+ if ( tx . type > 0 ) {
1668
+ // TODO varint
1669
+ tx . extraPayloadSizeHex = hex . substr ( tx . offset , 2 ) ;
1670
+ tx . extraPayloadSize = parseInt ( tx . extraPayloadSizeHex , 16 ) ;
1671
+ tx . offset += 2 ;
1672
+
1673
+ tx . extraPayloadHex = hex . substr ( tx . offset , 2 * tx . extraPayloadSize ) ;
1674
+ tx . offset += 2 * tx . extraPayloadSize ;
1675
+ }
1676
+
1641
1677
tx . sigHashTypeHex = hex . substr ( tx . offset ) ;
1642
1678
if ( tx . sigHashTypeHex ) {
1643
- tx . sigHashType = parseInt ( tx . sigHashTypeHex . slice ( 0 , 2 ) ) ;
1644
- hex = hex . slice ( 0 , - 8 ) ;
1679
+ let firstLEIntByte = tx . sigHashTypeHex . slice ( 0 , 2 ) ;
1680
+ tx . sigHashType = parseInt ( firstLEIntByte ) ;
1681
+ let fullLEIntHexSize = 8 ;
1682
+ hex = hex . slice ( 0 , - fullLEIntHexSize ) ; // but the size is actually 4 bytes
1645
1683
}
1646
1684
1647
1685
tx . size = hex . length / 2 ;
@@ -1806,6 +1844,18 @@ var DashTx = ("object" === typeof module && exports) || {};
1806
1844
throw err ;
1807
1845
} ;
1808
1846
1847
+ /**
1848
+ * Just assumes that all target CPUs are Little-Endian,
1849
+ * which is true in practice, and much simpler.
1850
+ * @param {BigInt|Number } n - 16-bit positive int to encode
1851
+ */
1852
+ TxUtils . _toUint16LE = function ( n ) {
1853
+ let hexLE = TxUtils . _toUint32LE ( n ) ;
1854
+ // ex: 03000800 => 0300
1855
+ hexLE = hexLE . slice ( 0 , 4 ) ;
1856
+ return hexLE ;
1857
+ } ;
1858
+
1809
1859
/**
1810
1860
* Just assumes that all target CPUs are Little-Endian,
1811
1861
* which is true in practice, and much simpler.
@@ -1916,6 +1966,7 @@ if ("object" === typeof module) {
1916
1966
1917
1967
/** @typedef {Number } Float64 */
1918
1968
/** @typedef {Number } Uint8 */
1969
+ /** @typedef {Number } Uint16 */
1919
1970
/** @typedef {Number } Uint32 */
1920
1971
/** @typedef {Number } Uint53 */
1921
1972
/** @typedef {String } Hex */
@@ -1953,11 +2004,13 @@ if ("object" === typeof module) {
1953
2004
1954
2005
/**
1955
2006
* @typedef TxInfo
2007
+ * @prop {Uint16 } [version]
2008
+ * @prop {Uint16 } [type]
1956
2009
* @prop {Array<TxInputForSig> } inputs
1957
- * @prop {Uint32 } [locktime] - 0 by default
1958
2010
* @prop {Array<TxOutput> } outputs
1959
- * @prop {Uint32 } [version]
1960
- * @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
1961
2014
* @prop {Boolean } [_debug] - bespoke debug output
1962
2015
*/
1963
2016
@@ -1971,10 +2024,12 @@ if ("object" === typeof module) {
1971
2024
1972
2025
/**
1973
2026
* @typedef TxInfoSigned
2027
+ * @prop {Uint16 } version
2028
+ * @prop {Uint16 } type
1974
2029
* @prop {Array<TxInputSigned> } inputs
1975
- * @prop {Uint32 } locktime - 0 by default
1976
2030
* @prop {Array<TxOutput> } outputs
1977
- * @prop {Uint32 } version
2031
+ * @prop {Uint32 } locktime - 0 by default
2032
+ * @prop {Hex } extraPayload - extra payload bytes
1978
2033
* @prop {String } transaction - signed transaction hex
1979
2034
* @prop {Boolean } [_debug] - bespoke debug output
1980
2035
*/
@@ -2127,9 +2182,12 @@ if ("object" === typeof module) {
2127
2182
/**
2128
2183
* @callback TxCreateRaw
2129
2184
* @param {Object } opts
2185
+ * @param {Uint16 } [opts.version]
2186
+ * @param {Uint16 } [opts.type]
2130
2187
* @param {Array<TxInputRaw> } opts.inputs
2131
2188
* @param {Array<TxOutput> } opts.outputs
2132
- * @param {Uint32 } [opts.version]
2189
+ * @param {Uint32 } [opts.locktime]
2190
+ * @param {Hex } [opts.extraPayload]
2133
2191
* @param {Boolean } [opts._debug] - bespoke debug output
2134
2192
*/
2135
2193
@@ -2142,9 +2200,12 @@ if ("object" === typeof module) {
2142
2200
/**
2143
2201
* @callback TxCreateSigned
2144
2202
* @param {Object } opts
2203
+ * @param {Uint16 } [opts.version]
2204
+ * @param {Uint16 } [opts.type]
2145
2205
* @param {Array<TxInputSigned> } opts.inputs
2146
2206
* @param {Array<TxOutput> } opts.outputs
2147
- * @param {Uint32 } [opts.version]
2207
+ * @param {Uint32 } [opts.locktime]
2208
+ * @param {Hex } [opts.extraPayload]
2148
2209
* @param {Boolean } [opts._debug] - bespoke debug output
2149
2210
* xparam {String} [opts.sigHashType] - hex, typically 01 (ALL)
2150
2211
*/
@@ -2252,21 +2313,25 @@ if ("object" === typeof module) {
2252
2313
/**
2253
2314
* @callback TxSerialize
2254
2315
* @param {Object } txInfo
2316
+ * @param {Uint16 } [txInfo.version]
2317
+ * @param {Uint16 } [txInfo.type]
2255
2318
* @param {Array<TxInputRaw|TxInputForSig|TxInputSigned> } txInfo.inputs
2256
- * @param {Uint32 } [txInfo.locktime]
2257
2319
* @param {Array<TxOutput> } txInfo.outputs
2258
- * @param {Uint32 } [txInfo.version]
2320
+ * @param {Uint32 } [txInfo.locktime]
2321
+ * @param {Hex? } [txInfo.extraPayload] - extra payload
2259
2322
* @param {Boolean } [txInfo._debug] - bespoke debug output
2260
2323
* @param {Uint32 } [sigHashType]
2261
2324
*/
2262
2325
2263
2326
/**
2264
2327
* @callback TxSerializeForSig
2265
2328
* @param {Object } txInfo
2329
+ * @param {Uint16 } [txInfo.version]
2330
+ * @param {Uint16 } [txInfo.type]
2266
2331
* @param {Array<TxInputRaw|TxInputForSig> } txInfo.inputs
2267
2332
* @param {Uint32 } [txInfo.locktime]
2268
2333
* @param {Array<TxOutput> } txInfo.outputs
2269
- * @param {Uint32 } [txInfo.version]
2334
+ * @param {Hex? } [txInfo.extraPayload] - extra payload
2270
2335
* @param {Boolean } [txInfo._debug] - bespoke debug output
2271
2336
* @param {Uint32 } sigHashType
2272
2337
*/
0 commit comments