github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/testutils/contract.go (about) 1 package testutils 2 3 import ( 4 "math" 5 "math/big" 6 "strings" 7 "testing" 8 9 "github.com/onflow/atree" 10 gethABI "github.com/onflow/go-ethereum/accounts/abi" 11 "github.com/stretchr/testify/require" 12 13 "github.com/onflow/flow-go/fvm/evm/emulator" 14 "github.com/onflow/flow-go/fvm/evm/testutils/contracts" 15 "github.com/onflow/flow-go/fvm/evm/types" 16 "github.com/onflow/flow-go/model/flow" 17 ) 18 19 type TestContract struct { 20 ABI string 21 ByteCode []byte 22 DeployedAt types.Address 23 } 24 25 func MakeCallData(t testing.TB, abiString string, name string, args ...interface{}) []byte { 26 abi, err := gethABI.JSON(strings.NewReader(abiString)) 27 require.NoError(t, err) 28 call, err := abi.Pack(name, args...) 29 require.NoError(t, err) 30 return call 31 } 32 33 func (tc *TestContract) MakeCallData(t testing.TB, name string, args ...interface{}) []byte { 34 return MakeCallData(t, tc.ABI, name, args...) 35 } 36 37 func (tc *TestContract) SetDeployedAt(deployedAt types.Address) { 38 tc.DeployedAt = deployedAt 39 } 40 41 func GetStorageTestContract(tb testing.TB) *TestContract { 42 return &TestContract{ 43 ABI: contracts.TestContractABIJSON, 44 ByteCode: contracts.TestContractBytes, 45 } 46 } 47 48 func GetDummyKittyTestContract(t testing.TB) *TestContract { 49 return &TestContract{ 50 ABI: contracts.DummyKittyContractABIJSON, 51 ByteCode: contracts.DummyKittyContractBytes, 52 } 53 } 54 55 func RunWithDeployedContract(t testing.TB, tc *TestContract, led atree.Ledger, flowEVMRootAddress flow.Address, f func(*TestContract)) { 56 DeployContract(t, RandomAddress(t), tc, led, flowEVMRootAddress) 57 f(tc) 58 } 59 60 func DeployContract(t testing.TB, caller types.Address, tc *TestContract, led atree.Ledger, flowEVMRootAddress flow.Address) { 61 // deploy contract 62 e := emulator.NewEmulator(led, flowEVMRootAddress) 63 64 ctx := types.NewDefaultBlockContext(2) 65 66 bl, err := e.NewReadOnlyBlockView(ctx) 67 require.NoError(t, err) 68 69 nonce, err := bl.NonceOf(caller) 70 require.NoError(t, err) 71 72 blk, err := e.NewBlockView(ctx) 73 require.NoError(t, err) 74 75 _, err = blk.DirectCall( 76 types.NewDepositCall( 77 RandomAddress(t), // any random non-empty address works here 78 caller, 79 new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1000)), 80 nonce, 81 ), 82 ) 83 require.NoError(t, err) 84 85 blk2, err := e.NewBlockView(types.NewDefaultBlockContext(3)) 86 require.NoError(t, err) 87 88 res, err := blk2.DirectCall( 89 types.NewDeployCall( 90 caller, 91 tc.ByteCode, 92 math.MaxUint64, 93 big.NewInt(0), 94 nonce+1, 95 ), 96 ) 97 require.NoError(t, err) 98 require.NotNil(t, res.DeployedContractAddress) 99 tc.SetDeployedAt(*res.DeployedContractAddress) 100 }