github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/accounts/abi/bind/base_test.go (about)

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