10 "github.com/bytom/vapor/common/bech32"
11 "github.com/bytom/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: "VP1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KPSCEPL",
28 encoded: "vp1qw508d6qejxtdg4y5r3zarvary0c5xw7kpscepl",
30 result: tstAddressWitnessPubKeyHash(
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) {
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)
42 net: &consensus.MainNetParams,
45 name: "segwit mainnet p2wsh v0",
46 addr: "vp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3ql5u263",
47 encoded: "vp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3ql5u263",
49 result: tstAddressWitnessScriptHash(
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) {
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)
65 net: &consensus.MainNetParams,
68 name: "segwit testnet p2wpkh v0",
69 addr: "tp1qw508d6qejxtdg4y5r3zarvary0c5xw7kvj35pt",
70 encoded: "tp1qw508d6qejxtdg4y5r3zarvary0c5xw7kvj35pt",
72 result: tstAddressWitnessPubKeyHash(
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) {
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)
84 net: &consensus.TestNetParams,
87 name: "segwit testnet p2wsh v0",
88 addr: "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qayxglu",
89 encoded: "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qayxglu",
91 result: tstAddressWitnessScriptHash(
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)
107 net: &consensus.TestNetParams,
110 name: "segwit testnet p2wsh witness v0",
111 addr: "tp1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses3jwx7x",
112 encoded: "tp1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses3jwx7x",
114 result: tstAddressWitnessScriptHash(
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)
130 net: &consensus.TestNetParams,
132 // Unsupported witness versions (version 0 only supported at this point)
134 name: "segwit mainnet witness v1",
135 addr: "vp1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
137 net: &consensus.MainNetParams,
140 name: "segwit mainnet witness v16",
141 addr: "VP1SW50QA3JX3S",
143 net: &consensus.MainNetParams,
146 name: "segwit mainnet witness v2",
147 addr: "vp1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
149 net: &consensus.MainNetParams,
151 // Invalid segwit addresses
153 name: "segwit invalid hrp",
154 addr: "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
156 net: &consensus.TestNetParams,
159 name: "segwit invalid checksum",
160 addr: "vp1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
162 net: &consensus.MainNetParams,
165 name: "segwit invalid witness version",
166 addr: "VP13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
168 net: &consensus.MainNetParams,
171 name: "segwit invalid program length",
172 addr: "vp1rw5uspcuh",
174 net: &consensus.MainNetParams,
177 name: "segwit invalid program length",
178 addr: "vp10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
180 net: &consensus.MainNetParams,
183 name: "segwit invalid program length for witness version 0 (per BIP141)",
184 addr: "VP1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
186 net: &consensus.MainNetParams,
189 name: "segwit mixed case",
190 addr: "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
192 net: &consensus.TestNetParams,
195 name: "segwit zero padding of more than 4 bits",
196 addr: "tp1pw508d6qejxtdg4y5r3zarqfsj6c3",
198 net: &consensus.TestNetParams,
201 name: "segwit non-zero padding in 8-to-5 conversion",
202 addr: "tp1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv",
204 net: &consensus.TestNetParams,
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)
217 // Ensure the stringer returns the same address as the
220 if decodedStringer, ok := decoded.(fmt.Stringer); ok {
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)
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())
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)
246 // Perform type-specific calculations.
248 switch decoded.(type) {
250 case *AddressWitnessPubKeyHash:
251 saddr = tstAddressSegwitSAddr(encoded)
252 case *AddressWitnessScriptHash:
253 saddr = tstAddressSegwitSAddr(encoded)
256 // Check script address, as well as the Hash160 method for P2PKH and
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())
263 switch a := decoded.(type) {
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)
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)
279 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
280 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
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)
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)
299 if p := a.WitnessProgram(); !bytes.Equal(saddr, p) {
300 t.Errorf("%v: witness programs do not match:\n%x != \n%x",
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",
315 // If address is invalid, but a creation function exists,
316 // verify that it returns a nil addr and non-nil error.
320 t.Errorf("%v: address is invalid but creating new address succeeded",
328 // Valid test, compare address created with f against expected result.
329 addr, err := test.f()
331 t.Errorf("%v: address is valid but creating new address failed with error %v",
336 if !reflect.DeepEqual(addr, test.result) {
337 t.Errorf("%v: created address does not match expected result",
344 // TstAddressWitnessPubKeyHash creates an AddressWitnessPubKeyHash, initiating
345 // the fields as given.
346 func tstAddressWitnessPubKeyHash(version byte, program [20]byte,
347 hrp string) *AddressWitnessPubKeyHash {
349 return &AddressWitnessPubKeyHash{
351 witnessVersion: version,
352 witnessProgram: program,
356 // TstAddressWitnessScriptHash creates an AddressWitnessScriptHash, initiating
357 // the fields as given.
358 func tstAddressWitnessScriptHash(version byte, program [32]byte,
359 hrp string) *AddressWitnessScriptHash {
361 return &AddressWitnessScriptHash{
363 witnessVersion: version,
364 witnessProgram: program,
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)
376 // First byte is version, rest is base 32 encoded data.
377 data, err = bech32.ConvertBits(data[1:], 5, 8, false)