// indexScriptPubKey indexes all data pushes greater than 8 bytes within the // passed SPK. Our "address" index is actually a hash160 index, where in the // ideal case the data push is either the hash160 of a publicKey (P2PKH) or // a Script (P2SH). func indexScriptPubKey(addrIndex database.BlockAddrIndex, scriptPubKey []byte, locInBlock *wire.TxLoc) error { dataPushes, err := txscript.PushedData(scriptPubKey) if err != nil { adxrLog.Tracef("Couldn't get pushes: %v", err) return err } for _, data := range dataPushes { // Only index pushes greater than 8 bytes. if len(data) < 8 { continue } var indexKey [ripemd160.Size]byte // A perfect little hash160. if len(data) <= 20 { copy(indexKey[:], data) // Otherwise, could be a payToPubKey or an OP_RETURN, so we'll // make a hash160 out of it. } else { copy(indexKey[:], btcutil.Hash160(data)) } addrIndex[indexKey] = append(addrIndex[indexKey], locInBlock) } return nil }
// TestPushedData ensured the PushedData function extracts the expected data out // of various scripts. func TestPushedData(t *testing.T) { t.Parallel() var tests = []struct { script string out [][]byte valid bool }{ { "0 IF 0 ELSE 2 ENDIF", [][]byte{nil, nil}, true, }, { "16777216 10000000", [][]byte{ {0x00, 0x00, 0x00, 0x01}, // 16777216 {0x80, 0x96, 0x98, 0x00}, // 10000000 }, true, }, { "DUP HASH160 '17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem' EQUALVERIFY CHECKSIG", [][]byte{ // 17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem { 0x31, 0x37, 0x56, 0x5a, 0x4e, 0x58, 0x31, 0x53, 0x4e, 0x35, 0x4e, 0x74, 0x4b, 0x61, 0x38, 0x55, 0x51, 0x46, 0x78, 0x77, 0x51, 0x62, 0x46, 0x65, 0x46, 0x63, 0x33, 0x69, 0x71, 0x52, 0x59, 0x68, 0x65, 0x6d, }, }, true, }, { "PUSHDATA4 1000 EQUAL", nil, false, }, } for i, test := range tests { script := mustParseShortForm(test.script) data, err := txscript.PushedData(script) if test.valid && err != nil { t.Errorf("TestPushedData failed test #%d: %v\n", i, err) continue } else if !test.valid && err == nil { t.Errorf("TestPushedData failed test #%d: test should "+ "be invalid\n", i) continue } if !reflect.DeepEqual(data, test.out) { t.Errorf("TestPushedData failed test #%d: want: %x "+ "got: %x\n", i, test.out, data) } } }