msgblock_test.go raw
1 package wire
2
3 import (
4 "bytes"
5 "io"
6 "reflect"
7 "testing"
8 "time"
9
10 "github.com/davecgh/go-spew/spew"
11
12 "github.com/p9c/p9/pkg/chainhash"
13 )
14
15 // TestBlock tests the Block API.
16 func TestBlock(t *testing.T) {
17 pver := ProtocolVersion
18 // Block 1 header.
19 prevHash := &blockOne.Header.PrevBlock
20 merkleHash := &blockOne.Header.MerkleRoot
21 bits := blockOne.Header.Bits
22 nonce := blockOne.Header.Nonce
23 bh := NewBlockHeader(1, prevHash, merkleHash, bits, nonce)
24 // Ensure the command is expected value.
25 wantCmd := "block"
26 msg := NewMsgBlock(bh)
27 if cmd := msg.Command(); cmd != wantCmd {
28 t.Errorf("NewMsgBlock: wrong command - got %v want %v",
29 cmd, wantCmd,
30 )
31 }
32 // Ensure max payload is expected value for latest protocol version. Num addresses (varInt) + max allowed addresses.
33 wantPayload := uint32(4000000)
34 maxPayload := msg.MaxPayloadLength(pver)
35 if maxPayload != wantPayload {
36 t.Errorf("MaxPayloadLength: wrong max payload length for "+
37 "protocol version %d - got %v, want %v", pver,
38 maxPayload, wantPayload,
39 )
40 }
41 // Ensure we get the same block header data back out.
42 if !reflect.DeepEqual(&msg.Header, bh) {
43 t.Errorf("NewMsgBlock: wrong block header - got %v, want %v",
44 spew.Sdump(&msg.Header), spew.Sdump(bh),
45 )
46 }
47 // Ensure transactions are added properly.
48 tx := blockOne.Transactions[0].Copy()
49 e := msg.AddTransaction(tx)
50 if e != nil {
51 t.Log(e)
52 }
53 if !reflect.DeepEqual(msg.Transactions, blockOne.Transactions) {
54 t.Errorf("AddTransaction: wrong transactions - got %v, want %v",
55 spew.Sdump(msg.Transactions),
56 spew.Sdump(blockOne.Transactions),
57 )
58 }
59 // Ensure transactions are properly cleared.
60 msg.ClearTransactions()
61 if len(msg.Transactions) != 0 {
62 t.Errorf("ClearTransactions: wrong transactions - got %v, want %v",
63 len(msg.Transactions), 0,
64 )
65 }
66 }
67
68 // TestBlockTxHashes tests the ability to generate a slice of all transaction hashes from a block accurately.
69 func TestBlockTxHashes(t *testing.T) {
70 // Block 1, transaction 1 hash.
71 hashStr := "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
72 wantHash, e := chainhash.NewHashFromStr(hashStr)
73 if e != nil {
74 t.Errorf("NewHashFromStr: %v", e)
75 return
76 }
77 wantHashes := []chainhash.Hash{*wantHash}
78 hashes, e := blockOne.TxHashes()
79 if e != nil {
80 t.Errorf("TxHashes: %v", e)
81 }
82 if !reflect.DeepEqual(hashes, wantHashes) {
83 t.Errorf("TxHashes: wrong transaction hashes - got %v, want %v",
84 spew.Sdump(hashes), spew.Sdump(wantHashes),
85 )
86 }
87 }
88
89 // TestBlockHash tests the ability to generate the hash of a block accurately.
90 func TestBlockHash(t *testing.T) {
91 // Block 1 hash.
92 hashStr := "839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
93 wantHash, e := chainhash.NewHashFromStr(hashStr)
94 if e != nil {
95 t.Errorf("NewHashFromStr: %v", e)
96 }
97 // Ensure the hash produced is expected.
98 blockHash := blockOne.BlockHash()
99 if !blockHash.IsEqual(wantHash) {
100 t.Errorf("BlockHash: wrong hash - got %v, want %v",
101 spew.Sprint(blockHash), spew.Sprint(wantHash),
102 )
103 }
104 }
105
106 // TestBlockWire tests the Block wire encode and decode for various numbers of transaction inputs and outputs and
107 // protocol versions.
108 func TestBlockWire(t *testing.T) {
109 tests := []struct {
110 in *Block // Message to encode
111 out *Block // Expected decoded message
112 buf []byte // Wire encoding
113 txLocs []TxLoc // Expected transaction locations
114 pver uint32 // Protocol version for wire encoding
115 enc MessageEncoding // Message encoding format
116 }{
117 // Latest protocol version.
118 {
119 &blockOne,
120 &blockOne,
121 blockOneBytes,
122 blockOneTxLocs,
123 ProtocolVersion,
124 BaseEncoding,
125 },
126 // Protocol version BIP0035Version.
127 {
128 &blockOne,
129 &blockOne,
130 blockOneBytes,
131 blockOneTxLocs,
132 BIP0035Version,
133 BaseEncoding,
134 },
135 // Protocol version BIP0031Version.
136 {
137 &blockOne,
138 &blockOne,
139 blockOneBytes,
140 blockOneTxLocs,
141 BIP0031Version,
142 BaseEncoding,
143 },
144 // Protocol version NetAddressTimeVersion.
145 {
146 &blockOne,
147 &blockOne,
148 blockOneBytes,
149 blockOneTxLocs,
150 NetAddressTimeVersion,
151 BaseEncoding,
152 },
153 // Protocol version MultipleAddressVersion.
154 {
155 &blockOne,
156 &blockOne,
157 blockOneBytes,
158 blockOneTxLocs,
159 MultipleAddressVersion,
160 BaseEncoding,
161 },
162 // TODO(roasbeef): add case for witnessy block
163 }
164 t.Logf("Running %d tests", len(tests))
165 for i, test := range tests {
166 // Encode the message to wire format.
167 var buf bytes.Buffer
168 e := test.in.BtcEncode(&buf, test.pver, test.enc)
169 if e != nil {
170 t.Errorf("BtcEncode #%d error %v", i, e)
171 continue
172 }
173 if !bytes.Equal(buf.Bytes(), test.buf) {
174 t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
175 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
176 )
177 continue
178 }
179 // Decode the message from wire format.
180 var msg Block
181 rbuf := bytes.NewReader(test.buf)
182 e = msg.BtcDecode(rbuf, test.pver, test.enc)
183 if e != nil {
184 t.Errorf("BtcDecode #%d error %v", i, e)
185 continue
186 }
187 if !reflect.DeepEqual(&msg, test.out) {
188 t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
189 spew.Sdump(&msg), spew.Sdump(test.out),
190 )
191 continue
192 }
193 }
194 }
195
196 // TestBlockWireErrors performs negative tests against wire encode and decode of Block to confirm error paths work
197 // correctly.
198 func TestBlockWireErrors(t *testing.T) {
199 // Use protocol version 60002 specifically here instead of the latest because the test data is using bytes encoded
200 // with that protocol version.
201 pver := uint32(60002)
202 tests := []struct {
203 in *Block // value to encode
204 buf []byte // Wire encoding
205 pver uint32 // Protocol version for wire encoding
206 enc MessageEncoding // Message encoding format
207 max int // Max size of fixed buffer to induce errors
208 writeErr error // Expected write error
209 readErr error // Expected read error
210 }{
211 // Force error in version.
212 {&blockOne, blockOneBytes, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
213 // Force error in prev block hash.
214 {&blockOne, blockOneBytes, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF},
215 // Force error in merkle root.
216 {&blockOne, blockOneBytes, pver, BaseEncoding, 36, io.ErrShortWrite, io.EOF},
217 // Force error in timestamp.
218 {&blockOne, blockOneBytes, pver, BaseEncoding, 68, io.ErrShortWrite, io.EOF},
219 // Force error in difficulty bits.
220 {&blockOne, blockOneBytes, pver, BaseEncoding, 72, io.ErrShortWrite, io.EOF},
221 // Force error in header nonce.
222 {&blockOne, blockOneBytes, pver, BaseEncoding, 76, io.ErrShortWrite, io.EOF},
223 // Force error in transaction count.
224 {&blockOne, blockOneBytes, pver, BaseEncoding, 80, io.ErrShortWrite, io.EOF},
225 // Force error in transactions.
226 {&blockOne, blockOneBytes, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF},
227 }
228 t.Logf("Running %d tests", len(tests))
229 for i, test := range tests {
230 // Encode to wire format.
231 w := newFixedWriter(test.max)
232 e := test.in.BtcEncode(w, test.pver, test.enc)
233 if e != test.writeErr {
234 t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
235 i, e, test.writeErr,
236 )
237 continue
238 }
239 // Decode from wire format.
240 var msg Block
241 r := newFixedReader(test.max, test.buf)
242 e = msg.BtcDecode(r, test.pver, test.enc)
243 if e != test.readErr {
244 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
245 i, e, test.readErr,
246 )
247 continue
248 }
249 }
250 }
251
252 // TestBlockSerialize tests Block serialize and deserialize.
253 func TestBlockSerialize(t *testing.T) {
254 tests := []struct {
255 in *Block // Message to encode
256 out *Block // Expected decoded message
257 buf []byte // Serialized data
258 txLocs []TxLoc // Expected transaction locations
259 }{
260 {
261 &blockOne,
262 &blockOne,
263 blockOneBytes,
264 blockOneTxLocs,
265 },
266 }
267 t.Logf("Running %d tests", len(tests))
268 for i, test := range tests {
269 // Serialize the block.
270 var buf bytes.Buffer
271 e := test.in.Serialize(&buf)
272 if e != nil {
273 t.Errorf("Serialize #%d error %v", i, e)
274 continue
275 }
276 if !bytes.Equal(buf.Bytes(), test.buf) {
277 t.Errorf("Serialize #%d\n got: %s want: %s", i,
278 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
279 )
280 continue
281 }
282 // Deserialize the block.
283 var block Block
284 rbuf := bytes.NewReader(test.buf)
285 e = block.Deserialize(rbuf)
286 if e != nil {
287 t.Errorf("Deserialize #%d error %v", i, e)
288 continue
289 }
290 if !reflect.DeepEqual(&block, test.out) {
291 t.Errorf("Deserialize #%d\n got: %s want: %s", i,
292 spew.Sdump(&block), spew.Sdump(test.out),
293 )
294 continue
295 }
296 // Deserialize the block while gathering transaction location information.
297 var txLocBlock Block
298 br := bytes.NewBuffer(test.buf)
299 txLocs, e := txLocBlock.DeserializeTxLoc(br)
300 if e != nil {
301 t.Errorf("DeserializeTxLoc #%d error %v", i, e)
302 continue
303 }
304 if !reflect.DeepEqual(&txLocBlock, test.out) {
305 t.Errorf("DeserializeTxLoc #%d\n got: %s want: %s", i,
306 spew.Sdump(&txLocBlock), spew.Sdump(test.out),
307 )
308 continue
309 }
310 if !reflect.DeepEqual(txLocs, test.txLocs) {
311 t.Errorf("DeserializeTxLoc #%d\n got: %s want: %s", i,
312 spew.Sdump(txLocs), spew.Sdump(test.txLocs),
313 )
314 continue
315 }
316 }
317 }
318
319 // TestBlockSerializeErrors performs negative tests against wire encode and decode of Block to confirm error paths
320 // work correctly.
321 func TestBlockSerializeErrors(t *testing.T) {
322 tests := []struct {
323 in *Block // value to encode
324 buf []byte // Serialized data
325 max int // Max size of fixed buffer to induce errors
326 writeErr error // Expected write error
327 readErr error // Expected read error
328 }{
329 // Force error in version.
330 {&blockOne, blockOneBytes, 0, io.ErrShortWrite, io.EOF},
331 // Force error in prev block hash.
332 {&blockOne, blockOneBytes, 4, io.ErrShortWrite, io.EOF},
333 // Force error in merkle root.
334 {&blockOne, blockOneBytes, 36, io.ErrShortWrite, io.EOF},
335 // Force error in timestamp.
336 {&blockOne, blockOneBytes, 68, io.ErrShortWrite, io.EOF},
337 // Force error in difficulty bits.
338 {&blockOne, blockOneBytes, 72, io.ErrShortWrite, io.EOF},
339 // Force error in header nonce.
340 {&blockOne, blockOneBytes, 76, io.ErrShortWrite, io.EOF},
341 // Force error in transaction count.
342 {&blockOne, blockOneBytes, 80, io.ErrShortWrite, io.EOF},
343 // Force error in transactions.
344 {&blockOne, blockOneBytes, 81, io.ErrShortWrite, io.EOF},
345 }
346 t.Logf("Running %d tests", len(tests))
347 for i, test := range tests {
348 // Serialize the block.
349 w := newFixedWriter(test.max)
350 e := test.in.Serialize(w)
351 if e != test.writeErr {
352 t.Errorf("Serialize #%d wrong error got: %v, want: %v",
353 i, e, test.writeErr,
354 )
355 continue
356 }
357 // Deserialize the block.
358 var block Block
359 r := newFixedReader(test.max, test.buf)
360 e = block.Deserialize(r)
361 if e != test.readErr {
362 t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
363 i, e, test.readErr,
364 )
365 continue
366 }
367 var txLocBlock Block
368 br := bytes.NewBuffer(test.buf[0:test.max])
369 _, e = txLocBlock.DeserializeTxLoc(br)
370 if e != test.readErr {
371 t.Errorf("DeserializeTxLoc #%d wrong error got: %v, want: %v",
372 i, e, test.readErr,
373 )
374 continue
375 }
376 }
377 }
378
379 // TestBlockOverflowErrors performs tests to ensure deserializing blocks, which are intentionally crafted to use large
380 // values for the number of transactions are handled properly. This could otherwise potentially be used as an attack
381 // vector.
382 func TestBlockOverflowErrors(t *testing.T) {
383 // Use protocol version 70001 specifically here instead of the latest protocol version because the test data is
384 // using bytes encoded with that version.
385 pver := uint32(70001)
386 tests := []struct {
387 buf []byte // Wire encoding
388 pver uint32 // Protocol version for wire encoding
389 enc MessageEncoding // Message encoding format
390 e error // Expected error
391 }{
392 // Block that claims to have ~uint64(0) transactions.
393 {
394 []byte{
395 0x01, 0x00, 0x00, 0x00, // Version 1
396 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
397 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
398 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
399 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
400 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
401 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
402 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
403 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
404 0x61, 0xbc, 0x66, 0x49, // Timestamp
405 0xff, 0xff, 0x00, 0x1d, // Bits
406 0x01, 0xe3, 0x62, 0x99, // Nonce
407 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
408 0xff, // TxnCount
409 }, pver, BaseEncoding, &MessageError{},
410 },
411 }
412 t.Logf("Running %d tests", len(tests))
413 for i, test := range tests {
414 // Decode from wire format.
415 var msg Block
416 r := bytes.NewReader(test.buf)
417 e := msg.BtcDecode(r, test.pver, test.enc)
418 if reflect.TypeOf(e) != reflect.TypeOf(test.e) {
419 t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
420 i, e, reflect.TypeOf(test.e),
421 )
422 continue
423 }
424 // Deserialize from wire format.
425 r = bytes.NewReader(test.buf)
426 e = msg.Deserialize(r)
427 if reflect.TypeOf(e) != reflect.TypeOf(test.e) {
428 t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
429 i, e, reflect.TypeOf(test.e),
430 )
431 continue
432 }
433 // Deserialize with transaction location info from wire format.
434 br := bytes.NewBuffer(test.buf)
435 _, e = msg.DeserializeTxLoc(br)
436 if reflect.TypeOf(e) != reflect.TypeOf(test.e) {
437 t.Errorf("DeserializeTxLoc #%d wrong error got: %v, "+
438 "want: %v", i, e, reflect.TypeOf(test.e),
439 )
440 continue
441 }
442 }
443 }
444
445 // TestBlockSerializeSize performs tests to ensure the serialize size for various blocks is accurate.
446 func TestBlockSerializeSize(t *testing.T) {
447 // Block with no transactions.
448 noTxBlock := NewMsgBlock(&blockOne.Header)
449 tests := []struct {
450 in *Block // Block to encode
451 size int // Expected serialized size
452 }{
453 // Block with no transactions.
454 {noTxBlock, 81},
455 // First block in the mainnet block chain.
456 {&blockOne, len(blockOneBytes)},
457 }
458 t.Logf("Running %d tests", len(tests))
459 for i, test := range tests {
460 serializedSize := test.in.SerializeSize()
461 if serializedSize != test.size {
462 t.Errorf("Block.SerializeSize: #%d got: %d, want: "+
463 "%d", i, serializedSize, test.size,
464 )
465 continue
466 }
467 }
468 }
469
470 // blockOne is the first block in the mainnet block chain.
471 var blockOne = Block{
472 Header: BlockHeader{
473 Version: 1,
474 PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
475 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
476 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
477 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
478 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
479 },
480 ),
481 MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
482 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
483 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
484 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
485 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e,
486 },
487 ),
488 Timestamp: time.Unix(0x4966bc61, 0), // 2009-01-08 20:54:25 -0600 CST
489 Bits: 0x1d00ffff, // 486604799
490 Nonce: 0x9962e301, // 2573394689
491 },
492 Transactions: []*MsgTx{
493 {
494 Version: 1,
495 TxIn: []*TxIn{
496 {
497 PreviousOutPoint: OutPoint{
498 Hash: chainhash.Hash{},
499 Index: 0xffffffff,
500 },
501 SignatureScript: []byte{
502 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04,
503 },
504 Sequence: 0xffffffff,
505 },
506 },
507 TxOut: []*TxOut{
508 {
509 Value: 0x12a05f200,
510 PkScript: []byte{
511 0x41, // OP_DATA_65
512 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
513 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
514 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
515 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
516 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
517 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
518 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
519 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
520 0xee, // 65-byte signature
521 0xac, // OP_CHECKSIG
522 },
523 },
524 },
525 LockTime: 0,
526 },
527 },
528 }
529
530 // Block one serialized bytes.
531 var blockOneBytes = []byte{
532 0x01, 0x00, 0x00, 0x00, // Version 1
533 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
534 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
535 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
536 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
537 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
538 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
539 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
540 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
541 0x61, 0xbc, 0x66, 0x49, // Timestamp
542 0xff, 0xff, 0x00, 0x1d, // Bits
543 0x01, 0xe3, 0x62, 0x99, // Nonce
544 0x01, // TxnCount
545 0x01, 0x00, 0x00, 0x00, // Version
546 0x01, // Varint for number of transaction inputs
547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
551 0xff, 0xff, 0xff, 0xff, // Prevous output index
552 0x07, // Varint for length of signature script
553 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script (coinbase)
554 0xff, 0xff, 0xff, 0xff, // Sequence
555 0x01, // Varint for number of transaction outputs
556 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
557 0x43, // Varint for length of pk script
558 0x41, // OP_DATA_65
559 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
560 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
561 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
562 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
563 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
564 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
565 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
566 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
567 0xee, // 65-byte uncompressed public key
568 0xac, // OP_CHECKSIG
569 0x00, 0x00, 0x00, 0x00, // Lock time
570 }
571
572 // Transaction location information for block one transactions.
573 var blockOneTxLocs = []TxLoc{
574 {TxStart: 81, TxLen: 134},
575 }
576