github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/accounts/abi/bind/base_test.go (about)

     1  package bind_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"math/big"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/neatlab/neatio"
    11  	"github.com/neatlab/neatio/chain/accounts/abi"
    12  	"github.com/neatlab/neatio/chain/accounts/abi/bind"
    13  	"github.com/neatlab/neatio/chain/core/types"
    14  	"github.com/neatlab/neatio/utilities/common"
    15  	"github.com/neatlab/neatio/utilities/common/hexutil"
    16  	"github.com/neatlab/neatio/utilities/crypto"
    17  	"github.com/neatlab/neatio/utilities/rlp"
    18  )
    19  
    20  type mockCaller struct {
    21  	codeAtBlockNumber       *big.Int
    22  	callContractBlockNumber *big.Int
    23  }
    24  
    25  func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
    26  	mc.codeAtBlockNumber = blockNumber
    27  	return []byte{1, 2, 3}, nil
    28  }
    29  
    30  func (mc *mockCaller) CallContract(ctx context.Context, call neatio.CallMsg, blockNumber *big.Int) ([]byte, error) {
    31  	mc.callContractBlockNumber = blockNumber
    32  	return nil, nil
    33  }
    34  func TestPassingBlockNumber(t *testing.T) {
    35  
    36  	mc := &mockCaller{}
    37  
    38  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{
    39  		Methods: map[string]abi.Method{
    40  			"something": {
    41  				Name:    "something",
    42  				Outputs: abi.Arguments{},
    43  			},
    44  		},
    45  	}, mc, nil, nil)
    46  	var ret string
    47  
    48  	blockNumber := big.NewInt(42)
    49  
    50  	bc.Call(&bind.CallOpts{BlockNumber: blockNumber}, &ret, "something")
    51  
    52  	if mc.callContractBlockNumber != blockNumber {
    53  		t.Fatalf("CallContract() was not passed the block number")
    54  	}
    55  
    56  	if mc.codeAtBlockNumber != blockNumber {
    57  		t.Fatalf("CodeAt() was not passed the block number")
    58  	}
    59  
    60  	bc.Call(&bind.CallOpts{}, &ret, "something")
    61  
    62  	if mc.callContractBlockNumber != nil {
    63  		t.Fatalf("CallContract() was passed a block number when it should not have been")
    64  	}
    65  
    66  	if mc.codeAtBlockNumber != nil {
    67  		t.Fatalf("CodeAt() was passed a block number when it should not have been")
    68  	}
    69  }
    70  
    71  const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158"
    72  
    73  func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) {
    74  	hash := crypto.Keccak256Hash([]byte("testName"))
    75  	mockLog := types.Log{
    76  		Address: common.HexToAddress("0x0"),
    77  		Topics: []common.Hash{
    78  			common.HexToHash("0x0"),
    79  			hash,
    80  		},
    81  		Data:        hexutil.MustDecode(hexData),
    82  		BlockNumber: uint64(26),
    83  		TxHash:      common.HexToHash("0x0"),
    84  		TxIndex:     111,
    85  		BlockHash:   common.BytesToHash([]byte{1, 2, 3, 4, 5}),
    86  		Index:       7,
    87  		Removed:     false,
    88  	}
    89  
    90  	abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"name","type":"string"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
    91  	parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
    92  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
    93  
    94  	receivedMap := make(map[string]interface{})
    95  	expectedReceivedMap := map[string]interface{}{
    96  		"name":   hash,
    97  		"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
    98  		"amount": big.NewInt(1),
    99  		"memo":   []byte{88},
   100  	}
   101  	if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
   102  		t.Error(err)
   103  	}
   104  
   105  	if len(receivedMap) != 4 {
   106  		t.Fatal("unpacked map expected to have length 4")
   107  	}
   108  	if receivedMap["name"] != expectedReceivedMap["name"] {
   109  		t.Error("unpacked map does not match expected map")
   110  	}
   111  	if receivedMap["sender"] != expectedReceivedMap["sender"] {
   112  		t.Error("unpacked map does not match expected map")
   113  	}
   114  	if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
   115  		t.Error("unpacked map does not match expected map")
   116  	}
   117  	if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
   118  		t.Error("unpacked map does not match expected map")
   119  	}
   120  }
   121  
   122  func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) {
   123  	sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"})
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  	hash := crypto.Keccak256Hash(sliceBytes)
   128  	mockLog := types.Log{
   129  		Address: common.HexToAddress("0x0"),
   130  		Topics: []common.Hash{
   131  			common.HexToHash("0x0"),
   132  			hash,
   133  		},
   134  		Data:        hexutil.MustDecode(hexData),
   135  		BlockNumber: uint64(26),
   136  		TxHash:      common.HexToHash("0x0"),
   137  		TxIndex:     111,
   138  		BlockHash:   common.BytesToHash([]byte{1, 2, 3, 4, 5}),
   139  		Index:       7,
   140  		Removed:     false,
   141  	}
   142  
   143  	abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"names","type":"string[]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
   144  	parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
   145  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
   146  
   147  	receivedMap := make(map[string]interface{})
   148  	expectedReceivedMap := map[string]interface{}{
   149  		"names":  hash,
   150  		"sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
   151  		"amount": big.NewInt(1),
   152  		"memo":   []byte{88},
   153  	}
   154  	if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
   155  		t.Error(err)
   156  	}
   157  
   158  	if len(receivedMap) != 4 {
   159  		t.Fatal("unpacked map expected to have length 4")
   160  	}
   161  	if receivedMap["names"] != expectedReceivedMap["names"] {
   162  		t.Error("unpacked map does not match expected map")
   163  	}
   164  	if receivedMap["sender"] != expectedReceivedMap["sender"] {
   165  		t.Error("unpacked map does not match expected map")
   166  	}
   167  	if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
   168  		t.Error("unpacked map does not match expected map")
   169  	}
   170  	if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
   171  		t.Error("unpacked map does not match expected map")
   172  	}
   173  }
   174  
   175  func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) {
   176  	arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")})
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	hash := crypto.Keccak256Hash(arrBytes)
   181  	mockLog := types.Log{
   182  		Address: common.HexToAddress("0x0"),
   183  		Topics: []common.Hash{
   184  			common.HexToHash("0x0"),
   185  			hash,
   186  		},
   187  		Data:        hexutil.MustDecode(hexData),
   188  		BlockNumber: uint64(26),
   189  		TxHash:      common.HexToHash("0x0"),
   190  		TxIndex:     111,
   191  		BlockHash:   common.BytesToHash([]byte{1, 2, 3, 4, 5}),
   192  		Index:       7,
   193  		Removed:     false,
   194  	}
   195  
   196  	abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"addresses","type":"address[2]"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
   197  	parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
   198  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
   199  
   200  	receivedMap := make(map[string]interface{})
   201  	expectedReceivedMap := map[string]interface{}{
   202  		"addresses": hash,
   203  		"sender":    common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
   204  		"amount":    big.NewInt(1),
   205  		"memo":      []byte{88},
   206  	}
   207  	if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
   208  		t.Error(err)
   209  	}
   210  
   211  	if len(receivedMap) != 4 {
   212  		t.Fatal("unpacked map expected to have length 4")
   213  	}
   214  	if receivedMap["addresses"] != expectedReceivedMap["addresses"] {
   215  		t.Error("unpacked map does not match expected map")
   216  	}
   217  	if receivedMap["sender"] != expectedReceivedMap["sender"] {
   218  		t.Error("unpacked map does not match expected map")
   219  	}
   220  	if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
   221  		t.Error("unpacked map does not match expected map")
   222  	}
   223  	if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
   224  		t.Error("unpacked map does not match expected map")
   225  	}
   226  }
   227  
   228  func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) {
   229  	mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")
   230  	addrBytes := mockAddress.Bytes()
   231  	hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)"))
   232  	functionSelector := hash[:4]
   233  	functionTyBytes := append(addrBytes, functionSelector...)
   234  	var functionTy [24]byte
   235  	copy(functionTy[:], functionTyBytes[0:24])
   236  	mockLog := types.Log{
   237  		Address: common.HexToAddress("0x0"),
   238  		Topics: []common.Hash{
   239  			common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"),
   240  			common.BytesToHash(functionTyBytes),
   241  		},
   242  		Data:        hexutil.MustDecode(hexData),
   243  		BlockNumber: uint64(26),
   244  		TxHash:      common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"),
   245  		TxIndex:     111,
   246  		BlockHash:   common.BytesToHash([]byte{1, 2, 3, 4, 5}),
   247  		Index:       7,
   248  		Removed:     false,
   249  	}
   250  
   251  	abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"function","type":"function"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
   252  	parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
   253  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
   254  
   255  	receivedMap := make(map[string]interface{})
   256  	expectedReceivedMap := map[string]interface{}{
   257  		"function": functionTy,
   258  		"sender":   common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
   259  		"amount":   big.NewInt(1),
   260  		"memo":     []byte{88},
   261  	}
   262  	if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
   263  		t.Error(err)
   264  	}
   265  
   266  	if len(receivedMap) != 4 {
   267  		t.Fatal("unpacked map expected to have length 4")
   268  	}
   269  	if receivedMap["function"] != expectedReceivedMap["function"] {
   270  		t.Error("unpacked map does not match expected map")
   271  	}
   272  	if receivedMap["sender"] != expectedReceivedMap["sender"] {
   273  		t.Error("unpacked map does not match expected map")
   274  	}
   275  	if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
   276  		t.Error("unpacked map does not match expected map")
   277  	}
   278  	if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
   279  		t.Error("unpacked map does not match expected map")
   280  	}
   281  }
   282  
   283  func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) {
   284  	byts := []byte{1, 2, 3, 4, 5}
   285  	hash := crypto.Keccak256Hash(byts)
   286  	mockLog := types.Log{
   287  		Address: common.HexToAddress("0x0"),
   288  		Topics: []common.Hash{
   289  			common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"),
   290  			hash,
   291  		},
   292  		Data:        hexutil.MustDecode(hexData),
   293  		BlockNumber: uint64(26),
   294  		TxHash:      common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42"),
   295  		TxIndex:     111,
   296  		BlockHash:   common.BytesToHash([]byte{1, 2, 3, 4, 5}),
   297  		Index:       7,
   298  		Removed:     false,
   299  	}
   300  
   301  	abiString := `[{"anonymous":false,"inputs":[{"indexed":true,"name":"content","type":"bytes"},{"indexed":false,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"memo","type":"bytes"}],"name":"received","type":"event"}]`
   302  	parsedAbi, _ := abi.JSON(strings.NewReader(abiString))
   303  	bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil)
   304  
   305  	receivedMap := make(map[string]interface{})
   306  	expectedReceivedMap := map[string]interface{}{
   307  		"content": hash,
   308  		"sender":  common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"),
   309  		"amount":  big.NewInt(1),
   310  		"memo":    []byte{88},
   311  	}
   312  	if err := bc.UnpackLogIntoMap(receivedMap, "received", mockLog); err != nil {
   313  		t.Error(err)
   314  	}
   315  
   316  	if len(receivedMap) != 4 {
   317  		t.Fatal("unpacked map expected to have length 4")
   318  	}
   319  	if receivedMap["content"] != expectedReceivedMap["content"] {
   320  		t.Error("unpacked map does not match expected map")
   321  	}
   322  	if receivedMap["sender"] != expectedReceivedMap["sender"] {
   323  		t.Error("unpacked map does not match expected map")
   324  	}
   325  	if receivedMap["amount"].(*big.Int).Cmp(expectedReceivedMap["amount"].(*big.Int)) != 0 {
   326  		t.Error("unpacked map does not match expected map")
   327  	}
   328  	if !bytes.Equal(receivedMap["memo"].([]byte), expectedReceivedMap["memo"].([]byte)) {
   329  		t.Error("unpacked map does not match expected map")
   330  	}
   331  }