10 "github.com/bytom/consensus"
11 "github.com/bytom/common/bech32"
15 func TestAddresses(t *testing.T) {
22 f func() (Address, error)
25 // Segwit address tests.
27 name: "segwit mainnet p2wpkh v0",
28 addr: "BM1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7K23GYYF",
29 encoded: "bm1qw508d6qejxtdg4y5r3zarvary0c5xw7k23gyyf",
31 result: tstAddressWitnessPubKeyHash(
34 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
35 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6},
36 consensus.MainNetParams.Bech32HRPSegwit),
37 f: func() (Address, error) {
39 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
40 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}
41 return NewAddressWitnessPubKeyHash(pkHash, &consensus.MainNetParams)
43 net: &consensus.MainNetParams,
46 name: "segwit mainnet p2wsh v0",
47 addr: "bm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qk5egtg",
48 encoded: "bm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qk5egtg",
50 result: tstAddressWitnessScriptHash(
53 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
54 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
55 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
56 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62},
57 consensus.MainNetParams.Bech32HRPSegwit),
58 f: func() (Address, error) {
60 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
61 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
62 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
63 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}
64 return NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams)
66 net: &consensus.MainNetParams,
69 name: "segwit testnet p2wpkh v0",
70 addr: "tm1qw508d6qejxtdg4y5r3zarvary0c5xw7kw8fqyc",
71 encoded: "tm1qw508d6qejxtdg4y5r3zarvary0c5xw7kw8fqyc",
73 result: tstAddressWitnessPubKeyHash(
76 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
77 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6},
78 consensus.TestNetParams.Bech32HRPSegwit),
79 f: func() (Address, error) {
81 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
82 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}
83 return NewAddressWitnessPubKeyHash(pkHash, &consensus.TestNetParams)
85 net: &consensus.TestNetParams,
88 name: "segwit testnet p2wsh v0",
89 addr: "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qqq379v",
90 encoded: "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qqq379v",
92 result: tstAddressWitnessScriptHash(
95 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
96 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
97 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
98 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62},
99 consensus.TestNetParams.Bech32HRPSegwit),
100 f: func() (Address, error) {
101 scriptHash := []byte{
102 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68,
103 0x04, 0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13,
104 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d, 0x27, 0xa1,
105 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}
106 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
108 net: &consensus.TestNetParams,
111 name: "segwit testnet p2wsh witness v0",
112 addr: "tm1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesvkesyk",
113 encoded: "tm1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesvkesyk",
115 result: tstAddressWitnessScriptHash(
118 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
119 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
120 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
121 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33},
122 consensus.TestNetParams.Bech32HRPSegwit),
123 f: func() (Address, error) {
124 scriptHash := []byte{
125 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62,
126 0x21, 0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66,
127 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c, 0x6c, 0xe2,
128 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}
129 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
131 net: &consensus.TestNetParams,
133 // Unsupported witness versions (version 0 only supported at this point)
135 name: "segwit mainnet witness v1",
136 addr: "bm1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
138 net: &consensus.MainNetParams,
141 name: "segwit mainnet witness v16",
142 addr: "BM1SW50QA3JX3S",
144 net: &consensus.MainNetParams,
147 name: "segwit mainnet witness v2",
148 addr: "bm1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
150 net: &consensus.MainNetParams,
152 // Invalid segwit addresses
154 name: "segwit invalid hrp",
155 addr: "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
157 net: &consensus.TestNetParams,
160 name: "segwit invalid checksum",
161 addr: "bm1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
163 net: &consensus.MainNetParams,
166 name: "segwit invalid witness version",
167 addr: "BM13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
169 net: &consensus.MainNetParams,
172 name: "segwit invalid program length",
173 addr: "bm1rw5uspcuh",
175 net: &consensus.MainNetParams,
178 name: "segwit invalid program length",
179 addr: "bm10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
181 net: &consensus.MainNetParams,
184 name: "segwit invalid program length for witness version 0 (per BIP141)",
185 addr: "BM1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
187 net: &consensus.MainNetParams,
190 name: "segwit mixed case",
191 addr: "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
193 net: &consensus.TestNetParams,
196 name: "segwit zero padding of more than 4 bits",
197 addr: "tm1pw508d6qejxtdg4y5r3zarqfsj6c3",
199 net: &consensus.TestNetParams,
202 name: "segwit non-zero padding in 8-to-5 conversion",
203 addr: "tm1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
205 net: &consensus.TestNetParams,
209 for _, test := range tests {
210 // Decode addr and compare error against valid.
211 decoded, err := DecodeAddress(test.addr, test.net)
212 if (err == nil) != test.valid {
213 t.Errorf("%v: decoding test failed: %v", test.name, err)
218 // Ensure the stringer returns the same address as the
221 if decodedStringer, ok := decoded.(fmt.Stringer); ok {
224 // For Segwit addresses the string representation
225 // will always be lower case, so in that case we
226 // convert the original to lower case first.
227 if strings.Contains(test.name, "segwit") {
228 addr = strings.ToLower(addr)
231 if addr != decodedStringer.String() {
232 t.Errorf("%v: String on decoded value does not match expected value: %v != %v",
233 test.name, test.addr, decodedStringer.String())
239 // Encode again and compare against the original.
240 encoded := decoded.EncodeAddress()
241 if test.encoded != encoded {
242 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v",
243 test.name, test.encoded, encoded)
247 // Perform type-specific calculations.
249 switch decoded.(type) {
251 case *AddressWitnessPubKeyHash:
252 saddr = tstAddressSegwitSAddr(encoded)
253 case *AddressWitnessScriptHash:
254 saddr = tstAddressSegwitSAddr(encoded)
257 // Check script address, as well as the Hash160 method for P2PKH and
259 if !bytes.Equal(saddr, decoded.ScriptAddress()) {
260 t.Errorf("%v: script addresses do not match:\n%x != \n%x",
261 test.name, saddr, decoded.ScriptAddress())
264 switch a := decoded.(type) {
266 case *AddressWitnessPubKeyHash:
267 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
268 t.Errorf("%v: hrps do not match:\n%x != \n%x",
269 test.name, test.net.Bech32HRPSegwit, hrp)
273 expVer := test.result.(*AddressWitnessPubKeyHash).WitnessVersion()
274 if v := a.WitnessVersion(); v != expVer {
275 t.Errorf("%v: witness versions do not match:\n%x != \n%x",
276 test.name, expVer, v)
280 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
281 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
286 case *AddressWitnessScriptHash:
287 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
288 t.Errorf("%v: hrps do not match:\n%x != \n%x",
289 test.name, test.net.Bech32HRPSegwit, hrp)
293 expVer := test.result.(*AddressWitnessScriptHash).WitnessVersion()
294 if v := a.WitnessVersion(); v != expVer {
295 t.Errorf("%v: witness versions do not match:\n%x != \n%x",
296 test.name, expVer, v)
300 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
301 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
307 // Ensure the address is for the expected network.
308 if !decoded.IsForNet(test.net) {
309 t.Errorf("%v: calculated network does not match expected",
316 // If address is invalid, but a creation function exists,
317 // verify that it returns a nil addr and non-nil error.
321 t.Errorf("%v: address is invalid but creating new address succeeded",
329 // Valid test, compare address created with f against expected result.
330 addr, err := test.f()
332 t.Errorf("%v: address is valid but creating new address failed with error %v",
337 if !reflect.DeepEqual(addr, test.result) {
338 t.Errorf("%v: created address does not match expected result",
346 // TstAddressWitnessPubKeyHash creates an AddressWitnessPubKeyHash, initiating
347 // the fields as given.
348 func tstAddressWitnessPubKeyHash(version byte, program [20]byte,
349 hrp string) *AddressWitnessPubKeyHash {
351 return &AddressWitnessPubKeyHash{
353 witnessVersion: version,
354 witnessProgram: program,
358 // TstAddressWitnessScriptHash creates an AddressWitnessScriptHash, initiating
359 // the fields as given.
360 func tstAddressWitnessScriptHash(version byte, program [32]byte,
361 hrp string) *AddressWitnessScriptHash {
363 return &AddressWitnessScriptHash{
365 witnessVersion: version,
366 witnessProgram: program,
370 // TstAddressSegwitSAddr returns the expected witness program bytes for
371 // bech32 encoded P2WPKH and P2WSH bitcoin addresses.
372 func tstAddressSegwitSAddr(addr string) []byte {
373 _, data, err := bech32.Decode(addr)
378 // First byte is version, rest is base 32 encoded data.
379 data, err = bech32.ConvertBits(data[1:], 5, 8, false)