@@ -89,6 +89,7 @@ var DashTx = ("object" === typeof module && exports) || {};
8989 let TxUtils = { } ;
9090
9191 const CURRENT_VERSION = 3 ;
92+ const TYPE_VERSION = 0 ;
9293 const SATOSHIS = 100000000 ;
9394
9495 const MAX_U8 = Math . pow ( 2 , 8 ) - 1 ;
@@ -143,11 +144,13 @@ var DashTx = ("object" === typeof module && exports) || {};
143144 Tx . LEGACY_DUST = 2000 ;
144145
145146 Tx . _HEADER_ONLY_SIZE =
146- 4 + // version
147+ 2 + // version
148+ 2 + // type
147149 4 ; // locktime
148150
149151 Tx . HEADER_SIZE =
150- 4 + // version
152+ 2 + // version
153+ 2 + // type
151154 1 + // input count
152155 1 + // output count
153156 4 ; // locktime
@@ -307,11 +310,13 @@ var DashTx = ("object" === typeof module && exports) || {};
307310
308311 /** @type {TxInfoSigned } */
309312 let txInfoSigned = {
313+ version : txInfo . version || CURRENT_VERSION ,
314+ type : txInfo . type || TYPE_VERSION ,
310315 /** @type {Array<TxInputSigned> } */
311316 inputs : [ ] ,
312317 outputs : txInfo . outputs ,
313- version : txInfo . version || CURRENT_VERSION ,
314318 locktime : txInfo . locktime || 0x00 ,
319+ extraPayload : txInfo . extraPayload || "" ,
315320 transaction : "" ,
316321 } ;
317322
@@ -694,9 +699,10 @@ var DashTx = ("object" === typeof module && exports) || {};
694699 * or the largest available coins until that total is met.
695700 */
696701 //@ts -ignore - TODO update typedefs
697- Tx . createLegacyTx = function ( coins , outputs , changeOutput ) {
702+ Tx . createLegacyTx = function ( coins , outputs , changeOutput , extraPayload ) {
698703 // TODO bump to 4 for DIP: enforce tx hygiene
699704 let version = CURRENT_VERSION ;
705+ let type = TYPE_VERSION ;
700706
701707 coins = coins . slice ( 0 ) ;
702708 outputs = outputs . slice ( 0 ) ;
@@ -780,10 +786,12 @@ var DashTx = ("object" === typeof module && exports) || {};
780786
781787 let txInfo = {
782788 version,
789+ type,
783790 inputs,
784791 outputs,
785792 changeIndex,
786793 locktime,
794+ extraPayload,
787795 } ;
788796 // let change = txInfo.outputs[txInfo.changeIndex];
789797
@@ -1127,9 +1135,11 @@ var DashTx = ("object" === typeof module && exports) || {};
11271135 Tx . serialize = function (
11281136 {
11291137 version = CURRENT_VERSION ,
1138+ type = TYPE_VERSION ,
11301139 inputs,
1131- locktime = 0x0 ,
11321140 outputs,
1141+ locktime = 0x0 ,
1142+ extraPayload = "" ,
11331143 /* maxFee = 10000, */
11341144 _debug = false ,
11351145 } ,
@@ -1142,22 +1152,29 @@ var DashTx = ("object" === typeof module && exports) || {};
11421152
11431153 /** @type Array<String> */
11441154 let tx = [ ] ;
1145- let v = TxUtils . _toUint32LE ( version ) ;
1155+ let v = TxUtils . _toUint16LE ( version ) ;
11461156 tx . push ( v ) ;
1157+ let t = TxUtils . _toUint16LE ( type ) ;
1158+ tx . push ( t ) ;
11471159
11481160 void Tx . serializeInputs ( inputs , { _tx : tx , _sep : _sep } ) ;
11491161 void Tx . serializeOutputs ( outputs , { _tx : tx , _sep : _sep } ) ;
11501162
11511163 let locktimeHex = TxUtils . _toUint32LE ( locktime ) ;
11521164 tx . push ( locktimeHex ) ;
11531165
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+ }
11551171
11561172 if ( sigHashType ) {
11571173 let sigHashTypeHex = TxUtils . _toUint32LE ( sigHashType ) ;
1158- txHex = ` ${ txHex } ${ sigHashTypeHex } ` ;
1174+ tx . push ( sigHashTypeHex ) ;
11591175 }
11601176
1177+ let txHex = tx . join ( _sep ) ;
11611178 return txHex ;
11621179 } ;
11631180 //@ts -ignore - same function, but typed and documented separately for clarity
@@ -1466,10 +1483,15 @@ var DashTx = ("object" === typeof module && exports) || {};
14661483
14671484 tx . offset = 0 ;
14681485
1469- tx . versionHex = hex . substr ( tx . offset , 8 ) ;
1486+ tx . versionHex = hex . substr ( tx . offset , 4 ) ;
14701487 let versionHexRev = Tx . utils . reverseHex ( tx . versionHex ) ;
14711488 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 ;
14731495
14741496 let [ numInputs , numInputsSize ] = TxUtils . _parseVarIntHex ( hex , tx . offset ) ;
14751497 tx . offset += numInputsSize ;
@@ -1638,10 +1660,26 @@ var DashTx = ("object" === typeof module && exports) || {};
16381660 tx . locktime = parseInt ( locktimeHexRev , 16 ) ;
16391661 tx . offset += 8 ;
16401662
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+
16411677 tx . sigHashTypeHex = hex . substr ( tx . offset ) ;
16421678 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
16451683 }
16461684
16471685 tx . size = hex . length / 2 ;
@@ -1806,6 +1844,18 @@ var DashTx = ("object" === typeof module && exports) || {};
18061844 throw err ;
18071845 } ;
18081846
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+
18091859 /**
18101860 * Just assumes that all target CPUs are Little-Endian,
18111861 * which is true in practice, and much simpler.
@@ -1916,6 +1966,7 @@ if ("object" === typeof module) {
19161966
19171967/** @typedef {Number } Float64 */
19181968/** @typedef {Number } Uint8 */
1969+ /** @typedef {Number } Uint16 */
19191970/** @typedef {Number } Uint32 */
19201971/** @typedef {Number } Uint53 */
19211972/** @typedef {String } Hex */
@@ -1953,11 +2004,13 @@ if ("object" === typeof module) {
19532004
19542005/**
19552006 * @typedef TxInfo
2007+ * @prop {Uint16 } [version]
2008+ * @prop {Uint16 } [type]
19562009 * @prop {Array<TxInputForSig> } inputs
1957- * @prop {Uint32 } [locktime] - 0 by default
19582010 * @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
19612014 * @prop {Boolean } [_debug] - bespoke debug output
19622015 */
19632016
@@ -1971,10 +2024,12 @@ if ("object" === typeof module) {
19712024
19722025/**
19732026 * @typedef TxInfoSigned
2027+ * @prop {Uint16 } version
2028+ * @prop {Uint16 } type
19742029 * @prop {Array<TxInputSigned> } inputs
1975- * @prop {Uint32 } locktime - 0 by default
19762030 * @prop {Array<TxOutput> } outputs
1977- * @prop {Uint32 } version
2031+ * @prop {Uint32 } locktime - 0 by default
2032+ * @prop {Hex } extraPayload - extra payload bytes
19782033 * @prop {String } transaction - signed transaction hex
19792034 * @prop {Boolean } [_debug] - bespoke debug output
19802035 */
@@ -2127,9 +2182,12 @@ if ("object" === typeof module) {
21272182/**
21282183 * @callback TxCreateRaw
21292184 * @param {Object } opts
2185+ * @param {Uint16 } [opts.version]
2186+ * @param {Uint16 } [opts.type]
21302187 * @param {Array<TxInputRaw> } opts.inputs
21312188 * @param {Array<TxOutput> } opts.outputs
2132- * @param {Uint32 } [opts.version]
2189+ * @param {Uint32 } [opts.locktime]
2190+ * @param {Hex } [opts.extraPayload]
21332191 * @param {Boolean } [opts._debug] - bespoke debug output
21342192 */
21352193
@@ -2142,9 +2200,12 @@ if ("object" === typeof module) {
21422200/**
21432201 * @callback TxCreateSigned
21442202 * @param {Object } opts
2203+ * @param {Uint16 } [opts.version]
2204+ * @param {Uint16 } [opts.type]
21452205 * @param {Array<TxInputSigned> } opts.inputs
21462206 * @param {Array<TxOutput> } opts.outputs
2147- * @param {Uint32 } [opts.version]
2207+ * @param {Uint32 } [opts.locktime]
2208+ * @param {Hex } [opts.extraPayload]
21482209 * @param {Boolean } [opts._debug] - bespoke debug output
21492210 * xparam {String} [opts.sigHashType] - hex, typically 01 (ALL)
21502211 */
@@ -2252,21 +2313,25 @@ if ("object" === typeof module) {
22522313/**
22532314 * @callback TxSerialize
22542315 * @param {Object } txInfo
2316+ * @param {Uint16 } [txInfo.version]
2317+ * @param {Uint16 } [txInfo.type]
22552318 * @param {Array<TxInputRaw|TxInputForSig|TxInputSigned> } txInfo.inputs
2256- * @param {Uint32 } [txInfo.locktime]
22572319 * @param {Array<TxOutput> } txInfo.outputs
2258- * @param {Uint32 } [txInfo.version]
2320+ * @param {Uint32 } [txInfo.locktime]
2321+ * @param {Hex? } [txInfo.extraPayload] - extra payload
22592322 * @param {Boolean } [txInfo._debug] - bespoke debug output
22602323 * @param {Uint32 } [sigHashType]
22612324 */
22622325
22632326/**
22642327 * @callback TxSerializeForSig
22652328 * @param {Object } txInfo
2329+ * @param {Uint16 } [txInfo.version]
2330+ * @param {Uint16 } [txInfo.type]
22662331 * @param {Array<TxInputRaw|TxInputForSig> } txInfo.inputs
22672332 * @param {Uint32 } [txInfo.locktime]
22682333 * @param {Array<TxOutput> } txInfo.outputs
2269- * @param {Uint32 } [txInfo.version]
2334+ * @param {Hex? } [txInfo.extraPayload] - extra payload
22702335 * @param {Boolean } [txInfo._debug] - bespoke debug output
22712336 * @param {Uint32 } sigHashType
22722337 */
0 commit comments