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 }