1 package wire
2 3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "strconv"
8 9 "github.com/p9c/p9/pkg/chainhash"
10 )
11 12 const (
13 // TxVersion is the current latest supported transaction version.
14 TxVersion = 1
15 // MaxTxInSequenceNum is the maximum sequence number the sequence field of a transaction input can be.
16 MaxTxInSequenceNum uint32 = 0xffffffff
17 // MaxPrevOutIndex is the maximum index the index field of a previous outpoint can be.
18 MaxPrevOutIndex uint32 = 0xffffffff
19 // SequenceLockTimeDisabled is a flag that if set on a transaction input's sequence number, the sequence number will
20 // not be interpreted as a relative locktime.
21 SequenceLockTimeDisabled = 1 << 31
22 // SequenceLockTimeIsSeconds is a flag that if set on a transaction input's sequence number, the relative locktime
23 // has units of 512 seconds.
24 SequenceLockTimeIsSeconds = 1 << 22
25 // SequenceLockTimeMask is a mask that extracts the relative locktime when masked against the transaction input
26 // sequence number.
27 SequenceLockTimeMask = 0x0000ffff
28 // SequenceLockTimeGranularity is the defined time based granularity for seconds-based relative time locks. When
29 // converting from seconds to a sequence number, the value is right shifted by this amount, therefore the
30 // granularity of relative time locks in 512 or 2^9 seconds. Enforced relative lock times are multiples of 512
31 // seconds.
32 SequenceLockTimeGranularity = 9
33 // defaultTxInOutAlloc is the default size used for the backing array for transaction inputs and outputs. The array
34 // will dynamically grow as needed, but this figure is intended to provide enough space for the number of inputs and
35 // outputs in a typical transaction without needing to grow the backing array multiple times.
36 defaultTxInOutAlloc = 15
37 // minTxInPayload is the minimum payload size for a transaction input. PreviousOutPoint.Hash +
38 // PreviousOutPoint.Index 4 bytes + Varint for SignatureScript length 1 byte + Sequence 4 bytes.
39 minTxInPayload = 9 + chainhash.HashSize
40 // maxTxInPerMessage is the maximum number of transactions inputs that a transaction which fits into a message could
41 // possibly have.
42 maxTxInPerMessage = (MaxMessagePayload / minTxInPayload) + 1
43 // MinTxOutPayload is the minimum payload size for a transaction output. value 8 bytes + Varint for PkScript length
44 // 1 byte.
45 MinTxOutPayload = 9
46 // maxTxOutPerMessage is the maximum number of transactions outputs that a transaction which fits into a message
47 // could possibly have.
48 maxTxOutPerMessage = (MaxMessagePayload / MinTxOutPayload) + 1
49 // minTxPayload is the minimum payload size for a transaction. Note that any realistically usable transaction must
50 // have at least one input or output, but that is a rule enforced at a higher layer, so it is intentionally not
51 // included here. Version 4 bytes + Varint number of transaction inputs 1 byte + Varint number of transaction
52 // outputs 1 byte + LockTime 4 bytes + min input payload + min output payload.
53 minTxPayload = 10
54 // freeListMaxScriptSize is the size of each buffer in the free list that is used for deserializing scripts from the
55 // wire before they are concatenated into a single contiguous buffers. This value was chosen because it is slightly
56 // more than twice the size of the vast majority of all "standard" scripts. Larger scripts are still deserialized
57 // properly as the free list will simply be bypassed for them.
58 freeListMaxScriptSize = 1024 // 512
59 // freeListMaxItems is the number of buffers to keep in the free list to use for script deserialization. This value
60 // allows up to 100 scripts per transaction being simultaneously deserialized by 125 peers. Thus, the peak usage of
61 // the free list is 12,500 * 512 = 6,400,000 bytes.
62 freeListMaxItems = 12500
63 // // maxWitnessItemsPerInput is the maximum number of witness items to be read for
64 // // the witness data for a single TxIn. This number is derived using a possble
65 // // lower bound for the encoding of a witness item: 1 byte for length + 1 byte
66 // // for the witness item itself, or two bytes. This value is then divided by the
67 // // currently allowed maximum "cost" for a transaction.
68 // maxWitnessItemsPerInput = 500000
69 // // maxWitnessItemSize is the maximum allowed size for an item within an input's
70 // // witness data. This number is derived from the fact that for script
71 // // validation, each pushed item onto the stack must be less than 10k bytes.
72 // maxWitnessItemSize = 11000
73 )
74 75 // witnessMarkerBytes are a pair of bytes specific to the witness encoding. If
76 // this sequence is encoutered, then it indicates a transaction has iwtness
77 // data. The first byte is an always 0x00 marker byte, which allows decoders to
78 // distinguish a serialized transaction with witnesses from a regular (legacy)
79 // one. The second byte is the Flag field, which at the moment is always 0x01,
80 // but may be extended in the future to accommodate auxiliary non-committed
81 // fields.
82 var witessMarkerBytes = []byte{0x00, 0x01}
83 84 // scriptFreeList defines a free list of byte slices (up to the maximum number defined by the freeListMaxItems constant)
85 // that have a cap according to the freeListMaxScriptSize constant. It is used to provide temporary buffers for
86 // deserializing scripts in order to greatly reduce the number of allocations required. The caller can obtain a buffer
87 // from the free list by calling the Borrow function and should return it via the Return function when done using it.
88 type scriptFreeList chan []byte
89 90 // Borrow returns a byte slice from the free list with a length according the provided size. A new buffer is allocated
91 // if there are any items available. When the size is larger than the max size allowed for items on the free list a new
92 // buffer of the appropriate size is allocated and returned. It is safe to attempt to return said buffer via the Return
93 // function as it will be ignored and allowed to go the garbage collector.
94 func (c scriptFreeList) Borrow(size uint64) []byte {
95 if size > freeListMaxScriptSize {
96 return make([]byte, size)
97 }
98 var buf []byte
99 select {
100 case buf = <-c:
101 default:
102 buf = make([]byte, freeListMaxScriptSize)
103 }
104 return buf[:size]
105 }
106 107 // Return puts the provided byte slice back on the free list when it has a cap of the expected length. The buffer is
108 // expected to have been obtained via the Borrow function. Any slices that are not of the appropriate size, such as
109 // those whose size is greater than the largest allowed free list item size are simply ignored so they can go to the
110 // garbage collector.
111 func (c scriptFreeList) Return(buf []byte) {
112 // Ignore any buffers returned that aren't the expected size for the free list.
113 if cap(buf) != freeListMaxScriptSize {
114 return
115 }
116 // Return the buffer to the free list when it's not full. Otherwise let it be garbage collected.
117 select {
118 case c <- buf:
119 default:
120 // Let it go to the garbage collector.
121 }
122 }
123 124 // Create the concurrent safe free list to use for script deserialization. As described, this free list is maintained to
125 // significantly reduce the number of allocations.
126 var scriptPool scriptFreeList = make(chan []byte, freeListMaxItems)
127 128 // OutPoint defines a bitcoin data type that is used to track previous transaction outputs.
129 type OutPoint struct {
130 Hash chainhash.Hash
131 Index uint32
132 }
133 134 // NewOutPoint returns a new bitcoin transaction outpoint point with the provided hash and index.
135 func NewOutPoint(hash *chainhash.Hash, index uint32) *OutPoint {
136 return &OutPoint{
137 Hash: *hash,
138 Index: index,
139 }
140 }
141 142 // String returns the OutPoint in the human-readable form "hash:index".
143 func (o OutPoint) String() string {
144 // Allocate enough for hash string, colon, and 10 digits. Although at the time of writing, the number of digits can
145 // be no greater than the length of the decimal representation of maxTxOutPerMessage, the maximum message payload
146 // may increase in the future and this optimization may go unnoticed, so allocate space for 10 decimal digits, which
147 // will fit any uint32.
148 buf := make([]byte, 2*chainhash.HashSize+1, 2*chainhash.HashSize+1+10)
149 copy(buf, o.Hash.String())
150 buf[2*chainhash.HashSize] = ':'
151 buf = strconv.AppendUint(buf, uint64(o.Index), 10)
152 return string(buf)
153 }
154 155 // TxIn defines a bitcoin transaction input.
156 type TxIn struct {
157 PreviousOutPoint OutPoint
158 SignatureScript []byte
159 // Witness TxWitness
160 Sequence uint32
161 }
162 163 // SerializeSize returns the number of bytes it would take to serialize the the transaction input.
164 func (t *TxIn) SerializeSize() int {
165 // Outpoint Hash 32 bytes + Outpoint Index 4 bytes + Sequence 4 bytes + serialized varint size for the length of
166 // SignatureScript + SignatureScript bytes.
167 return 40 + VarIntSerializeSize(uint64(len(t.SignatureScript))) +
168 len(t.SignatureScript)
169 }
170 171 // NewTxIn returns a new bitcoin transaction input with the provided previous outpoint point and signature script with a
172 // default sequence of MaxTxInSequenceNum.
173 func NewTxIn(prevOut *OutPoint, signatureScript []byte, witness [][]byte) *TxIn {
174 return &TxIn{
175 PreviousOutPoint: *prevOut,
176 SignatureScript: signatureScript,
177 // Witness: witness,
178 Sequence: MaxTxInSequenceNum,
179 }
180 }
181 182 // TxWitness defines the witness for a TxIn. A witness is to be interpreted as a
183 // slice of byte slices, or a stack with one or many elements.
184 type TxWitness [][]byte
185 186 // SerializeSize returns the number of bytes it would take to serialize the the
187 // transaction input's witness.
188 func (t TxWitness) SerializeSize() int {
189 // A varint to signal the number of elements the witness has.
190 n := VarIntSerializeSize(uint64(len(t)))
191 // For each element in the witness, we'll need a varint to signal the size of
192 // the element, then finally the number of bytes the element itself comprises.
193 for _, witItem := range t {
194 n += VarIntSerializeSize(uint64(len(witItem)))
195 n += len(witItem)
196 }
197 return n
198 }
199 200 // TxOut defines a bitcoin transaction output.
201 type TxOut struct {
202 Value int64
203 PkScript []byte
204 }
205 206 // SerializeSize returns the number of bytes it would take to serialize the the transaction output.
207 func (t *TxOut) SerializeSize() int {
208 // value 8 bytes + serialized varint size for the length of PkScript + PkScript bytes.
209 return 8 + VarIntSerializeSize(uint64(len(t.PkScript))) + len(t.PkScript)
210 }
211 212 // NewTxOut returns a new bitcoin transaction output with the provided transaction value and public key script.
213 func NewTxOut(value int64, pkScript []byte) *TxOut {
214 return &TxOut{
215 Value: value,
216 PkScript: pkScript,
217 }
218 }
219 220 // MsgTx implements the Message interface and represents a bitcoin tx message. It is used to deliver transaction
221 // information in response to a getdata message (MsgGetData) for a given transaction. Use the AddTxIn and AddTxOut
222 // functions to podbuild up the list of transaction inputs and outputs.
223 type MsgTx struct {
224 Version int32
225 TxIn []*TxIn
226 TxOut []*TxOut
227 LockTime uint32
228 }
229 230 // AddTxIn adds a transaction input to the message.
231 func (msg *MsgTx) AddTxIn(ti *TxIn) {
232 msg.TxIn = append(msg.TxIn, ti)
233 }
234 235 // AddTxOut adds a transaction output to the message.
236 func (msg *MsgTx) AddTxOut(to *TxOut) {
237 msg.TxOut = append(msg.TxOut, to)
238 }
239 240 // TxHash generates the Hash for the transaction.
241 func (msg *MsgTx) TxHash() (out chainhash.Hash) {
242 // Encode the transaction and calculate double sha256 on the result. Ignore the error returns since the only way the
243 // encode could fail is being out of memory or due to nil pointers, both of which would cause a run-time panic.
244 buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSizeStripped()))
245 _ = msg.SerializeNoWitness(buf)
246 return chainhash.DoubleHashH(buf.Bytes())
247 }
248 249 // // WitnessHash generates the hash of the transaction serialized according to the
250 // // new witness serialization defined in BIP0141 and BIP0144. The final output is
251 // // used within the Segregated Witness commitment of all the witnesses within a
252 // // block. If a transaction has no witness data, then the witness hash, is the
253 // // same as its txid.
254 // func (msg *MsgTx) WitnessHash() chainhash.Hash {
255 // if msg.HasWitness() {
256 // buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize()))
257 // _ = msg.Serialize(buf)
258 // return chainhash.DoubleHashH(buf.Bytes())
259 // }
260 // return msg.TxHash()
261 // }
262 263 // Copy creates a deep copy of a transaction so that the original does not get modified when the copy is manipulated.
264 func (msg *MsgTx) Copy() *MsgTx {
265 // Create new tx and start by copying primitive values and making space for the transaction inputs and outputs.
266 newTx := MsgTx{
267 Version: msg.Version,
268 TxIn: make([]*TxIn, 0, len(msg.TxIn)),
269 TxOut: make([]*TxOut, 0, len(msg.TxOut)),
270 LockTime: msg.LockTime,
271 }
272 var e error
273 // Deep copy the old TxIn data.
274 for _, oldTxIn := range msg.TxIn {
275 // Deep copy the old previous outpoint.
276 oldOutPoint := oldTxIn.PreviousOutPoint
277 newOutPoint := OutPoint{}
278 if e = newOutPoint.Hash.SetBytes(oldOutPoint.Hash[:]); E.Chk(e) {
279 }
280 newOutPoint.Index = oldOutPoint.Index
281 // Deep copy the old signature script.
282 var newScript []byte
283 oldScript := oldTxIn.SignatureScript
284 oldScriptLen := len(oldScript)
285 if oldScriptLen > 0 {
286 newScript = make([]byte, oldScriptLen)
287 copy(newScript, oldScript[:oldScriptLen])
288 }
289 // Create new txIn with the deep copied data.
290 newTxIn := TxIn{
291 PreviousOutPoint: newOutPoint,
292 SignatureScript: newScript,
293 Sequence: oldTxIn.Sequence,
294 }
295 // // If the transaction is witnessy, then also copy the witnesses.
296 // if len(oldTxIn.Witness) != 0 {
297 // // Deep copy the old witness data.
298 // newTxIn.Witness = make([][]byte, len(oldTxIn.Witness))
299 // for i, oldItem := range oldTxIn.Witness {
300 // newItem := make([]byte, len(oldItem))
301 // copy(newItem, oldItem)
302 // newTxIn.Witness[i] = newItem
303 // }
304 // }
305 // Finally, append this fully copied txin.
306 newTx.TxIn = append(newTx.TxIn, &newTxIn)
307 }
308 // Deep copy the old TxOut data.
309 for _, oldTxOut := range msg.TxOut {
310 // Deep copy the old PkScript
311 var newScript []byte
312 oldScript := oldTxOut.PkScript
313 oldScriptLen := len(oldScript)
314 if oldScriptLen > 0 {
315 newScript = make([]byte, oldScriptLen)
316 copy(newScript, oldScript[:oldScriptLen])
317 }
318 // Create new txOut with the deep copied data and append it to new Tx.
319 newTxOut := TxOut{
320 Value: oldTxOut.Value,
321 PkScript: newScript,
322 }
323 newTx.TxOut = append(newTx.TxOut, &newTxOut)
324 }
325 return &newTx
326 }
327 328 // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. This is part of the Message interface
329 // implementation. See Deserialize for decoding transactions stored to disk, such as in a database, as opposed to
330 // decoding transactions from the wire.
331 func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) (e error) {
332 var version uint32
333 if version, e = binarySerializer.Uint32(r, littleEndian); E.Chk(e) {
334 return
335 }
336 msg.Version = int32(version)
337 var count uint64
338 if count, e = ReadVarInt(r, pver); E.Chk(e) {
339 return
340 }
341 // // A count of zero (meaning no TxIn's to the uninitiated) indicates this is a
342 // // transaction with witness data.
343 // var flag [1]byte
344 // if count == 0 && enc == BaseEncoding {
345 // // Next, we need to read the flag, which is a single byte.
346 // if _, e = io.ReadFull(r, flag[:]); E.Chk(e) {
347 // return
348 // }
349 // // At the moment, the flag MUST be 0x01. In the future other flag types may be supported.
350 // if flag[0] != 0x01 {
351 // str := fmt.Sprintf("witness tx but flag byte is %x", flag)
352 // return messageError("MsgTx.BtcDecode", str)
353 // }
354 // // With the Segregated Witness specific fields decoded, we can now read in the
355 // // actual txin count.
356 // count, e = ReadVarInt(r, pver)
357 // if e != nil {
358 // return
359 // }
360 // }
361 // Prevent more input transactions than could possibly fit into a message. It would be possible to cause memory
362 // exhaustion and panics without a sane upper bound on this count.
363 if count > uint64(maxTxInPerMessage) {
364 str := fmt.Sprintf(
365 "too many input transactions to fit into "+
366 "max message size [count %d, max %d]", count,
367 maxTxInPerMessage,
368 )
369 return messageError("MsgTx.BtcDecode", str)
370 }
371 // returnScriptBuffers is a closure that returns any script buffers that were borrowed from the pool when there are
372 // any deserialization errors. This is only valid to call before the final step which replaces the scripts with the
373 // location in a contiguous buffer and returns them.
374 returnScriptBuffers := func() {
375 for _, txIn := range msg.TxIn {
376 if txIn == nil {
377 continue
378 }
379 if txIn.SignatureScript != nil {
380 scriptPool.Return(txIn.SignatureScript)
381 }
382 // for _, witnessElem := range txIn.Witness {
383 // if witnessElem != nil {
384 // scriptPool.Return(witnessElem)
385 // }
386 // }
387 }
388 for _, txOut := range msg.TxOut {
389 if txOut == nil || txOut.PkScript == nil {
390 continue
391 }
392 scriptPool.Return(txOut.PkScript)
393 }
394 }
395 // Deserialize the inputs.
396 var totalScriptSize uint64
397 txIns := make([]TxIn, count)
398 msg.TxIn = make([]*TxIn, count)
399 for i := uint64(0); i < count; i++ {
400 // The pointer is set now in case a script buffer is borrowed and needs to be returned to the pool on error.
401 ti := &txIns[i]
402 msg.TxIn[i] = ti
403 if e = readTxIn(r, pver, msg.Version, ti); E.Chk(e) {
404 returnScriptBuffers()
405 return
406 }
407 totalScriptSize += uint64(len(ti.SignatureScript))
408 }
409 if count, e = ReadVarInt(r, pver); E.Chk(e) {
410 returnScriptBuffers()
411 return
412 }
413 // Prevent more output transactions than could possibly fit into a message. It would be possible to cause memory
414 // exhaustion and panics without a sane upper bound on this count.
415 if count > uint64(maxTxOutPerMessage) {
416 returnScriptBuffers()
417 str := fmt.Sprintf(
418 "too many output transactions to fit into "+
419 "max message size [count %d, max %d]", count,
420 maxTxOutPerMessage,
421 )
422 return messageError("MsgTx.BtcDecode", str)
423 }
424 // Deserialize the outputs.
425 txOuts := make([]TxOut, count)
426 msg.TxOut = make([]*TxOut, count)
427 for i := uint64(0); i < count; i++ {
428 // The pointer is set now in case a script buffer is borrowed and needs to be returned to the pool on error.
429 to := &txOuts[i]
430 msg.TxOut[i] = to
431 e = readTxOut(r, pver, msg.Version, to)
432 if e != nil {
433 returnScriptBuffers()
434 return
435 }
436 totalScriptSize += uint64(len(to.PkScript))
437 }
438 // If the transaction's flag byte isn't 0x00 at this point, then one or more of
439 // // its inputs has accompanying witness data.
440 // if flag[0] != 0 && enc == BaseEncoding {
441 // for _, txin := range msg.TxIn {
442 // // For each input, the witness is encoded as a stack with one or more items.
443 // // Therefore, we first read a varint which encodes the number of stack items.
444 // var witCount uint64
445 // if witCount, e = ReadVarInt(r, pver); E.Chk(e) {
446 // returnScriptBuffers()
447 // return
448 // }
449 // // Prevent a possible memory exhaustion attack by limiting the witCount value to a sane upper bound.
450 // if witCount > maxWitnessItemsPerInput {
451 // returnScriptBuffers()
452 // str := fmt.Sprintf(
453 // "too many witness items to fit "+
454 // "into max message size [count %d, max %d]",
455 // witCount, maxWitnessItemsPerInput,
456 // )
457 // return messageError("MsgTx.BtcDecode", str)
458 // }
459 // // Then for witCount number of stack items, each item has a varint length
460 // // prefix, followed by the witness item itself. txin.Witness = make([][]byte,
461 // // witCount)
462 // for j := uint64(0); j < witCount; j++ {
463 // txin.Witness[j], e = readScript(
464 // r, pver,
465 // maxWitnessItemSize, "script witness item",
466 // )
467 // if e != nil {
468 // returnScriptBuffers()
469 // return
470 // }
471 // totalScriptSize += uint64(len(txin.Witness[j]))
472 // }
473 // }
474 // }
475 msg.LockTime, e = binarySerializer.Uint32(r, littleEndian)
476 if e != nil {
477 returnScriptBuffers()
478 return
479 }
480 // Create a single allocation to house all of the scripts and set each input
481 // signature script and output public key script to the appropriate subslice of
482 // the overall contiguous buffer. Then, return each individual script buffer
483 // back to the pool so they can be reused for future deserializations.
484 //
485 // This is done because it significantly reduces the number of allocations the
486 // garbage collector needs to track, which in turn improves performance and
487 // drastically reduces the amount of runtime overhead that would otherwise be
488 // needed to keep track of millions of small allocations.
489 //
490 // NOTE: It is no longer valid to call the returnScriptBuffers closure after
491 // these blocks of code run because it is already done and the scripts in the
492 // transaction inputs and outputs no longer point to the buffers.
493 var offset uint64
494 scripts := make([]byte, totalScriptSize)
495 for i := 0; i < len(msg.TxIn); i++ {
496 // Copy the signature script into the contiguous buffer at the appropriate offset.
497 signatureScript := msg.TxIn[i].SignatureScript
498 copy(scripts[offset:], signatureScript)
499 // Reset the signature script of the transaction input to the slice of the contiguous buffer where the script
500 // lives.
501 scriptSize := uint64(len(signatureScript))
502 end := offset + scriptSize
503 msg.TxIn[i].SignatureScript = scripts[offset:end:end]
504 offset += scriptSize
505 // Return the temporary script buffer to the pool.
506 scriptPool.Return(signatureScript)
507 // for j := 0; j < len(msg.TxIn[i].Witness); j++ {
508 // // Copy each item within the witness stack for this input into the contiguous
509 // // buffer at the appropriate offset.
510 // witnessElem := msg.TxIn[i].Witness[j]
511 // copy(scripts[offset:], witnessElem)
512 // // Reset the witness item within the stack to the slice of the contiguous buffer
513 // // where the witness lives.
514 // witnessElemSize := uint64(len(witnessElem))
515 // end := offset + witnessElemSize
516 // msg.TxIn[i].Witness[j] = scripts[offset:end:end]
517 // offset += witnessElemSize
518 // // Return the temporary buffer used for the witness stack item to the pool.
519 // scriptPool.Return(witnessElem)
520 // }
521 }
522 for i := 0; i < len(msg.TxOut); i++ {
523 // Copy the public key script into the contiguous buffer at the appropriate offset.
524 pkScript := msg.TxOut[i].PkScript
525 copy(scripts[offset:], pkScript)
526 // Reset the public key script of the transaction output to the slice of the contiguous buffer where the script
527 // lives.
528 scriptSize := uint64(len(pkScript))
529 end := offset + scriptSize
530 msg.TxOut[i].PkScript = scripts[offset:end:end]
531 offset += scriptSize
532 // Return the temporary script buffer to the pool.
533 scriptPool.Return(pkScript)
534 }
535 return nil
536 }
537 538 // Deserialize decodes a transaction from r into the receiver using a format that is suitable for long-term storage such
539 // as a database while respecting the Version field in the transaction. This function differs from BtcDecode in that
540 // BtcDecode decodes from the bitcoin wire protocol as it was sent across the network. The wire encoding can technically
541 // differ depending on the protocol version and doesn't even really need to match the format of a stored transaction at
542 // all. As of the time this comment was written, the encoded transaction is the same in both instances, but there is a
543 // distinct difference and separating the two allows the API to be flexible enough to deal with changes.
544 func (msg *MsgTx) Deserialize(r io.Reader) (e error) {
545 // At the current time, there is no difference between the wire encoding at protocol version 0 and the stable
546 // long-term storage format. As a result, make use of BtcDecode.
547 return msg.BtcDecode(r, 0, BaseEncoding)
548 }
549 550 // DeserializeNoWitness decodes a transaction from r into the receiver, where
551 // the transaction encoding format within r MUST NOT utilize the new
552 // serialization format created to encode transaction bearing witness data
553 // within inputs.
554 func (msg *MsgTx) DeserializeNoWitness(r io.Reader) (e error) {
555 return msg.BtcDecode(r, 0, BaseEncoding)
556 }
557 558 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. This is part of the Message interface
559 // implementation. See Serialize for encoding transactions to be stored to disk, such as in a database, as opposed to
560 // encoding transactions for the wire.
561 func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) (e error) {
562 if e = binarySerializer.PutUint32(w, littleEndian, uint32(msg.Version)); E.Chk(e) {
563 return
564 }
565 // // If the encoding version is set to BaseEncoding, and the Flags field for
566 // // the MsgTx aren't 0x00, then this indicates the transaction is to be encoded
567 // // using the new witness inclusionary structure defined in BIP0144.
568 // doWitness := enc == BaseEncoding && msg.HasWitness()
569 // if doWitness {
570 // // After the txn's Version field, we include two additional bytes specific to
571 // // the witness encoding. The first byte is an always 0x00 marker byte, which
572 // // allows decoders to distinguish a serialized transaction with witnesses from a
573 // // regular (legacy) one. The second byte is the Flag field, which at the moment
574 // // is always 0x01, but may be extended in the future to accommodate auxiliary
575 // // non-committed fields.
576 // if _, e = w.Write(witessMarkerBytes); E.Chk(e) {
577 // return
578 // }
579 // }
580 count := uint64(len(msg.TxIn))
581 e = WriteVarInt(w, pver, count)
582 if e != nil {
583 return
584 }
585 for _, ti := range msg.TxIn {
586 e = writeTxIn(w, pver, msg.Version, ti)
587 if e != nil {
588 return
589 }
590 }
591 count = uint64(len(msg.TxOut))
592 e = WriteVarInt(w, pver, count)
593 if e != nil {
594 return
595 }
596 for _, to := range msg.TxOut {
597 e = WriteTxOut(w, pver, msg.Version, to)
598 if e != nil {
599 return
600 }
601 }
602 // // If this transaction is a witness transaction, and the witness encoded is
603 // // desired, then encode the witness for each of the inputs within the
604 // // transaction.
605 // if doWitness {
606 // for _, ti := range msg.TxIn {
607 // e = writeTxWitness(w, pver, msg.Version, ti.Witness)
608 // if e != nil {
609 // return
610 // }
611 // }
612 // }
613 return binarySerializer.PutUint32(w, littleEndian, msg.LockTime)
614 }
615 616 // // HasWitness returns false if none of the inputs within the transaction contain
617 // // witness data, true false otherwise.
618 // func (msg *MsgTx) HasWitness() bool {
619 // for _, txIn := range msg.TxIn {
620 // if len(txIn.Witness) != 0 {
621 // return true
622 // }
623 // }
624 // return false
625 // }
626 627 // Serialize encodes the transaction to w using a format that suitable for long-term storage such as a database while
628 // respecting the Version field in the transaction. This function differs from BtcEncode in that BtcEncode encodes the
629 // transaction to the bitcoin wire protocol in order to be sent across the network. The wire encoding can technically
630 // differ depending on the protocol version and doesn't even really need to match the format of a stored transaction at
631 // all. As of the time this comment was written, the encoded transaction is the same in both instances, but there is a
632 // distinct difference and separating the two allows the API to be flexible enough to deal with changes.
633 func (msg *MsgTx) Serialize(w io.Writer) (e error) {
634 // At the current time, there is no difference between the wire encoding at
635 // protocol version 0 and the stable long-term storage format. As a result, make
636 // use of BtcEncode. Passing a encoding type of BaseEncoding to BtcEncode for
637 // MsgTx indicates that the transaction's witnesses (if any) should be
638 // serialized according to the new serialization structure defined in BIP0144.
639 return msg.BtcEncode(w, 0, BaseEncoding)
640 }
641 642 // SerializeNoWitness encodes the transaction to w in an identical manner to
643 // Serialize, however even if the source transaction has inputs with witness
644 // data, the old serialization format will still be used.
645 func (msg *MsgTx) SerializeNoWitness(w io.Writer) (e error) {
646 return msg.BtcEncode(w, 0, BaseEncoding)
647 }
648 649 // baseSize returns the serialized size of the transaction without accounting
650 // for any witness data.
651 func (msg *MsgTx) baseSize() int {
652 // Version 4 bytes + LockTime 4 bytes + Serialized varint size for the number of transaction inputs and outputs.
653 n := 8 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
654 VarIntSerializeSize(uint64(len(msg.TxOut)))
655 for _, txIn := range msg.TxIn {
656 n += txIn.SerializeSize()
657 }
658 for _, txOut := range msg.TxOut {
659 n += txOut.SerializeSize()
660 }
661 return n
662 }
663 664 // SerializeSize returns the number of bytes it would take to serialize the the transaction.
665 func (msg *MsgTx) SerializeSize() int {
666 n := msg.baseSize()
667 // if msg.HasWitness() {
668 // // The marker, and flag fields take up two additional bytes.
669 // n += 2
670 // // Additionally, factor in the serialized size of each of the witnesses for each
671 // // txin.
672 // for _, txin := range msg.TxIn {
673 // n += txin.Witness.SerializeSize()
674 // }
675 // }
676 return n
677 }
678 679 // SerializeSizeStripped returns the number of bytes it would take to serialize
680 // the transaction, excluding any included witness data.
681 func (msg *MsgTx) SerializeSizeStripped() int {
682 return msg.baseSize()
683 }
684 685 // Command returns the protocol command string for the message. This is part of the Message interface implementation.
686 func (msg *MsgTx) Command() string {
687 return CmdTx
688 }
689 690 // MaxPayloadLength returns the maximum length the payload can be for the receiver. This is part of the Message
691 // interface implementation.
692 func (msg *MsgTx) MaxPayloadLength(pver uint32) uint32 {
693 return MaxBlockPayload
694 }
695 696 // PkScriptLocs returns a slice containing the start of each public key script within the raw serialized transaction.
697 // The caller can easily obtain the length of each script by using len on the script available via the appropriate
698 // transaction output entry.
699 func (msg *MsgTx) PkScriptLocs() []int {
700 numTxOut := len(msg.TxOut)
701 if numTxOut == 0 {
702 return nil
703 }
704 // The starting offset in the serialized transaction of the first transaction output is:
705 //
706 // Version 4 bytes + serialized varint size for the number of transaction inputs and outputs + serialized size of
707 // each transaction input.
708 n := 4 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
709 VarIntSerializeSize(uint64(numTxOut))
710 // // If this transaction has a witness input, the an additional two bytes for the
711 // // marker, and flag byte need to be taken into account.
712 // if len(msg.TxIn) > 0 && msg.TxIn[0].Witness != nil {
713 // n += 2
714 // }
715 for _, txIn := range msg.TxIn {
716 n += txIn.SerializeSize()
717 }
718 // Calculate and set the appropriate offset for each public key script.
719 pkScriptLocs := make([]int, numTxOut)
720 for i, txOut := range msg.TxOut {
721 // The offset of the script in the transaction output is:
722 // value 8 bytes + serialized varint size for the length of PkScript.
723 n += 8 + VarIntSerializeSize(uint64(len(txOut.PkScript)))
724 pkScriptLocs[i] = n
725 n += len(txOut.PkScript)
726 }
727 return pkScriptLocs
728 }
729 730 // NewMsgTx returns a new bitcoin tx message that conforms to the Message interface. The return instance has a default
731 // version of TxVersion and there are no transaction inputs or outputs. Also, the lock time is set to zero to indicate
732 // the transaction is valid immediately as opposed to some time in future.
733 func NewMsgTx(version int32) *MsgTx {
734 return &MsgTx{
735 Version: version,
736 TxIn: make([]*TxIn, 0, defaultTxInOutAlloc),
737 TxOut: make([]*TxOut, 0, defaultTxInOutAlloc),
738 }
739 }
740 741 // readOutPoint reads the next sequence of bytes from r as an OutPoint.
742 func readOutPoint(r io.Reader, pver uint32, version int32, op *OutPoint) (e error) {
743 if _, e = io.ReadFull(r, op.Hash[:]); E.Chk(e) {
744 return
745 }
746 op.Index, e = binarySerializer.Uint32(r, littleEndian)
747 return
748 }
749 750 // writeOutPoint encodes op to the bitcoin protocol encoding for an OutPoint to w.
751 func writeOutPoint(w io.Writer, pver uint32, version int32, op *OutPoint) (e error) {
752 if _, e = w.Write(op.Hash[:]); E.Chk(e) {
753 return
754 }
755 return binarySerializer.PutUint32(w, littleEndian, op.Index)
756 }
757 758 // readScript reads a variable length byte array that represents a transaction script. It is encoded as a varInt
759 // containing the length of the array followed by the bytes themselves. An error is returned if the length is greater
760 // than the passed maxAllowed parameter which helps protect against memory exhaustion attacks and forced panics through
761 // malformed messages. The fieldName parameter is only used for the error message so it provides more context in the
762 // error.
763 func readScript(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) (b []byte, e error) {
764 var count uint64
765 if count, e = ReadVarInt(r, pver); E.Chk(e) {
766 return
767 }
768 // Prevent byte array larger than the max message size. It would be possible to cause memory exhaustion and panics
769 // without a sane upper bound on this count.
770 if count > uint64(maxAllowed) {
771 str := fmt.Sprintf(
772 "%s is larger than the max allowed size "+
773 "[count %d, max %d]", fieldName, count, maxAllowed,
774 )
775 return nil, messageError("readScript", str)
776 }
777 b = scriptPool.Borrow(count)
778 if _, e = io.ReadFull(r, b); E.Chk(e) {
779 scriptPool.Return(b)
780 return
781 }
782 return
783 }
784 785 // readTxIn reads the next sequence of bytes from r as a transaction input (TxIn).
786 func readTxIn(r io.Reader, pver uint32, version int32, ti *TxIn) (e error) {
787 if e = readOutPoint(r, pver, version, &ti.PreviousOutPoint); E.Chk(e) {
788 return
789 }
790 if ti.SignatureScript, e = readScript(
791 r, pver, MaxMessagePayload,
792 "transaction input signature script",
793 ); E.Chk(e) {
794 return
795 }
796 return readElement(r, &ti.Sequence)
797 }
798 799 // writeTxIn encodes ti to the bitcoin protocol encoding for a transaction input (TxIn) to w.
800 func writeTxIn(w io.Writer, pver uint32, version int32, ti *TxIn) (e error) {
801 if e = writeOutPoint(w, pver, version, &ti.PreviousOutPoint); E.Chk(e) {
802 return
803 }
804 if e = WriteVarBytes(w, pver, ti.SignatureScript); E.Chk(e) {
805 return
806 }
807 return binarySerializer.PutUint32(w, littleEndian, ti.Sequence)
808 }
809 810 // readTxOut reads the next sequence of bytes from r as a transaction output (TxOut).
811 func readTxOut(r io.Reader, pver uint32, version int32, to *TxOut) (e error) {
812 if e = readElement(r, &to.Value); E.Chk(e) {
813 return
814 }
815 to.PkScript, e = readScript(
816 r, pver, MaxMessagePayload,
817 "transaction output public key script",
818 )
819 return
820 }
821 822 // WriteTxOut encodes to into the bitcoin protocol encoding for a transaction
823 // output (TxOut) to w. NOTE: This function is exported in order to allow
824 // txscript to compute the new sighashes for witness transactions (BIP0143).
825 func WriteTxOut(w io.Writer, pver uint32, version int32, to *TxOut) (e error) {
826 if e = binarySerializer.PutUint64(w, littleEndian, uint64(to.Value)); E.Chk(e) {
827 return
828 }
829 return WriteVarBytes(w, pver, to.PkScript)
830 }
831 832 // writeTxWitness encodes the bitcoin protocol encoding for a transaction
833 // input's witness into to w.
834 func writeTxWitness(w io.Writer, pver uint32, version int32, wit [][]byte) (e error) {
835 if e = WriteVarInt(w, pver, uint64(len(wit))); E.Chk(e) {
836 return
837 }
838 for _, item := range wit {
839 if e = WriteVarBytes(w, pver, item); E.Chk(e) {
840 return
841 }
842 }
843 return nil
844 }
845