github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/stdlib/contract_test.go (about)

     1  package stdlib_test
     2  
     3  import (
     4  	"encoding/binary"
     5  	"encoding/hex"
     6  	"math/big"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/onflow/cadence"
    11  	"github.com/onflow/cadence/encoding/json"
    12  	"github.com/onflow/cadence/runtime"
    13  	"github.com/onflow/cadence/runtime/common"
    14  	"github.com/onflow/cadence/runtime/sema"
    15  	cadenceStdlib "github.com/onflow/cadence/runtime/stdlib"
    16  	"github.com/onflow/cadence/runtime/tests/utils"
    17  	coreContracts "github.com/onflow/flow-core-contracts/lib/go/contracts"
    18  	coreContractstemplates "github.com/onflow/flow-core-contracts/lib/go/templates"
    19  	"github.com/onflow/go-ethereum/crypto"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  
    23  	"github.com/onflow/flow-go/fvm/blueprints"
    24  	"github.com/onflow/flow-go/fvm/environment"
    25  	"github.com/onflow/flow-go/fvm/evm/stdlib"
    26  	. "github.com/onflow/flow-go/fvm/evm/testutils"
    27  	"github.com/onflow/flow-go/fvm/evm/types"
    28  	"github.com/onflow/flow-go/model/flow"
    29  )
    30  
    31  type testContractHandler struct {
    32  	flowTokenAddress     common.Address
    33  	evmContractAddress   common.Address
    34  	deployCOA            func(uint64) types.Address
    35  	accountByAddress     func(types.Address, bool) types.Account
    36  	lastExecutedBlock    func() *types.Block
    37  	run                  func(tx []byte, coinbase types.Address) *types.ResultSummary
    38  	batchRun             func(txs [][]byte, coinbase types.Address) []*types.ResultSummary
    39  	generateResourceUUID func() uint64
    40  	dryRun               func(tx []byte, from types.Address) *types.ResultSummary
    41  }
    42  
    43  var _ types.ContractHandler = &testContractHandler{}
    44  
    45  func (t *testContractHandler) FlowTokenAddress() common.Address {
    46  	return t.flowTokenAddress
    47  }
    48  
    49  func (t *testContractHandler) EVMContractAddress() common.Address {
    50  	return t.evmContractAddress
    51  }
    52  
    53  func (t *testContractHandler) DeployCOA(uuid uint64) types.Address {
    54  	if t.deployCOA == nil {
    55  		var address types.Address
    56  		binary.LittleEndian.PutUint64(address[:], uuid)
    57  		return address
    58  	}
    59  	return t.deployCOA(uuid)
    60  }
    61  
    62  func (t *testContractHandler) AccountByAddress(addr types.Address, isAuthorized bool) types.Account {
    63  	if t.accountByAddress == nil {
    64  		panic("unexpected AccountByAddress")
    65  	}
    66  	return t.accountByAddress(addr, isAuthorized)
    67  }
    68  
    69  func (t *testContractHandler) LastExecutedBlock() *types.Block {
    70  	if t.lastExecutedBlock == nil {
    71  		panic("unexpected LastExecutedBlock")
    72  	}
    73  	return t.lastExecutedBlock()
    74  }
    75  
    76  func (t *testContractHandler) Run(tx []byte, coinbase types.Address) *types.ResultSummary {
    77  	if t.run == nil {
    78  		panic("unexpected Run")
    79  	}
    80  	return t.run(tx, coinbase)
    81  }
    82  
    83  func (t *testContractHandler) DryRun(tx []byte, from types.Address) *types.ResultSummary {
    84  	if t.dryRun == nil {
    85  		panic("unexpected DryRun")
    86  	}
    87  	return t.dryRun(tx, from)
    88  }
    89  
    90  func (t *testContractHandler) BatchRun(txs [][]byte, coinbase types.Address) []*types.ResultSummary {
    91  	if t.batchRun == nil {
    92  		panic("unexpected BatchRun")
    93  	}
    94  	return t.batchRun(txs, coinbase)
    95  }
    96  
    97  func (t *testContractHandler) GenerateResourceUUID() uint64 {
    98  	if t.generateResourceUUID == nil {
    99  		panic("unexpected GenerateResourceUUID")
   100  	}
   101  	return t.generateResourceUUID()
   102  }
   103  
   104  type testFlowAccount struct {
   105  	address  types.Address
   106  	balance  func() types.Balance
   107  	code     func() types.Code
   108  	codeHash func() []byte
   109  	nonce    func() uint64
   110  	transfer func(address types.Address, balance types.Balance)
   111  	deposit  func(vault *types.FLOWTokenVault)
   112  	withdraw func(balance types.Balance) *types.FLOWTokenVault
   113  	deploy   func(code types.Code, limit types.GasLimit, balance types.Balance) *types.ResultSummary
   114  	call     func(address types.Address, data types.Data, limit types.GasLimit, balance types.Balance) *types.ResultSummary
   115  }
   116  
   117  var _ types.Account = &testFlowAccount{}
   118  
   119  func (t *testFlowAccount) Address() types.Address {
   120  	return t.address
   121  }
   122  
   123  func (t *testFlowAccount) Balance() types.Balance {
   124  	if t.balance == nil {
   125  		return types.NewBalanceFromUFix64(0)
   126  	}
   127  	return t.balance()
   128  }
   129  
   130  func (t *testFlowAccount) Code() types.Code {
   131  	if t.code == nil {
   132  		return types.Code{}
   133  	}
   134  	return t.code()
   135  }
   136  
   137  func (t *testFlowAccount) CodeHash() []byte {
   138  	if t.codeHash == nil {
   139  		return nil
   140  	}
   141  	return t.codeHash()
   142  }
   143  
   144  func (t *testFlowAccount) Nonce() uint64 {
   145  	if t.nonce == nil {
   146  		return 0
   147  	}
   148  	return t.nonce()
   149  }
   150  
   151  func (t *testFlowAccount) Transfer(address types.Address, balance types.Balance) {
   152  	if t.transfer == nil {
   153  		panic("unexpected Transfer")
   154  	}
   155  	t.transfer(address, balance)
   156  }
   157  
   158  func (t *testFlowAccount) Deposit(vault *types.FLOWTokenVault) {
   159  	if t.deposit == nil {
   160  		panic("unexpected Deposit")
   161  	}
   162  	t.deposit(vault)
   163  }
   164  
   165  func (t *testFlowAccount) Withdraw(balance types.Balance) *types.FLOWTokenVault {
   166  	if t.withdraw == nil {
   167  		panic("unexpected Withdraw")
   168  	}
   169  	return t.withdraw(balance)
   170  }
   171  
   172  func (t *testFlowAccount) Deploy(code types.Code, limit types.GasLimit, balance types.Balance) *types.ResultSummary {
   173  	if t.deploy == nil {
   174  		panic("unexpected Deploy")
   175  	}
   176  	return t.deploy(code, limit, balance)
   177  }
   178  
   179  func (t *testFlowAccount) Call(address types.Address, data types.Data, limit types.GasLimit, balance types.Balance) *types.ResultSummary {
   180  	if t.call == nil {
   181  		panic("unexpected Call")
   182  	}
   183  	return t.call(address, data, limit, balance)
   184  }
   185  
   186  func requireEqualEventAddress(t *testing.T, event cadence.Event, address types.Address) {
   187  	actual := cadence.SearchFieldByName(event, types.CadenceOwnedAccountCreatedTypeAddressFieldName)
   188  	strippedHex := strings.TrimPrefix(address.String(), "0x")
   189  	expected, err := cadence.NewString(strippedHex)
   190  	if err != nil {
   191  		require.NoError(t, err)
   192  	}
   193  	require.Equal(t, expected, actual)
   194  }
   195  
   196  func deployContracts(
   197  	t *testing.T,
   198  	rt runtime.Runtime,
   199  	contractsAddress flow.Address,
   200  	runtimeInterface *TestRuntimeInterface,
   201  	transactionEnvironment runtime.Environment,
   202  	nextTransactionLocation func() common.TransactionLocation,
   203  ) {
   204  
   205  	contractsAddressHex := contractsAddress.Hex()
   206  
   207  	env := coreContractstemplates.Environment{
   208  		ServiceAccountAddress:             contractsAddressHex,
   209  		ViewResolverAddress:               contractsAddressHex,
   210  		BurnerAddress:                     contractsAddressHex,
   211  		FungibleTokenAddress:              contractsAddressHex,
   212  		NonFungibleTokenAddress:           contractsAddressHex,
   213  		MetadataViewsAddress:              contractsAddressHex,
   214  		FungibleTokenMetadataViewsAddress: contractsAddressHex,
   215  	}
   216  
   217  	contracts := []struct {
   218  		name     string
   219  		code     []byte
   220  		deployTx []byte
   221  	}{
   222  		{
   223  			name: "ViewResolver",
   224  			code: coreContracts.ViewResolver(),
   225  		},
   226  		{
   227  			name: "Burner",
   228  			code: coreContracts.Burner(),
   229  		},
   230  		{
   231  			name: "FungibleToken",
   232  			code: coreContracts.FungibleToken(
   233  				env,
   234  			),
   235  		},
   236  		{
   237  			name: "NonFungibleToken",
   238  			code: coreContracts.NonFungibleToken(
   239  				env,
   240  			),
   241  		},
   242  		{
   243  			name: "MetadataViews",
   244  			code: coreContracts.MetadataViews(
   245  				env,
   246  			),
   247  		},
   248  		{
   249  			name: "FungibleTokenMetadataViews",
   250  			code: coreContracts.FungibleTokenMetadataViews(
   251  				env,
   252  			),
   253  		},
   254  		{
   255  			name: "FlowToken",
   256  			code: coreContracts.FlowToken(
   257  				env,
   258  			),
   259  			deployTx: []byte(`
   260                transaction(name: String, code: String) {
   261                  prepare(signer: auth(AddContract, Storage, Capabilities) &Account) {
   262                    signer.contracts.add(name: name, code: code.utf8, signer)
   263                  }
   264                }
   265              `),
   266  		},
   267  		{
   268  			name: stdlib.ContractName,
   269  			code: stdlib.ContractCode(contractsAddress, contractsAddress, contractsAddress),
   270  		},
   271  	}
   272  
   273  	for _, contract := range contracts {
   274  
   275  		deployTx := contract.deployTx
   276  		if len(deployTx) == 0 {
   277  			deployTx = blueprints.DeployContractTransactionTemplate
   278  		}
   279  
   280  		err := rt.ExecuteTransaction(
   281  			runtime.Script{
   282  				Source: deployTx,
   283  				Arguments: EncodeArgs([]cadence.Value{
   284  					cadence.String(contract.name),
   285  					cadence.String(contract.code),
   286  				}),
   287  			},
   288  			runtime.Context{
   289  				Interface:   runtimeInterface,
   290  				Environment: transactionEnvironment,
   291  				Location:    nextTransactionLocation(),
   292  			},
   293  		)
   294  		require.NoError(t, err)
   295  	}
   296  
   297  }
   298  
   299  func newEVMTransactionEnvironment(handler types.ContractHandler, contractAddress flow.Address) runtime.Environment {
   300  	transactionEnvironment := runtime.NewBaseInterpreterEnvironment(runtime.Config{})
   301  
   302  	stdlib.SetupEnvironment(
   303  		transactionEnvironment,
   304  		handler,
   305  		contractAddress,
   306  	)
   307  
   308  	return transactionEnvironment
   309  }
   310  
   311  func newEVMScriptEnvironment(handler types.ContractHandler, contractAddress flow.Address) runtime.Environment {
   312  	scriptEnvironment := runtime.NewScriptInterpreterEnvironment(runtime.Config{})
   313  
   314  	stdlib.SetupEnvironment(
   315  		scriptEnvironment,
   316  		handler,
   317  		contractAddress,
   318  	)
   319  
   320  	return scriptEnvironment
   321  }
   322  
   323  func TestEVMEncodeABI(t *testing.T) {
   324  
   325  	t.Parallel()
   326  
   327  	handler := &testContractHandler{}
   328  
   329  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   330  
   331  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   332  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   333  
   334  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   335  
   336  	script := []byte(`
   337        import EVM from 0x1
   338  
   339        access(all)
   340        fun main(): [UInt8] {
   341          return EVM.encodeABI(["John Doe", UInt64(33), false])
   342        }
   343  	`)
   344  
   345  	accountCodes := map[common.Location][]byte{}
   346  	var events []cadence.Event
   347  
   348  	computation := uint(0)
   349  	runtimeInterface := &TestRuntimeInterface{
   350  		Storage: NewTestLedger(nil, nil),
   351  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   352  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   353  		},
   354  		OnResolveLocation: LocationResolver,
   355  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   356  			accountCodes[location] = code
   357  			return nil
   358  		},
   359  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   360  			code = accountCodes[location]
   361  			return code, nil
   362  		},
   363  		OnEmitEvent: func(event cadence.Event) error {
   364  			events = append(events, event)
   365  			return nil
   366  		},
   367  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   368  			return json.Decode(nil, b)
   369  		},
   370  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   371  			if compKind == environment.ComputationKindEVMEncodeABI {
   372  				computation += intensity
   373  			}
   374  			return nil
   375  		},
   376  	}
   377  
   378  	nextTransactionLocation := NewTransactionLocationGenerator()
   379  	nextScriptLocation := NewScriptLocationGenerator()
   380  
   381  	// Deploy contracts
   382  
   383  	deployContracts(
   384  		t,
   385  		rt,
   386  		contractsAddress,
   387  		runtimeInterface,
   388  		transactionEnvironment,
   389  		nextTransactionLocation,
   390  	)
   391  
   392  	// Run script
   393  
   394  	result, err := rt.ExecuteScript(
   395  		runtime.Script{
   396  			Source:    script,
   397  			Arguments: [][]byte{},
   398  		},
   399  		runtime.Context{
   400  			Interface:   runtimeInterface,
   401  			Environment: scriptEnvironment,
   402  			Location:    nextScriptLocation(),
   403  		},
   404  	)
   405  	require.NoError(t, err)
   406  
   407  	abiBytes := []byte{
   408  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   409  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   410  		0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   411  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   412  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   413  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   414  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   415  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   416  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   417  		0x0, 0x8, 0x4a, 0x6f, 0x68, 0x6e, 0x20, 0x44, 0x6f, 0x65, 0x0, 0x0,
   418  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   419  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   420  	}
   421  	cdcBytes := make([]cadence.Value, 0)
   422  	for _, bt := range abiBytes {
   423  		cdcBytes = append(cdcBytes, cadence.UInt8(bt))
   424  	}
   425  	encodedABI := cadence.NewArray(
   426  		cdcBytes,
   427  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
   428  
   429  	assert.Equal(t,
   430  		encodedABI,
   431  		result,
   432  	)
   433  	assert.Equal(t, computation, uint(len(cdcBytes)))
   434  }
   435  
   436  func TestEVMEncodeABIComputation(t *testing.T) {
   437  
   438  	t.Parallel()
   439  
   440  	handler := &testContractHandler{}
   441  
   442  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   443  
   444  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   445  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   446  
   447  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   448  
   449  	script := []byte(`
   450        import EVM from 0x1
   451  
   452        access(all)
   453        fun main(): [UInt8] {
   454          let address = EVM.EVMAddress(
   455            bytes: [
   456              122, 88, 192, 190, 114, 190, 33, 139, 65, 198,
   457              8, 183, 254, 124, 91, 182, 48, 115, 108, 113
   458            ]
   459          )
   460          let arr: [UInt8] = [1, 2, 3, 4, 5]
   461  
   462          return EVM.encodeABI([
   463            "John Doe",
   464            UInt64(33),
   465            false,
   466            address,
   467            [arr],
   468            ["one", "two", "three"]
   469          ])
   470        }
   471  	`)
   472  
   473  	accountCodes := map[common.Location][]byte{}
   474  	var events []cadence.Event
   475  
   476  	computation := uint(0)
   477  	runtimeInterface := &TestRuntimeInterface{
   478  		Storage: NewTestLedger(nil, nil),
   479  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   480  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   481  		},
   482  		OnResolveLocation: LocationResolver,
   483  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   484  			accountCodes[location] = code
   485  			return nil
   486  		},
   487  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   488  			code = accountCodes[location]
   489  			return code, nil
   490  		},
   491  		OnEmitEvent: func(event cadence.Event) error {
   492  			events = append(events, event)
   493  			return nil
   494  		},
   495  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   496  			return json.Decode(nil, b)
   497  		},
   498  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   499  			if compKind == environment.ComputationKindEVMEncodeABI {
   500  				computation += intensity
   501  			}
   502  			return nil
   503  		},
   504  	}
   505  
   506  	nextTransactionLocation := NewTransactionLocationGenerator()
   507  	nextScriptLocation := NewScriptLocationGenerator()
   508  
   509  	// Deploy contracts
   510  
   511  	deployContracts(
   512  		t,
   513  		rt,
   514  		contractsAddress,
   515  		runtimeInterface,
   516  		transactionEnvironment,
   517  		nextTransactionLocation,
   518  	)
   519  
   520  	// Run script
   521  
   522  	result, err := rt.ExecuteScript(
   523  		runtime.Script{
   524  			Source:    script,
   525  			Arguments: [][]byte{},
   526  		},
   527  		runtime.Context{
   528  			Interface:   runtimeInterface,
   529  			Environment: scriptEnvironment,
   530  			Location:    nextScriptLocation(),
   531  		},
   532  	)
   533  	require.NoError(t, err)
   534  
   535  	cdcBytes, ok := result.(cadence.Array)
   536  	require.True(t, ok)
   537  	// computation & len(cdcBytes.Values) is equal to 832
   538  	assert.Equal(t, computation, uint(len(cdcBytes.Values)))
   539  }
   540  
   541  func TestEVMEncodeABIComputationEmptyDynamicVariables(t *testing.T) {
   542  
   543  	t.Parallel()
   544  
   545  	handler := &testContractHandler{}
   546  
   547  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   548  
   549  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   550  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   551  
   552  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   553  
   554  	script := []byte(`
   555        import EVM from 0x1
   556  
   557        access(all)
   558        fun main(): [UInt8] {
   559          return EVM.encodeABI([
   560            "",
   561            [[""], [] as [String]],
   562            [] as [UInt8],
   563            ["", "", ""]
   564          ])
   565        }
   566  	`)
   567  
   568  	accountCodes := map[common.Location][]byte{}
   569  	var events []cadence.Event
   570  
   571  	computation := uint(0)
   572  	runtimeInterface := &TestRuntimeInterface{
   573  		Storage: NewTestLedger(nil, nil),
   574  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   575  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   576  		},
   577  		OnResolveLocation: LocationResolver,
   578  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   579  			accountCodes[location] = code
   580  			return nil
   581  		},
   582  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   583  			code = accountCodes[location]
   584  			return code, nil
   585  		},
   586  		OnEmitEvent: func(event cadence.Event) error {
   587  			events = append(events, event)
   588  			return nil
   589  		},
   590  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   591  			return json.Decode(nil, b)
   592  		},
   593  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   594  			if compKind == environment.ComputationKindEVMEncodeABI {
   595  				computation += intensity
   596  			}
   597  			return nil
   598  		},
   599  	}
   600  
   601  	nextTransactionLocation := NewTransactionLocationGenerator()
   602  	nextScriptLocation := NewScriptLocationGenerator()
   603  
   604  	// Deploy contracts
   605  
   606  	deployContracts(
   607  		t,
   608  		rt,
   609  		contractsAddress,
   610  		runtimeInterface,
   611  		transactionEnvironment,
   612  		nextTransactionLocation,
   613  	)
   614  
   615  	// Run script
   616  
   617  	result, err := rt.ExecuteScript(
   618  		runtime.Script{
   619  			Source:    script,
   620  			Arguments: [][]byte{},
   621  		},
   622  		runtime.Context{
   623  			Interface:   runtimeInterface,
   624  			Environment: scriptEnvironment,
   625  			Location:    nextScriptLocation(),
   626  		},
   627  	)
   628  	require.NoError(t, err)
   629  
   630  	cdcBytes, ok := result.(cadence.Array)
   631  	require.True(t, ok)
   632  	// computation & len(cdcBytes.Values) is equal to 832
   633  	assert.Equal(t, computation, uint(len(cdcBytes.Values)))
   634  }
   635  
   636  func TestEVMEncodeABIComputationDynamicVariablesAboveChunkSize(t *testing.T) {
   637  
   638  	t.Parallel()
   639  
   640  	handler := &testContractHandler{}
   641  
   642  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   643  
   644  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   645  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   646  
   647  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   648  
   649  	script := []byte(`
   650        import EVM from 0x1
   651  
   652        access(all)
   653        fun main(): [UInt8] {
   654          let str = "abcdefghijklmnopqrstuvwxyz"
   655          let arr: [UInt64] = [
   656            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
   657            20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
   658            37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53
   659          ]
   660  
   661          return EVM.encodeABI([
   662            str,
   663            str.concat(str).concat(str),
   664            [[str]],
   665            arr,
   666            [arr],
   667            arr.concat(arr).concat(arr)
   668          ])
   669        }
   670  	`)
   671  
   672  	accountCodes := map[common.Location][]byte{}
   673  	var events []cadence.Event
   674  
   675  	computation := uint(0)
   676  	runtimeInterface := &TestRuntimeInterface{
   677  		Storage: NewTestLedger(nil, nil),
   678  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   679  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   680  		},
   681  		OnResolveLocation: LocationResolver,
   682  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   683  			accountCodes[location] = code
   684  			return nil
   685  		},
   686  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   687  			code = accountCodes[location]
   688  			return code, nil
   689  		},
   690  		OnEmitEvent: func(event cadence.Event) error {
   691  			events = append(events, event)
   692  			return nil
   693  		},
   694  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   695  			return json.Decode(nil, b)
   696  		},
   697  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   698  			if compKind == environment.ComputationKindEVMEncodeABI {
   699  				computation += intensity
   700  			}
   701  			return nil
   702  		},
   703  	}
   704  
   705  	nextTransactionLocation := NewTransactionLocationGenerator()
   706  	nextScriptLocation := NewScriptLocationGenerator()
   707  
   708  	// Deploy contracts
   709  
   710  	deployContracts(
   711  		t,
   712  		rt,
   713  		contractsAddress,
   714  		runtimeInterface,
   715  		transactionEnvironment,
   716  		nextTransactionLocation,
   717  	)
   718  
   719  	// Run script
   720  
   721  	result, err := rt.ExecuteScript(
   722  		runtime.Script{
   723  			Source:    script,
   724  			Arguments: [][]byte{},
   725  		},
   726  		runtime.Context{
   727  			Interface:   runtimeInterface,
   728  			Environment: scriptEnvironment,
   729  			Location:    nextScriptLocation(),
   730  		},
   731  	)
   732  	require.NoError(t, err)
   733  
   734  	cdcBytes, ok := result.(cadence.Array)
   735  	require.True(t, ok)
   736  	// computation & len(cdcBytes.Values) is equal to 832
   737  	assert.Equal(t, computation, uint(len(cdcBytes.Values)))
   738  }
   739  
   740  func TestEVMDecodeABI(t *testing.T) {
   741  
   742  	t.Parallel()
   743  
   744  	handler := &testContractHandler{}
   745  
   746  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   747  
   748  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   749  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   750  
   751  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   752  
   753  	script := []byte(`
   754        import EVM from 0x1
   755  
   756        access(all)
   757        fun main(data: [UInt8]): Bool {
   758          let types = [Type<String>(), Type<UInt64>(), Type<Bool>()]
   759          let values = EVM.decodeABI(types: types, data: data)
   760  
   761          assert(values.length == 3)
   762          assert((values[0] as! String) == "John Doe")
   763          assert((values[1] as! UInt64) == UInt64(33))
   764          assert((values[2] as! Bool) == false)
   765  
   766          return true
   767        }
   768  	`)
   769  
   770  	accountCodes := map[common.Location][]byte{}
   771  	var events []cadence.Event
   772  
   773  	computation := uint(0)
   774  	runtimeInterface := &TestRuntimeInterface{
   775  		Storage: NewTestLedger(nil, nil),
   776  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   777  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   778  		},
   779  		OnResolveLocation: LocationResolver,
   780  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   781  			accountCodes[location] = code
   782  			return nil
   783  		},
   784  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   785  			code = accountCodes[location]
   786  			return code, nil
   787  		},
   788  		OnEmitEvent: func(event cadence.Event) error {
   789  			events = append(events, event)
   790  			return nil
   791  		},
   792  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   793  			return json.Decode(nil, b)
   794  		},
   795  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   796  			if compKind == environment.ComputationKindEVMDecodeABI {
   797  				computation += intensity
   798  			}
   799  			return nil
   800  		},
   801  	}
   802  
   803  	nextTransactionLocation := NewTransactionLocationGenerator()
   804  	nextScriptLocation := NewScriptLocationGenerator()
   805  
   806  	// Deploy contracts
   807  
   808  	deployContracts(
   809  		t,
   810  		rt,
   811  		contractsAddress,
   812  		runtimeInterface,
   813  		transactionEnvironment,
   814  		nextTransactionLocation,
   815  	)
   816  
   817  	// Run script
   818  	abiBytes := []byte{
   819  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   820  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   821  		0x0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   822  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   823  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   824  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   825  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   826  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   827  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   828  		0x0, 0x8, 0x4a, 0x6f, 0x68, 0x6e, 0x20, 0x44, 0x6f, 0x65, 0x0, 0x0,
   829  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   830  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   831  	}
   832  	cdcBytes := make([]cadence.Value, 0)
   833  	for _, bt := range abiBytes {
   834  		cdcBytes = append(cdcBytes, cadence.UInt8(bt))
   835  	}
   836  	encodedABI := cadence.NewArray(
   837  		cdcBytes,
   838  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
   839  
   840  	result, err := rt.ExecuteScript(
   841  		runtime.Script{
   842  			Source: script,
   843  			Arguments: EncodeArgs([]cadence.Value{
   844  				encodedABI,
   845  			}),
   846  		},
   847  		runtime.Context{
   848  			Interface:   runtimeInterface,
   849  			Environment: scriptEnvironment,
   850  			Location:    nextScriptLocation(),
   851  		},
   852  	)
   853  	require.NoError(t, err)
   854  
   855  	assert.Equal(t, cadence.NewBool(true), result)
   856  	assert.Equal(t, computation, uint(len(cdcBytes)))
   857  }
   858  
   859  func TestEVMDecodeABIComputation(t *testing.T) {
   860  
   861  	t.Parallel()
   862  
   863  	handler := &testContractHandler{}
   864  
   865  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   866  
   867  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   868  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   869  
   870  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   871  
   872  	script := []byte(`
   873        import EVM from 0x1
   874  
   875        access(all)
   876        fun main(): [UInt8] {
   877          let address = EVM.EVMAddress(
   878            bytes: [
   879              122, 88, 192, 190, 114, 190, 33, 139, 65, 198,
   880              8, 183, 254, 124, 91, 182, 48, 115, 108, 113
   881            ]
   882          )
   883          let arr: [UInt8] = [1, 2, 3, 4, 5]
   884  
   885          let data = EVM.encodeABI([
   886            "John Doe",
   887            UInt64(33),
   888            true,
   889            address,
   890            [arr],
   891            ["one", "two", "three"]
   892          ])
   893  
   894          let types = [
   895            Type<String>(), Type<UInt64>(), Type<Bool>(), Type<EVM.EVMAddress>(),
   896            Type<[[UInt8]]>(), Type<[String]>()
   897          ]
   898          let values = EVM.decodeABI(types: types, data: data)
   899  
   900          return data
   901        }
   902  	`)
   903  
   904  	accountCodes := map[common.Location][]byte{}
   905  	var events []cadence.Event
   906  
   907  	computation := uint(0)
   908  	runtimeInterface := &TestRuntimeInterface{
   909  		Storage: NewTestLedger(nil, nil),
   910  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
   911  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
   912  		},
   913  		OnResolveLocation: LocationResolver,
   914  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
   915  			accountCodes[location] = code
   916  			return nil
   917  		},
   918  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
   919  			code = accountCodes[location]
   920  			return code, nil
   921  		},
   922  		OnEmitEvent: func(event cadence.Event) error {
   923  			events = append(events, event)
   924  			return nil
   925  		},
   926  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
   927  			return json.Decode(nil, b)
   928  		},
   929  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
   930  			if compKind == environment.ComputationKindEVMDecodeABI {
   931  				computation += intensity
   932  			}
   933  			return nil
   934  		},
   935  	}
   936  
   937  	nextTransactionLocation := NewTransactionLocationGenerator()
   938  	nextScriptLocation := NewScriptLocationGenerator()
   939  
   940  	// Deploy contracts
   941  
   942  	deployContracts(
   943  		t,
   944  		rt,
   945  		contractsAddress,
   946  		runtimeInterface,
   947  		transactionEnvironment,
   948  		nextTransactionLocation,
   949  	)
   950  
   951  	// Run script
   952  
   953  	result, err := rt.ExecuteScript(
   954  		runtime.Script{
   955  			Source:    script,
   956  			Arguments: [][]byte{},
   957  		},
   958  		runtime.Context{
   959  			Interface:   runtimeInterface,
   960  			Environment: scriptEnvironment,
   961  			Location:    nextScriptLocation(),
   962  		},
   963  	)
   964  	require.NoError(t, err)
   965  
   966  	cdcBytes, ok := result.(cadence.Array)
   967  	require.True(t, ok)
   968  	// computation & len(cdcBytes.Values) is equal to 832
   969  	assert.Equal(t, computation, uint(len(cdcBytes.Values)))
   970  }
   971  
   972  func TestEVMEncodeDecodeABIRoundtrip(t *testing.T) {
   973  
   974  	t.Parallel()
   975  
   976  	handler := &testContractHandler{}
   977  
   978  	contractsAddress := flow.BytesToAddress([]byte{0x1})
   979  
   980  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
   981  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
   982  
   983  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
   984  
   985  	script := []byte(`
   986        import EVM from 0x1
   987  
   988        access(all)
   989        fun main(): Bool {
   990          // Check EVM.EVMAddress encode/decode
   991          // bytes for address 0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71
   992          let address = EVM.EVMAddress(
   993            bytes: [
   994              122, 88, 192, 190, 114, 190, 33, 139, 65, 198,
   995              8, 183, 254, 124, 91, 182, 48, 115, 108, 113
   996            ]
   997          )
   998          var data = EVM.encodeABI([address])
   999          var values = EVM.decodeABI(types: [Type<EVM.EVMAddress>()], data: data)
  1000          assert(values.length == 1)
  1001          assert((values[0] as! EVM.EVMAddress).bytes == address.bytes)
  1002  
  1003          // Check String encode/decode
  1004          data = EVM.encodeABI(["John Doe", ""])
  1005          values = EVM.decodeABI(types: [Type<String>(), Type<String>()], data: data)
  1006          assert((values[0] as! String) == "John Doe")
  1007          assert((values[1] as! String) == "")
  1008  
  1009          // Check Bool encode/decode
  1010          data = EVM.encodeABI([true, false])
  1011          values = EVM.decodeABI(types: [Type<Bool>(), Type<Bool>()], data: data)
  1012          assert((values[0] as! Bool) == true)
  1013          assert((values[1] as! Bool) == false)
  1014  
  1015          // Check UInt*/Int* encode/decode
  1016          data = EVM.encodeABI([
  1017            UInt8(33),
  1018            UInt16(33),
  1019            UInt32(33),
  1020            UInt64(33),
  1021            UInt128(33),
  1022            UInt256(33),
  1023            Int8(-33),
  1024            Int16(-33),
  1025            Int32(-33),
  1026            Int64(-33),
  1027            Int128(-33),
  1028            Int256(-33)
  1029          ])
  1030          values = EVM.decodeABI(
  1031            types: [
  1032              Type<UInt8>(),
  1033              Type<UInt16>(),
  1034              Type<UInt32>(),
  1035              Type<UInt64>(),
  1036              Type<UInt128>(),
  1037              Type<UInt256>(),
  1038              Type<Int8>(),
  1039              Type<Int16>(),
  1040              Type<Int32>(),
  1041              Type<Int64>(),
  1042              Type<Int128>(),
  1043              Type<Int256>()
  1044            ],
  1045            data: data
  1046          )
  1047          assert((values[0] as! UInt8) == 33)
  1048          assert((values[1] as! UInt16) == 33)
  1049          assert((values[2] as! UInt32) == 33)
  1050          assert((values[3] as! UInt64) == 33)
  1051          assert((values[4] as! UInt128) == 33)
  1052          assert((values[5] as! UInt256) == 33)
  1053          assert((values[6] as! Int8) == -33)
  1054          assert((values[7] as! Int16) == -33)
  1055          assert((values[8] as! Int32) == -33)
  1056          assert((values[9] as! Int64) == -33)
  1057          assert((values[10] as! Int128) == -33)
  1058          assert((values[11] as! Int256) == -33)
  1059  
  1060          // Check variable-size array of leaf types encode/decode
  1061          data = EVM.encodeABI([
  1062            ["one", "two"],
  1063            [true, false],
  1064            [5, 10] as [UInt8],
  1065            [5, 10] as [UInt16],
  1066            [5, 10] as [UInt32],
  1067            [5, 10] as [UInt64],
  1068            [5, 10] as [UInt128],
  1069            [5, 10] as [UInt256],
  1070            [-5, -10] as [Int8],
  1071            [-5, -10] as [Int16],
  1072            [-5, -10] as [Int32],
  1073            [-5, -10] as [Int64],
  1074            [-5, -10] as [Int128],
  1075            [-5, -10] as [Int256],
  1076            [address] as [EVM.EVMAddress]
  1077          ])
  1078          values = EVM.decodeABI(
  1079            types: [
  1080              Type<[String]>(),
  1081              Type<[Bool]>(),
  1082              Type<[UInt8]>(),
  1083              Type<[UInt16]>(),
  1084              Type<[UInt32]>(),
  1085              Type<[UInt64]>(),
  1086              Type<[UInt128]>(),
  1087              Type<[UInt256]>(),
  1088              Type<[Int8]>(),
  1089              Type<[Int16]>(),
  1090              Type<[Int32]>(),
  1091              Type<[Int64]>(),
  1092              Type<[Int128]>(),
  1093              Type<[Int256]>(),
  1094              Type<[EVM.EVMAddress]>()
  1095            ],
  1096            data: data
  1097          )
  1098          assert((values[0] as! [String]) == ["one", "two"])
  1099          assert((values[1] as! [Bool]) == [true, false])
  1100          assert((values[2] as! [UInt8]) == [5, 10])
  1101          assert((values[3] as! [UInt16]) == [5, 10])
  1102          assert((values[4] as! [UInt32]) == [5, 10])
  1103          assert((values[5] as! [UInt64]) == [5, 10])
  1104          assert((values[6] as! [UInt128]) == [5, 10])
  1105          assert((values[7] as! [UInt256]) == [5, 10])
  1106          assert((values[8] as! [Int8]) == [-5, -10])
  1107          assert((values[9] as! [Int16]) == [-5, -10])
  1108          assert((values[10] as! [Int32]) == [-5, -10])
  1109          assert((values[11] as! [Int64]) == [-5, -10])
  1110          assert((values[12] as! [Int128]) == [-5, -10])
  1111          assert((values[13] as! [Int256]) == [-5, -10])
  1112          assert((values[14] as! [EVM.EVMAddress])[0].bytes == [address][0].bytes)
  1113  
  1114          // Check constant-size array of leaf types encode/decode
  1115          data = EVM.encodeABI([
  1116            ["one", "two"] as [String; 2],
  1117            [true, false] as [Bool; 2],
  1118            [5, 10] as [UInt8; 2],
  1119            [5, 10] as [UInt16; 2],
  1120            [5, 10] as [UInt32; 2],
  1121            [5, 10] as [UInt64; 2],
  1122            [5, 10] as [UInt128; 2],
  1123            [5, 10] as [UInt256; 2],
  1124            [-5, -10] as [Int8; 2],
  1125            [-5, -10] as [Int16; 2],
  1126            [-5, -10] as [Int32; 2],
  1127            [-5, -10] as [Int64; 2],
  1128            [-5, -10] as [Int128; 2],
  1129            [-5, -10] as [Int256; 2],
  1130            [address] as [EVM.EVMAddress; 1]
  1131          ])
  1132          values = EVM.decodeABI(
  1133            types: [
  1134              Type<[String; 2]>(),
  1135              Type<[Bool; 2]>(),
  1136              Type<[UInt8; 2]>(),
  1137              Type<[UInt16; 2]>(),
  1138              Type<[UInt32; 2]>(),
  1139              Type<[UInt64; 2]>(),
  1140              Type<[UInt128; 2]>(),
  1141              Type<[UInt256; 2]>(),
  1142              Type<[Int8; 2]>(),
  1143              Type<[Int16; 2]>(),
  1144              Type<[Int32; 2]>(),
  1145              Type<[Int64; 2]>(),
  1146              Type<[Int128; 2]>(),
  1147              Type<[Int256; 2]>(),
  1148              Type<[EVM.EVMAddress; 1]>()
  1149            ],
  1150            data: data
  1151          )
  1152          assert((values[0] as! [String; 2]) == ["one", "two"])
  1153          assert((values[1] as! [Bool; 2]) == [true, false])
  1154          assert((values[2] as! [UInt8; 2]) == [5, 10])
  1155          assert((values[3] as! [UInt16; 2]) == [5, 10])
  1156          assert((values[4] as! [UInt32; 2]) == [5, 10])
  1157          assert((values[5] as! [UInt64; 2]) == [5, 10])
  1158          assert((values[6] as! [UInt128; 2]) == [5, 10])
  1159          assert((values[7] as! [UInt256; 2]) == [5, 10])
  1160          assert((values[8] as! [Int8; 2]) == [-5, -10])
  1161          assert((values[9] as! [Int16; 2]) == [-5, -10])
  1162          assert((values[10] as! [Int32; 2]) == [-5, -10])
  1163          assert((values[11] as! [Int64; 2]) == [-5, -10])
  1164          assert((values[12] as! [Int128; 2]) == [-5, -10])
  1165          assert((values[13] as! [Int256; 2]) == [-5, -10])
  1166          assert((values[14] as! [EVM.EVMAddress; 1])[0].bytes == [address][0].bytes)
  1167  
  1168          // Check partial decoding of encoded data
  1169          data = EVM.encodeABI(["Peter", UInt64(9999)])
  1170          values = EVM.decodeABI(types: [Type<String>()], data: data)
  1171          assert(values.length == 1)
  1172          assert((values[0] as! String) == "Peter")
  1173  
  1174          // Check nested arrays of leaf values
  1175          data = EVM.encodeABI([[["Foo", "Bar"], ["Baz", "Qux"]]])
  1176          values = EVM.decodeABI(types: [Type<[[String]]>()], data: data)
  1177          assert(values.length == 1)
  1178          assert((values[0] as! [[String]]) == [["Foo", "Bar"], ["Baz", "Qux"]])
  1179  
  1180          return true
  1181        }
  1182  	`)
  1183  
  1184  	accountCodes := map[common.Location][]byte{}
  1185  	var events []cadence.Event
  1186  
  1187  	runtimeInterface := &TestRuntimeInterface{
  1188  		Storage: NewTestLedger(nil, nil),
  1189  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1190  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1191  		},
  1192  		OnResolveLocation: LocationResolver,
  1193  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1194  			accountCodes[location] = code
  1195  			return nil
  1196  		},
  1197  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1198  			code = accountCodes[location]
  1199  			return code, nil
  1200  		},
  1201  		OnEmitEvent: func(event cadence.Event) error {
  1202  			events = append(events, event)
  1203  			return nil
  1204  		},
  1205  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1206  			return json.Decode(nil, b)
  1207  		},
  1208  	}
  1209  
  1210  	nextTransactionLocation := NewTransactionLocationGenerator()
  1211  	nextScriptLocation := NewScriptLocationGenerator()
  1212  
  1213  	// Deploy contracts
  1214  
  1215  	deployContracts(
  1216  		t,
  1217  		rt,
  1218  		contractsAddress,
  1219  		runtimeInterface,
  1220  		transactionEnvironment,
  1221  		nextTransactionLocation,
  1222  	)
  1223  
  1224  	// Run script
  1225  
  1226  	result, err := rt.ExecuteScript(
  1227  		runtime.Script{
  1228  			Source:    script,
  1229  			Arguments: [][]byte{},
  1230  		},
  1231  		runtime.Context{
  1232  			Interface:   runtimeInterface,
  1233  			Environment: scriptEnvironment,
  1234  			Location:    nextScriptLocation(),
  1235  		},
  1236  	)
  1237  	require.NoError(t, err)
  1238  
  1239  	assert.Equal(t,
  1240  		cadence.Bool(true),
  1241  		result,
  1242  	)
  1243  }
  1244  
  1245  func TestEVMEncodeDecodeABIErrors(t *testing.T) {
  1246  
  1247  	t.Parallel()
  1248  
  1249  	t.Run("encodeABI with unsupported Address type", func(t *testing.T) {
  1250  
  1251  		t.Parallel()
  1252  
  1253  		handler := &testContractHandler{}
  1254  
  1255  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1256  
  1257  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1258  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1259  
  1260  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1261  
  1262  		accountCodes := map[common.Location][]byte{}
  1263  		var events []cadence.Event
  1264  
  1265  		runtimeInterface := &TestRuntimeInterface{
  1266  			Storage: NewTestLedger(nil, nil),
  1267  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1268  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1269  			},
  1270  			OnResolveLocation: LocationResolver,
  1271  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1272  				accountCodes[location] = code
  1273  				return nil
  1274  			},
  1275  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1276  				code = accountCodes[location]
  1277  				return code, nil
  1278  			},
  1279  			OnEmitEvent: func(event cadence.Event) error {
  1280  				events = append(events, event)
  1281  				return nil
  1282  			},
  1283  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1284  				return json.Decode(nil, b)
  1285  			},
  1286  		}
  1287  
  1288  		nextTransactionLocation := NewTransactionLocationGenerator()
  1289  		nextScriptLocation := NewScriptLocationGenerator()
  1290  
  1291  		// Deploy contracts
  1292  
  1293  		deployContracts(
  1294  			t,
  1295  			rt,
  1296  			contractsAddress,
  1297  			runtimeInterface,
  1298  			transactionEnvironment,
  1299  			nextTransactionLocation,
  1300  		)
  1301  
  1302  		// Run script
  1303  
  1304  		script := []byte(`
  1305            import EVM from 0x1
  1306  
  1307            access(all)
  1308            fun main(): Bool {
  1309              let address: Address = 0x045a1763c93006ca
  1310              let data = EVM.encodeABI([address])
  1311  
  1312              return true
  1313            }
  1314  		`)
  1315  
  1316  		_, err := rt.ExecuteScript(
  1317  			runtime.Script{
  1318  				Source:    script,
  1319  				Arguments: [][]byte{},
  1320  			},
  1321  			runtime.Context{
  1322  				Interface:   runtimeInterface,
  1323  				Environment: scriptEnvironment,
  1324  				Location:    nextScriptLocation(),
  1325  			},
  1326  		)
  1327  		utils.RequireError(t, err)
  1328  		assert.ErrorContains(
  1329  			t,
  1330  			err,
  1331  			"failed to ABI encode value of type Address",
  1332  		)
  1333  	})
  1334  
  1335  	t.Run("encodeABI with unsupported fixed-point number type", func(t *testing.T) {
  1336  
  1337  		t.Parallel()
  1338  
  1339  		handler := &testContractHandler{}
  1340  
  1341  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1342  
  1343  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1344  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1345  
  1346  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1347  
  1348  		accountCodes := map[common.Location][]byte{}
  1349  		var events []cadence.Event
  1350  
  1351  		runtimeInterface := &TestRuntimeInterface{
  1352  			Storage: NewTestLedger(nil, nil),
  1353  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1354  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1355  			},
  1356  			OnResolveLocation: LocationResolver,
  1357  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1358  				accountCodes[location] = code
  1359  				return nil
  1360  			},
  1361  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1362  				code = accountCodes[location]
  1363  				return code, nil
  1364  			},
  1365  			OnEmitEvent: func(event cadence.Event) error {
  1366  				events = append(events, event)
  1367  				return nil
  1368  			},
  1369  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1370  				return json.Decode(nil, b)
  1371  			},
  1372  		}
  1373  
  1374  		nextTransactionLocation := NewTransactionLocationGenerator()
  1375  		nextScriptLocation := NewScriptLocationGenerator()
  1376  
  1377  		// Deploy contracts
  1378  
  1379  		deployContracts(
  1380  			t,
  1381  			rt,
  1382  			contractsAddress,
  1383  			runtimeInterface,
  1384  			transactionEnvironment,
  1385  			nextTransactionLocation,
  1386  		)
  1387  
  1388  		// Run script
  1389  
  1390  		script := []byte(`
  1391            import EVM from 0x1
  1392  
  1393            access(all)
  1394            fun main(): Bool {
  1395              let data = EVM.encodeABI([0.2])
  1396  
  1397              return true
  1398            }
  1399  		`)
  1400  
  1401  		_, err := rt.ExecuteScript(
  1402  			runtime.Script{
  1403  				Source:    script,
  1404  				Arguments: [][]byte{},
  1405  			},
  1406  			runtime.Context{
  1407  				Interface:   runtimeInterface,
  1408  				Environment: scriptEnvironment,
  1409  				Location:    nextScriptLocation(),
  1410  			},
  1411  		)
  1412  		utils.RequireError(t, err)
  1413  		assert.ErrorContains(
  1414  			t,
  1415  			err,
  1416  			"failed to ABI encode value of type UFix64",
  1417  		)
  1418  	})
  1419  
  1420  	t.Run("encodeABI with unsupported dictionary type", func(t *testing.T) {
  1421  
  1422  		t.Parallel()
  1423  
  1424  		handler := &testContractHandler{}
  1425  
  1426  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1427  
  1428  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1429  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1430  
  1431  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1432  
  1433  		accountCodes := map[common.Location][]byte{}
  1434  		var events []cadence.Event
  1435  
  1436  		runtimeInterface := &TestRuntimeInterface{
  1437  			Storage: NewTestLedger(nil, nil),
  1438  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1439  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1440  			},
  1441  			OnResolveLocation: LocationResolver,
  1442  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1443  				accountCodes[location] = code
  1444  				return nil
  1445  			},
  1446  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1447  				code = accountCodes[location]
  1448  				return code, nil
  1449  			},
  1450  			OnEmitEvent: func(event cadence.Event) error {
  1451  				events = append(events, event)
  1452  				return nil
  1453  			},
  1454  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1455  				return json.Decode(nil, b)
  1456  			},
  1457  		}
  1458  
  1459  		nextTransactionLocation := NewTransactionLocationGenerator()
  1460  		nextScriptLocation := NewScriptLocationGenerator()
  1461  
  1462  		// Deploy contracts
  1463  
  1464  		deployContracts(
  1465  			t,
  1466  			rt,
  1467  			contractsAddress,
  1468  			runtimeInterface,
  1469  			transactionEnvironment,
  1470  			nextTransactionLocation,
  1471  		)
  1472  
  1473  		// Run script
  1474  
  1475  		script := []byte(`
  1476            import EVM from 0x1
  1477  
  1478            access(all)
  1479            fun main(): Bool {
  1480              let dict: {Int: Bool} = {0: false, 1: true}
  1481              let data = EVM.encodeABI([dict])
  1482  
  1483              return true
  1484            }
  1485  		`)
  1486  
  1487  		_, err := rt.ExecuteScript(
  1488  			runtime.Script{
  1489  				Source:    script,
  1490  				Arguments: [][]byte{},
  1491  			},
  1492  			runtime.Context{
  1493  				Interface:   runtimeInterface,
  1494  				Environment: scriptEnvironment,
  1495  				Location:    nextScriptLocation(),
  1496  			},
  1497  		)
  1498  		utils.RequireError(t, err)
  1499  		assert.ErrorContains(
  1500  			t,
  1501  			err,
  1502  			"failed to ABI encode value of type {Int: Bool}",
  1503  		)
  1504  	})
  1505  
  1506  	t.Run("encodeABI with unsupported array element type", func(t *testing.T) {
  1507  
  1508  		t.Parallel()
  1509  
  1510  		handler := &testContractHandler{}
  1511  
  1512  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1513  
  1514  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1515  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1516  
  1517  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1518  
  1519  		accountCodes := map[common.Location][]byte{}
  1520  		var events []cadence.Event
  1521  
  1522  		runtimeInterface := &TestRuntimeInterface{
  1523  			Storage: NewTestLedger(nil, nil),
  1524  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1525  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1526  			},
  1527  			OnResolveLocation: LocationResolver,
  1528  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1529  				accountCodes[location] = code
  1530  				return nil
  1531  			},
  1532  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1533  				code = accountCodes[location]
  1534  				return code, nil
  1535  			},
  1536  			OnEmitEvent: func(event cadence.Event) error {
  1537  				events = append(events, event)
  1538  				return nil
  1539  			},
  1540  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1541  				return json.Decode(nil, b)
  1542  			},
  1543  		}
  1544  
  1545  		nextTransactionLocation := NewTransactionLocationGenerator()
  1546  		nextScriptLocation := NewScriptLocationGenerator()
  1547  
  1548  		// Deploy contracts
  1549  
  1550  		deployContracts(
  1551  			t,
  1552  			rt,
  1553  			contractsAddress,
  1554  			runtimeInterface,
  1555  			transactionEnvironment,
  1556  			nextTransactionLocation,
  1557  		)
  1558  
  1559  		// Run script
  1560  
  1561  		script := []byte(`
  1562            import EVM from 0x1
  1563  
  1564            access(all)
  1565            fun main(): Bool {
  1566              let chars: [Character] = ["a", "b", "c"]
  1567              let data = EVM.encodeABI([chars])
  1568  
  1569              return true
  1570            }
  1571  		`)
  1572  
  1573  		_, err := rt.ExecuteScript(
  1574  			runtime.Script{
  1575  				Source:    script,
  1576  				Arguments: [][]byte{},
  1577  			},
  1578  			runtime.Context{
  1579  				Interface:   runtimeInterface,
  1580  				Environment: scriptEnvironment,
  1581  				Location:    nextScriptLocation(),
  1582  			},
  1583  		)
  1584  		utils.RequireError(t, err)
  1585  		assert.ErrorContains(
  1586  			t,
  1587  			err,
  1588  			"failed to ABI encode value of type Character",
  1589  		)
  1590  	})
  1591  
  1592  	t.Run("encodeABI with unsupported custom composite type", func(t *testing.T) {
  1593  
  1594  		t.Parallel()
  1595  
  1596  		handler := &testContractHandler{}
  1597  
  1598  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1599  
  1600  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1601  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1602  
  1603  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1604  
  1605  		accountCodes := map[common.Location][]byte{}
  1606  		var events []cadence.Event
  1607  
  1608  		runtimeInterface := &TestRuntimeInterface{
  1609  			Storage: NewTestLedger(nil, nil),
  1610  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1611  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1612  			},
  1613  			OnResolveLocation: LocationResolver,
  1614  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1615  				accountCodes[location] = code
  1616  				return nil
  1617  			},
  1618  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1619  				code = accountCodes[location]
  1620  				return code, nil
  1621  			},
  1622  			OnEmitEvent: func(event cadence.Event) error {
  1623  				events = append(events, event)
  1624  				return nil
  1625  			},
  1626  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1627  				return json.Decode(nil, b)
  1628  			},
  1629  		}
  1630  
  1631  		nextTransactionLocation := NewTransactionLocationGenerator()
  1632  		nextScriptLocation := NewScriptLocationGenerator()
  1633  
  1634  		// Deploy contracts
  1635  
  1636  		deployContracts(
  1637  			t,
  1638  			rt,
  1639  			contractsAddress,
  1640  			runtimeInterface,
  1641  			transactionEnvironment,
  1642  			nextTransactionLocation,
  1643  		)
  1644  
  1645  		// Run script
  1646  
  1647  		script := []byte(`
  1648            import EVM from 0x1
  1649  
  1650            access(all) struct Token {
  1651              access(all) let id: Int
  1652              access(all) var balance: UInt
  1653  
  1654              init(id: Int, balance: UInt) {
  1655                self.id = id
  1656                self.balance = balance
  1657              }
  1658            }
  1659  
  1660            access(all)
  1661            fun main(): Bool {
  1662              let token = Token(id: 9, balance: 150)
  1663              let data = EVM.encodeABI([token])
  1664  
  1665              return true
  1666            }
  1667  		`)
  1668  
  1669  		_, err := rt.ExecuteScript(
  1670  			runtime.Script{
  1671  				Source:    script,
  1672  				Arguments: [][]byte{},
  1673  			},
  1674  			runtime.Context{
  1675  				Interface:   runtimeInterface,
  1676  				Environment: scriptEnvironment,
  1677  				Location:    nextScriptLocation(),
  1678  			},
  1679  		)
  1680  		utils.RequireError(t, err)
  1681  		assert.ErrorContains(
  1682  			t,
  1683  			err,
  1684  			"failed to ABI encode value of type s.0100000000000000000000000000000000000000000000000000000000000000.Token",
  1685  		)
  1686  	})
  1687  
  1688  	t.Run("decodeABI with mismatched type", func(t *testing.T) {
  1689  
  1690  		t.Parallel()
  1691  
  1692  		handler := &testContractHandler{}
  1693  
  1694  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1695  
  1696  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1697  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1698  
  1699  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1700  
  1701  		accountCodes := map[common.Location][]byte{}
  1702  		var events []cadence.Event
  1703  
  1704  		runtimeInterface := &TestRuntimeInterface{
  1705  			Storage: NewTestLedger(nil, nil),
  1706  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1707  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1708  			},
  1709  			OnResolveLocation: LocationResolver,
  1710  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1711  				accountCodes[location] = code
  1712  				return nil
  1713  			},
  1714  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1715  				code = accountCodes[location]
  1716  				return code, nil
  1717  			},
  1718  			OnEmitEvent: func(event cadence.Event) error {
  1719  				events = append(events, event)
  1720  				return nil
  1721  			},
  1722  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1723  				return json.Decode(nil, b)
  1724  			},
  1725  		}
  1726  
  1727  		nextTransactionLocation := NewTransactionLocationGenerator()
  1728  		nextScriptLocation := NewScriptLocationGenerator()
  1729  
  1730  		// Deploy contracts
  1731  
  1732  		deployContracts(
  1733  			t,
  1734  			rt,
  1735  			contractsAddress,
  1736  			runtimeInterface,
  1737  			transactionEnvironment,
  1738  			nextTransactionLocation,
  1739  		)
  1740  
  1741  		// Run script
  1742  
  1743  		script := []byte(`
  1744            import EVM from 0x1
  1745  
  1746            access(all)
  1747            fun main(): Bool {
  1748              let data = EVM.encodeABI(["Peter"])
  1749              let values = EVM.decodeABI(types: [Type<Bool>()], data: data)
  1750  
  1751              return true
  1752            }
  1753  		`)
  1754  
  1755  		_, err := rt.ExecuteScript(
  1756  			runtime.Script{
  1757  				Source:    script,
  1758  				Arguments: [][]byte{},
  1759  			},
  1760  			runtime.Context{
  1761  				Interface:   runtimeInterface,
  1762  				Environment: scriptEnvironment,
  1763  				Location:    nextScriptLocation(),
  1764  			},
  1765  		)
  1766  		utils.RequireError(t, err)
  1767  		assert.ErrorContains(
  1768  			t,
  1769  			err,
  1770  			"failed to ABI decode data",
  1771  		)
  1772  	})
  1773  
  1774  	t.Run("decodeABI with surplus of types", func(t *testing.T) {
  1775  
  1776  		t.Parallel()
  1777  
  1778  		handler := &testContractHandler{}
  1779  
  1780  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1781  
  1782  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1783  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1784  
  1785  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1786  
  1787  		accountCodes := map[common.Location][]byte{}
  1788  		var events []cadence.Event
  1789  
  1790  		runtimeInterface := &TestRuntimeInterface{
  1791  			Storage: NewTestLedger(nil, nil),
  1792  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1793  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1794  			},
  1795  			OnResolveLocation: LocationResolver,
  1796  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1797  				accountCodes[location] = code
  1798  				return nil
  1799  			},
  1800  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1801  				code = accountCodes[location]
  1802  				return code, nil
  1803  			},
  1804  			OnEmitEvent: func(event cadence.Event) error {
  1805  				events = append(events, event)
  1806  				return nil
  1807  			},
  1808  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1809  				return json.Decode(nil, b)
  1810  			},
  1811  		}
  1812  
  1813  		nextTransactionLocation := NewTransactionLocationGenerator()
  1814  		nextScriptLocation := NewScriptLocationGenerator()
  1815  
  1816  		// Deploy contracts
  1817  
  1818  		deployContracts(
  1819  			t,
  1820  			rt,
  1821  			contractsAddress,
  1822  			runtimeInterface,
  1823  			transactionEnvironment,
  1824  			nextTransactionLocation,
  1825  		)
  1826  
  1827  		// Run script
  1828  
  1829  		script := []byte(`
  1830            import EVM from 0x1
  1831  
  1832            access(all)
  1833            fun main(): Bool {
  1834              let data = EVM.encodeABI(["Peter"])
  1835              let values = EVM.decodeABI(types: [Type<String>(), Type<Bool>()], data: data)
  1836  
  1837              return true
  1838            }
  1839  		`)
  1840  
  1841  		_, err := rt.ExecuteScript(
  1842  			runtime.Script{
  1843  				Source:    script,
  1844  				Arguments: [][]byte{},
  1845  			},
  1846  			runtime.Context{
  1847  				Interface:   runtimeInterface,
  1848  				Environment: scriptEnvironment,
  1849  				Location:    nextScriptLocation(),
  1850  			},
  1851  		)
  1852  		utils.RequireError(t, err)
  1853  		assert.ErrorContains(
  1854  			t,
  1855  			err,
  1856  			"failed to ABI decode data",
  1857  		)
  1858  	})
  1859  
  1860  	t.Run("decodeABI with unsupported fixed-point number type", func(t *testing.T) {
  1861  
  1862  		t.Parallel()
  1863  
  1864  		handler := &testContractHandler{}
  1865  
  1866  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1867  
  1868  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1869  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1870  
  1871  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1872  
  1873  		accountCodes := map[common.Location][]byte{}
  1874  		var events []cadence.Event
  1875  
  1876  		runtimeInterface := &TestRuntimeInterface{
  1877  			Storage: NewTestLedger(nil, nil),
  1878  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1879  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1880  			},
  1881  			OnResolveLocation: LocationResolver,
  1882  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1883  				accountCodes[location] = code
  1884  				return nil
  1885  			},
  1886  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1887  				code = accountCodes[location]
  1888  				return code, nil
  1889  			},
  1890  			OnEmitEvent: func(event cadence.Event) error {
  1891  				events = append(events, event)
  1892  				return nil
  1893  			},
  1894  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1895  				return json.Decode(nil, b)
  1896  			},
  1897  		}
  1898  
  1899  		nextTransactionLocation := NewTransactionLocationGenerator()
  1900  		nextScriptLocation := NewScriptLocationGenerator()
  1901  
  1902  		// Deploy contracts
  1903  
  1904  		deployContracts(
  1905  			t,
  1906  			rt,
  1907  			contractsAddress,
  1908  			runtimeInterface,
  1909  			transactionEnvironment,
  1910  			nextTransactionLocation,
  1911  		)
  1912  
  1913  		// Run script
  1914  
  1915  		script := []byte(`
  1916            import EVM from 0x1
  1917  
  1918            access(all)
  1919            fun main(): Bool {
  1920              let data = EVM.encodeABI(["Peter"])
  1921              let values = EVM.decodeABI(types: [Type<UFix64>()], data: data)
  1922  
  1923              return true
  1924            }
  1925  		`)
  1926  
  1927  		_, err := rt.ExecuteScript(
  1928  			runtime.Script{
  1929  				Source:    script,
  1930  				Arguments: [][]byte{},
  1931  			},
  1932  			runtime.Context{
  1933  				Interface:   runtimeInterface,
  1934  				Environment: scriptEnvironment,
  1935  				Location:    nextScriptLocation(),
  1936  			},
  1937  		)
  1938  		utils.RequireError(t, err)
  1939  		assert.ErrorContains(
  1940  			t,
  1941  			err,
  1942  			"failed to ABI decode data with type UFix64",
  1943  		)
  1944  	})
  1945  
  1946  	t.Run("decodeABI with unsupported dictionary type", func(t *testing.T) {
  1947  
  1948  		t.Parallel()
  1949  
  1950  		handler := &testContractHandler{}
  1951  
  1952  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  1953  
  1954  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  1955  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  1956  
  1957  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  1958  
  1959  		accountCodes := map[common.Location][]byte{}
  1960  		var events []cadence.Event
  1961  
  1962  		runtimeInterface := &TestRuntimeInterface{
  1963  			Storage: NewTestLedger(nil, nil),
  1964  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  1965  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  1966  			},
  1967  			OnResolveLocation: LocationResolver,
  1968  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  1969  				accountCodes[location] = code
  1970  				return nil
  1971  			},
  1972  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  1973  				code = accountCodes[location]
  1974  				return code, nil
  1975  			},
  1976  			OnEmitEvent: func(event cadence.Event) error {
  1977  				events = append(events, event)
  1978  				return nil
  1979  			},
  1980  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  1981  				return json.Decode(nil, b)
  1982  			},
  1983  		}
  1984  
  1985  		nextTransactionLocation := NewTransactionLocationGenerator()
  1986  		nextScriptLocation := NewScriptLocationGenerator()
  1987  
  1988  		// Deploy contracts
  1989  
  1990  		deployContracts(
  1991  			t,
  1992  			rt,
  1993  			contractsAddress,
  1994  			runtimeInterface,
  1995  			transactionEnvironment,
  1996  			nextTransactionLocation,
  1997  		)
  1998  
  1999  		// Run script
  2000  
  2001  		script := []byte(`
  2002            import EVM from 0x1
  2003  
  2004            access(all)
  2005            fun main(): Bool {
  2006              let data = EVM.encodeABI(["Peter"])
  2007              let values = EVM.decodeABI(types: [Type<{Int: Bool}>()], data: data)
  2008  
  2009              return true
  2010            }
  2011  		`)
  2012  
  2013  		_, err := rt.ExecuteScript(
  2014  			runtime.Script{
  2015  				Source:    script,
  2016  				Arguments: [][]byte{},
  2017  			},
  2018  			runtime.Context{
  2019  				Interface:   runtimeInterface,
  2020  				Environment: scriptEnvironment,
  2021  				Location:    nextScriptLocation(),
  2022  			},
  2023  		)
  2024  		utils.RequireError(t, err)
  2025  		assert.ErrorContains(
  2026  			t,
  2027  			err,
  2028  			"failed to ABI decode data with type {Int: Bool}",
  2029  		)
  2030  	})
  2031  
  2032  	t.Run("decodeABI with unsupported array element type", func(t *testing.T) {
  2033  
  2034  		t.Parallel()
  2035  
  2036  		handler := &testContractHandler{}
  2037  
  2038  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  2039  
  2040  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2041  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2042  
  2043  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2044  
  2045  		accountCodes := map[common.Location][]byte{}
  2046  		var events []cadence.Event
  2047  
  2048  		runtimeInterface := &TestRuntimeInterface{
  2049  			Storage: NewTestLedger(nil, nil),
  2050  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2051  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2052  			},
  2053  			OnResolveLocation: LocationResolver,
  2054  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2055  				accountCodes[location] = code
  2056  				return nil
  2057  			},
  2058  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2059  				code = accountCodes[location]
  2060  				return code, nil
  2061  			},
  2062  			OnEmitEvent: func(event cadence.Event) error {
  2063  				events = append(events, event)
  2064  				return nil
  2065  			},
  2066  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2067  				return json.Decode(nil, b)
  2068  			},
  2069  		}
  2070  
  2071  		nextTransactionLocation := NewTransactionLocationGenerator()
  2072  		nextScriptLocation := NewScriptLocationGenerator()
  2073  
  2074  		// Deploy contracts
  2075  
  2076  		deployContracts(
  2077  			t,
  2078  			rt,
  2079  			contractsAddress,
  2080  			runtimeInterface,
  2081  			transactionEnvironment,
  2082  			nextTransactionLocation,
  2083  		)
  2084  
  2085  		// Run script
  2086  
  2087  		script := []byte(`
  2088            import EVM from 0x1
  2089  
  2090            access(all)
  2091            fun main(): Bool {
  2092              let data = EVM.encodeABI(["Peter"])
  2093              let values = EVM.decodeABI(types: [Type<[Character]>()], data: data)
  2094  
  2095              return true
  2096            }
  2097  		`)
  2098  
  2099  		_, err := rt.ExecuteScript(
  2100  			runtime.Script{
  2101  				Source:    script,
  2102  				Arguments: [][]byte{},
  2103  			},
  2104  			runtime.Context{
  2105  				Interface:   runtimeInterface,
  2106  				Environment: scriptEnvironment,
  2107  				Location:    nextScriptLocation(),
  2108  			},
  2109  		)
  2110  		utils.RequireError(t, err)
  2111  		assert.ErrorContains(
  2112  			t,
  2113  			err,
  2114  			"failed to ABI decode data with type [Character]",
  2115  		)
  2116  	})
  2117  
  2118  	t.Run("decodeABI with unsupported custom composite type", func(t *testing.T) {
  2119  
  2120  		t.Parallel()
  2121  
  2122  		handler := &testContractHandler{}
  2123  
  2124  		contractsAddress := flow.BytesToAddress([]byte{0x1})
  2125  
  2126  		transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2127  		scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2128  
  2129  		rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2130  
  2131  		accountCodes := map[common.Location][]byte{}
  2132  		var events []cadence.Event
  2133  
  2134  		runtimeInterface := &TestRuntimeInterface{
  2135  			Storage: NewTestLedger(nil, nil),
  2136  			OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2137  				return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2138  			},
  2139  			OnResolveLocation: LocationResolver,
  2140  			OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2141  				accountCodes[location] = code
  2142  				return nil
  2143  			},
  2144  			OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2145  				code = accountCodes[location]
  2146  				return code, nil
  2147  			},
  2148  			OnEmitEvent: func(event cadence.Event) error {
  2149  				events = append(events, event)
  2150  				return nil
  2151  			},
  2152  			OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2153  				return json.Decode(nil, b)
  2154  			},
  2155  		}
  2156  
  2157  		nextTransactionLocation := NewTransactionLocationGenerator()
  2158  		nextScriptLocation := NewScriptLocationGenerator()
  2159  
  2160  		// Deploy contracts
  2161  
  2162  		deployContracts(
  2163  			t,
  2164  			rt,
  2165  			contractsAddress,
  2166  			runtimeInterface,
  2167  			transactionEnvironment,
  2168  			nextTransactionLocation,
  2169  		)
  2170  
  2171  		// Run script
  2172  
  2173  		script := []byte(`
  2174            import EVM from 0x1
  2175  
  2176            access(all) struct Token {
  2177              access(all) let id: Int
  2178              access(all) var balance: UInt
  2179  
  2180              init(id: Int, balance: UInt) {
  2181                self.id = id
  2182                self.balance = balance
  2183              }
  2184            }
  2185  
  2186            access(all)
  2187            fun main(): Bool {
  2188              let data = EVM.encodeABI(["Peter"])
  2189              let values = EVM.decodeABI(types: [Type<Token>()], data: data)
  2190  
  2191              return true
  2192            }
  2193  		`)
  2194  
  2195  		_, err := rt.ExecuteScript(
  2196  			runtime.Script{
  2197  				Source:    script,
  2198  				Arguments: [][]byte{},
  2199  			},
  2200  			runtime.Context{
  2201  				Interface:   runtimeInterface,
  2202  				Environment: scriptEnvironment,
  2203  				Location:    nextScriptLocation(),
  2204  			},
  2205  		)
  2206  		utils.RequireError(t, err)
  2207  		assert.ErrorContains(
  2208  			t,
  2209  			err,
  2210  			"failed to ABI decode data with type s.0100000000000000000000000000000000000000000000000000000000000000.Token",
  2211  		)
  2212  	})
  2213  }
  2214  
  2215  func TestEVMEncodeABIWithSignature(t *testing.T) {
  2216  
  2217  	t.Parallel()
  2218  
  2219  	handler := &testContractHandler{}
  2220  
  2221  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2222  
  2223  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2224  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2225  
  2226  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2227  
  2228  	script := []byte(`
  2229        import EVM from 0x1
  2230  
  2231        access(all)
  2232        fun main(): [UInt8] {
  2233          // bytes for address 0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71
  2234          let address = EVM.EVMAddress(
  2235            bytes: [
  2236              122, 88, 192, 190, 114, 190, 33, 139, 65, 198,
  2237              8, 183, 254, 124, 91, 182, 48, 115, 108, 113
  2238            ]
  2239          )
  2240  
  2241          return EVM.encodeABIWithSignature(
  2242            "withdraw(address,uint256)",
  2243            [address, UInt256(250)]
  2244          )
  2245        }
  2246  	`)
  2247  
  2248  	accountCodes := map[common.Location][]byte{}
  2249  	var events []cadence.Event
  2250  
  2251  	computation := uint(0)
  2252  	runtimeInterface := &TestRuntimeInterface{
  2253  		Storage: NewTestLedger(nil, nil),
  2254  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2255  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2256  		},
  2257  		OnResolveLocation: LocationResolver,
  2258  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2259  			accountCodes[location] = code
  2260  			return nil
  2261  		},
  2262  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2263  			code = accountCodes[location]
  2264  			return code, nil
  2265  		},
  2266  		OnEmitEvent: func(event cadence.Event) error {
  2267  			events = append(events, event)
  2268  			return nil
  2269  		},
  2270  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2271  			return json.Decode(nil, b)
  2272  		},
  2273  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
  2274  			if compKind == environment.ComputationKindEVMEncodeABI {
  2275  				computation += intensity
  2276  			}
  2277  			return nil
  2278  		},
  2279  		OnHash: func(
  2280  			data []byte,
  2281  			tag string,
  2282  			hashAlgorithm runtime.HashAlgorithm,
  2283  		) ([]byte, error) {
  2284  			return crypto.Keccak256(data), nil
  2285  		},
  2286  	}
  2287  
  2288  	nextTransactionLocation := NewTransactionLocationGenerator()
  2289  	nextScriptLocation := NewScriptLocationGenerator()
  2290  
  2291  	// Deploy contracts
  2292  
  2293  	deployContracts(
  2294  		t,
  2295  		rt,
  2296  		contractsAddress,
  2297  		runtimeInterface,
  2298  		transactionEnvironment,
  2299  		nextTransactionLocation,
  2300  	)
  2301  
  2302  	// Run script
  2303  
  2304  	result, err := rt.ExecuteScript(
  2305  		runtime.Script{
  2306  			Source:    script,
  2307  			Arguments: [][]byte{},
  2308  		},
  2309  		runtime.Context{
  2310  			Interface:   runtimeInterface,
  2311  			Environment: scriptEnvironment,
  2312  			Location:    nextScriptLocation(),
  2313  		},
  2314  	)
  2315  	require.NoError(t, err)
  2316  
  2317  	abiBytes := []byte{
  2318  		0xf3, 0xfe, 0xf3, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2319  		0x0, 0x0, 0x0, 0x7a, 0x58, 0xc0, 0xbe, 0x72, 0xbe, 0x21, 0x8b, 0x41,
  2320  		0xc6, 0x8, 0xb7, 0xfe, 0x7c, 0x5b, 0xb6, 0x30, 0x73, 0x6c, 0x71, 0x0,
  2321  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2322  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2323  		0x0, 0x0, 0xfa,
  2324  	}
  2325  	cdcBytes := make([]cadence.Value, 0)
  2326  	for _, bt := range abiBytes {
  2327  		cdcBytes = append(cdcBytes, cadence.UInt8(bt))
  2328  	}
  2329  	encodedABI := cadence.NewArray(
  2330  		cdcBytes,
  2331  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  2332  
  2333  	assert.Equal(t,
  2334  		encodedABI,
  2335  		result,
  2336  	)
  2337  	// The method ID is a byte array of length 4
  2338  	assert.Equal(t, computation+4, uint(len(cdcBytes)))
  2339  }
  2340  
  2341  func TestEVMDecodeABIWithSignature(t *testing.T) {
  2342  
  2343  	t.Parallel()
  2344  
  2345  	handler := &testContractHandler{}
  2346  
  2347  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2348  
  2349  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2350  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2351  
  2352  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2353  
  2354  	script := []byte(`
  2355        import EVM from 0x1
  2356  
  2357        access(all)
  2358        fun main(data: [UInt8]): Bool {
  2359          let values = EVM.decodeABIWithSignature(
  2360            "withdraw(address,uint256)",
  2361            types: [Type<EVM.EVMAddress>(), Type<UInt256>()],
  2362            data: data
  2363          )
  2364  
  2365          // bytes for address 0x7A58c0Be72BE218B41C608b7Fe7C5bB630736C71
  2366          let address = EVM.EVMAddress(
  2367            bytes: [
  2368              122, 88, 192, 190, 114, 190, 33, 139, 65, 198,
  2369              8, 183, 254, 124, 91, 182, 48, 115, 108, 113
  2370            ]
  2371          )
  2372  
  2373          assert(values.length == 2)
  2374          assert((values[0] as! EVM.EVMAddress).bytes == address.bytes)
  2375          assert((values[1] as! UInt256) == UInt256(250))
  2376  
  2377          return true
  2378        }
  2379  	`)
  2380  
  2381  	accountCodes := map[common.Location][]byte{}
  2382  	var events []cadence.Event
  2383  
  2384  	computation := uint(0)
  2385  	runtimeInterface := &TestRuntimeInterface{
  2386  		Storage: NewTestLedger(nil, nil),
  2387  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2388  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2389  		},
  2390  		OnResolveLocation: LocationResolver,
  2391  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2392  			accountCodes[location] = code
  2393  			return nil
  2394  		},
  2395  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2396  			code = accountCodes[location]
  2397  			return code, nil
  2398  		},
  2399  		OnEmitEvent: func(event cadence.Event) error {
  2400  			events = append(events, event)
  2401  			return nil
  2402  		},
  2403  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2404  			return json.Decode(nil, b)
  2405  		},
  2406  		OnMeterComputation: func(compKind common.ComputationKind, intensity uint) error {
  2407  			if compKind == environment.ComputationKindEVMDecodeABI {
  2408  				computation += intensity
  2409  			}
  2410  			return nil
  2411  		},
  2412  		OnHash: func(
  2413  			data []byte,
  2414  			tag string,
  2415  			hashAlgorithm runtime.HashAlgorithm,
  2416  		) ([]byte, error) {
  2417  			return crypto.Keccak256(data), nil
  2418  		},
  2419  	}
  2420  
  2421  	nextTransactionLocation := NewTransactionLocationGenerator()
  2422  	nextScriptLocation := NewScriptLocationGenerator()
  2423  
  2424  	// Deploy contracts
  2425  
  2426  	deployContracts(
  2427  		t,
  2428  		rt,
  2429  		contractsAddress,
  2430  		runtimeInterface,
  2431  		transactionEnvironment,
  2432  		nextTransactionLocation,
  2433  	)
  2434  
  2435  	// Run script
  2436  	abiBytes := []byte{
  2437  		0xf3, 0xfe, 0xf3, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2438  		0x0, 0x0, 0x0, 0x7a, 0x58, 0xc0, 0xbe, 0x72, 0xbe, 0x21, 0x8b, 0x41,
  2439  		0xc6, 0x8, 0xb7, 0xfe, 0x7c, 0x5b, 0xb6, 0x30, 0x73, 0x6c, 0x71, 0x0,
  2440  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2441  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2442  		0x0, 0x0, 0xfa,
  2443  	}
  2444  	cdcBytes := make([]cadence.Value, 0)
  2445  	for _, bt := range abiBytes {
  2446  		cdcBytes = append(cdcBytes, cadence.UInt8(bt))
  2447  	}
  2448  	encodedABI := cadence.NewArray(
  2449  		cdcBytes,
  2450  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  2451  
  2452  	result, err := rt.ExecuteScript(
  2453  		runtime.Script{
  2454  			Source: script,
  2455  			Arguments: EncodeArgs([]cadence.Value{
  2456  				encodedABI,
  2457  			}),
  2458  		},
  2459  		runtime.Context{
  2460  			Interface:   runtimeInterface,
  2461  			Environment: scriptEnvironment,
  2462  			Location:    nextScriptLocation(),
  2463  		},
  2464  	)
  2465  	require.NoError(t, err)
  2466  
  2467  	assert.Equal(t, cadence.NewBool(true), result)
  2468  	// The method ID is a byte array of length 4
  2469  	assert.Equal(t, computation+4, uint(len(cdcBytes)))
  2470  }
  2471  
  2472  func TestEVMDecodeABIWithSignatureMismatch(t *testing.T) {
  2473  
  2474  	t.Parallel()
  2475  
  2476  	handler := &testContractHandler{}
  2477  
  2478  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2479  
  2480  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2481  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2482  
  2483  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2484  
  2485  	script := []byte(`
  2486        import EVM from 0x1
  2487  
  2488        access(all)
  2489        fun main(data: [UInt8]): Bool {
  2490          // The data was encoded for the function "withdraw(address,uint256)",
  2491          // but we pass a different function signature
  2492          let values = EVM.decodeABIWithSignature(
  2493            "deposit(uint256, address)",
  2494            types: [Type<UInt256>(), Type<EVM.EVMAddress>()],
  2495            data: data
  2496          )
  2497  
  2498          return true
  2499        }
  2500  	`)
  2501  
  2502  	accountCodes := map[common.Location][]byte{}
  2503  	var events []cadence.Event
  2504  
  2505  	runtimeInterface := &TestRuntimeInterface{
  2506  		Storage: NewTestLedger(nil, nil),
  2507  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2508  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2509  		},
  2510  		OnResolveLocation: LocationResolver,
  2511  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2512  			accountCodes[location] = code
  2513  			return nil
  2514  		},
  2515  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2516  			code = accountCodes[location]
  2517  			return code, nil
  2518  		},
  2519  		OnEmitEvent: func(event cadence.Event) error {
  2520  			events = append(events, event)
  2521  			return nil
  2522  		},
  2523  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2524  			return json.Decode(nil, b)
  2525  		},
  2526  		OnHash: func(
  2527  			data []byte,
  2528  			tag string,
  2529  			hashAlgorithm runtime.HashAlgorithm,
  2530  		) ([]byte, error) {
  2531  			return crypto.Keccak256(data), nil
  2532  		},
  2533  	}
  2534  
  2535  	nextTransactionLocation := NewTransactionLocationGenerator()
  2536  	nextScriptLocation := NewScriptLocationGenerator()
  2537  
  2538  	// Deploy contracts
  2539  
  2540  	deployContracts(
  2541  		t,
  2542  		rt,
  2543  		contractsAddress,
  2544  		runtimeInterface,
  2545  		transactionEnvironment,
  2546  		nextTransactionLocation,
  2547  	)
  2548  
  2549  	// Run script
  2550  	abiBytes := []byte{
  2551  		0xf3, 0xfe, 0xf3, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2552  		0x0, 0x0, 0x0, 0x7a, 0x58, 0xc0, 0xbe, 0x72, 0xbe, 0x21, 0x8b, 0x41,
  2553  		0xc6, 0x8, 0xb7, 0xfe, 0x7c, 0x5b, 0xb6, 0x30, 0x73, 0x6c, 0x71, 0x0,
  2554  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2555  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  2556  		0x0, 0x0, 0xfa,
  2557  	}
  2558  	cdcBytes := make([]cadence.Value, 0)
  2559  	for _, bt := range abiBytes {
  2560  		cdcBytes = append(cdcBytes, cadence.UInt8(bt))
  2561  	}
  2562  	encodedABI := cadence.NewArray(
  2563  		cdcBytes,
  2564  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  2565  
  2566  	_, err := rt.ExecuteScript(
  2567  		runtime.Script{
  2568  			Source: script,
  2569  			Arguments: EncodeArgs([]cadence.Value{
  2570  				encodedABI,
  2571  			}),
  2572  		},
  2573  		runtime.Context{
  2574  			Interface:   runtimeInterface,
  2575  			Environment: scriptEnvironment,
  2576  			Location:    nextScriptLocation(),
  2577  		},
  2578  	)
  2579  	require.Error(t, err)
  2580  	assert.ErrorContains(t, err, "panic: signature mismatch")
  2581  }
  2582  
  2583  func TestEVMAddressConstructionAndReturn(t *testing.T) {
  2584  
  2585  	t.Parallel()
  2586  
  2587  	handler := &testContractHandler{}
  2588  
  2589  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2590  
  2591  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2592  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2593  
  2594  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2595  
  2596  	script := []byte(`
  2597        import EVM from 0x1
  2598  
  2599        access(all)
  2600        fun main(_ bytes: [UInt8; 20]): EVM.EVMAddress {
  2601            return EVM.EVMAddress(bytes: bytes)
  2602        }
  2603      `)
  2604  
  2605  	accountCodes := map[common.Location][]byte{}
  2606  	var events []cadence.Event
  2607  
  2608  	runtimeInterface := &TestRuntimeInterface{
  2609  		Storage: NewTestLedger(nil, nil),
  2610  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2611  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2612  		},
  2613  		OnResolveLocation: LocationResolver,
  2614  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2615  			accountCodes[location] = code
  2616  			return nil
  2617  		},
  2618  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2619  			code = accountCodes[location]
  2620  			return code, nil
  2621  		},
  2622  		OnEmitEvent: func(event cadence.Event) error {
  2623  			events = append(events, event)
  2624  			return nil
  2625  		},
  2626  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2627  			return json.Decode(nil, b)
  2628  		},
  2629  	}
  2630  
  2631  	addressBytesArray := cadence.NewArray([]cadence.Value{
  2632  		cadence.UInt8(1), cadence.UInt8(1),
  2633  		cadence.UInt8(2), cadence.UInt8(2),
  2634  		cadence.UInt8(3), cadence.UInt8(3),
  2635  		cadence.UInt8(4), cadence.UInt8(4),
  2636  		cadence.UInt8(5), cadence.UInt8(5),
  2637  		cadence.UInt8(6), cadence.UInt8(6),
  2638  		cadence.UInt8(7), cadence.UInt8(7),
  2639  		cadence.UInt8(8), cadence.UInt8(8),
  2640  		cadence.UInt8(9), cadence.UInt8(9),
  2641  		cadence.UInt8(10), cadence.UInt8(10),
  2642  	}).WithType(stdlib.EVMAddressBytesCadenceType)
  2643  
  2644  	nextTransactionLocation := NewTransactionLocationGenerator()
  2645  	nextScriptLocation := NewScriptLocationGenerator()
  2646  
  2647  	// Deploy contracts
  2648  
  2649  	deployContracts(
  2650  		t,
  2651  		rt,
  2652  		contractsAddress,
  2653  		runtimeInterface,
  2654  		transactionEnvironment,
  2655  		nextTransactionLocation,
  2656  	)
  2657  
  2658  	// Run script
  2659  
  2660  	result, err := rt.ExecuteScript(
  2661  		runtime.Script{
  2662  			Source: script,
  2663  			Arguments: EncodeArgs([]cadence.Value{
  2664  				addressBytesArray,
  2665  			}),
  2666  		},
  2667  		runtime.Context{
  2668  			Interface:   runtimeInterface,
  2669  			Environment: scriptEnvironment,
  2670  			Location:    nextScriptLocation(),
  2671  		},
  2672  	)
  2673  	require.NoError(t, err)
  2674  
  2675  	evmAddressCadenceType := stdlib.NewEVMAddressCadenceType(common.Address(contractsAddress))
  2676  
  2677  	assert.Equal(t,
  2678  		cadence.NewStruct([]cadence.Value{
  2679  			addressBytesArray,
  2680  		}).WithType(evmAddressCadenceType),
  2681  		result,
  2682  	)
  2683  }
  2684  
  2685  func TestEVMAddressSerializationAndDeserialization(t *testing.T) {
  2686  
  2687  	t.Parallel()
  2688  
  2689  	handler := &testContractHandler{}
  2690  
  2691  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2692  
  2693  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2694  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2695  
  2696  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2697  
  2698  	addressFromBytesScript := []byte(`
  2699        import EVM from 0x1
  2700  
  2701        access(all)
  2702        fun main(_ bytes: [UInt8; 20]): EVM.EVMAddress {
  2703            return EVM.EVMAddress(bytes: bytes)
  2704        }
  2705      `)
  2706  
  2707  	accountCodes := map[common.Location][]byte{}
  2708  	var events []cadence.Event
  2709  
  2710  	runtimeInterface := &TestRuntimeInterface{
  2711  		Storage: NewTestLedger(nil, nil),
  2712  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2713  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2714  		},
  2715  		OnResolveLocation: LocationResolver,
  2716  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2717  			accountCodes[location] = code
  2718  			return nil
  2719  		},
  2720  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2721  			code = accountCodes[location]
  2722  			return code, nil
  2723  		},
  2724  		OnEmitEvent: func(event cadence.Event) error {
  2725  			events = append(events, event)
  2726  			return nil
  2727  		},
  2728  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2729  			return json.Decode(nil, b)
  2730  		},
  2731  	}
  2732  
  2733  	sourceBytes := []byte{
  2734  		1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
  2735  		6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
  2736  	}
  2737  
  2738  	// construct the address as a cadence value from sourceBytes
  2739  	addressBytesArray := cadence.NewArray([]cadence.Value{
  2740  		cadence.UInt8(sourceBytes[0]), cadence.UInt8(sourceBytes[1]),
  2741  		cadence.UInt8(sourceBytes[2]), cadence.UInt8(sourceBytes[3]),
  2742  		cadence.UInt8(sourceBytes[4]), cadence.UInt8(sourceBytes[5]),
  2743  		cadence.UInt8(sourceBytes[6]), cadence.UInt8(sourceBytes[7]),
  2744  		cadence.UInt8(sourceBytes[8]), cadence.UInt8(sourceBytes[9]),
  2745  		cadence.UInt8(sourceBytes[10]), cadence.UInt8(sourceBytes[11]),
  2746  		cadence.UInt8(sourceBytes[12]), cadence.UInt8(sourceBytes[13]),
  2747  		cadence.UInt8(sourceBytes[14]), cadence.UInt8(sourceBytes[15]),
  2748  		cadence.UInt8(sourceBytes[16]), cadence.UInt8(sourceBytes[17]),
  2749  		cadence.UInt8(sourceBytes[18]), cadence.UInt8(sourceBytes[19]),
  2750  	}).WithType(stdlib.EVMAddressBytesCadenceType)
  2751  
  2752  	nextTransactionLocation := NewTransactionLocationGenerator()
  2753  	nextScriptLocation := NewScriptLocationGenerator()
  2754  
  2755  	// Deploy contracts
  2756  
  2757  	deployContracts(
  2758  		t,
  2759  		rt,
  2760  		contractsAddress,
  2761  		runtimeInterface,
  2762  		transactionEnvironment,
  2763  		nextTransactionLocation,
  2764  	)
  2765  
  2766  	// Run script
  2767  
  2768  	constructAddrResult, err := rt.ExecuteScript(
  2769  		runtime.Script{
  2770  			Source: addressFromBytesScript,
  2771  			Arguments: EncodeArgs([]cadence.Value{
  2772  				addressBytesArray,
  2773  			}),
  2774  		},
  2775  		runtime.Context{
  2776  			Interface:   runtimeInterface,
  2777  			Environment: scriptEnvironment,
  2778  			Location:    nextScriptLocation(),
  2779  		},
  2780  	)
  2781  	require.NoError(t, err)
  2782  
  2783  	evmAddressCadenceType := stdlib.NewEVMAddressCadenceType(common.Address(contractsAddress))
  2784  	evmAddress := cadence.NewStruct([]cadence.Value{
  2785  		addressBytesArray,
  2786  	}).WithType(evmAddressCadenceType)
  2787  
  2788  	assert.Equal(t,
  2789  		evmAddress,
  2790  		constructAddrResult,
  2791  	)
  2792  
  2793  	// Attempt to serialize and deserialize the address
  2794  
  2795  	addressSerializationScript := []byte(`
  2796  	  import EVM from 0x1
  2797  
  2798  	  access(all)
  2799  	  fun main(address: EVM.EVMAddress): String {
  2800  		return address.toString()
  2801  	  }
  2802  	`)
  2803  
  2804  	serializeAddrResult, err := rt.ExecuteScript(
  2805  		runtime.Script{
  2806  			Source: addressSerializationScript,
  2807  			Arguments: EncodeArgs([]cadence.Value{
  2808  				evmAddress,
  2809  			}),
  2810  		},
  2811  		runtime.Context{
  2812  			Interface:   runtimeInterface,
  2813  			Environment: scriptEnvironment,
  2814  			Location:    nextScriptLocation(),
  2815  		},
  2816  	)
  2817  
  2818  	require.NoError(t, err)
  2819  
  2820  	// Encode the sourceBytes array as a hex string as the expected value to compare the result against
  2821  
  2822  	expectedHex, _ := cadence.NewString(hex.EncodeToString(sourceBytes))
  2823  
  2824  	assert.Equal(t,
  2825  		expectedHex,
  2826  		serializeAddrResult,
  2827  	)
  2828  
  2829  	// Attempt to deserialize the address
  2830  
  2831  	addressDeserializationScript := []byte(`
  2832  	  import EVM from 0x1
  2833  
  2834  	  access(all)
  2835  	  fun main(hexString: String): EVM.EVMAddress {
  2836  		return EVM.addressFromString(hexString)
  2837  	  }
  2838  	`)
  2839  
  2840  	deserializeAddrResult, err := rt.ExecuteScript(
  2841  		runtime.Script{
  2842  			Source: addressDeserializationScript,
  2843  			Arguments: EncodeArgs([]cadence.Value{
  2844  				serializeAddrResult,
  2845  			}),
  2846  		},
  2847  		runtime.Context{
  2848  			Interface:   runtimeInterface,
  2849  			Environment: scriptEnvironment,
  2850  			Location:    nextScriptLocation(),
  2851  		},
  2852  	)
  2853  
  2854  	require.NoError(t, err)
  2855  
  2856  	assert.Equal(t,
  2857  		evmAddress,
  2858  		deserializeAddrResult,
  2859  	)
  2860  }
  2861  
  2862  func TestBalanceConstructionAndReturn(t *testing.T) {
  2863  
  2864  	t.Parallel()
  2865  
  2866  	handler := &testContractHandler{}
  2867  
  2868  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2869  
  2870  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2871  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2872  
  2873  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  2874  
  2875  	script := []byte(`
  2876        import EVM from 0x1
  2877  
  2878        access(all)
  2879        fun main(_ attoflow: UInt): EVM.Balance {
  2880            return EVM.Balance(attoflow: attoflow)
  2881        }
  2882      `)
  2883  
  2884  	accountCodes := map[common.Location][]byte{}
  2885  	var events []cadence.Event
  2886  
  2887  	runtimeInterface := &TestRuntimeInterface{
  2888  		Storage: NewTestLedger(nil, nil),
  2889  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  2890  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  2891  		},
  2892  		OnResolveLocation: LocationResolver,
  2893  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  2894  			accountCodes[location] = code
  2895  			return nil
  2896  		},
  2897  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  2898  			code = accountCodes[location]
  2899  			return code, nil
  2900  		},
  2901  		OnEmitEvent: func(event cadence.Event) error {
  2902  			events = append(events, event)
  2903  			return nil
  2904  		},
  2905  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  2906  			return json.Decode(nil, b)
  2907  		},
  2908  	}
  2909  
  2910  	nextTransactionLocation := NewTransactionLocationGenerator()
  2911  	nextScriptLocation := NewScriptLocationGenerator()
  2912  
  2913  	// Deploy contracts
  2914  
  2915  	deployContracts(
  2916  		t,
  2917  		rt,
  2918  		contractsAddress,
  2919  		runtimeInterface,
  2920  		transactionEnvironment,
  2921  		nextTransactionLocation,
  2922  	)
  2923  
  2924  	// Run script
  2925  
  2926  	flowValue := cadence.NewUInt(1230000000000000000)
  2927  
  2928  	result, err := rt.ExecuteScript(
  2929  		runtime.Script{
  2930  			Source: script,
  2931  			Arguments: EncodeArgs([]cadence.Value{
  2932  				flowValue,
  2933  			}),
  2934  		},
  2935  		runtime.Context{
  2936  			Interface:   runtimeInterface,
  2937  			Environment: scriptEnvironment,
  2938  			Location:    nextScriptLocation(),
  2939  		},
  2940  	)
  2941  	require.NoError(t, err)
  2942  
  2943  	evmBalanceCadenceType := stdlib.NewBalanceCadenceType(common.Address(contractsAddress))
  2944  
  2945  	assert.Equal(t,
  2946  		cadence.NewStruct([]cadence.Value{
  2947  			flowValue,
  2948  		}).WithType(evmBalanceCadenceType),
  2949  		result,
  2950  	)
  2951  }
  2952  
  2953  func TestEVMRun(t *testing.T) {
  2954  
  2955  	t.Parallel()
  2956  
  2957  	evmTx := cadence.NewArray([]cadence.Value{
  2958  		cadence.UInt8(1),
  2959  		cadence.UInt8(2),
  2960  		cadence.UInt8(3),
  2961  	}).WithType(stdlib.EVMTransactionBytesCadenceType)
  2962  
  2963  	coinbase := cadence.NewArray([]cadence.Value{
  2964  		cadence.UInt8(1), cadence.UInt8(1),
  2965  		cadence.UInt8(2), cadence.UInt8(2),
  2966  		cadence.UInt8(3), cadence.UInt8(3),
  2967  		cadence.UInt8(4), cadence.UInt8(4),
  2968  		cadence.UInt8(5), cadence.UInt8(5),
  2969  		cadence.UInt8(6), cadence.UInt8(6),
  2970  		cadence.UInt8(7), cadence.UInt8(7),
  2971  		cadence.UInt8(8), cadence.UInt8(8),
  2972  		cadence.UInt8(9), cadence.UInt8(9),
  2973  		cadence.UInt8(10), cadence.UInt8(10),
  2974  	}).WithType(stdlib.EVMAddressBytesCadenceType)
  2975  
  2976  	runCalled := false
  2977  
  2978  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  2979  	handler := &testContractHandler{
  2980  		evmContractAddress: common.Address(contractsAddress),
  2981  		run: func(tx []byte, coinbase types.Address) *types.ResultSummary {
  2982  			runCalled = true
  2983  
  2984  			assert.Equal(t, []byte{1, 2, 3}, tx)
  2985  			assert.Equal(t,
  2986  				types.Address{
  2987  					1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
  2988  				},
  2989  				coinbase,
  2990  			)
  2991  			return &types.ResultSummary{
  2992  				Status: types.StatusSuccessful,
  2993  			}
  2994  		},
  2995  	}
  2996  
  2997  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  2998  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  2999  
  3000  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3001  
  3002  	script := []byte(`
  3003        import EVM from 0x1
  3004  
  3005        access(all)
  3006        fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]): UInt8 {
  3007            let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
  3008            let res = EVM.run(tx: tx, coinbase: coinbase)
  3009  		  let st = res.status
  3010  		  return st.rawValue
  3011        }
  3012      `)
  3013  
  3014  	accountCodes := map[common.Location][]byte{}
  3015  	var events []cadence.Event
  3016  
  3017  	runtimeInterface := &TestRuntimeInterface{
  3018  		Storage: NewTestLedger(nil, nil),
  3019  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3020  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3021  		},
  3022  		OnResolveLocation: LocationResolver,
  3023  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3024  			accountCodes[location] = code
  3025  			return nil
  3026  		},
  3027  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3028  			code = accountCodes[location]
  3029  			return code, nil
  3030  		},
  3031  		OnEmitEvent: func(event cadence.Event) error {
  3032  			events = append(events, event)
  3033  			return nil
  3034  		},
  3035  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3036  			return json.Decode(nil, b)
  3037  		},
  3038  	}
  3039  
  3040  	nextTransactionLocation := NewTransactionLocationGenerator()
  3041  	nextScriptLocation := NewScriptLocationGenerator()
  3042  
  3043  	// Deploy contracts
  3044  
  3045  	deployContracts(
  3046  		t,
  3047  		rt,
  3048  		contractsAddress,
  3049  		runtimeInterface,
  3050  		transactionEnvironment,
  3051  		nextTransactionLocation,
  3052  	)
  3053  
  3054  	// Run script
  3055  
  3056  	val, err := rt.ExecuteScript(
  3057  		runtime.Script{
  3058  			Source:    script,
  3059  			Arguments: EncodeArgs([]cadence.Value{evmTx, coinbase}),
  3060  		},
  3061  		runtime.Context{
  3062  			Interface:   runtimeInterface,
  3063  			Environment: scriptEnvironment,
  3064  			Location:    nextScriptLocation(),
  3065  		},
  3066  	)
  3067  	require.NoError(t, err)
  3068  
  3069  	assert.Equal(t, types.StatusSuccessful, types.Status(val.(cadence.UInt8)))
  3070  	assert.True(t, runCalled)
  3071  
  3072  	// test must run
  3073  	script = []byte(`
  3074  		import EVM from 0x1
  3075  
  3076  		access(all)
  3077  		fun main(tx: [UInt8], coinbaseBytes: [UInt8; 20]): UInt8 {
  3078  			let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
  3079  			let res = EVM.mustRun(tx: tx, coinbase: coinbase)
  3080  			let st = res.status
  3081  			return st.rawValue
  3082  		}
  3083    	`)
  3084  	val, err = rt.ExecuteScript(
  3085  		runtime.Script{
  3086  			Source:    script,
  3087  			Arguments: EncodeArgs([]cadence.Value{evmTx, coinbase}),
  3088  		},
  3089  		runtime.Context{
  3090  			Interface:   runtimeInterface,
  3091  			Environment: scriptEnvironment,
  3092  			Location:    nextScriptLocation(),
  3093  		},
  3094  	)
  3095  	require.NoError(t, err)
  3096  
  3097  	assert.Equal(t, types.StatusSuccessful, types.Status(val.(cadence.UInt8)))
  3098  	assert.True(t, runCalled)
  3099  }
  3100  
  3101  func TestEVMDryRun(t *testing.T) {
  3102  
  3103  	t.Parallel()
  3104  
  3105  	dryRunCalled := false
  3106  	evmTx := cadence.NewArray([]cadence.Value{
  3107  		cadence.UInt8(1),
  3108  		cadence.UInt8(2),
  3109  		cadence.UInt8(3),
  3110  	}).WithType(stdlib.EVMTransactionBytesCadenceType)
  3111  
  3112  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3113  	handler := &testContractHandler{
  3114  		evmContractAddress: common.Address(contractsAddress),
  3115  		dryRun: func(tx []byte, from types.Address) *types.ResultSummary {
  3116  			dryRunCalled = true
  3117  			assert.Equal(t, types.Address{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, from)
  3118  			assert.Equal(t, tx, []byte{1, 2, 3})
  3119  
  3120  			return &types.ResultSummary{
  3121  				Status: types.StatusSuccessful,
  3122  			}
  3123  		},
  3124  	}
  3125  
  3126  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3127  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3128  
  3129  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3130  
  3131  	accountCodes := map[common.Location][]byte{}
  3132  	var events []cadence.Event
  3133  
  3134  	runtimeInterface := &TestRuntimeInterface{
  3135  		Storage: NewTestLedger(nil, nil),
  3136  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3137  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3138  		},
  3139  		OnResolveLocation: LocationResolver,
  3140  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3141  			accountCodes[location] = code
  3142  			return nil
  3143  		},
  3144  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3145  			code = accountCodes[location]
  3146  			return code, nil
  3147  		},
  3148  		OnEmitEvent: func(event cadence.Event) error {
  3149  			events = append(events, event)
  3150  			return nil
  3151  		},
  3152  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3153  			return json.Decode(nil, b)
  3154  		},
  3155  	}
  3156  
  3157  	nextTransactionLocation := NewTransactionLocationGenerator()
  3158  	nextScriptLocation := NewScriptLocationGenerator()
  3159  
  3160  	// Deploy contracts
  3161  
  3162  	deployContracts(
  3163  		t,
  3164  		rt,
  3165  		contractsAddress,
  3166  		runtimeInterface,
  3167  		transactionEnvironment,
  3168  		nextTransactionLocation,
  3169  	)
  3170  
  3171  	// Run script
  3172  
  3173  	script := []byte(`
  3174        import EVM from 0x1
  3175  
  3176        access(all)
  3177        fun main(tx: [UInt8]): EVM.Result {
  3178            return EVM.dryRun(
  3179  			tx: tx,
  3180  			from: EVM.EVMAddress(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), // random address 
  3181            )
  3182        }
  3183      `)
  3184  
  3185  	val, err := rt.ExecuteScript(
  3186  		runtime.Script{
  3187  			Source:    script,
  3188  			Arguments: EncodeArgs([]cadence.Value{evmTx}),
  3189  		},
  3190  		runtime.Context{
  3191  			Interface:   runtimeInterface,
  3192  			Environment: scriptEnvironment,
  3193  			Location:    nextScriptLocation(),
  3194  		},
  3195  	)
  3196  	require.NoError(t, err)
  3197  	res, err := stdlib.ResultSummaryFromEVMResultValue(val)
  3198  	require.NoError(t, err)
  3199  	assert.Equal(t, types.StatusSuccessful, res.Status)
  3200  	assert.True(t, dryRunCalled)
  3201  }
  3202  
  3203  func TestEVMBatchRun(t *testing.T) {
  3204  
  3205  	t.Parallel()
  3206  
  3207  	evmTxs := cadence.NewArray([]cadence.Value{
  3208  		cadence.NewArray([]cadence.Value{cadence.UInt8(1), cadence.UInt8(2), cadence.UInt8(3)}),
  3209  		cadence.NewArray([]cadence.Value{cadence.UInt8(4), cadence.UInt8(5), cadence.UInt8(6)}),
  3210  		cadence.NewArray([]cadence.Value{cadence.UInt8(7), cadence.UInt8(8), cadence.UInt8(9)}),
  3211  	}).WithType(cadence.NewVariableSizedArrayType(cadence.NewVariableSizedArrayType(cadence.UInt8Type)))
  3212  
  3213  	coinbase := cadence.NewArray([]cadence.Value{
  3214  		cadence.UInt8(1), cadence.UInt8(1),
  3215  		cadence.UInt8(2), cadence.UInt8(2),
  3216  		cadence.UInt8(3), cadence.UInt8(3),
  3217  		cadence.UInt8(4), cadence.UInt8(4),
  3218  		cadence.UInt8(5), cadence.UInt8(5),
  3219  		cadence.UInt8(6), cadence.UInt8(6),
  3220  		cadence.UInt8(7), cadence.UInt8(7),
  3221  		cadence.UInt8(8), cadence.UInt8(8),
  3222  		cadence.UInt8(9), cadence.UInt8(9),
  3223  		cadence.UInt8(10), cadence.UInt8(10),
  3224  	}).WithType(stdlib.EVMAddressBytesCadenceType)
  3225  
  3226  	runCalled := false
  3227  
  3228  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3229  	handler := &testContractHandler{
  3230  		evmContractAddress: common.Address(contractsAddress),
  3231  		batchRun: func(txs [][]byte, coinbase types.Address) []*types.ResultSummary {
  3232  			runCalled = true
  3233  
  3234  			assert.EqualValues(t, [][]byte{
  3235  				{1, 2, 3}, {4, 5, 6}, {7, 8, 9},
  3236  			}, txs)
  3237  			assert.Equal(t,
  3238  				types.Address{
  3239  					1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
  3240  				},
  3241  				coinbase,
  3242  			)
  3243  
  3244  			results := make([]*types.ResultSummary, 3)
  3245  			for i := range results {
  3246  				results[i] = &types.ResultSummary{
  3247  					Status: types.StatusSuccessful,
  3248  				}
  3249  			}
  3250  
  3251  			return results
  3252  		},
  3253  	}
  3254  
  3255  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3256  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3257  
  3258  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3259  
  3260  	script := []byte(`
  3261        import EVM from 0x1
  3262  
  3263        access(all)
  3264        fun main(txs: [[UInt8]], coinbaseBytes: [UInt8; 20]): [EVM.Result] {
  3265            let coinbase = EVM.EVMAddress(bytes: coinbaseBytes)
  3266            return EVM.batchRun(txs: txs, coinbase: coinbase)
  3267        }
  3268      `)
  3269  
  3270  	accountCodes := map[common.Location][]byte{}
  3271  	var events []cadence.Event
  3272  
  3273  	runtimeInterface := &TestRuntimeInterface{
  3274  		Storage: NewTestLedger(nil, nil),
  3275  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3276  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3277  		},
  3278  		OnResolveLocation: LocationResolver,
  3279  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3280  			accountCodes[location] = code
  3281  			return nil
  3282  		},
  3283  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3284  			code = accountCodes[location]
  3285  			return code, nil
  3286  		},
  3287  		OnEmitEvent: func(event cadence.Event) error {
  3288  			events = append(events, event)
  3289  			return nil
  3290  		},
  3291  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3292  			return json.Decode(nil, b)
  3293  		},
  3294  	}
  3295  
  3296  	nextTransactionLocation := NewTransactionLocationGenerator()
  3297  	nextScriptLocation := NewScriptLocationGenerator()
  3298  
  3299  	// Deploy contracts
  3300  
  3301  	deployContracts(
  3302  		t,
  3303  		rt,
  3304  		contractsAddress,
  3305  		runtimeInterface,
  3306  		transactionEnvironment,
  3307  		nextTransactionLocation,
  3308  	)
  3309  
  3310  	// Run script
  3311  
  3312  	val, err := rt.ExecuteScript(
  3313  		runtime.Script{
  3314  			Source:    script,
  3315  			Arguments: EncodeArgs([]cadence.Value{evmTxs, coinbase}),
  3316  		},
  3317  		runtime.Context{
  3318  			Interface:   runtimeInterface,
  3319  			Environment: scriptEnvironment,
  3320  			Location:    nextScriptLocation(),
  3321  		},
  3322  	)
  3323  	require.NoError(t, err)
  3324  
  3325  	resultsCadence, ok := val.(cadence.Array)
  3326  	require.True(t, ok)
  3327  
  3328  	for _, v := range resultsCadence.Values {
  3329  		res, err := stdlib.ResultSummaryFromEVMResultValue(v)
  3330  		require.NoError(t, err)
  3331  		assert.Equal(t, types.StatusSuccessful, res.Status)
  3332  	}
  3333  	assert.True(t, runCalled)
  3334  }
  3335  
  3336  func TestEVMCreateCadenceOwnedAccount(t *testing.T) {
  3337  
  3338  	t.Parallel()
  3339  
  3340  	uuidCounter := uint64(0)
  3341  	handler := &testContractHandler{
  3342  		deployCOA: func(uuid uint64) types.Address {
  3343  			require.Equal(t, uuidCounter, uuid)
  3344  			return types.Address{uint8(uuidCounter)}
  3345  		},
  3346  	}
  3347  
  3348  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3349  
  3350  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3351  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3352  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3353  
  3354  	script := []byte(`
  3355        import EVM from 0x1
  3356  
  3357        access(all)
  3358        fun main(): [UInt8; 20] {
  3359            let cadenceOwnedAccount1 <- EVM.createCadenceOwnedAccount()
  3360            destroy cadenceOwnedAccount1
  3361  
  3362            let cadenceOwnedAccount2 <- EVM.createCadenceOwnedAccount()
  3363            let bytes = cadenceOwnedAccount2.address().bytes
  3364            destroy cadenceOwnedAccount2
  3365  
  3366            return bytes
  3367        }
  3368      `)
  3369  
  3370  	accountCodes := map[common.Location][]byte{}
  3371  	var events []cadence.Event
  3372  
  3373  	runtimeInterface := &TestRuntimeInterface{
  3374  		Storage: NewTestLedger(nil, nil),
  3375  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3376  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3377  		},
  3378  		OnResolveLocation: LocationResolver,
  3379  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3380  			accountCodes[location] = code
  3381  			return nil
  3382  		},
  3383  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3384  			code = accountCodes[location]
  3385  			return code, nil
  3386  		},
  3387  		OnEmitEvent: func(event cadence.Event) error {
  3388  			events = append(events, event)
  3389  			return nil
  3390  		},
  3391  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3392  			return json.Decode(nil, b)
  3393  		},
  3394  		OnGenerateUUID: func() (uint64, error) {
  3395  			uuidCounter++
  3396  			return uuidCounter, nil
  3397  		},
  3398  	}
  3399  
  3400  	nextTransactionLocation := NewTransactionLocationGenerator()
  3401  	nextScriptLocation := NewScriptLocationGenerator()
  3402  
  3403  	// Deploy contracts
  3404  
  3405  	deployContracts(
  3406  		t,
  3407  		rt,
  3408  		contractsAddress,
  3409  		runtimeInterface,
  3410  		transactionEnvironment,
  3411  		nextTransactionLocation,
  3412  	)
  3413  
  3414  	// reset events
  3415  	events = make([]cadence.Event, 0)
  3416  
  3417  	// Run script
  3418  	actual, err := rt.ExecuteScript(
  3419  		runtime.Script{
  3420  			Source: script,
  3421  		},
  3422  		runtime.Context{
  3423  			Interface:   runtimeInterface,
  3424  			Environment: scriptEnvironment,
  3425  			Location:    nextScriptLocation(),
  3426  		},
  3427  	)
  3428  	require.NoError(t, err)
  3429  
  3430  	expected := cadence.NewArray([]cadence.Value{
  3431  		cadence.UInt8(4), cadence.UInt8(0),
  3432  		cadence.UInt8(0), cadence.UInt8(0),
  3433  		cadence.UInt8(0), cadence.UInt8(0),
  3434  		cadence.UInt8(0), cadence.UInt8(0),
  3435  		cadence.UInt8(0), cadence.UInt8(0),
  3436  		cadence.UInt8(0), cadence.UInt8(0),
  3437  		cadence.UInt8(0), cadence.UInt8(0),
  3438  		cadence.UInt8(0), cadence.UInt8(0),
  3439  		cadence.UInt8(0), cadence.UInt8(0),
  3440  		cadence.UInt8(0), cadence.UInt8(0),
  3441  	}).WithType(cadence.NewConstantSizedArrayType(
  3442  		types.AddressLength,
  3443  		cadence.UInt8Type,
  3444  	))
  3445  
  3446  	require.Equal(t, expected, actual)
  3447  
  3448  	// check deposit event
  3449  	expectedEventTypes := []string{
  3450  		"EVM.CadenceOwnedAccountCreated",
  3451  		"EVM.CadenceOwnedAccountCreated",
  3452  	}
  3453  	CheckCadenceEventTypes(t, events, expectedEventTypes)
  3454  
  3455  	// check cadence owned account created events
  3456  	expectedCoaAddress := types.Address{3}
  3457  	requireEqualEventAddress(t, events[0], expectedCoaAddress)
  3458  
  3459  	expectedCoaAddress = types.Address{4}
  3460  	requireEqualEventAddress(t, events[1], expectedCoaAddress)
  3461  }
  3462  
  3463  func TestCadenceOwnedAccountCall(t *testing.T) {
  3464  
  3465  	t.Parallel()
  3466  
  3467  	expectedBalance, err := cadence.NewUFix64FromParts(1, 23000000)
  3468  	require.NoError(t, err)
  3469  
  3470  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3471  
  3472  	handler := &testContractHandler{
  3473  		evmContractAddress: common.Address(contractsAddress),
  3474  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  3475  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  3476  			assert.True(t, isAuthorized)
  3477  
  3478  			return &testFlowAccount{
  3479  				address: fromAddress,
  3480  				call: func(
  3481  					toAddress types.Address,
  3482  					data types.Data,
  3483  					limit types.GasLimit,
  3484  					balance types.Balance,
  3485  				) *types.ResultSummary {
  3486  					assert.Equal(t, types.Address{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, toAddress)
  3487  					assert.Equal(t, types.Data{4, 5, 6}, data)
  3488  					assert.Equal(t, types.GasLimit(9999), limit)
  3489  					assert.Equal(t, types.NewBalanceFromUFix64(expectedBalance), balance)
  3490  
  3491  					return &types.ResultSummary{
  3492  						Status:        types.StatusSuccessful,
  3493  						ReturnedValue: types.Data{3, 1, 4},
  3494  					}
  3495  				},
  3496  			}
  3497  		},
  3498  	}
  3499  
  3500  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3501  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3502  
  3503  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3504  
  3505  	script := []byte(`
  3506        import EVM from 0x1
  3507  
  3508        access(all)
  3509        fun main(): [UInt8] {
  3510            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  3511  		  let bal = EVM.Balance(attoflow: 0)
  3512  		  bal.setFLOW(flow: 1.23)
  3513            let response = cadenceOwnedAccount.call(
  3514                to: EVM.EVMAddress(
  3515                    bytes: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  3516                ),
  3517                data: [4, 5, 6],
  3518                gasLimit: 9999,
  3519                value: bal
  3520            )
  3521            destroy cadenceOwnedAccount
  3522            return response.data
  3523        }
  3524     `)
  3525  
  3526  	accountCodes := map[common.Location][]byte{}
  3527  	var events []cadence.Event
  3528  
  3529  	runtimeInterface := &TestRuntimeInterface{
  3530  		Storage: NewTestLedger(nil, nil),
  3531  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3532  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3533  		},
  3534  		OnResolveLocation: LocationResolver,
  3535  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3536  			accountCodes[location] = code
  3537  			return nil
  3538  		},
  3539  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3540  			code = accountCodes[location]
  3541  			return code, nil
  3542  		},
  3543  		OnEmitEvent: func(event cadence.Event) error {
  3544  			events = append(events, event)
  3545  			return nil
  3546  		},
  3547  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3548  			return json.Decode(nil, b)
  3549  		},
  3550  	}
  3551  
  3552  	nextTransactionLocation := NewTransactionLocationGenerator()
  3553  	nextScriptLocation := NewScriptLocationGenerator()
  3554  
  3555  	// Deploy contracts
  3556  
  3557  	deployContracts(
  3558  		t,
  3559  		rt,
  3560  		contractsAddress,
  3561  		runtimeInterface,
  3562  		transactionEnvironment,
  3563  		nextTransactionLocation,
  3564  	)
  3565  
  3566  	// Run script
  3567  
  3568  	actual, err := rt.ExecuteScript(
  3569  		runtime.Script{
  3570  			Source: script,
  3571  		},
  3572  		runtime.Context{
  3573  			Interface:   runtimeInterface,
  3574  			Environment: scriptEnvironment,
  3575  			Location:    nextScriptLocation(),
  3576  		},
  3577  	)
  3578  	require.NoError(t, err)
  3579  
  3580  	expected := cadence.NewArray([]cadence.Value{
  3581  		cadence.UInt8(3),
  3582  		cadence.UInt8(1),
  3583  		cadence.UInt8(4),
  3584  	}).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  3585  
  3586  	require.Equal(t, expected, actual)
  3587  }
  3588  
  3589  func TestEVMAddressDeposit(t *testing.T) {
  3590  
  3591  	t.Parallel()
  3592  
  3593  	expectedBalanceInUFix64, err := cadence.NewUFix64FromParts(1, 23000000)
  3594  	require.NoError(t, err)
  3595  	expectedBalance := types.NewBalanceFromUFix64(expectedBalanceInUFix64)
  3596  
  3597  	var deposited bool
  3598  
  3599  	handler := &testContractHandler{
  3600  
  3601  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  3602  			assert.Equal(t, types.Address{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  3603  			assert.False(t, isAuthorized)
  3604  
  3605  			return &testFlowAccount{
  3606  				address: fromAddress,
  3607  				deposit: func(vault *types.FLOWTokenVault) {
  3608  					deposited = true
  3609  					assert.Equal(
  3610  						t,
  3611  						expectedBalance,
  3612  						vault.Balance(),
  3613  					)
  3614  				},
  3615  			}
  3616  		},
  3617  	}
  3618  
  3619  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3620  
  3621  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3622  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3623  
  3624  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3625  
  3626  	script := []byte(`
  3627        import EVM from 0x1
  3628        import FlowToken from 0x1
  3629  
  3630        access(all)
  3631        fun main() {
  3632            let admin = getAuthAccount<auth(Storage) &Account>(0x1)
  3633                .storage.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)!
  3634            let minter <- admin.createNewMinter(allowedAmount: 1.23)
  3635            let vault <- minter.mintTokens(amount: 1.23)
  3636            destroy minter
  3637  
  3638            let address = EVM.EVMAddress(
  3639                bytes: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  3640            )
  3641            address.deposit(from: <-vault)
  3642        }
  3643     `)
  3644  
  3645  	accountCodes := map[common.Location][]byte{}
  3646  	var events []cadence.Event
  3647  
  3648  	runtimeInterface := &TestRuntimeInterface{
  3649  		Storage: NewTestLedger(nil, nil),
  3650  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3651  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3652  		},
  3653  		OnResolveLocation: LocationResolver,
  3654  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3655  			accountCodes[location] = code
  3656  			return nil
  3657  		},
  3658  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3659  			code = accountCodes[location]
  3660  			return code, nil
  3661  		},
  3662  		OnEmitEvent: func(event cadence.Event) error {
  3663  			events = append(events, event)
  3664  			return nil
  3665  		},
  3666  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3667  			return json.Decode(nil, b)
  3668  		},
  3669  	}
  3670  
  3671  	nextTransactionLocation := NewTransactionLocationGenerator()
  3672  	nextScriptLocation := NewScriptLocationGenerator()
  3673  
  3674  	// Deploy contracts
  3675  
  3676  	deployContracts(
  3677  		t,
  3678  		rt,
  3679  		contractsAddress,
  3680  		runtimeInterface,
  3681  		transactionEnvironment,
  3682  		nextTransactionLocation,
  3683  	)
  3684  
  3685  	// Run script
  3686  
  3687  	_, err = rt.ExecuteScript(
  3688  		runtime.Script{
  3689  			Source: script,
  3690  		},
  3691  		runtime.Context{
  3692  			Interface:   runtimeInterface,
  3693  			Environment: scriptEnvironment,
  3694  			Location:    nextScriptLocation(),
  3695  		},
  3696  	)
  3697  	require.NoError(t, err)
  3698  
  3699  	require.True(t, deposited)
  3700  }
  3701  
  3702  func TestCOADeposit(t *testing.T) {
  3703  
  3704  	t.Parallel()
  3705  
  3706  	expectedBalance, err := cadence.NewUFix64FromParts(1, 23000000)
  3707  	require.NoError(t, err)
  3708  
  3709  	var deposited bool
  3710  
  3711  	var expectedCoaAddress = types.Address{5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  3712  
  3713  	handler := &testContractHandler{
  3714  
  3715  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  3716  			assert.Equal(t, expectedCoaAddress, fromAddress)
  3717  			assert.False(t, isAuthorized)
  3718  
  3719  			return &testFlowAccount{
  3720  				address: fromAddress,
  3721  				deposit: func(vault *types.FLOWTokenVault) {
  3722  					deposited = true
  3723  					assert.Equal(
  3724  						t,
  3725  						types.NewBalanceFromUFix64(expectedBalance),
  3726  						vault.Balance(),
  3727  					)
  3728  				},
  3729  			}
  3730  		},
  3731  	}
  3732  
  3733  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3734  
  3735  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3736  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3737  
  3738  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3739  
  3740  	script := []byte(`
  3741        import EVM from 0x1
  3742        import FlowToken from 0x1
  3743  
  3744        access(all)
  3745        fun main() {
  3746            let admin = getAuthAccount<auth(BorrowValue) &Account>(0x1)
  3747                .storage.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)!
  3748            let minter <- admin.createNewMinter(allowedAmount: 1.23)
  3749            let vault <- minter.mintTokens(amount: 1.23)
  3750            destroy minter
  3751  
  3752            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  3753            cadenceOwnedAccount.deposit(from: <-vault)
  3754  		  destroy cadenceOwnedAccount
  3755        }
  3756     `)
  3757  
  3758  	accountCodes := map[common.Location][]byte{}
  3759  	var events []cadence.Event
  3760  
  3761  	runtimeInterface := &TestRuntimeInterface{
  3762  		Storage: NewTestLedger(nil, nil),
  3763  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3764  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3765  		},
  3766  		OnResolveLocation: LocationResolver,
  3767  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3768  			accountCodes[location] = code
  3769  			return nil
  3770  		},
  3771  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3772  			code = accountCodes[location]
  3773  			return code, nil
  3774  		},
  3775  		OnEmitEvent: func(event cadence.Event) error {
  3776  			events = append(events, event)
  3777  			return nil
  3778  		},
  3779  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3780  			return json.Decode(nil, b)
  3781  		},
  3782  	}
  3783  
  3784  	nextTransactionLocation := NewTransactionLocationGenerator()
  3785  	nextScriptLocation := NewScriptLocationGenerator()
  3786  
  3787  	// Deploy contracts
  3788  
  3789  	deployContracts(
  3790  		t,
  3791  		rt,
  3792  		contractsAddress,
  3793  		runtimeInterface,
  3794  		transactionEnvironment,
  3795  		nextTransactionLocation,
  3796  	)
  3797  
  3798  	// Run script
  3799  
  3800  	// reset events before script execution
  3801  	events = make([]cadence.Event, 0)
  3802  
  3803  	_, err = rt.ExecuteScript(
  3804  		runtime.Script{
  3805  			Source: script,
  3806  		},
  3807  		runtime.Context{
  3808  			Interface:   runtimeInterface,
  3809  			Environment: scriptEnvironment,
  3810  			Location:    nextScriptLocation(),
  3811  		},
  3812  	)
  3813  	require.NoError(t, err)
  3814  
  3815  	require.True(t, deposited)
  3816  
  3817  	// check deposit event
  3818  	expectedEventTypes := []string{
  3819  		"FlowToken.MinterCreated",
  3820  		"FlowToken.TokensMinted",
  3821  		"EVM.CadenceOwnedAccountCreated",
  3822  		"EVM.FLOWTokensDeposited",
  3823  	}
  3824  	CheckCadenceEventTypes(t, events, expectedEventTypes)
  3825  
  3826  	// token deposit event
  3827  	tokenDepositEvent := events[3]
  3828  	tokenDepositEventFields := cadence.FieldsMappedByName(tokenDepositEvent)
  3829  
  3830  	requireEqualEventAddress(t, tokenDepositEvent, expectedCoaAddress)
  3831  
  3832  	// check amount
  3833  	require.Equal(t,
  3834  		expectedBalance,
  3835  		tokenDepositEventFields["amount"],
  3836  	)
  3837  }
  3838  
  3839  func TestCadenceOwnedAccountWithdraw(t *testing.T) {
  3840  
  3841  	t.Parallel()
  3842  
  3843  	expectedDepositBalance, err := cadence.NewUFix64FromParts(2, 34000000)
  3844  	require.NoError(t, err)
  3845  
  3846  	expectedWithdrawBalance, err := cadence.NewUFix64FromParts(1, 23000000)
  3847  	require.NoError(t, err)
  3848  
  3849  	var deposited bool
  3850  	var withdrew bool
  3851  
  3852  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  3853  
  3854  	var nextUUID uint64 = 1
  3855  
  3856  	var expectedCoaAddress = types.Address{5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  3857  
  3858  	handler := &testContractHandler{
  3859  		flowTokenAddress: common.Address(contractsAddress),
  3860  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  3861  			assert.Equal(t, expectedCoaAddress, fromAddress)
  3862  			assert.Equal(t, deposited, isAuthorized)
  3863  
  3864  			return &testFlowAccount{
  3865  				address: fromAddress,
  3866  				deposit: func(vault *types.FLOWTokenVault) {
  3867  					deposited = true
  3868  					assert.Equal(t,
  3869  						types.NewBalanceFromUFix64(expectedDepositBalance),
  3870  						vault.Balance(),
  3871  					)
  3872  				},
  3873  				withdraw: func(balance types.Balance) *types.FLOWTokenVault {
  3874  					assert.Equal(t,
  3875  						types.NewBalanceFromUFix64(expectedWithdrawBalance),
  3876  						balance,
  3877  					)
  3878  					withdrew = true
  3879  					return types.NewFlowTokenVault(balance)
  3880  				},
  3881  			}
  3882  		},
  3883  		generateResourceUUID: func() uint64 {
  3884  			uuid := nextUUID
  3885  			nextUUID++
  3886  			return uuid
  3887  		},
  3888  	}
  3889  
  3890  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  3891  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  3892  
  3893  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  3894  
  3895  	script := []byte(`
  3896        import EVM from 0x1
  3897        import FlowToken from 0x1
  3898  
  3899        access(all)
  3900        fun main(): UFix64 {
  3901            let admin = getAuthAccount<auth(BorrowValue) &Account>(0x1)
  3902                .storage.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)!
  3903            let minter <- admin.createNewMinter(allowedAmount: 2.34)
  3904            let vault <- minter.mintTokens(amount: 2.34)
  3905            destroy minter
  3906  
  3907            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  3908            cadenceOwnedAccount.deposit(from: <-vault)
  3909  
  3910            let vault2 <- cadenceOwnedAccount.withdraw(balance: EVM.Balance(attoflow: 1230000000000000000))
  3911            let balance = vault2.balance
  3912            log(vault2.uuid)
  3913  
  3914            destroy cadenceOwnedAccount
  3915            destroy vault2
  3916  
  3917            return balance
  3918        }
  3919     `)
  3920  
  3921  	accountCodes := map[common.Location][]byte{}
  3922  	var events []cadence.Event
  3923  	var logs []string
  3924  
  3925  	runtimeInterface := &TestRuntimeInterface{
  3926  		Storage: NewTestLedger(nil, nil),
  3927  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  3928  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  3929  		},
  3930  		OnResolveLocation: LocationResolver,
  3931  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  3932  			accountCodes[location] = code
  3933  			return nil
  3934  		},
  3935  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  3936  			code = accountCodes[location]
  3937  			return code, nil
  3938  		},
  3939  		OnEmitEvent: func(event cadence.Event) error {
  3940  			events = append(events, event)
  3941  			return nil
  3942  		},
  3943  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  3944  			return json.Decode(nil, b)
  3945  		},
  3946  		OnProgramLog: func(s string) {
  3947  			logs = append(logs, s)
  3948  		},
  3949  	}
  3950  
  3951  	nextTransactionLocation := NewTransactionLocationGenerator()
  3952  	nextScriptLocation := NewScriptLocationGenerator()
  3953  
  3954  	// Deploy contracts
  3955  
  3956  	deployContracts(
  3957  		t,
  3958  		rt,
  3959  		contractsAddress,
  3960  		runtimeInterface,
  3961  		transactionEnvironment,
  3962  		nextTransactionLocation,
  3963  	)
  3964  
  3965  	// reset events
  3966  	events = make([]cadence.Event, 0)
  3967  	// Run script
  3968  	result, err := rt.ExecuteScript(
  3969  		runtime.Script{
  3970  			Source: script,
  3971  		},
  3972  		runtime.Context{
  3973  			Interface:   runtimeInterface,
  3974  			Environment: scriptEnvironment,
  3975  			Location:    nextScriptLocation(),
  3976  		},
  3977  	)
  3978  	require.NoError(t, err)
  3979  
  3980  	assert.True(t, deposited)
  3981  	assert.True(t, withdrew)
  3982  	assert.Equal(t, expectedWithdrawBalance, result)
  3983  
  3984  	assert.Equal(t, []string{"1"}, logs)
  3985  
  3986  	// check deposit event
  3987  	expectedEventTypes := []string{
  3988  		"FlowToken.MinterCreated",
  3989  		"FlowToken.TokensMinted",
  3990  		"EVM.CadenceOwnedAccountCreated",
  3991  		"EVM.FLOWTokensDeposited",
  3992  		"EVM.FLOWTokensWithdrawn",
  3993  	}
  3994  	CheckCadenceEventTypes(t, events, expectedEventTypes)
  3995  
  3996  	// token deposit event
  3997  	tokenWithdrawEvent := events[4]
  3998  	tokenWithdrawEventFields := cadence.FieldsMappedByName(tokenWithdrawEvent)
  3999  
  4000  	requireEqualEventAddress(t, tokenWithdrawEvent, expectedCoaAddress)
  4001  
  4002  	// check amount
  4003  	require.Equal(t,
  4004  		expectedWithdrawBalance,
  4005  		tokenWithdrawEventFields["amount"],
  4006  	)
  4007  }
  4008  
  4009  func TestCadenceOwnedAccountDeploy(t *testing.T) {
  4010  
  4011  	t.Parallel()
  4012  
  4013  	var deployed bool
  4014  
  4015  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4016  
  4017  	expectedBalance, err := cadence.NewUFix64FromParts(1, 23000000)
  4018  	require.NoError(t, err)
  4019  
  4020  	handler := &testContractHandler{
  4021  		evmContractAddress: common.Address(contractsAddress),
  4022  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  4023  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  4024  			assert.True(t, isAuthorized)
  4025  
  4026  			return &testFlowAccount{
  4027  				address: fromAddress,
  4028  				deploy: func(code types.Code, limit types.GasLimit, balance types.Balance) *types.ResultSummary {
  4029  					deployed = true
  4030  					assert.Equal(t, types.Code{4, 5, 6}, code)
  4031  					assert.Equal(t, types.GasLimit(9999), limit)
  4032  					assert.Equal(t, types.NewBalanceFromUFix64(expectedBalance), balance)
  4033  
  4034  					return &types.ResultSummary{
  4035  						Status:                  types.StatusSuccessful,
  4036  						DeployedContractAddress: &types.Address{4},
  4037  						ReturnedValue:           types.Data{5},
  4038  					}
  4039  				},
  4040  			}
  4041  		},
  4042  	}
  4043  
  4044  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  4045  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  4046  
  4047  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  4048  
  4049  	script := []byte(`
  4050        import EVM from 0x1
  4051  
  4052        access(all)
  4053        fun main(): [UInt8] {
  4054            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4055            let res = cadenceOwnedAccount.deploy(
  4056                code: [4, 5, 6],
  4057                gasLimit: 9999,
  4058                value: EVM.Balance(attoflow: 1230000000000000000)
  4059            )
  4060            destroy cadenceOwnedAccount
  4061  
  4062            assert(res.deployedContract?.bytes == [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
  4063            return res.data
  4064        }
  4065     `)
  4066  
  4067  	accountCodes := map[common.Location][]byte{}
  4068  	var events []cadence.Event
  4069  
  4070  	runtimeInterface := &TestRuntimeInterface{
  4071  		Storage: NewTestLedger(nil, nil),
  4072  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  4073  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  4074  		},
  4075  		OnResolveLocation: LocationResolver,
  4076  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  4077  			accountCodes[location] = code
  4078  			return nil
  4079  		},
  4080  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  4081  			code = accountCodes[location]
  4082  			return code, nil
  4083  		},
  4084  		OnEmitEvent: func(event cadence.Event) error {
  4085  			events = append(events, event)
  4086  			return nil
  4087  		},
  4088  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  4089  			return json.Decode(nil, b)
  4090  		},
  4091  	}
  4092  
  4093  	nextTransactionLocation := NewTransactionLocationGenerator()
  4094  	nextScriptLocation := NewScriptLocationGenerator()
  4095  
  4096  	// Deploy contracts
  4097  
  4098  	deployContracts(
  4099  		t,
  4100  		rt,
  4101  		contractsAddress,
  4102  		runtimeInterface,
  4103  		transactionEnvironment,
  4104  		nextTransactionLocation,
  4105  	)
  4106  
  4107  	// Run script
  4108  
  4109  	actual, err := rt.ExecuteScript(
  4110  		runtime.Script{
  4111  			Source: script,
  4112  		},
  4113  		runtime.Context{
  4114  			Interface:   runtimeInterface,
  4115  			Environment: scriptEnvironment,
  4116  			Location:    nextScriptLocation(),
  4117  		},
  4118  	)
  4119  	require.NoError(t, err)
  4120  
  4121  	expected := cadence.
  4122  		NewArray([]cadence.Value{cadence.UInt8(5)}).
  4123  		WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  4124  
  4125  	require.Equal(t, expected, actual)
  4126  
  4127  	require.True(t, deployed)
  4128  }
  4129  
  4130  func RunEVMScript(
  4131  	t *testing.T,
  4132  	handler *testContractHandler,
  4133  	script []byte,
  4134  	expectedValue cadence.Value,
  4135  ) {
  4136  	contractsAddress := flow.Address(handler.evmContractAddress)
  4137  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  4138  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  4139  
  4140  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  4141  
  4142  	accountCodes := map[common.Location][]byte{}
  4143  	var events []cadence.Event
  4144  
  4145  	runtimeInterface := &TestRuntimeInterface{
  4146  		Storage: NewTestLedger(nil, nil),
  4147  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  4148  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  4149  		},
  4150  		OnResolveLocation: LocationResolver,
  4151  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  4152  			accountCodes[location] = code
  4153  			return nil
  4154  		},
  4155  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  4156  			code = accountCodes[location]
  4157  			return code, nil
  4158  		},
  4159  		OnEmitEvent: func(event cadence.Event) error {
  4160  			events = append(events, event)
  4161  			return nil
  4162  		},
  4163  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  4164  			return json.Decode(nil, b)
  4165  		},
  4166  	}
  4167  
  4168  	nextTransactionLocation := NewTransactionLocationGenerator()
  4169  	nextScriptLocation := NewScriptLocationGenerator()
  4170  
  4171  	// Deploy contracts
  4172  
  4173  	deployContracts(
  4174  		t,
  4175  		rt,
  4176  		contractsAddress,
  4177  		runtimeInterface,
  4178  		transactionEnvironment,
  4179  		nextTransactionLocation,
  4180  	)
  4181  
  4182  	// Run script
  4183  
  4184  	actual, err := rt.ExecuteScript(
  4185  		runtime.Script{
  4186  			Source: script,
  4187  		},
  4188  		runtime.Context{
  4189  			Interface:   runtimeInterface,
  4190  			Environment: scriptEnvironment,
  4191  			Location:    nextScriptLocation(),
  4192  		},
  4193  	)
  4194  	require.NoError(t, err)
  4195  
  4196  	require.Equal(t, expectedValue, actual)
  4197  }
  4198  
  4199  func TestEVMAccountBalance(t *testing.T) {
  4200  	t.Parallel()
  4201  
  4202  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4203  	expectedBalanceValue := cadence.NewUInt(1013370000000000000)
  4204  	expectedBalance := cadence.
  4205  		NewStruct([]cadence.Value{expectedBalanceValue}).
  4206  		WithType(stdlib.NewBalanceCadenceType(common.Address(contractsAddress)))
  4207  
  4208  	handler := &testContractHandler{
  4209  		flowTokenAddress:   common.Address(contractsAddress),
  4210  		evmContractAddress: common.Address(contractsAddress),
  4211  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  4212  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  4213  			assert.False(t, isAuthorized)
  4214  
  4215  			return &testFlowAccount{
  4216  				address: fromAddress,
  4217  				balance: func() types.Balance {
  4218  					return types.NewBalance(expectedBalanceValue.Value)
  4219  				},
  4220  			}
  4221  		},
  4222  	}
  4223  
  4224  	script := []byte(`
  4225  	import EVM from 0x1
  4226  
  4227  	access(all)
  4228  	fun main(): EVM.Balance {
  4229  			let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4230  			let balance = cadenceOwnedAccount.balance()
  4231  			destroy cadenceOwnedAccount
  4232  			return balance
  4233  		}
  4234  	`)
  4235  	RunEVMScript(t, handler, script, expectedBalance)
  4236  }
  4237  
  4238  func TestEVMAccountNonce(t *testing.T) {
  4239  	t.Parallel()
  4240  
  4241  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4242  	expectedNonceValue := cadence.NewUInt64(2000)
  4243  	handler := &testContractHandler{
  4244  		flowTokenAddress:   common.Address(contractsAddress),
  4245  		evmContractAddress: common.Address(contractsAddress),
  4246  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  4247  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  4248  			assert.False(t, isAuthorized)
  4249  
  4250  			return &testFlowAccount{
  4251  				address: fromAddress,
  4252  				nonce: func() uint64 {
  4253  					return uint64(expectedNonceValue)
  4254  				},
  4255  			}
  4256  		},
  4257  	}
  4258  
  4259  	script := []byte(`
  4260        import EVM from 0x1
  4261  
  4262        access(all)
  4263        fun main(): UInt64 {
  4264            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4265            let nonce = cadenceOwnedAccount.address().nonce()
  4266            destroy cadenceOwnedAccount
  4267            return nonce
  4268        }
  4269      `)
  4270  
  4271  	RunEVMScript(t, handler, script, expectedNonceValue)
  4272  }
  4273  
  4274  func TestEVMAccountCode(t *testing.T) {
  4275  	t.Parallel()
  4276  
  4277  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4278  	expectedCodeRaw := []byte{1, 2, 3}
  4279  	expectedCodeValue := cadence.NewArray(
  4280  		[]cadence.Value{cadence.UInt8(1), cadence.UInt8(2), cadence.UInt8(3)},
  4281  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  4282  
  4283  	handler := &testContractHandler{
  4284  		flowTokenAddress:   common.Address(contractsAddress),
  4285  		evmContractAddress: common.Address(contractsAddress),
  4286  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  4287  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  4288  			assert.False(t, isAuthorized)
  4289  
  4290  			return &testFlowAccount{
  4291  				address: fromAddress,
  4292  				code: func() types.Code {
  4293  					return expectedCodeRaw
  4294  				},
  4295  			}
  4296  		},
  4297  	}
  4298  
  4299  	script := []byte(`
  4300        import EVM from 0x1
  4301  
  4302        access(all)
  4303        fun main(): [UInt8] {
  4304            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4305            let code = cadenceOwnedAccount.address().code()
  4306            destroy cadenceOwnedAccount
  4307            return code
  4308        }
  4309      `)
  4310  
  4311  	RunEVMScript(t, handler, script, expectedCodeValue)
  4312  }
  4313  
  4314  func TestEVMAccountCodeHash(t *testing.T) {
  4315  	t.Parallel()
  4316  
  4317  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4318  	expectedCodeHashRaw := []byte{1, 2, 3}
  4319  	expectedCodeHashValue := cadence.NewArray(
  4320  		[]cadence.Value{cadence.UInt8(1), cadence.UInt8(2), cadence.UInt8(3)},
  4321  	).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type))
  4322  
  4323  	handler := &testContractHandler{
  4324  		flowTokenAddress:   common.Address(contractsAddress),
  4325  		evmContractAddress: common.Address(contractsAddress),
  4326  		accountByAddress: func(fromAddress types.Address, isAuthorized bool) types.Account {
  4327  			assert.Equal(t, types.Address{3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, fromAddress)
  4328  			assert.False(t, isAuthorized)
  4329  
  4330  			return &testFlowAccount{
  4331  				address: fromAddress,
  4332  				codeHash: func() []byte {
  4333  					return expectedCodeHashRaw
  4334  				},
  4335  			}
  4336  		},
  4337  	}
  4338  
  4339  	script := []byte(`
  4340        import EVM from 0x1
  4341  
  4342        access(all)
  4343        fun main(): [UInt8] {
  4344            let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4345            let codeHash = cadenceOwnedAccount.address().codeHash()
  4346            destroy cadenceOwnedAccount
  4347            return codeHash
  4348        }
  4349      `)
  4350  
  4351  	RunEVMScript(t, handler, script, expectedCodeHashValue)
  4352  }
  4353  
  4354  func TestEVMValidateCOAOwnershipProof(t *testing.T) {
  4355  	t.Parallel()
  4356  
  4357  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4358  
  4359  	proof := &types.COAOwnershipProofInContext{
  4360  		COAOwnershipProof: types.COAOwnershipProof{
  4361  			Address:        types.FlowAddress(contractsAddress),
  4362  			CapabilityPath: "coa",
  4363  			Signatures:     []types.Signature{[]byte("signature")},
  4364  			KeyIndices:     []uint64{0},
  4365  		},
  4366  		SignedData: []byte("signedData"),
  4367  		EVMAddress: RandomAddress(t),
  4368  	}
  4369  
  4370  	handler := &testContractHandler{
  4371  		deployCOA: func(_ uint64) types.Address {
  4372  			return proof.EVMAddress
  4373  		},
  4374  	}
  4375  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  4376  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  4377  
  4378  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  4379  
  4380  	accountCodes := map[common.Location][]byte{}
  4381  	var events []cadence.Event
  4382  
  4383  	runtimeInterface := &TestRuntimeInterface{
  4384  		Storage: NewTestLedger(nil, nil),
  4385  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  4386  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  4387  		},
  4388  		OnResolveLocation: LocationResolver,
  4389  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  4390  			accountCodes[location] = code
  4391  			return nil
  4392  		},
  4393  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  4394  			code = accountCodes[location]
  4395  			return code, nil
  4396  		},
  4397  		OnEmitEvent: func(event cadence.Event) error {
  4398  			events = append(events, event)
  4399  			return nil
  4400  		},
  4401  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  4402  			return json.Decode(nil, b)
  4403  		},
  4404  		OnGetAccountKey: func(addr runtime.Address, index int) (*cadenceStdlib.AccountKey, error) {
  4405  			require.Equal(t, proof.Address[:], addr[:])
  4406  			return &cadenceStdlib.AccountKey{
  4407  				PublicKey: &cadenceStdlib.PublicKey{},
  4408  				KeyIndex:  index,
  4409  				Weight:    100,
  4410  				HashAlgo:  sema.HashAlgorithmKECCAK_256,
  4411  				IsRevoked: false,
  4412  			}, nil
  4413  		},
  4414  		OnVerifySignature: func(
  4415  			signature []byte,
  4416  			tag string,
  4417  			sd,
  4418  			publicKey []byte,
  4419  			signatureAlgorithm runtime.SignatureAlgorithm,
  4420  			hashAlgorithm runtime.HashAlgorithm) (bool, error) {
  4421  			// require.Equal(t, []byte(signedData.ToGoValue()), st)
  4422  			return true, nil
  4423  		},
  4424  	}
  4425  
  4426  	nextTransactionLocation := NewTransactionLocationGenerator()
  4427  	nextScriptLocation := NewScriptLocationGenerator()
  4428  
  4429  	// Deploy contracts
  4430  
  4431  	deployContracts(
  4432  		t,
  4433  		rt,
  4434  		contractsAddress,
  4435  		runtimeInterface,
  4436  		transactionEnvironment,
  4437  		nextTransactionLocation,
  4438  	)
  4439  
  4440  	setupTx := []byte(`
  4441  		import EVM from 0x1
  4442  
  4443  		transaction {
  4444  			prepare(account: auth(Capabilities, SaveValue) &Account) {
  4445  				let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount()
  4446  
  4447  				account.storage.save(
  4448  				    <-cadenceOwnedAccount,
  4449  					to: /storage/coa
  4450  				)
  4451  
  4452  				let cap = account.capabilities.storage
  4453  				    .issue<&EVM.CadenceOwnedAccount>(/storage/coa)
  4454  				account.capabilities.publish(cap, at: /public/coa)
  4455  			}
  4456  		}`)
  4457  
  4458  	err := rt.ExecuteTransaction(
  4459  		runtime.Script{
  4460  			Source: setupTx,
  4461  		},
  4462  		runtime.Context{
  4463  			Interface:   runtimeInterface,
  4464  			Environment: transactionEnvironment,
  4465  			Location:    nextTransactionLocation(),
  4466  		},
  4467  	)
  4468  	require.NoError(t, err)
  4469  
  4470  	script := []byte(`
  4471        import EVM from 0x1
  4472  
  4473        access(all)
  4474        fun main(
  4475  		  address: Address,
  4476  		  path: PublicPath,
  4477  		  signedData: [UInt8],
  4478  		  keyIndices: [UInt64],
  4479  		  signatures: [[UInt8]],
  4480  		  evmAddress: [UInt8; 20]
  4481  
  4482  		) {
  4483            EVM.validateCOAOwnershipProof(
  4484  			address: address,
  4485  			path: path,
  4486  			signedData: signedData,
  4487  			keyIndices: keyIndices,
  4488  			signatures: signatures, 
  4489  			evmAddress: evmAddress
  4490  		  )
  4491        }
  4492      `)
  4493  
  4494  	// Run script
  4495  	_, err = rt.ExecuteScript(
  4496  		runtime.Script{
  4497  			Source:    script,
  4498  			Arguments: EncodeArgs(proof.ToCadenceValues()),
  4499  		},
  4500  		runtime.Context{
  4501  			Interface:   runtimeInterface,
  4502  			Environment: scriptEnvironment,
  4503  			Location:    nextScriptLocation(),
  4504  		},
  4505  	)
  4506  	require.NoError(t, err)
  4507  }
  4508  
  4509  func TestInternalEVMAccess(t *testing.T) {
  4510  
  4511  	t.Parallel()
  4512  
  4513  	handler := &testContractHandler{}
  4514  
  4515  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4516  	transactionEnvironment := newEVMTransactionEnvironment(handler, contractsAddress)
  4517  	scriptEnvironment := newEVMScriptEnvironment(handler, contractsAddress)
  4518  	rt := runtime.NewInterpreterRuntime(runtime.Config{})
  4519  
  4520  	script := []byte(`
  4521        import EVM from 0x1
  4522  
  4523        access(all)
  4524        fun main() {
  4525            let a = InternalEVM.createBridgedAccount()
  4526        }
  4527      `)
  4528  
  4529  	accountCodes := map[common.Location][]byte{}
  4530  
  4531  	runtimeInterface := &TestRuntimeInterface{
  4532  		Storage: NewTestLedger(nil, nil),
  4533  		OnGetSigningAccounts: func() ([]runtime.Address, error) {
  4534  			return []runtime.Address{runtime.Address(contractsAddress)}, nil
  4535  		},
  4536  		OnResolveLocation: LocationResolver,
  4537  		OnUpdateAccountContractCode: func(location common.AddressLocation, code []byte) error {
  4538  			accountCodes[location] = code
  4539  			return nil
  4540  		},
  4541  		OnGetAccountContractCode: func(location common.AddressLocation) (code []byte, err error) {
  4542  			code = accountCodes[location]
  4543  			return code, nil
  4544  		},
  4545  		OnEmitEvent: func(event cadence.Event) error {
  4546  			return nil
  4547  		},
  4548  		OnDecodeArgument: func(b []byte, t cadence.Type) (cadence.Value, error) {
  4549  			return json.Decode(nil, b)
  4550  		},
  4551  	}
  4552  
  4553  	nextTransactionLocation := NewTransactionLocationGenerator()
  4554  	nextScriptLocation := NewScriptLocationGenerator()
  4555  
  4556  	// Deploy contracts
  4557  
  4558  	deployContracts(
  4559  		t,
  4560  		rt,
  4561  		contractsAddress,
  4562  		runtimeInterface,
  4563  		transactionEnvironment,
  4564  		nextTransactionLocation,
  4565  	)
  4566  
  4567  	// Run script
  4568  
  4569  	_, err := rt.ExecuteScript(
  4570  		runtime.Script{
  4571  			Source: script,
  4572  		},
  4573  		runtime.Context{
  4574  			Interface:   runtimeInterface,
  4575  			Environment: scriptEnvironment,
  4576  			Location:    nextScriptLocation(),
  4577  		},
  4578  	)
  4579  	require.Error(t, err)
  4580  }
  4581  
  4582  func TestEVMGetLatestBlock(t *testing.T) {
  4583  	t.Parallel()
  4584  
  4585  	contractsAddress := flow.BytesToAddress([]byte{0x1})
  4586  
  4587  	latestBlock := &types.Block{
  4588  		Height:      uint64(2),
  4589  		TotalSupply: big.NewInt(1500000000000000000),
  4590  		Timestamp:   uint64(1337),
  4591  	}
  4592  	handler := &testContractHandler{
  4593  		evmContractAddress: common.Address(contractsAddress),
  4594  		lastExecutedBlock: func() *types.Block {
  4595  			return latestBlock
  4596  		},
  4597  	}
  4598  
  4599  	script := []byte(`
  4600        import EVM from 0x1
  4601  
  4602        access(all)
  4603        fun main(): EVM.EVMBlock {
  4604          return EVM.getLatestBlock()
  4605        }
  4606  	`)
  4607  
  4608  	evmBlockCadenceType := stdlib.NewEVMBlockCadenceType(
  4609  		common.Address(contractsAddress),
  4610  	)
  4611  
  4612  	blockHeight := cadence.NewUInt64(latestBlock.Height)
  4613  	hash, err := latestBlock.Hash()
  4614  	require.NoError(t, err)
  4615  	blockHash, err := cadence.NewString(hash.Hex())
  4616  	require.NoError(t, err)
  4617  	blockTotalSupply := cadence.NewIntFromBig(latestBlock.TotalSupply)
  4618  	timestamp := cadence.NewUInt64(latestBlock.Timestamp)
  4619  
  4620  	expectedEVMBlock := cadence.NewStruct([]cadence.Value{
  4621  		blockHeight,
  4622  		blockHash,
  4623  		blockTotalSupply,
  4624  		timestamp,
  4625  	}).WithType(evmBlockCadenceType)
  4626  
  4627  	RunEVMScript(t, handler, script, expectedEVMBlock)
  4628  }