github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/common/address_test.go (about) 1 package common 2 3 import ( 4 "bytes" 5 "fmt" 6 "reflect" 7 "strings" 8 "testing" 9 10 "github.com/bytom/bytom/common/bech32" 11 "github.com/bytom/bytom/consensus" 12 ) 13 14 func TestAddresses(t *testing.T) { 15 tests := []struct { 16 name string 17 addr string 18 encoded string 19 valid bool 20 result Address 21 f func() (Address, error) 22 net *consensus.Params 23 }{ 24 // Segwit address tests. 25 { 26 name: "segwit mainnet p2wpkh v0", 27 addr: "BN1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KCG05Q0", 28 encoded: "bn1qw508d6qejxtdg4y5r3zarvary0c5xw7kcg05q0", 29 valid: true, 30 result: tstAddressWitnessPubKeyHash( 31 0, 32 [20]byte{ 33 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 34 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}, 35 consensus.MainNetParams.Bech32HRPSegwit), 36 f: func() (Address, error) { 37 pkHash := []byte{ 38 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 39 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6} 40 return NewAddressWitnessPubKeyHash(pkHash, &consensus.MainNetParams) 41 }, 42 net: &consensus.MainNetParams, 43 }, 44 { 45 name: "segwit mainnet p2wsh v0", 46 addr: "bn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q4ej274", 47 encoded: "bn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q4ej274", 48 valid: true, 49 result: tstAddressWitnessScriptHash( 50 0, 51 [32]byte{ 52 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 53 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 54 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 55 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}, 56 consensus.MainNetParams.Bech32HRPSegwit), 57 f: func() (Address, error) { 58 scriptHash := []byte{ 59 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 60 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 61 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 62 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62} 63 return NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams) 64 }, 65 net: &consensus.MainNetParams, 66 }, 67 { 68 name: "segwit testnet p2wpkh v0", 69 addr: "tn1qw508d6qejxtdg4y5r3zarvary0c5xw7ku7wsq7", 70 encoded: "tn1qw508d6qejxtdg4y5r3zarvary0c5xw7ku7wsq7", 71 valid: true, 72 result: tstAddressWitnessPubKeyHash( 73 0, 74 [20]byte{ 75 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 76 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}, 77 consensus.TestNetParams.Bech32HRPSegwit), 78 f: func() (Address, error) { 79 pkHash := []byte{ 80 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 81 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6} 82 return NewAddressWitnessPubKeyHash(pkHash, &consensus.TestNetParams) 83 }, 84 net: &consensus.TestNetParams, 85 }, 86 { 87 name: "segwit testnet p2wsh v0", 88 addr: "tn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qrd6us3", 89 encoded: "tn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qrd6us3", 90 valid: true, 91 result: tstAddressWitnessScriptHash( 92 0, 93 [32]byte{ 94 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 95 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 96 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 97 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}, 98 consensus.TestNetParams.Bech32HRPSegwit), 99 f: func() (Address, error) { 100 scriptHash := []byte{ 101 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 102 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 103 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1, 104 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62} 105 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams) 106 }, 107 net: &consensus.TestNetParams, 108 }, 109 { 110 name: "segwit testnet p2wsh witness v0", 111 addr: "tn1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses0mjj3t", 112 encoded: "tn1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses0mjj3t", 113 valid: true, 114 result: tstAddressWitnessScriptHash( 115 0, 116 [32]byte{ 117 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 118 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 119 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2, 120 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}, 121 consensus.TestNetParams.Bech32HRPSegwit), 122 f: func() (Address, error) { 123 scriptHash := []byte{ 124 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 125 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 126 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2, 127 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33} 128 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams) 129 }, 130 net: &consensus.TestNetParams, 131 }, 132 // Unsupported witness versions (version 0 only supported at this point) 133 { 134 name: "segwit mainnet witness v1", 135 addr: "bn1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", 136 valid: false, 137 net: &consensus.MainNetParams, 138 }, 139 { 140 name: "segwit mainnet witness v16", 141 addr: "BN1SW50QA3JX3S", 142 valid: false, 143 net: &consensus.MainNetParams, 144 }, 145 { 146 name: "segwit mainnet witness v2", 147 addr: "bn1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", 148 valid: false, 149 net: &consensus.MainNetParams, 150 }, 151 // Invalid segwit addresses 152 { 153 name: "segwit invalid hrp", 154 addr: "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", 155 valid: false, 156 net: &consensus.TestNetParams, 157 }, 158 { 159 name: "segwit invalid checksum", 160 addr: "bn1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", 161 valid: false, 162 net: &consensus.MainNetParams, 163 }, 164 { 165 name: "segwit invalid witness version", 166 addr: "BN13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", 167 valid: false, 168 net: &consensus.MainNetParams, 169 }, 170 { 171 name: "segwit invalid program length", 172 addr: "bn1rw5uspcuh", 173 valid: false, 174 net: &consensus.MainNetParams, 175 }, 176 { 177 name: "segwit invalid program length", 178 addr: "bn10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", 179 valid: false, 180 net: &consensus.MainNetParams, 181 }, 182 { 183 name: "segwit invalid program length for witness version 0 (per BIP141)", 184 addr: "BN1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", 185 valid: false, 186 net: &consensus.MainNetParams, 187 }, 188 { 189 name: "segwit mixed case", 190 addr: "tn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", 191 valid: false, 192 net: &consensus.TestNetParams, 193 }, 194 { 195 name: "segwit zero padding of more than 4 bits", 196 addr: "tn1pw508d6qejxtdg4y5r3zarqfsj6c3", 197 valid: false, 198 net: &consensus.TestNetParams, 199 }, 200 { 201 name: "segwit non-zero padding in 8-to-5 conversion", 202 addr: "tn1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", 203 valid: false, 204 net: &consensus.TestNetParams, 205 }, 206 } 207 208 for _, test := range tests { 209 // Decode addr and compare error against valid. 210 decoded, err := DecodeAddress(test.addr, test.net) 211 if (err == nil) != test.valid { 212 t.Errorf("%v: decoding test failed: %v", test.name, err) 213 return 214 } 215 216 if err == nil { 217 // Ensure the stringer returns the same address as the 218 // original. 219 220 if decodedStringer, ok := decoded.(fmt.Stringer); ok { 221 addr := test.addr 222 223 // For Segwit addresses the string representation 224 // will always be lower case, so in that case we 225 // convert the original to lower case first. 226 if strings.Contains(test.name, "segwit") { 227 addr = strings.ToLower(addr) 228 } 229 230 if addr != decodedStringer.String() { 231 t.Errorf("%v: String on decoded value does not match expected value: %v != %v", 232 test.name, test.addr, decodedStringer.String()) 233 return 234 } 235 236 } 237 238 // Encode again and compare against the original. 239 encoded := decoded.EncodeAddress() 240 if test.encoded != encoded { 241 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v", 242 test.name, test.encoded, encoded) 243 return 244 } 245 246 // Perform type-specific calculations. 247 var saddr []byte 248 switch decoded.(type) { 249 250 case *AddressWitnessPubKeyHash: 251 saddr = tstAddressSegwitSAddr(encoded) 252 case *AddressWitnessScriptHash: 253 saddr = tstAddressSegwitSAddr(encoded) 254 } 255 256 // Check script address, as well as the Hash160 method for P2PKH and 257 // P2SH addresses. 258 if !bytes.Equal(saddr, decoded.ScriptAddress()) { 259 t.Errorf("%v: script addresses do not match:\n%x != \n%x", 260 test.name, saddr, decoded.ScriptAddress()) 261 return 262 } 263 switch a := decoded.(type) { 264 265 case *AddressWitnessPubKeyHash: 266 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp { 267 t.Errorf("%v: hrps do not match:\n%x != \n%x", 268 test.name, test.net.Bech32HRPSegwit, hrp) 269 return 270 } 271 272 expVer := test.result.(*AddressWitnessPubKeyHash).WitnessVersion() 273 if v := a.WitnessVersion(); v != expVer { 274 t.Errorf("%v: witness versions do not match:\n%x != \n%x", 275 test.name, expVer, v) 276 return 277 } 278 279 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) { 280 t.Errorf("%v: witness programs do not match:\n%x != \n%x", 281 test.name, saddr, p) 282 return 283 } 284 285 case *AddressWitnessScriptHash: 286 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp { 287 t.Errorf("%v: hrps do not match:\n%x != \n%x", 288 test.name, test.net.Bech32HRPSegwit, hrp) 289 return 290 } 291 292 expVer := test.result.(*AddressWitnessScriptHash).WitnessVersion() 293 if v := a.WitnessVersion(); v != expVer { 294 t.Errorf("%v: witness versions do not match:\n%x != \n%x", 295 test.name, expVer, v) 296 return 297 } 298 299 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) { 300 t.Errorf("%v: witness programs do not match:\n%x != \n%x", 301 test.name, saddr, p) 302 return 303 } 304 } 305 306 // Ensure the address is for the expected network. 307 if !decoded.IsForNet(test.net) { 308 t.Errorf("%v: calculated network does not match expected", 309 test.name) 310 return 311 } 312 } 313 314 if !test.valid { 315 // If address is invalid, but a creation function exists, 316 // verify that it returns a nil addr and non-nil error. 317 if test.f != nil { 318 _, err := test.f() 319 if err == nil { 320 t.Errorf("%v: address is invalid but creating new address succeeded", 321 test.name) 322 return 323 } 324 } 325 continue 326 } 327 328 // Valid test, compare address created with f against expected result. 329 addr, err := test.f() 330 if err != nil { 331 t.Errorf("%v: address is valid but creating new address failed with error %v", 332 test.name, err) 333 return 334 } 335 336 if !reflect.DeepEqual(addr, test.result) { 337 t.Errorf("%v: created address does not match expected result", 338 test.name) 339 return 340 } 341 } 342 } 343 344 // TstAddressWitnessPubKeyHash creates an AddressWitnessPubKeyHash, initiating 345 // the fields as given. 346 func tstAddressWitnessPubKeyHash(version byte, program [20]byte, 347 hrp string) *AddressWitnessPubKeyHash { 348 349 return &AddressWitnessPubKeyHash{ 350 hrp: hrp, 351 witnessVersion: version, 352 witnessProgram: program, 353 } 354 } 355 356 // TstAddressWitnessScriptHash creates an AddressWitnessScriptHash, initiating 357 // the fields as given. 358 func tstAddressWitnessScriptHash(version byte, program [32]byte, 359 hrp string) *AddressWitnessScriptHash { 360 361 return &AddressWitnessScriptHash{ 362 hrp: hrp, 363 witnessVersion: version, 364 witnessProgram: program, 365 } 366 } 367 368 // TstAddressSegwitSAddr returns the expected witness program bytes for 369 // bech32 encoded P2WPKH and P2WSH bitcoin addresses. 370 func tstAddressSegwitSAddr(addr string) []byte { 371 _, data, err := bech32.Bech32Decode(addr) 372 if err != nil { 373 return []byte{} 374 } 375 376 // First byte is version, rest is base 32 encoded data. 377 data, err = bech32.ConvertBits(data[1:], 5, 8, false) 378 if err != nil { 379 return []byte{} 380 } 381 return data 382 }