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  }