UNPKG

5.15 kBJavaScriptView Raw
1/*
2 * Transaction Input
3 * =================
4 *
5 * An input to a transaction. The way you probably want to use this is through
6 * the convenient method of new TxIn(txHashBuf, txOutNum, script, nSequence) (i.e., you
7 * can leave out the scriptVi, which is computed automatically if you leave it
8 * out.)
9 */
10'use strict'
11
12import { Bw } from './bw'
13import { VarInt } from './var-int'
14import { OpCode } from './op-code'
15import { Script } from './script'
16import { Struct } from './struct'
17
18class TxIn extends Struct {
19 constructor (txHashBuf, txOutNum, scriptVi, script, nSequence = 0xffffffff) {
20 super({ txHashBuf, txOutNum, scriptVi, script, nSequence })
21 }
22
23 setScript (script) {
24 this.scriptVi = VarInt.fromNumber(script.toBuffer().length)
25 this.script = script
26 return this
27 }
28
29 fromProperties (txHashBuf, txOutNum, script, nSequence) {
30 this.fromObject({ txHashBuf, txOutNum, nSequence })
31 this.setScript(script)
32 return this
33 }
34
35 static fromProperties (txHashBuf, txOutNum, script, nSequence) {
36 return new this().fromProperties(txHashBuf, txOutNum, script, nSequence)
37 }
38
39 fromJSON (json) {
40 this.fromObject({
41 txHashBuf:
42 typeof json.txHashBuf !== 'undefined'
43 ? Buffer.from(json.txHashBuf, 'hex')
44 : undefined,
45 txOutNum: json.txOutNum,
46 scriptVi:
47 typeof json.scriptVi !== 'undefined'
48 ? VarInt.fromJSON(json.scriptVi)
49 : undefined,
50 script:
51 typeof json.script !== 'undefined'
52 ? Script.fromJSON(json.script)
53 : undefined,
54 nSequence: json.nSequence
55 })
56 return this
57 }
58
59 toJSON () {
60 return {
61 txHashBuf:
62 typeof this.txHashBuf !== 'undefined'
63 ? this.txHashBuf.toString('hex')
64 : undefined,
65 txOutNum: this.txOutNum,
66 scriptVi:
67 typeof this.scriptVi !== 'undefined'
68 ? this.scriptVi.toJSON()
69 : undefined,
70 script:
71 typeof this.script !== 'undefined' ? this.script.toJSON() : undefined,
72 nSequence: this.nSequence
73 }
74 }
75
76 fromBr (br) {
77 this.txHashBuf = br.read(32)
78 this.txOutNum = br.readUInt32LE()
79 this.scriptVi = VarInt.fromBuffer(br.readVarIntBuf())
80 this.script = Script.fromBuffer(br.read(this.scriptVi.toNumber()))
81 this.nSequence = br.readUInt32LE()
82 return this
83 }
84
85 toBw (bw) {
86 if (!bw) {
87 bw = new Bw()
88 }
89 bw.write(this.txHashBuf)
90 bw.writeUInt32LE(this.txOutNum)
91 bw.write(this.scriptVi.buf)
92 bw.write(this.script.toBuffer())
93 bw.writeUInt32LE(this.nSequence)
94 return bw
95 }
96
97 /**
98 * Generate txIn with blank signatures from a txOut and its
99 * txHashBuf+txOutNum. A "blank" signature is just an OP_0. The pubKey also
100 * defaults to blank but can be substituted with the real public key if you
101 * know what it is.
102 */
103 fromPubKeyHashTxOut (txHashBuf, txOutNum, txOut, pubKey) {
104 const script = new Script()
105 if (txOut.script.isPubKeyHashOut()) {
106 script.writeOpCode(OpCode.OP_0) // blank signature
107 if (pubKey) {
108 script.writeBuffer(pubKey.toBuffer())
109 } else {
110 script.writeOpCode(OpCode.OP_0)
111 }
112 } else {
113 throw new Error('txOut must be of type pubKeyHash')
114 }
115 this.txHashBuf = txHashBuf
116 this.txOutNum = txOutNum
117 this.setScript(script)
118 return this
119 }
120
121 hasNullInput () {
122 const hex = this.txHashBuf.toString('hex')
123 if (
124 hex ===
125 '0000000000000000000000000000000000000000000000000000000000000000' &&
126 this.txOutNum === 0xffffffff
127 ) {
128 return true
129 }
130 return false
131 }
132
133 /**
134 * Analagous to bitcoind's SetNull in COutPoint
135 */
136 setNullInput () {
137 this.txHashBuf = Buffer.alloc(32)
138 this.txHashBuf.fill(0)
139 this.txOutNum = 0xffffffff // -1 cast to unsigned int
140 }
141}
142
143/* Interpret sequence numbers as relative lock-time constraints. */
144TxIn.LOCKTIME_VERIFY_SEQUENCE = 1 << 0
145
146/* Setting nSequence to this value for every input in a transaction disables
147 * nLockTime. */
148TxIn.SEQUENCE_FINAL = 0xffffffff
149
150/* Below flags apply in the context of Bip 68 */
151/* If this flag set, txIn.nSequence is NOT interpreted as a relative lock-time.
152 * */
153TxIn.SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31
154
155/* If txIn.nSequence encodes a relative lock-time and this flag is set, the
156 * relative lock-time has units of 512 seconds, otherwise it specifies blocks
157 * with a granularity of 1. */
158TxIn.SEQUENCE_LOCKTIME_TYPE_FLAG = 1 << 22
159
160/* If txIn.nSequence encodes a relative lock-time, this mask is applied to
161 * extract that lock-time from the sequence field. */
162TxIn.SEQUENCE_LOCKTIME_MASK = 0x0000ffff
163
164/* In order to use the same number of bits to encode roughly the same
165 * wall-clock duration, and because blocks are naturally limited to occur
166 * every 600s on average, the minimum granularity for time-based relative
167 * lock-time is fixed at 512 seconds. Converting from CTxIn::nSequence to
168 * seconds is performed by multiplying by 512 = 2^9, or equivalently
169 * shifting up by 9 bits. */
170TxIn.SEQUENCE_LOCKTIME_GRANULARITY = 9
171
172export { TxIn }