5bcc7790a0
This change removes all occurances of btcwire.BitcoinNet from exported APIs, replacing each with *btcnet.Params. This simplifies the logic for verifying string encodings of addresses and WIF private keys which use leading identifier numbers to differentiate between address types and the network they are intended for. It also allows the use of this package for non-standard networks (not mainnet, regtest, or testnet3) and future proofs it for the possible addition of future testnet networks. To update across this change, replace each btcwire.BitcoinNet parameter with the associated *btcnet.Params. For the standard networks, these changes are: btcwire.MainNet -> &btcnet.MainNetParams btcwire.TestNet -> &btcnet.RegressionNetParams btcwire.TestNet3 -> &btcnet.TestNet3Params ok @davecgh
571 lines
22 KiB
Go
571 lines
22 KiB
Go
// Copyright (c) 2013, 2014 Conformal Systems LLC.
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package btcutil_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"code.google.com/p/go.crypto/ripemd160"
|
|
|
|
"github.com/conformal/btcnet"
|
|
"github.com/conformal/btcutil"
|
|
"github.com/conformal/btcwire"
|
|
)
|
|
|
|
// invalidNet is an invalid bitcoin network.
|
|
const invalidNet = btcwire.BitcoinNet(0xffffffff)
|
|
|
|
func TestAddresses(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
addr string
|
|
encoded string
|
|
valid bool
|
|
result btcutil.Address
|
|
f func() (btcutil.Address, error)
|
|
net *btcnet.Params
|
|
}{
|
|
// Positive P2PKH tests.
|
|
{
|
|
name: "mainnet p2pkh",
|
|
addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX",
|
|
encoded: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKeyHash(
|
|
[ripemd160.Size]byte{
|
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
|
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84},
|
|
btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
pkHash := []byte{
|
|
0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc,
|
|
0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84}
|
|
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "mainnet p2pkh 2",
|
|
addr: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG",
|
|
encoded: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKeyHash(
|
|
[ripemd160.Size]byte{
|
|
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
|
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa},
|
|
btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
pkHash := []byte{
|
|
0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4,
|
|
0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa}
|
|
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "testnet p2pkh",
|
|
addr: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
|
|
encoded: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKeyHash(
|
|
[ripemd160.Size]byte{
|
|
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
|
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f},
|
|
btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
pkHash := []byte{
|
|
0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83,
|
|
0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}
|
|
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
|
|
// Negative P2PKH tests.
|
|
{
|
|
name: "p2pkh wrong hash length",
|
|
addr: "",
|
|
valid: false,
|
|
f: func() (btcutil.Address, error) {
|
|
pkHash := []byte{
|
|
0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b,
|
|
0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad,
|
|
0xaa}
|
|
return btcutil.NewAddressPubKeyHash(pkHash, &btcnet.MainNetParams)
|
|
},
|
|
},
|
|
{
|
|
name: "p2pkh bad checksum",
|
|
addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gY",
|
|
valid: false,
|
|
},
|
|
|
|
// Positive P2SH tests.
|
|
{
|
|
// Taken from transactions:
|
|
// output: 3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac
|
|
// input: 837dea37ddc8b1e3ce646f1a656e79bbd8cc7f558ac56a169626d649ebe2a3ba.
|
|
name: "mainnet p2sh",
|
|
addr: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC",
|
|
encoded: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC",
|
|
valid: true,
|
|
result: btcutil.TstAddressScriptHash(
|
|
[ripemd160.Size]byte{
|
|
0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 0xf2,
|
|
0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55, 0x10},
|
|
btcnet.MainNetParams.ScriptHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
script := []byte{
|
|
0x52, 0x41, 0x04, 0x91, 0xbb, 0xa2, 0x51, 0x09, 0x12, 0xa5,
|
|
0xbd, 0x37, 0xda, 0x1f, 0xb5, 0xb1, 0x67, 0x30, 0x10, 0xe4,
|
|
0x3d, 0x2c, 0x6d, 0x81, 0x2c, 0x51, 0x4e, 0x91, 0xbf, 0xa9,
|
|
0xf2, 0xeb, 0x12, 0x9e, 0x1c, 0x18, 0x33, 0x29, 0xdb, 0x55,
|
|
0xbd, 0x86, 0x8e, 0x20, 0x9a, 0xac, 0x2f, 0xbc, 0x02, 0xcb,
|
|
0x33, 0xd9, 0x8f, 0xe7, 0x4b, 0xf2, 0x3f, 0x0c, 0x23, 0x5d,
|
|
0x61, 0x26, 0xb1, 0xd8, 0x33, 0x4f, 0x86, 0x41, 0x04, 0x86,
|
|
0x5c, 0x40, 0x29, 0x3a, 0x68, 0x0c, 0xb9, 0xc0, 0x20, 0xe7,
|
|
0xb1, 0xe1, 0x06, 0xd8, 0xc1, 0x91, 0x6d, 0x3c, 0xef, 0x99,
|
|
0xaa, 0x43, 0x1a, 0x56, 0xd2, 0x53, 0xe6, 0x92, 0x56, 0xda,
|
|
0xc0, 0x9e, 0xf1, 0x22, 0xb1, 0xa9, 0x86, 0x81, 0x8a, 0x7c,
|
|
0xb6, 0x24, 0x53, 0x2f, 0x06, 0x2c, 0x1d, 0x1f, 0x87, 0x22,
|
|
0x08, 0x48, 0x61, 0xc5, 0xc3, 0x29, 0x1c, 0xcf, 0xfe, 0xf4,
|
|
0xec, 0x68, 0x74, 0x41, 0x04, 0x8d, 0x24, 0x55, 0xd2, 0x40,
|
|
0x3e, 0x08, 0x70, 0x8f, 0xc1, 0xf5, 0x56, 0x00, 0x2f, 0x1b,
|
|
0x6c, 0xd8, 0x3f, 0x99, 0x2d, 0x08, 0x50, 0x97, 0xf9, 0x97,
|
|
0x4a, 0xb0, 0x8a, 0x28, 0x83, 0x8f, 0x07, 0x89, 0x6f, 0xba,
|
|
0xb0, 0x8f, 0x39, 0x49, 0x5e, 0x15, 0xfa, 0x6f, 0xad, 0x6e,
|
|
0xdb, 0xfb, 0x1e, 0x75, 0x4e, 0x35, 0xfa, 0x1c, 0x78, 0x44,
|
|
0xc4, 0x1f, 0x32, 0x2a, 0x18, 0x63, 0xd4, 0x62, 0x13, 0x53,
|
|
0xae}
|
|
return btcutil.NewAddressScriptHash(script, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
// Taken from transactions:
|
|
// output: b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
|
|
// input: (not yet redeemed at time test was written)
|
|
name: "mainnet p2sh 2",
|
|
addr: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8",
|
|
encoded: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8",
|
|
valid: true,
|
|
result: btcutil.TstAddressScriptHash(
|
|
[ripemd160.Size]byte{
|
|
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
|
|
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4},
|
|
btcnet.MainNetParams.ScriptHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
hash := []byte{
|
|
0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37,
|
|
0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4}
|
|
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
// Taken from bitcoind base58_keys_valid.
|
|
name: "testnet p2sh",
|
|
addr: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n",
|
|
encoded: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n",
|
|
valid: true,
|
|
result: btcutil.TstAddressScriptHash(
|
|
[ripemd160.Size]byte{
|
|
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
|
|
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a},
|
|
btcnet.TestNet3Params.ScriptHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
hash := []byte{
|
|
0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e,
|
|
0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}
|
|
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
|
|
// Negative P2SH tests.
|
|
{
|
|
name: "p2sh wrong hash length",
|
|
addr: "",
|
|
valid: false,
|
|
f: func() (btcutil.Address, error) {
|
|
hash := []byte{
|
|
0x00, 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9,
|
|
0xf2, 0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55,
|
|
0x10}
|
|
return btcutil.NewAddressScriptHashFromHash(hash, &btcnet.MainNetParams)
|
|
},
|
|
},
|
|
|
|
// Positive P2PK tests.
|
|
{
|
|
name: "mainnet p2pk compressed (0x02)",
|
|
addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4",
|
|
encoded: "13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4},
|
|
btcutil.PKFCompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "mainnet p2pk compressed (0x03)",
|
|
addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65",
|
|
encoded: "15sHANNUBSh6nDp8XkDPmQcW6n3EFwmvE6",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65},
|
|
btcutil.PKFCompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "mainnet p2pk uncompressed (0x04)",
|
|
addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2" +
|
|
"e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3",
|
|
encoded: "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
|
0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38,
|
|
0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6,
|
|
0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc,
|
|
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
|
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
|
0xf6, 0x56, 0xb4, 0x12, 0xa3},
|
|
btcutil.PKFUncompressed, btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
|
0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38,
|
|
0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6,
|
|
0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc,
|
|
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
|
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
|
0xf6, 0x56, 0xb4, 0x12, 0xa3}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "mainnet p2pk hybrid (0x06)",
|
|
addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4" +
|
|
"0d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e",
|
|
encoded: "1Ja5rs7XBZnK88EuLVcFqYGMEbBitzchmX",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd,
|
|
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
|
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
|
0x44, 0xd3, 0x3f, 0x45, 0x3e},
|
|
btcutil.PKFHybrid, btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd,
|
|
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
|
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
|
0x44, 0xd3, 0x3f, 0x45, 0x3e}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "mainnet p2pk hybrid (0x07)",
|
|
addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65" +
|
|
"37a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b",
|
|
encoded: "1ExqMmf6yMxcBMzHjbj41wbqYuqoX6uBLG",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66,
|
|
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
|
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
|
0x1e, 0x09, 0x08, 0xef, 0x7b},
|
|
btcutil.PKFHybrid, btcnet.MainNetParams.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66,
|
|
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
|
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
|
0x1e, 0x09, 0x08, 0xef, 0x7b}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.MainNetParams)
|
|
},
|
|
net: &btcnet.MainNetParams,
|
|
},
|
|
{
|
|
name: "testnet p2pk compressed (0x02)",
|
|
addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4",
|
|
encoded: "mhiDPVP2nJunaAgTjzWSHCYfAqxxrxzjmo",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4},
|
|
btcutil.PKFCompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
{
|
|
name: "testnet p2pk compressed (0x03)",
|
|
addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65",
|
|
encoded: "mkPETRTSzU8MZLHkFKBmbKppxmdw9qT42t",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65},
|
|
btcutil.PKFCompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
{
|
|
name: "testnet p2pk uncompressed (0x04)",
|
|
addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5" +
|
|
"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3",
|
|
encoded: "mh8YhPYEAYs3E7EVyKtB5xrcfMExkkdEMF",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
|
0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38,
|
|
0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6,
|
|
0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc,
|
|
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
|
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
|
0xf6, 0x56, 0xb4, 0x12, 0xa3},
|
|
btcutil.PKFUncompressed, btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b,
|
|
0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38,
|
|
0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6,
|
|
0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc,
|
|
0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b,
|
|
0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43,
|
|
0xf6, 0x56, 0xb4, 0x12, 0xa3}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
{
|
|
name: "testnet p2pk hybrid (0x06)",
|
|
addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b" +
|
|
"40d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e",
|
|
encoded: "my639vCVzbDZuEiX44adfTUg6anRomZLEP",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd,
|
|
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
|
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
|
0x44, 0xd3, 0x3f, 0x45, 0x3e},
|
|
btcutil.PKFHybrid, btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95,
|
|
0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03,
|
|
0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca,
|
|
0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd,
|
|
0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73,
|
|
0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c,
|
|
0x44, 0xd3, 0x3f, 0x45, 0x3e}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
{
|
|
name: "testnet p2pk hybrid (0x07)",
|
|
addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6" +
|
|
"537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b",
|
|
encoded: "muUnepk5nPPrxUTuTAhRqrpAQuSWS5fVii",
|
|
valid: true,
|
|
result: btcutil.TstAddressPubKey(
|
|
[]byte{
|
|
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66,
|
|
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
|
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
|
0x1e, 0x09, 0x08, 0xef, 0x7b},
|
|
btcutil.PKFHybrid, btcnet.TestNet3Params.PubKeyHashAddrID),
|
|
f: func() (btcutil.Address, error) {
|
|
serializedPubKey := []byte{
|
|
0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1,
|
|
0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0,
|
|
0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e,
|
|
0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66,
|
|
0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71,
|
|
0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c,
|
|
0x1e, 0x09, 0x08, 0xef, 0x7b}
|
|
return btcutil.NewAddressPubKey(serializedPubKey, &btcnet.TestNet3Params)
|
|
},
|
|
net: &btcnet.TestNet3Params,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
// Decode addr and compare error against valid.
|
|
decoded, err := btcutil.DecodeAddress(test.addr, test.net)
|
|
if (err == nil) != test.valid {
|
|
t.Errorf("%v: decoding test failed: %v", test.name, err)
|
|
return
|
|
}
|
|
|
|
if err == nil {
|
|
// Ensure the stringer returns the same address as the
|
|
// original.
|
|
if decodedStringer, ok := decoded.(fmt.Stringer); ok {
|
|
if test.addr != decodedStringer.String() {
|
|
t.Errorf("%v: String on decoded value does not match expected value: %v != %v",
|
|
test.name, test.addr, decodedStringer.String())
|
|
return
|
|
}
|
|
}
|
|
|
|
// Encode again and compare against the original.
|
|
encoded := decoded.EncodeAddress()
|
|
if test.encoded != encoded {
|
|
t.Errorf("%v: decoding and encoding produced different addressess: %v != %v",
|
|
test.name, test.encoded, encoded)
|
|
return
|
|
}
|
|
|
|
// Perform type-specific calculations.
|
|
var saddr []byte
|
|
switch d := decoded.(type) {
|
|
case *btcutil.AddressPubKeyHash:
|
|
saddr = btcutil.TstAddressSAddr(encoded)
|
|
|
|
case *btcutil.AddressScriptHash:
|
|
saddr = btcutil.TstAddressSAddr(encoded)
|
|
|
|
case *btcutil.AddressPubKey:
|
|
// Ignore the error here since the script
|
|
// address is checked below.
|
|
saddr, _ = hex.DecodeString(d.String())
|
|
}
|
|
|
|
// Check script address, as well as the Hash160 method for P2PKH and
|
|
// P2SH addresses.
|
|
if !bytes.Equal(saddr, decoded.ScriptAddress()) {
|
|
t.Errorf("%v: script addresses do not match:\n%x != \n%x",
|
|
test.name, saddr, decoded.ScriptAddress())
|
|
return
|
|
}
|
|
switch a := decoded.(type) {
|
|
case *btcutil.AddressPubKeyHash:
|
|
if h := a.Hash160()[:]; !bytes.Equal(saddr, h) {
|
|
t.Errorf("%v: hashes do not match:\n%x != \n%x",
|
|
test.name, saddr, h)
|
|
return
|
|
}
|
|
|
|
case *btcutil.AddressScriptHash:
|
|
if h := a.Hash160()[:]; !bytes.Equal(saddr, h) {
|
|
t.Errorf("%v: hashes do not match:\n%x != \n%x",
|
|
test.name, saddr, h)
|
|
return
|
|
}
|
|
}
|
|
|
|
// Ensure the address is for the expected network.
|
|
if !decoded.IsForNet(test.net) {
|
|
t.Errorf("%v: calculated network does not match expected",
|
|
test.name)
|
|
return
|
|
}
|
|
}
|
|
|
|
if !test.valid {
|
|
// If address is invalid, but a creation function exists,
|
|
// verify that it returns a nil addr and non-nil error.
|
|
if test.f != nil {
|
|
_, err := test.f()
|
|
if err == nil {
|
|
t.Errorf("%v: address is invalid but creating new address succeeded",
|
|
test.name)
|
|
return
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
// Valid test, compare address created with f against expected result.
|
|
addr, err := test.f()
|
|
if err != nil {
|
|
t.Errorf("%v: address is valid but creating new address failed with error %v",
|
|
test.name, err)
|
|
return
|
|
}
|
|
|
|
if !reflect.DeepEqual(addr, test.result) {
|
|
t.Errorf("%v: created address does not match expected result",
|
|
test.name)
|
|
return
|
|
}
|
|
}
|
|
}
|