1 // Package tx is the transaction the wallet builds and the id it is known by.
2 //
3 // Only the parts a signer needs are here: an unsigned transaction, its non-witness
4 // serialisation (which is what a txid is), and the same transaction with witnesses once it has
5 // been signed. The wire form and the txid are pinned against a transaction the rig node built,
6 // because a serialiser that is one byte wrong is a different transaction with a different id.
7 package tx
8 9 import (
10 "crypto/sha256"
11 "encoding/binary"
12 "encoding/hex"
13 "errors"
14 )
15 16 // Errors the builder refuses.
17 var (
18 // ErrNoInputs is a transaction that spends nothing.
19 ErrNoInputs = errors.New("tx: a transaction needs an input")
20 // ErrNoOutputs is a transaction that pays nobody.
21 ErrNoOutputs = errors.New("tx: a transaction needs an output")
22 // ErrTooMany is a count that does not fit a compact size.
23 ErrTooMany = errors.New("tx: too many entries")
24 // ErrScriptTooLong is an output script that cannot be length-prefixed in the usual form.
25 ErrScriptTooLong = errors.New("tx: the output script is too long")
26 )
27 28 // Version is the transaction version the wallet writes. BIP68 relative locktimes need 2.
29 const Version uint32 = 2
30 31 // SequenceFinal is a sequence number that makes a locktime usable and a relative locktime
32 // meaningless, which is what a cooperative spend wants.
33 const SequenceFinal uint32 = 0xffffffff
34 35 // Outpoint names one output of one transaction.
36 type Outpoint struct {
37 // Hash is the transaction id, in its wire order (the reverse of the displayed hex).
38 Hash [32]byte
39 // Index is the output's position in that transaction.
40 Index uint32
41 }
42 43 // Input spends one outpoint.
44 type Input struct {
45 // Outpoint is what it spends.
46 Outpoint
47 // ScriptSig is the unlocking script. It is empty for a segwit spend.
48 ScriptSig []byte
49 // Sequence is the input's sequence number.
50 Sequence uint32
51 // Witness is the stack, in push order, deepest first. It is empty until signed.
52 Witness [][]byte
53 }
54 55 // Output pays an amount to a script.
56 type Output struct {
57 // Value is the amount in satoshis.
58 Value uint64
59 // Script is the scriptPubKey.
60 Script []byte
61 }
62 63 // Tx is one transaction.
64 type Tx struct {
65 // Version is the transaction version.
66 Version uint32
67 // Inputs spend.
68 Inputs []Input
69 // Outputs pay.
70 Outputs []Output
71 // LockTime is the transaction's absolute locktime.
72 LockTime uint32
73 }
74 75 // New starts a transaction with the wallet's version.
76 func New() *Tx { return &Tx{Version: Version} }
77 78 // AddInput spends an outpoint.
79 func (t *Tx) AddInput(outpoint Outpoint, sequence uint32) {
80 t.Inputs = append(t.Inputs, Input{Outpoint: outpoint, Sequence: sequence})
81 }
82 83 // AddOutput pays a script.
84 func (t *Tx) AddOutput(value uint64, script []byte) {
85 t.Outputs = append(t.Outputs, Output{Value: value, Script: script})
86 }
87 88 // Serialize is the non-witness form: version, inputs, outputs, locktime.
89 //
90 // This is the form a txid is hashed from, and the form a legacy sighash commits to. A segwit
91 // transaction is serialised with witnesses for the wire but is still identified by this.
92 func (t *Tx) Serialize() ([]byte, error) {
93 if len(t.Inputs) == 0 {
94 return nil, ErrNoInputs
95 }
96 97 if len(t.Outputs) == 0 {
98 return nil, ErrNoOutputs
99 }
100 101 out := make([]byte, 0, 128)
102 103 out = binary.LittleEndian.AppendUint32(out, t.Version)
104 out = appendCompactSize(out, len(t.Inputs))
105 106 for _, input := range t.Inputs {
107 if len(input.ScriptSig) > 0xffff {
108 return nil, ErrScriptTooLong
109 }
110 111 out = append(out, input.Hash[:]...)
112 out = binary.LittleEndian.AppendUint32(out, input.Index)
113 out = appendCompactSize(out, len(input.ScriptSig))
114 out = append(out, input.ScriptSig...)
115 out = binary.LittleEndian.AppendUint32(out, input.Sequence)
116 }
117 118 out = appendCompactSize(out, len(t.Outputs))
119 120 for _, output := range t.Outputs {
121 if len(output.Script) > 0xffff {
122 return nil, ErrScriptTooLong
123 }
124 125 out = binary.LittleEndian.AppendUint64(out, output.Value)
126 out = appendCompactSize(out, len(output.Script))
127 out = append(out, output.Script...)
128 }
129 130 return binary.LittleEndian.AppendUint32(out, t.LockTime), nil
131 }
132 133 // SerializeWitness is the wire form once there are witnesses.
134 //
135 // The marker and flag are only written when at least one input has a witness: a transaction
136 // with none is not a segwit transaction, and writing the marker anyway is a different
137 // serialisation that a node would reject.
138 func (t *Tx) SerializeWitness() ([]byte, error) {
139 base, err := t.Serialize()
140 141 if err != nil {
142 return nil, err
143 }
144 145 any := false
146 147 for _, input := range t.Inputs {
148 if len(input.Witness) > 0 {
149 any = true
150 151 break
152 }
153 }
154 155 if !any {
156 return base, nil
157 }
158 159 out := make([]byte, 0, len(base)+128)
160 161 out = binary.LittleEndian.AppendUint32(out, t.Version)
162 out = append(out, 0x00, 0x01)
163 out = appendCompactSize(out, len(t.Inputs))
164 165 for _, input := range t.Inputs {
166 out = append(out, input.Hash[:]...)
167 out = binary.LittleEndian.AppendUint32(out, input.Index)
168 out = appendCompactSize(out, len(input.ScriptSig))
169 out = append(out, input.ScriptSig...)
170 out = binary.LittleEndian.AppendUint32(out, input.Sequence)
171 }
172 173 out = appendCompactSize(out, len(t.Outputs))
174 175 for _, output := range t.Outputs {
176 out = binary.LittleEndian.AppendUint64(out, output.Value)
177 out = appendCompactSize(out, len(output.Script))
178 out = append(out, output.Script...)
179 }
180 181 for _, input := range t.Inputs {
182 out = appendCompactSize(out, len(input.Witness))
183 184 for _, item := range input.Witness {
185 out = appendCompactSize(out, len(item))
186 out = append(out, item...)
187 }
188 }
189 190 return binary.LittleEndian.AppendUint32(out, t.LockTime), nil
191 }
192 193 // TxID is the double SHA-256 of the non-witness serialisation, in wire order.
194 func (t *Tx) TxID() ([32]byte, error) {
195 raw, err := t.Serialize()
196 197 if err != nil {
198 return [32]byte{}, err
199 }
200 201 first := sha256.Sum256(raw)
202 203 return sha256.Sum256(first[:]), nil
204 }
205 206 // TxIDHex is the id as a person sees it: reversed, because the hash is stored in wire order.
207 func (t *Tx) TxIDHex() (string, error) {
208 id, err := t.TxID()
209 210 if err != nil {
211 return "", err
212 }
213 214 reversed := make([]byte, len(id))
215 216 for index := range id {
217 reversed[len(id)-1-index] = id[index]
218 }
219 220 return hex.EncodeToString(reversed), nil
221 }
222 223 // Hex is the wire form, witnesses and all.
224 func (t *Tx) Hex() (string, error) {
225 raw, err := t.SerializeWitness()
226 227 if err != nil {
228 return "", err
229 }
230 231 return hex.EncodeToString(raw), nil
232 }
233 234 // appendCompactSize writes Bitcoin's compact size integer.
235 func appendCompactSize(out []byte, value int) []byte {
236 switch {
237 case value < 0xfd:
238 return append(out, byte(value))
239 case value <= 0xffff:
240 return append(out, 0xfd, byte(value), byte(value>>8))
241 case value <= 0xffffffff:
242 return append(out, 0xfe, byte(value), byte(value>>8), byte(value>>16), byte(value>>24))
243 }
244 245 return append(out, 0xff, byte(value), byte(uint64(value)>>8), byte(uint64(value)>>16),
246 byte(uint64(value)>>24), byte(uint64(value)>>32), byte(uint64(value)>>40),
247 byte(uint64(value)>>48), byte(uint64(value)>>56))
248 }
249