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