10 "github.com/vapor/common/bech32"
11 "github.com/vapor/consensus"
14 func TestAddresses(t *testing.T) {
21 f func() (Address, error)
24 // Segwit address tests.
26 name: "segwit mainnet p2wpkh v0",
27 addr: "VBM1QZAPS6230EM2WVR4STEMF46DX2GK9V0LXZ9WEEL",
28 encoded: "vbm1qzaps6230em2wvr4stemf46dx2gk9v0lxz9weel",
30 result: tstAddressWitnessPubKeyHash(
33 0x17, 0x43, 0x0d, 0x2a, 0x2f, 0xce, 0xd4, 0xe6, 0x0e, 0xb0,
34 0x5e, 0x76, 0x9a, 0xe9, 0xa6, 0x52, 0x2c, 0x56, 0x3f, 0xe6},
35 consensus.MainNetParams.Bech32HRPSegwit),
36 f: func() (Address, error) {
38 0x17, 0x43, 0x0d, 0x2a, 0x2f, 0xce, 0xd4, 0xe6, 0x0e, 0xb0,
39 0x5e, 0x76, 0x9a, 0xe9, 0xa6, 0x52, 0x2c, 0x56, 0x3f, 0xe6}
40 return NewAddressWitnessPubKeyHash(pkHash, &consensus.MainNetParams)
42 net: &consensus.MainNetParams,
45 name: "segwit mainnet p2wsh v0",
46 addr: "VBM1QSG9QUUNLD2SY752QZ3G8V6NCGHAKZ7GUWSL5HE8PM3CUZXKQQ2AQ3767CL",
47 encoded: "vbm1qsg9quunld2sy752qz3g8v6ncghakz7guwsl5he8pm3cuzxkqq2aq3767cl",
49 result: tstAddressWitnessScriptHash(
52 0x82, 0x0a, 0x0e, 0x72, 0x7f, 0x6a, 0xa0, 0x4f,
53 0x51, 0x40, 0x14, 0x50, 0x76, 0x6a, 0x78, 0x45,
54 0xfb, 0x61, 0x79, 0x1c, 0x74, 0x3f, 0x4b, 0xe4,
55 0xe1, 0xdc, 0x71, 0xc1, 0x1a, 0xc0, 0x02, 0xba},
56 consensus.MainNetParams.Bech32HRPSegwit),
57 f: func() (Address, error) {
59 0x82, 0x0a, 0x0e, 0x72, 0x7f, 0x6a, 0xa0, 0x4f,
60 0x51, 0x40, 0x14, 0x50, 0x76, 0x6a, 0x78, 0x45,
61 0xfb, 0x61, 0x79, 0x1c, 0x74, 0x3f, 0x4b, 0xe4,
62 0xe1, 0xdc, 0x71, 0xc1, 0x1a, 0xc0, 0x02, 0xba}
63 return NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams)
65 net: &consensus.MainNetParams,
68 name: "segwit testnet p2wpkh v0",
69 addr: "vtm1qpzap59m2kadjwumj8nv4qevfjqwraytjnxap6u",
70 encoded: "vtm1qpzap59m2kadjwumj8nv4qevfjqwraytjnxap6u",
72 result: tstAddressWitnessPubKeyHash(
75 0x08, 0xba, 0x1a, 0x17, 0x6a, 0xb7, 0x5b, 0x27, 0x73, 0x72,
76 0x3c, 0xd9, 0x50, 0x65, 0x89, 0x90, 0x1c, 0x3e, 0x91, 0x72},
77 consensus.TestNetParams.Bech32HRPSegwit),
78 f: func() (Address, error) {
80 0x08, 0xba, 0x1a, 0x17, 0x6a, 0xb7, 0x5b, 0x27, 0x73, 0x72,
81 0x3c, 0xd9, 0x50, 0x65, 0x89, 0x90, 0x1c, 0x3e, 0x91, 0x72}
82 return NewAddressWitnessPubKeyHash(pkHash, &consensus.TestNetParams)
84 net: &consensus.TestNetParams,
87 name: "segwit testnet p2wsh v0",
88 addr: "vtm1qf5cwj7fydpgdqgcf5lmwp55zdvykwy5qnrtk08w3uefurkwqztcqgkzap0",
89 encoded: "vtm1qf5cwj7fydpgdqgcf5lmwp55zdvykwy5qnrtk08w3uefurkwqztcqgkzap0",
91 result: tstAddressWitnessScriptHash(
94 0x4d, 0x30, 0xe9, 0x79, 0x24, 0x68, 0x50, 0xd0,
95 0x23, 0x09, 0xa7, 0xf6, 0xe0, 0xd2, 0x82, 0x6b,
96 0x09, 0x67, 0x12, 0x80, 0x98, 0xd7, 0x67, 0x9d,
97 0xd1, 0xe6, 0x53, 0xc1, 0xd9, 0xc0, 0x12, 0xf0},
98 consensus.TestNetParams.Bech32HRPSegwit),
99 f: func() (Address, error) {
100 scriptHash := []byte{
101 0x4d, 0x30, 0xe9, 0x79, 0x24, 0x68, 0x50, 0xd0,
102 0x23, 0x09, 0xa7, 0xf6, 0xe0, 0xd2, 0x82, 0x6b,
103 0x09, 0x67, 0x12, 0x80, 0x98, 0xd7, 0x67, 0x9d,
104 0xd1, 0xe6, 0x53, 0xc1, 0xd9, 0xc0, 0x12, 0xf0}
105 return NewAddressWitnessScriptHash(scriptHash, &consensus.TestNetParams)
107 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,
210 for _, test := range tests {
211 // Decode addr and compare error against valid.
212 decoded, err := DecodeAddress(test.addr, test.net)
213 if (err == nil) != test.valid {
214 t.Errorf("%v: decoding test failed: %v", test.name, err)
219 // Ensure the stringer returns the same address as the
222 if decodedStringer, ok := decoded.(fmt.Stringer); ok {
225 // For Segwit addresses the string representation
226 // will always be lower case, so in that case we
227 // convert the original to lower case first.
228 if strings.Contains(test.name, "segwit") {
229 addr = strings.ToLower(addr)
232 if addr != decodedStringer.String() {
233 t.Errorf("%v: String on decoded value does not match expected value: %v != %v",
234 test.name, test.addr, decodedStringer.String())
240 // Encode again and compare against the original.
241 encoded := decoded.EncodeAddress()
242 if test.encoded != encoded {
243 t.Errorf("%v: decoding and encoding produced different addressess: %v != %v",
244 test.name, test.encoded, encoded)
248 // Perform type-specific calculations.
250 switch decoded.(type) {
252 case *AddressWitnessPubKeyHash:
253 saddr = tstAddressSegwitSAddr(encoded)
254 case *AddressWitnessScriptHash:
255 saddr = tstAddressSegwitSAddr(encoded)
258 // Check script address, as well as the Hash160 method for P2PKH and
260 if !bytes.Equal(saddr, decoded.ScriptAddress()) {
261 t.Errorf("%v: script addresses do not match:\n%x != \n%x",
262 test.name, saddr, decoded.ScriptAddress())
265 switch a := decoded.(type) {
267 case *AddressWitnessPubKeyHash:
268 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
269 t.Errorf("%v: hrps do not match:\n%x != \n%x",
270 test.name, test.net.Bech32HRPSegwit, hrp)
274 expVer := test.result.(*AddressWitnessPubKeyHash).WitnessVersion()
275 if v := a.WitnessVersion(); v != expVer {
276 t.Errorf("%v: witness versions do not match:\n%x != \n%x",
277 test.name, expVer, v)
281 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
282 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
287 case *AddressWitnessScriptHash:
288 if hrp := a.Hrp(); test.net.Bech32HRPSegwit != hrp {
289 t.Errorf("%v: hrps do not match:\n%x != \n%x",
290 test.name, test.net.Bech32HRPSegwit, hrp)
294 expVer := test.result.(*AddressWitnessScriptHash).WitnessVersion()
295 if v := a.WitnessVersion(); v != expVer {
296 t.Errorf("%v: witness versions do not match:\n%x != \n%x",
297 test.name, expVer, v)
301 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
302 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
308 // Ensure the address is for the expected network.
309 if !decoded.IsForNet(test.net) {
310 t.Errorf("%v: calculated network does not match expected",
317 // If address is invalid, but a creation function exists,
318 // verify that it returns a nil addr and non-nil error.
322 t.Errorf("%v: address is invalid but creating new address succeeded",
330 // Valid test, compare address created with f against expected result.
331 addr, err := test.f()
333 t.Errorf("%v: address is valid but creating new address failed with error %v",
338 if !reflect.DeepEqual(addr, test.result) {
339 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.Bech32Decode(addr)
378 // First byte is version, rest is base 32 encoded data.
379 data, err = bech32.ConvertBits(data[1:], 5, 8, false)