1// Copyright (c) 2013-2017 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 5package btcutil_test 6 7import ( 8 "bytes" 9 "encoding/hex" 10 "fmt" 11 "reflect" 12 "strings" 13 "testing" 14 15 "github.com/btcsuite/btcd/chaincfg" 16 "github.com/btcsuite/btcutil" 17 "golang.org/x/crypto/ripemd160" 18) 19 20type CustomParamStruct struct { 21 PubKeyHashAddrID byte 22 ScriptHashAddrID byte 23} 24 25var CustomParams = CustomParamStruct{ 26 PubKeyHashAddrID: 0x30, // starts with L 27 ScriptHashAddrID: 0x32, // starts with M 28} 29 30// We use this function to be able to test functionality in DecodeAddress for 31// defaultNet addresses 32func applyCustomParams(params chaincfg.Params, customParams CustomParamStruct) chaincfg.Params { 33 params.PubKeyHashAddrID = customParams.PubKeyHashAddrID 34 params.ScriptHashAddrID = customParams.ScriptHashAddrID 35 return params 36} 37 38var customParams = applyCustomParams(chaincfg.MainNetParams, CustomParams) 39 40func TestAddresses(t *testing.T) { 41 tests := []struct { 42 name string 43 addr string 44 encoded string 45 valid bool 46 result btcutil.Address 47 f func() (btcutil.Address, error) 48 net *chaincfg.Params 49 }{ 50 // Positive P2PKH tests. 51 { 52 name: "mainnet p2pkh", 53 addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX", 54 encoded: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX", 55 valid: true, 56 result: btcutil.TstAddressPubKeyHash( 57 [ripemd160.Size]byte{ 58 0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc, 59 0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84}, 60 chaincfg.MainNetParams.PubKeyHashAddrID), 61 f: func() (btcutil.Address, error) { 62 pkHash := []byte{ 63 0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc, 64 0xc5, 0x4c, 0xe7, 0xd2, 0xa4, 0x91, 0xbb, 0x4a, 0x0e, 0x84} 65 return btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams) 66 }, 67 net: &chaincfg.MainNetParams, 68 }, 69 { 70 name: "mainnet p2pkh 2", 71 addr: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", 72 encoded: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", 73 valid: true, 74 result: btcutil.TstAddressPubKeyHash( 75 [ripemd160.Size]byte{ 76 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4, 77 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa}, 78 chaincfg.MainNetParams.PubKeyHashAddrID), 79 f: func() (btcutil.Address, error) { 80 pkHash := []byte{ 81 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4, 82 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 0xaa} 83 return btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams) 84 }, 85 net: &chaincfg.MainNetParams, 86 }, 87 { 88 name: "litecoin mainnet p2pkh", 89 addr: "LM2WMpR1Rp6j3Sa59cMXMs1SPzj9eXpGc1", 90 encoded: "LM2WMpR1Rp6j3Sa59cMXMs1SPzj9eXpGc1", 91 valid: true, 92 result: btcutil.TstAddressPubKeyHash( 93 [ripemd160.Size]byte{ 94 0x13, 0xc6, 0x0d, 0x8e, 0x68, 0xd7, 0x34, 0x9f, 0x5b, 0x4c, 95 0xa3, 0x62, 0xc3, 0x95, 0x4b, 0x15, 0x04, 0x50, 0x61, 0xb1}, 96 CustomParams.PubKeyHashAddrID), 97 f: func() (btcutil.Address, error) { 98 pkHash := []byte{ 99 0x13, 0xc6, 0x0d, 0x8e, 0x68, 0xd7, 0x34, 0x9f, 0x5b, 0x4c, 100 0xa3, 0x62, 0xc3, 0x95, 0x4b, 0x15, 0x04, 0x50, 0x61, 0xb1} 101 return btcutil.NewAddressPubKeyHash(pkHash, &customParams) 102 }, 103 net: &customParams, 104 }, 105 { 106 name: "testnet p2pkh", 107 addr: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", 108 encoded: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", 109 valid: true, 110 result: btcutil.TstAddressPubKeyHash( 111 [ripemd160.Size]byte{ 112 0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83, 113 0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f}, 114 chaincfg.TestNet3Params.PubKeyHashAddrID), 115 f: func() (btcutil.Address, error) { 116 pkHash := []byte{ 117 0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83, 118 0xe5, 0x12, 0xd3, 0x60, 0x3f, 0x1f, 0x1c, 0x8d, 0xe6, 0x8f} 119 return btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.TestNet3Params) 120 }, 121 net: &chaincfg.TestNet3Params, 122 }, 123 124 // Negative P2PKH tests. 125 { 126 name: "p2pkh wrong hash length", 127 addr: "", 128 valid: false, 129 f: func() (btcutil.Address, error) { 130 pkHash := []byte{ 131 0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 132 0xf4, 0x05, 0x12, 0xbc, 0xa2, 0xce, 0xb1, 0xdd, 0x80, 0xad, 133 0xaa} 134 return btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams) 135 }, 136 net: &chaincfg.MainNetParams, 137 }, 138 { 139 name: "p2pkh bad checksum", 140 addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gY", 141 valid: false, 142 net: &chaincfg.MainNetParams, 143 }, 144 145 // Positive P2SH tests. 146 { 147 // Taken from transactions: 148 // output: 3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac 149 // input: 837dea37ddc8b1e3ce646f1a656e79bbd8cc7f558ac56a169626d649ebe2a3ba. 150 name: "mainnet p2sh", 151 addr: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", 152 encoded: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", 153 valid: true, 154 result: btcutil.TstAddressScriptHash( 155 [ripemd160.Size]byte{ 156 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 0xf2, 157 0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55, 0x10}, 158 chaincfg.MainNetParams.ScriptHashAddrID), 159 f: func() (btcutil.Address, error) { 160 script := []byte{ 161 0x52, 0x41, 0x04, 0x91, 0xbb, 0xa2, 0x51, 0x09, 0x12, 0xa5, 162 0xbd, 0x37, 0xda, 0x1f, 0xb5, 0xb1, 0x67, 0x30, 0x10, 0xe4, 163 0x3d, 0x2c, 0x6d, 0x81, 0x2c, 0x51, 0x4e, 0x91, 0xbf, 0xa9, 164 0xf2, 0xeb, 0x12, 0x9e, 0x1c, 0x18, 0x33, 0x29, 0xdb, 0x55, 165 0xbd, 0x86, 0x8e, 0x20, 0x9a, 0xac, 0x2f, 0xbc, 0x02, 0xcb, 166 0x33, 0xd9, 0x8f, 0xe7, 0x4b, 0xf2, 0x3f, 0x0c, 0x23, 0x5d, 167 0x61, 0x26, 0xb1, 0xd8, 0x33, 0x4f, 0x86, 0x41, 0x04, 0x86, 168 0x5c, 0x40, 0x29, 0x3a, 0x68, 0x0c, 0xb9, 0xc0, 0x20, 0xe7, 169 0xb1, 0xe1, 0x06, 0xd8, 0xc1, 0x91, 0x6d, 0x3c, 0xef, 0x99, 170 0xaa, 0x43, 0x1a, 0x56, 0xd2, 0x53, 0xe6, 0x92, 0x56, 0xda, 171 0xc0, 0x9e, 0xf1, 0x22, 0xb1, 0xa9, 0x86, 0x81, 0x8a, 0x7c, 172 0xb6, 0x24, 0x53, 0x2f, 0x06, 0x2c, 0x1d, 0x1f, 0x87, 0x22, 173 0x08, 0x48, 0x61, 0xc5, 0xc3, 0x29, 0x1c, 0xcf, 0xfe, 0xf4, 174 0xec, 0x68, 0x74, 0x41, 0x04, 0x8d, 0x24, 0x55, 0xd2, 0x40, 175 0x3e, 0x08, 0x70, 0x8f, 0xc1, 0xf5, 0x56, 0x00, 0x2f, 0x1b, 176 0x6c, 0xd8, 0x3f, 0x99, 0x2d, 0x08, 0x50, 0x97, 0xf9, 0x97, 177 0x4a, 0xb0, 0x8a, 0x28, 0x83, 0x8f, 0x07, 0x89, 0x6f, 0xba, 178 0xb0, 0x8f, 0x39, 0x49, 0x5e, 0x15, 0xfa, 0x6f, 0xad, 0x6e, 179 0xdb, 0xfb, 0x1e, 0x75, 0x4e, 0x35, 0xfa, 0x1c, 0x78, 0x44, 180 0xc4, 0x1f, 0x32, 0x2a, 0x18, 0x63, 0xd4, 0x62, 0x13, 0x53, 181 0xae} 182 return btcutil.NewAddressScriptHash(script, &chaincfg.MainNetParams) 183 }, 184 net: &chaincfg.MainNetParams, 185 }, 186 { 187 name: "litecoin mainnet P2SH ", 188 addr: "MVcg9uEvtWuP5N6V48EHfEtbz48qR8TKZ9", 189 encoded: "MVcg9uEvtWuP5N6V48EHfEtbz48qR8TKZ9", 190 valid: true, 191 result: btcutil.TstAddressScriptHash( 192 [ripemd160.Size]byte{ 193 0xee, 0x34, 0xac, 0x67, 0x6b, 0xda, 0xf6, 0xe3, 0x70, 0xc8, 194 0xc8, 0x20, 0xb9, 0x48, 0xed, 0xfa, 0xd3, 0xa8, 0x73, 0xd8}, 195 CustomParams.ScriptHashAddrID), 196 f: func() (btcutil.Address, error) { 197 pkHash := []byte{ 198 0xEE, 0x34, 0xAC, 0x67, 0x6B, 0xDA, 0xF6, 0xE3, 0x70, 0xC8, 199 0xC8, 0x20, 0xB9, 0x48, 0xED, 0xFA, 0xD3, 0xA8, 0x73, 0xD8} 200 return btcutil.NewAddressScriptHashFromHash(pkHash, &customParams) 201 }, 202 net: &customParams, 203 }, 204 { 205 // Taken from transactions: 206 // output: b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d 207 // input: (not yet redeemed at time test was written) 208 name: "mainnet p2sh 2", 209 addr: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8", 210 encoded: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8", 211 valid: true, 212 result: btcutil.TstAddressScriptHash( 213 [ripemd160.Size]byte{ 214 0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37, 215 0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4}, 216 chaincfg.MainNetParams.ScriptHashAddrID), 217 f: func() (btcutil.Address, error) { 218 hash := []byte{ 219 0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37, 220 0xc0, 0x51, 0x99, 0x29, 0x01, 0x9e, 0xf8, 0x6e, 0xb5, 0xb4} 221 return btcutil.NewAddressScriptHashFromHash(hash, &chaincfg.MainNetParams) 222 }, 223 net: &chaincfg.MainNetParams, 224 }, 225 { 226 // Taken from bitcoind base58_keys_valid. 227 name: "testnet p2sh", 228 addr: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", 229 encoded: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", 230 valid: true, 231 result: btcutil.TstAddressScriptHash( 232 [ripemd160.Size]byte{ 233 0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e, 234 0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a}, 235 chaincfg.TestNet3Params.ScriptHashAddrID), 236 f: func() (btcutil.Address, error) { 237 hash := []byte{ 238 0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e, 239 0x2c, 0xdc, 0x28, 0x56, 0x17, 0x04, 0x0c, 0x92, 0x4a, 0x0a} 240 return btcutil.NewAddressScriptHashFromHash(hash, &chaincfg.TestNet3Params) 241 }, 242 net: &chaincfg.TestNet3Params, 243 }, 244 245 // Negative P2SH tests. 246 { 247 name: "p2sh wrong hash length", 248 addr: "", 249 valid: false, 250 f: func() (btcutil.Address, error) { 251 hash := []byte{ 252 0x00, 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 253 0xf2, 0xa0, 0x0a, 0xbd, 0x1b, 0xf3, 0xdc, 0x91, 0xe9, 0x55, 254 0x10} 255 return btcutil.NewAddressScriptHashFromHash(hash, &chaincfg.MainNetParams) 256 }, 257 net: &chaincfg.MainNetParams, 258 }, 259 260 // Positive P2PK tests. 261 { 262 name: "mainnet p2pk compressed (0x02)", 263 addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4", 264 encoded: "13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg", 265 valid: true, 266 result: btcutil.TstAddressPubKey( 267 []byte{ 268 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 269 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 270 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 271 0x52, 0xc6, 0xb4}, 272 btcutil.PKFCompressed, chaincfg.MainNetParams.PubKeyHashAddrID), 273 f: func() (btcutil.Address, error) { 274 serializedPubKey := []byte{ 275 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 276 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 277 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 278 0x52, 0xc6, 0xb4} 279 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams) 280 }, 281 net: &chaincfg.MainNetParams, 282 }, 283 { 284 name: "mainnet p2pk compressed (0x03)", 285 addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65", 286 encoded: "15sHANNUBSh6nDp8XkDPmQcW6n3EFwmvE6", 287 valid: true, 288 result: btcutil.TstAddressPubKey( 289 []byte{ 290 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 291 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 292 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 293 0xb1, 0x6e, 0x65}, 294 btcutil.PKFCompressed, chaincfg.MainNetParams.PubKeyHashAddrID), 295 f: func() (btcutil.Address, error) { 296 serializedPubKey := []byte{ 297 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 298 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 299 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 300 0xb1, 0x6e, 0x65} 301 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams) 302 }, 303 net: &chaincfg.MainNetParams, 304 }, 305 { 306 name: "mainnet p2pk uncompressed (0x04)", 307 addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2" + 308 "e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", 309 encoded: "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", 310 valid: true, 311 result: btcutil.TstAddressPubKey( 312 []byte{ 313 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, 314 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38, 315 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, 316 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, 317 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 318 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 319 0xf6, 0x56, 0xb4, 0x12, 0xa3}, 320 btcutil.PKFUncompressed, chaincfg.MainNetParams.PubKeyHashAddrID), 321 f: func() (btcutil.Address, error) { 322 serializedPubKey := []byte{ 323 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, 324 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38, 325 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, 326 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, 327 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 328 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 329 0xf6, 0x56, 0xb4, 0x12, 0xa3} 330 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams) 331 }, 332 net: &chaincfg.MainNetParams, 333 }, 334 { 335 name: "mainnet p2pk hybrid (0x06)", 336 addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4" + 337 "0d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e", 338 encoded: "1Ja5rs7XBZnK88EuLVcFqYGMEbBitzchmX", 339 valid: true, 340 result: btcutil.TstAddressPubKey( 341 []byte{ 342 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 343 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 344 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 345 0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd, 346 0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73, 347 0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c, 348 0x44, 0xd3, 0x3f, 0x45, 0x3e}, 349 btcutil.PKFHybrid, chaincfg.MainNetParams.PubKeyHashAddrID), 350 f: func() (btcutil.Address, error) { 351 serializedPubKey := []byte{ 352 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 353 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 354 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 355 0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd, 356 0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73, 357 0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c, 358 0x44, 0xd3, 0x3f, 0x45, 0x3e} 359 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams) 360 }, 361 net: &chaincfg.MainNetParams, 362 }, 363 { 364 name: "mainnet p2pk hybrid (0x07)", 365 addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65" + 366 "37a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b", 367 encoded: "1ExqMmf6yMxcBMzHjbj41wbqYuqoX6uBLG", 368 valid: true, 369 result: btcutil.TstAddressPubKey( 370 []byte{ 371 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 372 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 373 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 374 0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66, 375 0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71, 376 0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c, 377 0x1e, 0x09, 0x08, 0xef, 0x7b}, 378 btcutil.PKFHybrid, chaincfg.MainNetParams.PubKeyHashAddrID), 379 f: func() (btcutil.Address, error) { 380 serializedPubKey := []byte{ 381 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 382 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 383 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 384 0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66, 385 0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71, 386 0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c, 387 0x1e, 0x09, 0x08, 0xef, 0x7b} 388 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.MainNetParams) 389 }, 390 net: &chaincfg.MainNetParams, 391 }, 392 { 393 name: "testnet p2pk compressed (0x02)", 394 addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4", 395 encoded: "mhiDPVP2nJunaAgTjzWSHCYfAqxxrxzjmo", 396 valid: true, 397 result: btcutil.TstAddressPubKey( 398 []byte{ 399 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 400 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 401 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 402 0x52, 0xc6, 0xb4}, 403 btcutil.PKFCompressed, chaincfg.TestNet3Params.PubKeyHashAddrID), 404 f: func() (btcutil.Address, error) { 405 serializedPubKey := []byte{ 406 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 407 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 408 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 409 0x52, 0xc6, 0xb4} 410 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.TestNet3Params) 411 }, 412 net: &chaincfg.TestNet3Params, 413 }, 414 { 415 name: "testnet p2pk compressed (0x03)", 416 addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65", 417 encoded: "mkPETRTSzU8MZLHkFKBmbKppxmdw9qT42t", 418 valid: true, 419 result: btcutil.TstAddressPubKey( 420 []byte{ 421 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 422 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 423 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 424 0xb1, 0x6e, 0x65}, 425 btcutil.PKFCompressed, chaincfg.TestNet3Params.PubKeyHashAddrID), 426 f: func() (btcutil.Address, error) { 427 serializedPubKey := []byte{ 428 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 429 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 430 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 431 0xb1, 0x6e, 0x65} 432 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.TestNet3Params) 433 }, 434 net: &chaincfg.TestNet3Params, 435 }, 436 { 437 name: "testnet p2pk uncompressed (0x04)", 438 addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5" + 439 "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", 440 encoded: "mh8YhPYEAYs3E7EVyKtB5xrcfMExkkdEMF", 441 valid: true, 442 result: btcutil.TstAddressPubKey( 443 []byte{ 444 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, 445 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38, 446 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, 447 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, 448 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 449 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 450 0xf6, 0x56, 0xb4, 0x12, 0xa3}, 451 btcutil.PKFUncompressed, chaincfg.TestNet3Params.PubKeyHashAddrID), 452 f: func() (btcutil.Address, error) { 453 serializedPubKey := []byte{ 454 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, 455 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38, 456 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, 457 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, 458 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 459 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 460 0xf6, 0x56, 0xb4, 0x12, 0xa3} 461 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.TestNet3Params) 462 }, 463 net: &chaincfg.TestNet3Params, 464 }, 465 { 466 name: "testnet p2pk hybrid (0x06)", 467 addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b" + 468 "40d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e", 469 encoded: "my639vCVzbDZuEiX44adfTUg6anRomZLEP", 470 valid: true, 471 result: btcutil.TstAddressPubKey( 472 []byte{ 473 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 474 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 475 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 476 0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd, 477 0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73, 478 0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c, 479 0x44, 0xd3, 0x3f, 0x45, 0x3e}, 480 btcutil.PKFHybrid, chaincfg.TestNet3Params.PubKeyHashAddrID), 481 f: func() (btcutil.Address, error) { 482 serializedPubKey := []byte{ 483 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, 484 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d, 0x8d, 0x79, 0x03, 485 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 486 0x52, 0xc6, 0xb4, 0x0d, 0x45, 0x26, 0x48, 0x38, 0xc0, 0xbd, 487 0x96, 0x85, 0x26, 0x62, 0xce, 0x6a, 0x84, 0x7b, 0x19, 0x73, 488 0x76, 0x83, 0x01, 0x60, 0xc6, 0xd2, 0xeb, 0x5e, 0x6a, 0x4c, 489 0x44, 0xd3, 0x3f, 0x45, 0x3e} 490 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.TestNet3Params) 491 }, 492 net: &chaincfg.TestNet3Params, 493 }, 494 { 495 name: "testnet p2pk hybrid (0x07)", 496 addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6" + 497 "537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b", 498 encoded: "muUnepk5nPPrxUTuTAhRqrpAQuSWS5fVii", 499 valid: true, 500 result: btcutil.TstAddressPubKey( 501 []byte{ 502 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 503 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 504 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 505 0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66, 506 0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71, 507 0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c, 508 0x1e, 0x09, 0x08, 0xef, 0x7b}, 509 btcutil.PKFHybrid, chaincfg.TestNet3Params.PubKeyHashAddrID), 510 f: func() (btcutil.Address, error) { 511 serializedPubKey := []byte{ 512 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, 513 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, 514 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 515 0xb1, 0x6e, 0x65, 0x37, 0xa5, 0x76, 0x78, 0x2e, 0xba, 0x66, 516 0x8a, 0x7e, 0xf8, 0xbd, 0x3b, 0x3c, 0xfb, 0x1e, 0xdb, 0x71, 517 0x17, 0xab, 0x65, 0x12, 0x9b, 0x8a, 0x2e, 0x68, 0x1f, 0x3c, 518 0x1e, 0x09, 0x08, 0xef, 0x7b} 519 return btcutil.NewAddressPubKey(serializedPubKey, &chaincfg.TestNet3Params) 520 }, 521 net: &chaincfg.TestNet3Params, 522 }, 523 // Segwit address tests. 524 { 525 name: "segwit mainnet p2wpkh v0", 526 addr: "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", 527 encoded: "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", 528 valid: true, 529 result: btcutil.TstAddressWitnessPubKeyHash( 530 0, 531 [20]byte{ 532 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 533 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}, 534 chaincfg.MainNetParams.Bech32HRPSegwit), 535 f: func() (btcutil.Address, error) { 536 pkHash := []byte{ 537 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 538 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6} 539 return btcutil.NewAddressWitnessPubKeyHash(pkHash, &chaincfg.MainNetParams) 540 }, 541 net: &chaincfg.MainNetParams, 542 }, 543 { 544 name: "segwit mainnet p2wsh v0", 545 addr: "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", 546 encoded: "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", 547 valid: true, 548 result: btcutil.TstAddressWitnessScriptHash( 549 0, 550 [32]byte{ 551 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 552 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 553 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 554 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}, 555 chaincfg.MainNetParams.Bech32HRPSegwit), 556 f: func() (btcutil.Address, error) { 557 scriptHash := []byte{ 558 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 559 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 560 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 561 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62} 562 return btcutil.NewAddressWitnessScriptHash(scriptHash, &chaincfg.MainNetParams) 563 }, 564 net: &chaincfg.MainNetParams, 565 }, 566 { 567 name: "segwit testnet p2wpkh v0", 568 addr: "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", 569 encoded: "tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx", 570 valid: true, 571 result: btcutil.TstAddressWitnessPubKeyHash( 572 0, 573 [20]byte{ 574 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 575 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}, 576 chaincfg.TestNet3Params.Bech32HRPSegwit), 577 f: func() (btcutil.Address, error) { 578 pkHash := []byte{ 579 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 580 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6} 581 return btcutil.NewAddressWitnessPubKeyHash(pkHash, &chaincfg.TestNet3Params) 582 }, 583 net: &chaincfg.TestNet3Params, 584 }, 585 { 586 name: "segwit testnet p2wsh v0", 587 addr: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", 588 encoded: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", 589 valid: true, 590 result: btcutil.TstAddressWitnessScriptHash( 591 0, 592 [32]byte{ 593 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 594 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 595 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 596 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}, 597 chaincfg.TestNet3Params.Bech32HRPSegwit), 598 f: func() (btcutil.Address, error) { 599 scriptHash := []byte{ 600 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 601 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 602 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 603 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62} 604 return btcutil.NewAddressWitnessScriptHash(scriptHash, &chaincfg.TestNet3Params) 605 }, 606 net: &chaincfg.TestNet3Params, 607 }, 608 { 609 name: "segwit testnet p2wsh witness v0", 610 addr: "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", 611 encoded: "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", 612 valid: true, 613 result: btcutil.TstAddressWitnessScriptHash( 614 0, 615 [32]byte{ 616 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 617 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 618 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2, 619 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}, 620 chaincfg.TestNet3Params.Bech32HRPSegwit), 621 f: func() (btcutil.Address, error) { 622 scriptHash := []byte{ 623 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 624 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 625 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2, 626 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33} 627 return btcutil.NewAddressWitnessScriptHash(scriptHash, &chaincfg.TestNet3Params) 628 }, 629 net: &chaincfg.TestNet3Params, 630 }, 631 // Unsupported witness versions (version 0 only supported at this point) 632 { 633 name: "segwit mainnet witness v1", 634 addr: "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", 635 valid: false, 636 net: &chaincfg.MainNetParams, 637 }, 638 { 639 name: "segwit mainnet witness v16", 640 addr: "BC1SW50QA3JX3S", 641 valid: false, 642 net: &chaincfg.MainNetParams, 643 }, 644 { 645 name: "segwit mainnet witness v2", 646 addr: "bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", 647 valid: false, 648 net: &chaincfg.MainNetParams, 649 }, 650 // Invalid segwit addresses 651 { 652 name: "segwit invalid hrp", 653 addr: "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", 654 valid: false, 655 net: &chaincfg.TestNet3Params, 656 }, 657 { 658 name: "segwit invalid checksum", 659 addr: "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", 660 valid: false, 661 net: &chaincfg.MainNetParams, 662 }, 663 { 664 name: "segwit invalid witness version", 665 addr: "BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", 666 valid: false, 667 net: &chaincfg.MainNetParams, 668 }, 669 { 670 name: "segwit invalid program length", 671 addr: "bc1rw5uspcuh", 672 valid: false, 673 net: &chaincfg.MainNetParams, 674 }, 675 { 676 name: "segwit invalid program length", 677 addr: "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", 678 valid: false, 679 net: &chaincfg.MainNetParams, 680 }, 681 { 682 name: "segwit invalid program length for witness version 0 (per BIP141)", 683 addr: "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", 684 valid: false, 685 net: &chaincfg.MainNetParams, 686 }, 687 { 688 name: "segwit mixed case", 689 addr: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", 690 valid: false, 691 net: &chaincfg.TestNet3Params, 692 }, 693 { 694 name: "segwit zero padding of more than 4 bits", 695 addr: "tb1pw508d6qejxtdg4y5r3zarqfsj6c3", 696 valid: false, 697 net: &chaincfg.TestNet3Params, 698 }, 699 { 700 name: "segwit non-zero padding in 8-to-5 conversion", 701 addr: "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", 702 valid: false, 703 net: &chaincfg.TestNet3Params, 704 }, 705 } 706 707 for _, test := range tests { 708 // Decode addr and compare error against valid. 709 decoded, err := btcutil.DecodeAddress(test.addr, test.net) 710 if (err == nil) != test.valid { 711 t.Errorf("%v: decoding test failed: %v", test.name, err) 712 return 713 } 714 715 if err == nil { 716 // Ensure the stringer returns the same address as the 717 // original. 718 if decodedStringer, ok := decoded.(fmt.Stringer); ok { 719 addr := test.addr 720 721 // For Segwit addresses the string representation 722 // will always be lower case, so in that case we 723 // convert the original to lower case first. 724 if strings.Contains(test.name, "segwit") { 725 addr = strings.ToLower(addr) 726 } 727 728 if addr != decodedStringer.String() { 729 t.Errorf("%v: String on decoded value does not match expected value: %v != %v", 730 test.name, test.addr, decodedStringer.String()) 731 return 732 } 733 } 734 735 // Encode again and compare against the original. 736 encoded := decoded.EncodeAddress() 737 if test.encoded != encoded { 738 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v", 739 test.name, test.encoded, encoded) 740 return 741 } 742 743 // Perform type-specific calculations. 744 var saddr []byte 745 switch d := decoded.(type) { 746 case *btcutil.AddressPubKeyHash: 747 saddr = btcutil.TstAddressSAddr(encoded) 748 749 case *btcutil.AddressScriptHash: 750 saddr = btcutil.TstAddressSAddr(encoded) 751 752 case *btcutil.AddressPubKey: 753 // Ignore the error here since the script 754 // address is checked below. 755 saddr, _ = hex.DecodeString(d.String()) 756 case *btcutil.AddressWitnessPubKeyHash: 757 saddr = btcutil.TstAddressSegwitSAddr(encoded) 758 case *btcutil.AddressWitnessScriptHash: 759 saddr = btcutil.TstAddressSegwitSAddr(encoded) 760 } 761 762 // Check script address, as well as the Hash160 method for P2PKH and 763 // P2SH addresses. 764 if !bytes.Equal(saddr, decoded.ScriptAddress()) { 765 t.Errorf("%v: script addresses do not match:\n%x != \n%x", 766 test.name, saddr, decoded.ScriptAddress()) 767 return 768 } 769 switch a := decoded.(type) { 770 case *btcutil.AddressPubKeyHash: 771 if h := a.Hash160()[:]; !bytes.Equal(saddr, h) { 772 t.Errorf("%v: hashes do not match:\n%x != \n%x", 773 test.name, saddr, h) 774 return 775 } 776 777 case *btcutil.AddressScriptHash: 778 if h := a.Hash160()[:]; !bytes.Equal(saddr, h) { 779 t.Errorf("%v: hashes do not match:\n%x != \n%x", 780 test.name, saddr, h) 781 return 782 } 783 784 case *btcutil.AddressWitnessPubKeyHash: 785 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp { 786 t.Errorf("%v: hrps do not match:\n%x != \n%x", 787 test.name, test.net.Bech32HRPSegwit, hrp) 788 return 789 } 790 791 expVer := test.result.(*btcutil.AddressWitnessPubKeyHash).WitnessVersion() 792 if v := a.WitnessVersion(); v != expVer { 793 t.Errorf("%v: witness versions do not match:\n%x != \n%x", 794 test.name, expVer, v) 795 return 796 } 797 798 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) { 799 t.Errorf("%v: witness programs do not match:\n%x != \n%x", 800 test.name, saddr, p) 801 return 802 } 803 804 case *btcutil.AddressWitnessScriptHash: 805 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp { 806 t.Errorf("%v: hrps do not match:\n%x != \n%x", 807 test.name, test.net.Bech32HRPSegwit, hrp) 808 return 809 } 810 811 expVer := test.result.(*btcutil.AddressWitnessScriptHash).WitnessVersion() 812 if v := a.WitnessVersion(); v != expVer { 813 t.Errorf("%v: witness versions do not match:\n%x != \n%x", 814 test.name, expVer, v) 815 return 816 } 817 818 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) { 819 t.Errorf("%v: witness programs do not match:\n%x != \n%x", 820 test.name, saddr, p) 821 return 822 } 823 } 824 825 // Ensure the address is for the expected network. 826 if !decoded.IsForNet(test.net) { 827 t.Errorf("%v: calculated network does not match expected", 828 test.name) 829 return 830 } 831 } 832 833 if !test.valid { 834 // If address is invalid, but a creation function exists, 835 // verify that it returns a nil addr and non-nil error. 836 if test.f != nil { 837 _, err := test.f() 838 if err == nil { 839 t.Errorf("%v: address is invalid but creating new address succeeded", 840 test.name) 841 return 842 } 843 } 844 continue 845 } 846 847 // Valid test, compare address created with f against expected result. 848 addr, err := test.f() 849 if err != nil { 850 t.Errorf("%v: address is valid but creating new address failed with error %v", 851 test.name, err) 852 return 853 } 854 855 if !reflect.DeepEqual(addr, test.result) { 856 t.Errorf("%v: created address does not match expected result", 857 test.name) 858 return 859 } 860 } 861} 862