github.com/CommerciumBlockchain/go-commercium@v0.0.0-20220709212705-b46438a77516/accounts/abi/bind/base_test.go (about) 1 // Copyright 2022 Commercium 2 // Copyright 2019 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package bind_test 19 20 import ( 21 "context" 22 "math/big" 23 "reflect" 24 "strings" 25 "testing" 26 27 "github.com/CommerciumBlockchain/go-commercium" 28 "github.com/CommerciumBlockchain/go-commercium/accounts/abi" 29 "github.com/CommerciumBlockchain/go-commercium/accounts/abi/bind" 30 "github.com/CommerciumBlockchain/go-commercium/common" 31 "github.com/CommerciumBlockchain/go-commercium/common/hexutil" 32 "github.com/CommerciumBlockchain/go-commercium/core/types" 33 "github.com/CommerciumBlockchain/go-commercium/crypto" 34 "github.com/CommerciumBlockchain/go-commercium/rlp" 35 ) 36 37 type mockCaller struct { 38 codeAtBlockNumber *big.Int 39 callContractBlockNumber *big.Int 40 pendingCodeAtCalled bool 41 pendingCallContractCalled bool 42 } 43 44 func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) { 45 mc.codeAtBlockNumber = blockNumber 46 return []byte{1, 2, 3}, nil 47 } 48 49 func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { 50 mc.callContractBlockNumber = blockNumber 51 return nil, nil 52 } 53 54 func (mc *mockCaller) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { 55 mc.pendingCodeAtCalled = true 56 return nil, nil 57 } 58 59 func (mc *mockCaller) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { 60 mc.pendingCallContractCalled = true 61 return nil, nil 62 } 63 func TestPassingBlockNumber(t *testing.T) { 64 65 mc := &mockCaller{} 66 67 bc := bind.NewBoundContract(common.HexToAddress("0x0"), abi.ABI{ 68 Methods: map[string]abi.Method{ 69 "something": { 70 Name: "something", 71 Outputs: abi.Arguments{}, 72 }, 73 }, 74 }, mc, nil, nil) 75 76 blockNumber := big.NewInt(42) 77 78 bc.Call(&bind.CallOpts{BlockNumber: blockNumber}, nil, "something") 79 80 if mc.callContractBlockNumber != blockNumber { 81 t.Fatalf("CallContract() was not passed the block number") 82 } 83 84 if mc.codeAtBlockNumber != blockNumber { 85 t.Fatalf("CodeAt() was not passed the block number") 86 } 87 88 bc.Call(&bind.CallOpts{}, nil, "something") 89 90 if mc.callContractBlockNumber != nil { 91 t.Fatalf("CallContract() was passed a block number when it should not have been") 92 } 93 94 if mc.codeAtBlockNumber != nil { 95 t.Fatalf("CodeAt() was passed a block number when it should not have been") 96 } 97 98 bc.Call(&bind.CallOpts{BlockNumber: blockNumber, Pending: true}, nil, "something") 99 100 if !mc.pendingCallContractCalled { 101 t.Fatalf("CallContract() was not passed the block number") 102 } 103 104 if !mc.pendingCodeAtCalled { 105 t.Fatalf("CodeAt() was not passed the block number") 106 } 107 } 108 109 const hexData = "0x000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158" 110 111 func TestUnpackIndexedStringTyLogIntoMap(t *testing.T) { 112 hash := crypto.Keccak256Hash([]byte("testName")) 113 topics := []common.Hash{ 114 common.HexToHash("0x0"), 115 hash, 116 } 117 mockLog := newMockLog(topics, common.HexToHash("0x0")) 118 119 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"}]` 120 parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) 121 bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) 122 123 expectedReceivedMap := map[string]interface{}{ 124 "name": hash, 125 "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), 126 "amount": big.NewInt(1), 127 "memo": []byte{88}, 128 } 129 unpackAndCheck(t, bc, expectedReceivedMap, mockLog) 130 } 131 132 func TestUnpackIndexedSliceTyLogIntoMap(t *testing.T) { 133 sliceBytes, err := rlp.EncodeToBytes([]string{"name1", "name2", "name3", "name4"}) 134 if err != nil { 135 t.Fatal(err) 136 } 137 hash := crypto.Keccak256Hash(sliceBytes) 138 topics := []common.Hash{ 139 common.HexToHash("0x0"), 140 hash, 141 } 142 mockLog := newMockLog(topics, common.HexToHash("0x0")) 143 144 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"}]` 145 parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) 146 bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) 147 148 expectedReceivedMap := map[string]interface{}{ 149 "names": hash, 150 "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), 151 "amount": big.NewInt(1), 152 "memo": []byte{88}, 153 } 154 unpackAndCheck(t, bc, expectedReceivedMap, mockLog) 155 } 156 157 func TestUnpackIndexedArrayTyLogIntoMap(t *testing.T) { 158 arrBytes, err := rlp.EncodeToBytes([2]common.Address{common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")}) 159 if err != nil { 160 t.Fatal(err) 161 } 162 hash := crypto.Keccak256Hash(arrBytes) 163 topics := []common.Hash{ 164 common.HexToHash("0x0"), 165 hash, 166 } 167 mockLog := newMockLog(topics, common.HexToHash("0x0")) 168 169 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"}]` 170 parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) 171 bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) 172 173 expectedReceivedMap := map[string]interface{}{ 174 "addresses": hash, 175 "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), 176 "amount": big.NewInt(1), 177 "memo": []byte{88}, 178 } 179 unpackAndCheck(t, bc, expectedReceivedMap, mockLog) 180 } 181 182 func TestUnpackIndexedFuncTyLogIntoMap(t *testing.T) { 183 mockAddress := common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2") 184 addrBytes := mockAddress.Bytes() 185 hash := crypto.Keccak256Hash([]byte("mockFunction(address,uint)")) 186 functionSelector := hash[:4] 187 functionTyBytes := append(addrBytes, functionSelector...) 188 var functionTy [24]byte 189 copy(functionTy[:], functionTyBytes[0:24]) 190 topics := []common.Hash{ 191 common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), 192 common.BytesToHash(functionTyBytes), 193 } 194 mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) 195 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"}]` 196 parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) 197 bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) 198 199 expectedReceivedMap := map[string]interface{}{ 200 "function": functionTy, 201 "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), 202 "amount": big.NewInt(1), 203 "memo": []byte{88}, 204 } 205 unpackAndCheck(t, bc, expectedReceivedMap, mockLog) 206 } 207 208 func TestUnpackIndexedBytesTyLogIntoMap(t *testing.T) { 209 bytes := []byte{1, 2, 3, 4, 5} 210 hash := crypto.Keccak256Hash(bytes) 211 topics := []common.Hash{ 212 common.HexToHash("0x99b5620489b6ef926d4518936cfec15d305452712b88bd59da2d9c10fb0953e8"), 213 hash, 214 } 215 mockLog := newMockLog(topics, common.HexToHash("0x5c698f13940a2153440c6d19660878bc90219d9298fdcf37365aa8d88d40fc42")) 216 217 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"}]` 218 parsedAbi, _ := abi.JSON(strings.NewReader(abiString)) 219 bc := bind.NewBoundContract(common.HexToAddress("0x0"), parsedAbi, nil, nil, nil) 220 221 expectedReceivedMap := map[string]interface{}{ 222 "content": hash, 223 "sender": common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2"), 224 "amount": big.NewInt(1), 225 "memo": []byte{88}, 226 } 227 unpackAndCheck(t, bc, expectedReceivedMap, mockLog) 228 } 229 230 func unpackAndCheck(t *testing.T, bc *bind.BoundContract, expected map[string]interface{}, mockLog types.Log) { 231 received := make(map[string]interface{}) 232 if err := bc.UnpackLogIntoMap(received, "received", mockLog); err != nil { 233 t.Error(err) 234 } 235 236 if len(received) != len(expected) { 237 t.Fatalf("unpacked map length %v not equal expected length of %v", len(received), len(expected)) 238 } 239 for name, elem := range expected { 240 if !reflect.DeepEqual(elem, received[name]) { 241 t.Errorf("field %v does not match expected, want %v, got %v", name, elem, received[name]) 242 } 243 } 244 } 245 246 func newMockLog(topics []common.Hash, txHash common.Hash) types.Log { 247 return types.Log{ 248 Address: common.HexToAddress("0x0"), 249 Topics: topics, 250 Data: hexutil.MustDecode(hexData), 251 BlockNumber: uint64(26), 252 TxHash: txHash, 253 TxIndex: 111, 254 BlockHash: common.BytesToHash([]byte{1, 2, 3, 4, 5}), 255 Index: 7, 256 Removed: false, 257 } 258 }