lbcutil/address_test.go
Josh Rickmar bff18e5a93 Introduce better WIF API.
The old functions DecodePrivateKey and EncodePrivateKey have been
removed in favor of the DecodeWIF function and the String method of
the new WIF type.

ok @davecgh
2014-05-21 17:49:37 -05:00

591 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"
"code.google.com/p/go.crypto/ripemd160"
"encoding/hex"
"fmt"
"github.com/conformal/btcutil"
"github.com/conformal/btcwire"
"reflect"
"testing"
)
// 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 btcwire.BitcoinNet
}{
// 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},
btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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},
btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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},
btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
// Negative P2PKH tests.
{
name: "p2pkh wrong byte identifier/net",
addr: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
encoded: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz",
valid: false,
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, invalidNet)
},
},
{
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, btcwire.MainNet)
},
},
{
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},
btcutil.MainNetScriptHash),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
// 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},
btcutil.MainNetScriptHash),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
// 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},
btcutil.TestNetScriptHash),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
// 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, btcwire.MainNet)
},
},
{
name: "p2sh wrong byte identifier/net",
addr: "0NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n",
valid: false,
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, invalidNet)
},
},
// 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, btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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, btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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, btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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, btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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, btcutil.MainNetAddr),
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, btcwire.MainNet)
},
net: btcwire.MainNet,
},
{
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, btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
{
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, btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
{
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, btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
{
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, btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
{
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, btcutil.TestNetAddr),
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, btcwire.TestNet3)
},
net: btcwire.TestNet3,
},
}
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
}
}
}