|
| 1 | +// (c) 2024, Ava Labs, Inc. All rights reserved. |
| 2 | +// See the file LICENSE for licensing terms. |
| 3 | + |
| 4 | +package bind_test |
| 5 | + |
| 6 | +import ( |
| 7 | + "bytes" |
| 8 | + "math/big" |
| 9 | + "testing" |
| 10 | + |
| 11 | + "github.com/ava-labs/coreth/accounts/abi" |
| 12 | + "github.com/ava-labs/coreth/accounts/abi/bind" |
| 13 | + "github.com/ava-labs/coreth/accounts/abi/bind/backends" |
| 14 | + "github.com/ava-labs/coreth/core/types" |
| 15 | + "github.com/ava-labs/coreth/eth/ethconfig" |
| 16 | + "github.com/ava-labs/coreth/ethclient/simulated" |
| 17 | + "github.com/ava-labs/coreth/node" |
| 18 | + "github.com/ava-labs/coreth/params" |
| 19 | + "github.com/ava-labs/libevm/common" |
| 20 | + "github.com/ava-labs/libevm/crypto" |
| 21 | +) |
| 22 | + |
| 23 | +// TestGetSenderNativeAssetCall checks that the NativeAssetCall proxies the |
| 24 | +// caller address This behavior is disabled on the network and is only to test |
| 25 | +// previous behavior. Note the test uses ApricotPhase2Config. |
| 26 | +func TestGetSenderNativeAssetCall(t *testing.T) { |
| 27 | + // pragma solidity >=0.8.0 <0.9.0; |
| 28 | + // contract GetSenderNativeAssetCall { |
| 29 | + // address _sender; |
| 30 | + // function getSender() public view returns (address){ |
| 31 | + // return _sender; |
| 32 | + // } |
| 33 | + // function setSender() public { |
| 34 | + // _sender = msg.sender; |
| 35 | + // } |
| 36 | + // } |
| 37 | + rawABI := `[ |
| 38 | + { |
| 39 | + "inputs": [], |
| 40 | + "name": "getSender", |
| 41 | + "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], |
| 42 | + "stateMutability": "view", |
| 43 | + "type": "function" |
| 44 | + }, |
| 45 | + { |
| 46 | + "inputs": [], |
| 47 | + "name": "setSender", |
| 48 | + "outputs": [], |
| 49 | + "stateMutability": "nonpayable", |
| 50 | + "type": "function" |
| 51 | + } |
| 52 | + ]` |
| 53 | + bytecode := common.FromHex(`6080604052348015600f57600080fd5b506101608061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806350c36a521461003b5780635e01eb5a14610045575b600080fd5b610043610063565b005b61004d6100a5565b60405161005a919061010f565b60405180910390f35b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100f9826100ce565b9050919050565b610109816100ee565b82525050565b60006020820190506101246000830184610100565b9291505056fea26469706673582212209023ce54f38e749b58f44e8da750354578080ce16df95037b7305ed7e480c36d64736f6c634300081b0033`) |
| 54 | + setSenderMethodName := "setSender" |
| 55 | + getSenderMethodName := "getSender" |
| 56 | + |
| 57 | + parsedABI, err := abi.JSON(bytes.NewReader([]byte(rawABI))) |
| 58 | + if err != nil { |
| 59 | + t.Fatalf("Failed to parse ABI: %v", err) |
| 60 | + } |
| 61 | + |
| 62 | + // Generate a new random account and a funded simulator |
| 63 | + key, _ := crypto.GenerateKey() |
| 64 | + auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) |
| 65 | + alloc := types.GenesisAlloc{auth.From: {Balance: big.NewInt(1000000000000000000)}} |
| 66 | + atApricotPhase2 := func(nodeConf *node.Config, ethConf *ethconfig.Config) { |
| 67 | + chainConfig := *params.TestApricotPhase2Config |
| 68 | + chainConfig.ChainID = big.NewInt(1337) |
| 69 | + ethConf.Genesis.Config = &chainConfig |
| 70 | + } |
| 71 | + b := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(10000000), atApricotPhase2) |
| 72 | + sim := &backends.SimulatedBackend{ |
| 73 | + Backend: b, |
| 74 | + Client: b.Client(), |
| 75 | + } |
| 76 | + defer sim.Close() |
| 77 | + |
| 78 | + // Deploy the get/setSender contract |
| 79 | + _, _, interactor, err := bind.DeployContract(auth, parsedABI, bytecode, sim) |
| 80 | + if err != nil { |
| 81 | + t.Fatalf("Failed to deploy interactor contract: %v", err) |
| 82 | + } |
| 83 | + sim.Commit(false) |
| 84 | + |
| 85 | + // Setting NativeAssetCall in the transact opts will proxy the call through |
| 86 | + // the NativeAssetCall precompile |
| 87 | + opts := &bind.TransactOpts{ |
| 88 | + From: auth.From, |
| 89 | + Signer: auth.Signer, |
| 90 | + NativeAssetCall: &bind.NativeAssetCallOpts{ |
| 91 | + AssetAmount: big.NewInt(0), |
| 92 | + }, |
| 93 | + } |
| 94 | + if _, err := interactor.Transact(opts, setSenderMethodName); err != nil { |
| 95 | + t.Fatalf("Failed to set sender: %v", err) |
| 96 | + } |
| 97 | + sim.Commit(true) |
| 98 | + |
| 99 | + var results []interface{} |
| 100 | + if err := interactor.Call(nil, &results, getSenderMethodName); err != nil { |
| 101 | + t.Fatalf("Failed to get sender: %v", err) |
| 102 | + } |
| 103 | + if len(results) != 1 { |
| 104 | + t.Fatalf("Expected one result, got %d", len(results)) |
| 105 | + } |
| 106 | + if addr, ok := results[0].(common.Address); !ok { |
| 107 | + t.Fatalf("Expected address, got %T", results[0]) |
| 108 | + } else if addr != auth.From { |
| 109 | + t.Fatalf("Address mismatch: have '%v'", addr) |
| 110 | + } |
| 111 | +} |
0 commit comments