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

     1  package stdlib
     2  
     3  import (
     4  	_ "embed"
     5  	"fmt"
     6  	"math"
     7  	"math/big"
     8  	"reflect"
     9  	"regexp"
    10  	"strings"
    11  
    12  	"github.com/onflow/cadence"
    13  	"github.com/onflow/cadence/runtime"
    14  	"github.com/onflow/cadence/runtime/common"
    15  	"github.com/onflow/cadence/runtime/errors"
    16  	"github.com/onflow/cadence/runtime/interpreter"
    17  	"github.com/onflow/cadence/runtime/sema"
    18  	"github.com/onflow/cadence/runtime/stdlib"
    19  	gethABI "github.com/onflow/go-ethereum/accounts/abi"
    20  	gethCommon "github.com/onflow/go-ethereum/common"
    21  
    22  	"github.com/onflow/flow-go/fvm/environment"
    23  	"github.com/onflow/flow-go/fvm/evm/types"
    24  	"github.com/onflow/flow-go/model/flow"
    25  )
    26  
    27  //go:embed contract.cdc
    28  var contractCode string
    29  
    30  var nftImportPattern = regexp.MustCompile(`(?m)^import "NonFungibleToken"`)
    31  var fungibleTokenImportPattern = regexp.MustCompile(`(?m)^import "FungibleToken"`)
    32  var flowTokenImportPattern = regexp.MustCompile(`(?m)^import "FlowToken"`)
    33  
    34  func ContractCode(nonFungibleTokenAddress, fungibleTokenAddress, flowTokenAddress flow.Address) []byte {
    35  	evmContract := nftImportPattern.ReplaceAllString(
    36  		contractCode,
    37  		fmt.Sprintf("import NonFungibleToken from %s", nonFungibleTokenAddress.HexWithPrefix()),
    38  	)
    39  	evmContract = fungibleTokenImportPattern.ReplaceAllString(
    40  		evmContract,
    41  		fmt.Sprintf("import FungibleToken from %s", fungibleTokenAddress.HexWithPrefix()),
    42  	)
    43  	evmContract = flowTokenImportPattern.ReplaceAllString(
    44  		evmContract,
    45  		fmt.Sprintf("import FlowToken from %s", flowTokenAddress.HexWithPrefix()),
    46  	)
    47  	return []byte(evmContract)
    48  }
    49  
    50  const (
    51  	ContractName = "EVM"
    52  
    53  	evmAddressTypeBytesFieldName = "bytes"
    54  
    55  	evmAddressTypeQualifiedIdentifier = "EVM.EVMAddress"
    56  
    57  	evmBalanceTypeQualifiedIdentifier = "EVM.Balance"
    58  
    59  	evmResultTypeQualifiedIdentifier       = "EVM.Result"
    60  	evmResultTypeStatusFieldName           = "status"
    61  	evmResultTypeErrorCodeFieldName        = "errorCode"
    62  	evmResultTypeGasUsedFieldName          = "gasUsed"
    63  	evmResultTypeDataFieldName             = "data"
    64  	evmResultTypeDeployedContractFieldName = "deployedContract"
    65  
    66  	evmStatusTypeQualifiedIdentifier = "EVM.Status"
    67  
    68  	evmBlockTypeQualifiedIdentifier = "EVM.EVMBlock"
    69  	abiEncodingByteSize             = 32
    70  )
    71  
    72  var (
    73  	EVMTransactionBytesCadenceType = cadence.NewVariableSizedArrayType(cadence.UInt8Type)
    74  
    75  	evmTransactionBytesType       = sema.NewVariableSizedType(nil, sema.UInt8Type)
    76  	evmTransactionsBatchBytesType = sema.NewVariableSizedType(nil, evmTransactionBytesType)
    77  	evmAddressBytesType           = sema.NewConstantSizedType(nil, sema.UInt8Type, types.AddressLength)
    78  
    79  	evmAddressBytesStaticType = interpreter.ConvertSemaArrayTypeToStaticArrayType(nil, evmAddressBytesType)
    80  
    81  	EVMAddressBytesCadenceType = cadence.NewConstantSizedArrayType(types.AddressLength, cadence.UInt8Type)
    82  )
    83  
    84  // abiEncodingError
    85  type abiEncodingError struct {
    86  	Type interpreter.StaticType
    87  }
    88  
    89  var _ errors.UserError = abiEncodingError{}
    90  
    91  func (abiEncodingError) IsUserError() {}
    92  
    93  func (e abiEncodingError) Error() string {
    94  	var b strings.Builder
    95  	b.WriteString("failed to ABI encode value")
    96  
    97  	ty := e.Type
    98  	if ty != nil {
    99  		b.WriteString(" of type ")
   100  		b.WriteString(ty.String())
   101  	}
   102  
   103  	return b.String()
   104  }
   105  
   106  // abiDecodingError
   107  type abiDecodingError struct {
   108  	Type    interpreter.StaticType
   109  	Message string
   110  }
   111  
   112  var _ errors.UserError = abiDecodingError{}
   113  
   114  func (abiDecodingError) IsUserError() {}
   115  
   116  func (e abiDecodingError) Error() string {
   117  	var b strings.Builder
   118  	b.WriteString("failed to ABI decode data")
   119  
   120  	ty := e.Type
   121  	if ty != nil {
   122  		b.WriteString(" with type ")
   123  		b.WriteString(ty.String())
   124  	}
   125  
   126  	message := e.Message
   127  	if message != "" {
   128  		b.WriteString(": ")
   129  		b.WriteString(message)
   130  	}
   131  
   132  	return b.String()
   133  }
   134  
   135  func reportABIEncodingComputation(
   136  	inter *interpreter.Interpreter,
   137  	locationRange interpreter.LocationRange,
   138  	values *interpreter.ArrayValue,
   139  	evmAddressTypeID common.TypeID,
   140  	reportComputation func(intensity uint),
   141  ) {
   142  	values.Iterate(
   143  		inter,
   144  		func(element interpreter.Value) (resume bool) {
   145  			switch value := element.(type) {
   146  			case *interpreter.StringValue:
   147  				// Dynamic variables, such as strings, are encoded
   148  				// in 2+ chunks of 32 bytes. The first chunk contains
   149  				// the index where information for the string begin,
   150  				// the second chunk contains the number of bytes the
   151  				// string occupies, and the third chunk contains the
   152  				// value of the string itself.
   153  				computation := uint(2 * abiEncodingByteSize)
   154  				stringLength := len(value.Str)
   155  				chunks := math.Ceil(float64(stringLength) / float64(abiEncodingByteSize))
   156  				computation += uint(chunks * abiEncodingByteSize)
   157  				reportComputation(computation)
   158  
   159  			case interpreter.BoolValue,
   160  				interpreter.UInt8Value,
   161  				interpreter.UInt16Value,
   162  				interpreter.UInt32Value,
   163  				interpreter.UInt64Value,
   164  				interpreter.UInt128Value,
   165  				interpreter.UInt256Value,
   166  				interpreter.Int8Value,
   167  				interpreter.Int16Value,
   168  				interpreter.Int32Value,
   169  				interpreter.Int64Value,
   170  				interpreter.Int128Value,
   171  				interpreter.Int256Value:
   172  
   173  				// Numeric and bool variables are also static variables
   174  				// with a fixed size of 32 bytes.
   175  				reportComputation(abiEncodingByteSize)
   176  
   177  			case *interpreter.CompositeValue:
   178  				if value.TypeID() == evmAddressTypeID {
   179  					// EVM addresses are static variables with a fixed
   180  					// size of 32 bytes.
   181  					reportComputation(abiEncodingByteSize)
   182  				} else {
   183  					panic(abiEncodingError{
   184  						Type: value.StaticType(inter),
   185  					})
   186  				}
   187  			case *interpreter.ArrayValue:
   188  				// Dynamic variables, such as arrays & slices, are encoded
   189  				// in 2+ chunks of 32 bytes. The first chunk contains
   190  				// the index where information for the array begin,
   191  				// the second chunk contains the number of bytes the
   192  				// array occupies, and the third chunk contains the
   193  				// values of the array itself.
   194  				computation := uint(2 * abiEncodingByteSize)
   195  				reportComputation(computation)
   196  				reportABIEncodingComputation(
   197  					inter,
   198  					locationRange,
   199  					value,
   200  					evmAddressTypeID,
   201  					reportComputation,
   202  				)
   203  
   204  			default:
   205  				panic(abiEncodingError{
   206  					Type: element.StaticType(inter),
   207  				})
   208  			}
   209  
   210  			// continue iteration
   211  			return true
   212  		},
   213  		false,
   214  		locationRange,
   215  	)
   216  }
   217  
   218  // EVM.encodeABI
   219  
   220  const internalEVMTypeEncodeABIFunctionName = "encodeABI"
   221  
   222  var internalEVMTypeEncodeABIFunctionType = &sema.FunctionType{
   223  	Parameters: []sema.Parameter{
   224  		{
   225  			Label:      sema.ArgumentLabelNotRequired,
   226  			Identifier: "values",
   227  			TypeAnnotation: sema.NewTypeAnnotation(
   228  				sema.NewVariableSizedType(nil, sema.AnyStructType),
   229  			),
   230  		},
   231  	},
   232  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
   233  }
   234  
   235  func newInternalEVMTypeEncodeABIFunction(
   236  	gauge common.MemoryGauge,
   237  	location common.AddressLocation,
   238  ) *interpreter.HostFunctionValue {
   239  
   240  	evmAddressTypeID := location.TypeID(gauge, evmAddressTypeQualifiedIdentifier)
   241  
   242  	return interpreter.NewStaticHostFunctionValue(
   243  		gauge,
   244  		internalEVMTypeEncodeABIFunctionType,
   245  		func(invocation interpreter.Invocation) interpreter.Value {
   246  			inter := invocation.Interpreter
   247  			locationRange := invocation.LocationRange
   248  
   249  			// Get `values` argument
   250  
   251  			valuesArray, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
   252  			if !ok {
   253  				panic(errors.NewUnreachableError())
   254  			}
   255  
   256  			reportABIEncodingComputation(
   257  				inter,
   258  				locationRange,
   259  				valuesArray,
   260  				evmAddressTypeID,
   261  				func(intensity uint) {
   262  					inter.ReportComputation(environment.ComputationKindEVMEncodeABI, intensity)
   263  				},
   264  			)
   265  
   266  			size := valuesArray.Count()
   267  
   268  			values := make([]any, 0, size)
   269  			arguments := make(gethABI.Arguments, 0, size)
   270  
   271  			valuesArray.Iterate(
   272  				inter,
   273  				func(element interpreter.Value) (resume bool) {
   274  					value, ty, err := encodeABI(
   275  						inter,
   276  						locationRange,
   277  						element,
   278  						element.StaticType(inter),
   279  						evmAddressTypeID,
   280  					)
   281  					if err != nil {
   282  						panic(err)
   283  					}
   284  
   285  					values = append(values, value)
   286  					arguments = append(arguments, gethABI.Argument{Type: ty})
   287  
   288  					// continue iteration
   289  					return true
   290  				},
   291  				false,
   292  				locationRange,
   293  			)
   294  
   295  			encodedValues, err := arguments.Pack(values...)
   296  			if err != nil {
   297  				panic(abiEncodingError{})
   298  			}
   299  
   300  			return interpreter.ByteSliceToByteArrayValue(inter, encodedValues)
   301  		},
   302  	)
   303  }
   304  
   305  var gethTypeString = gethABI.Type{T: gethABI.StringTy}
   306  
   307  var gethTypeBool = gethABI.Type{T: gethABI.BoolTy}
   308  
   309  var gethTypeUint8 = gethABI.Type{T: gethABI.UintTy, Size: 8}
   310  
   311  var gethTypeUint16 = gethABI.Type{T: gethABI.UintTy, Size: 16}
   312  
   313  var gethTypeUint32 = gethABI.Type{T: gethABI.UintTy, Size: 32}
   314  
   315  var gethTypeUint64 = gethABI.Type{T: gethABI.UintTy, Size: 64}
   316  
   317  var gethTypeUint128 = gethABI.Type{T: gethABI.UintTy, Size: 128}
   318  
   319  var gethTypeUint256 = gethABI.Type{T: gethABI.UintTy, Size: 256}
   320  
   321  var gethTypeInt8 = gethABI.Type{T: gethABI.IntTy, Size: 8}
   322  
   323  var gethTypeInt16 = gethABI.Type{T: gethABI.IntTy, Size: 16}
   324  
   325  var gethTypeInt32 = gethABI.Type{T: gethABI.IntTy, Size: 32}
   326  
   327  var gethTypeInt64 = gethABI.Type{T: gethABI.IntTy, Size: 64}
   328  
   329  var gethTypeInt128 = gethABI.Type{T: gethABI.IntTy, Size: 128}
   330  
   331  var gethTypeInt256 = gethABI.Type{T: gethABI.IntTy, Size: 256}
   332  
   333  var gethTypeAddress = gethABI.Type{Size: 20, T: gethABI.AddressTy}
   334  
   335  func gethABIType(staticType interpreter.StaticType, evmAddressTypeID common.TypeID) (gethABI.Type, bool) {
   336  	switch staticType {
   337  	case interpreter.PrimitiveStaticTypeString:
   338  		return gethTypeString, true
   339  	case interpreter.PrimitiveStaticTypeBool:
   340  		return gethTypeBool, true
   341  	case interpreter.PrimitiveStaticTypeUInt8:
   342  		return gethTypeUint8, true
   343  	case interpreter.PrimitiveStaticTypeUInt16:
   344  		return gethTypeUint16, true
   345  	case interpreter.PrimitiveStaticTypeUInt32:
   346  		return gethTypeUint32, true
   347  	case interpreter.PrimitiveStaticTypeUInt64:
   348  		return gethTypeUint64, true
   349  	case interpreter.PrimitiveStaticTypeUInt128:
   350  		return gethTypeUint128, true
   351  	case interpreter.PrimitiveStaticTypeUInt256:
   352  		return gethTypeUint256, true
   353  	case interpreter.PrimitiveStaticTypeInt8:
   354  		return gethTypeInt8, true
   355  	case interpreter.PrimitiveStaticTypeInt16:
   356  		return gethTypeInt16, true
   357  	case interpreter.PrimitiveStaticTypeInt32:
   358  		return gethTypeInt32, true
   359  	case interpreter.PrimitiveStaticTypeInt64:
   360  		return gethTypeInt64, true
   361  	case interpreter.PrimitiveStaticTypeInt128:
   362  		return gethTypeInt128, true
   363  	case interpreter.PrimitiveStaticTypeInt256:
   364  		return gethTypeInt256, true
   365  	case interpreter.PrimitiveStaticTypeAddress:
   366  		return gethTypeAddress, true
   367  	}
   368  
   369  	switch staticType := staticType.(type) {
   370  	case *interpreter.CompositeStaticType:
   371  		if staticType.TypeID != evmAddressTypeID {
   372  			break
   373  		}
   374  
   375  		return gethTypeAddress, true
   376  
   377  	case *interpreter.ConstantSizedStaticType:
   378  		elementGethABIType, ok := gethABIType(
   379  			staticType.ElementType(),
   380  			evmAddressTypeID,
   381  		)
   382  		if !ok {
   383  			break
   384  		}
   385  
   386  		return gethABI.Type{
   387  			T:    gethABI.ArrayTy,
   388  			Elem: &elementGethABIType,
   389  			Size: int(staticType.Size),
   390  		}, true
   391  
   392  	case *interpreter.VariableSizedStaticType:
   393  		elementGethABIType, ok := gethABIType(
   394  			staticType.ElementType(),
   395  			evmAddressTypeID,
   396  		)
   397  		if !ok {
   398  			break
   399  		}
   400  
   401  		return gethABI.Type{
   402  			T:    gethABI.SliceTy,
   403  			Elem: &elementGethABIType,
   404  		}, true
   405  
   406  	}
   407  
   408  	return gethABI.Type{}, false
   409  }
   410  
   411  func goType(
   412  	staticType interpreter.StaticType,
   413  	evmAddressTypeID common.TypeID,
   414  ) (reflect.Type, bool) {
   415  	switch staticType {
   416  	case interpreter.PrimitiveStaticTypeString:
   417  		return reflect.TypeOf(""), true
   418  	case interpreter.PrimitiveStaticTypeBool:
   419  		return reflect.TypeOf(true), true
   420  	case interpreter.PrimitiveStaticTypeUInt8:
   421  		return reflect.TypeOf(uint8(0)), true
   422  	case interpreter.PrimitiveStaticTypeUInt16:
   423  		return reflect.TypeOf(uint16(0)), true
   424  	case interpreter.PrimitiveStaticTypeUInt32:
   425  		return reflect.TypeOf(uint32(0)), true
   426  	case interpreter.PrimitiveStaticTypeUInt64:
   427  		return reflect.TypeOf(uint64(0)), true
   428  	case interpreter.PrimitiveStaticTypeUInt128:
   429  		return reflect.TypeOf((*big.Int)(nil)), true
   430  	case interpreter.PrimitiveStaticTypeUInt256:
   431  		return reflect.TypeOf((*big.Int)(nil)), true
   432  	case interpreter.PrimitiveStaticTypeInt8:
   433  		return reflect.TypeOf(int8(0)), true
   434  	case interpreter.PrimitiveStaticTypeInt16:
   435  		return reflect.TypeOf(int16(0)), true
   436  	case interpreter.PrimitiveStaticTypeInt32:
   437  		return reflect.TypeOf(int32(0)), true
   438  	case interpreter.PrimitiveStaticTypeInt64:
   439  		return reflect.TypeOf(int64(0)), true
   440  	case interpreter.PrimitiveStaticTypeInt128:
   441  		return reflect.TypeOf((*big.Int)(nil)), true
   442  	case interpreter.PrimitiveStaticTypeInt256:
   443  		return reflect.TypeOf((*big.Int)(nil)), true
   444  	case interpreter.PrimitiveStaticTypeAddress:
   445  		return reflect.TypeOf((*big.Int)(nil)), true
   446  	}
   447  
   448  	switch staticType := staticType.(type) {
   449  	case *interpreter.ConstantSizedStaticType:
   450  		elementType, ok := goType(staticType.ElementType(), evmAddressTypeID)
   451  		if !ok {
   452  			break
   453  		}
   454  
   455  		return reflect.ArrayOf(int(staticType.Size), elementType), true
   456  
   457  	case *interpreter.VariableSizedStaticType:
   458  		elementType, ok := goType(staticType.ElementType(), evmAddressTypeID)
   459  		if !ok {
   460  			break
   461  		}
   462  
   463  		return reflect.SliceOf(elementType), true
   464  	}
   465  
   466  	if staticType.ID() == evmAddressTypeID {
   467  		return reflect.TypeOf(gethCommon.Address{}), true
   468  	}
   469  
   470  	return nil, false
   471  }
   472  
   473  func encodeABI(
   474  	inter *interpreter.Interpreter,
   475  	locationRange interpreter.LocationRange,
   476  	value interpreter.Value,
   477  	staticType interpreter.StaticType,
   478  	evmAddressTypeID common.TypeID,
   479  ) (
   480  	any,
   481  	gethABI.Type,
   482  	error,
   483  ) {
   484  
   485  	switch value := value.(type) {
   486  	case *interpreter.StringValue:
   487  		if staticType == interpreter.PrimitiveStaticTypeString {
   488  			return value.Str, gethTypeString, nil
   489  		}
   490  
   491  	case interpreter.BoolValue:
   492  		if staticType == interpreter.PrimitiveStaticTypeBool {
   493  			return bool(value), gethTypeBool, nil
   494  		}
   495  
   496  	case interpreter.UInt8Value:
   497  		if staticType == interpreter.PrimitiveStaticTypeUInt8 {
   498  			return uint8(value), gethTypeUint8, nil
   499  		}
   500  
   501  	case interpreter.UInt16Value:
   502  		if staticType == interpreter.PrimitiveStaticTypeUInt16 {
   503  			return uint16(value), gethTypeUint16, nil
   504  		}
   505  
   506  	case interpreter.UInt32Value:
   507  		if staticType == interpreter.PrimitiveStaticTypeUInt32 {
   508  			return uint32(value), gethTypeUint32, nil
   509  		}
   510  
   511  	case interpreter.UInt64Value:
   512  		if staticType == interpreter.PrimitiveStaticTypeUInt64 {
   513  			return uint64(value), gethTypeUint64, nil
   514  		}
   515  
   516  	case interpreter.UInt128Value:
   517  		if staticType == interpreter.PrimitiveStaticTypeUInt128 {
   518  			return value.BigInt, gethTypeUint128, nil
   519  		}
   520  
   521  	case interpreter.UInt256Value:
   522  		if staticType == interpreter.PrimitiveStaticTypeUInt256 {
   523  			return value.BigInt, gethTypeUint256, nil
   524  		}
   525  
   526  	case interpreter.Int8Value:
   527  		if staticType == interpreter.PrimitiveStaticTypeInt8 {
   528  			return int8(value), gethTypeInt8, nil
   529  		}
   530  
   531  	case interpreter.Int16Value:
   532  		if staticType == interpreter.PrimitiveStaticTypeInt16 {
   533  			return int16(value), gethTypeInt16, nil
   534  		}
   535  
   536  	case interpreter.Int32Value:
   537  		if staticType == interpreter.PrimitiveStaticTypeInt32 {
   538  			return int32(value), gethTypeInt32, nil
   539  		}
   540  
   541  	case interpreter.Int64Value:
   542  		if staticType == interpreter.PrimitiveStaticTypeInt64 {
   543  			return int64(value), gethTypeInt64, nil
   544  		}
   545  
   546  	case interpreter.Int128Value:
   547  		if staticType == interpreter.PrimitiveStaticTypeInt128 {
   548  			return value.BigInt, gethTypeInt128, nil
   549  		}
   550  
   551  	case interpreter.Int256Value:
   552  		if staticType == interpreter.PrimitiveStaticTypeInt256 {
   553  			return value.BigInt, gethTypeInt256, nil
   554  		}
   555  
   556  	case *interpreter.CompositeValue:
   557  		if value.TypeID() == evmAddressTypeID {
   558  			addressBytesArrayValue := value.GetMember(inter, locationRange, evmAddressTypeBytesFieldName)
   559  			bytes, err := interpreter.ByteArrayValueToByteSlice(
   560  				inter,
   561  				addressBytesArrayValue,
   562  				locationRange,
   563  			)
   564  			if err != nil {
   565  				panic(err)
   566  			}
   567  
   568  			return gethCommon.Address(bytes), gethTypeAddress, nil
   569  		}
   570  
   571  	case *interpreter.ArrayValue:
   572  		arrayStaticType := value.Type
   573  
   574  		arrayGethABIType, ok := gethABIType(arrayStaticType, evmAddressTypeID)
   575  		if !ok {
   576  			break
   577  		}
   578  
   579  		elementStaticType := arrayStaticType.ElementType()
   580  
   581  		elementGoType, ok := goType(elementStaticType, evmAddressTypeID)
   582  		if !ok {
   583  			break
   584  		}
   585  
   586  		var result reflect.Value
   587  
   588  		switch arrayStaticType := arrayStaticType.(type) {
   589  		case *interpreter.ConstantSizedStaticType:
   590  			size := int(arrayStaticType.Size)
   591  			result = reflect.Indirect(reflect.New(reflect.ArrayOf(size, elementGoType)))
   592  
   593  		case *interpreter.VariableSizedStaticType:
   594  			size := value.Count()
   595  			result = reflect.MakeSlice(reflect.SliceOf(elementGoType), size, size)
   596  		}
   597  
   598  		var index int
   599  		value.Iterate(
   600  			inter,
   601  			func(element interpreter.Value) (resume bool) {
   602  
   603  				arrayElement, _, err := encodeABI(
   604  					inter,
   605  					locationRange,
   606  					element,
   607  					element.StaticType(inter),
   608  					evmAddressTypeID,
   609  				)
   610  				if err != nil {
   611  					panic(err)
   612  				}
   613  
   614  				result.Index(index).Set(reflect.ValueOf(arrayElement))
   615  
   616  				index++
   617  
   618  				// continue iteration
   619  				return true
   620  			},
   621  			false,
   622  			locationRange,
   623  		)
   624  
   625  		return result.Interface(), arrayGethABIType, nil
   626  	}
   627  
   628  	return nil, gethABI.Type{}, abiEncodingError{
   629  		Type: value.StaticType(inter),
   630  	}
   631  }
   632  
   633  // EVM.decodeABI
   634  
   635  const internalEVMTypeDecodeABIFunctionName = "decodeABI"
   636  
   637  var internalEVMTypeDecodeABIFunctionType = &sema.FunctionType{
   638  	Parameters: []sema.Parameter{
   639  		{
   640  			Identifier: "types",
   641  			TypeAnnotation: sema.NewTypeAnnotation(
   642  				sema.NewVariableSizedType(nil, sema.MetaType),
   643  			),
   644  		},
   645  		{
   646  			Label:          "data",
   647  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
   648  		},
   649  	},
   650  	ReturnTypeAnnotation: sema.NewTypeAnnotation(
   651  		sema.NewVariableSizedType(nil, sema.AnyStructType),
   652  	),
   653  }
   654  
   655  func newInternalEVMTypeDecodeABIFunction(
   656  	gauge common.MemoryGauge,
   657  	location common.AddressLocation,
   658  ) *interpreter.HostFunctionValue {
   659  	evmAddressTypeID := location.TypeID(gauge, evmAddressTypeQualifiedIdentifier)
   660  
   661  	return interpreter.NewStaticHostFunctionValue(
   662  		gauge,
   663  		internalEVMTypeDecodeABIFunctionType,
   664  		func(invocation interpreter.Invocation) interpreter.Value {
   665  			inter := invocation.Interpreter
   666  			locationRange := invocation.LocationRange
   667  
   668  			// Get `types` argument
   669  
   670  			typesArray, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
   671  			if !ok {
   672  				panic(errors.NewUnreachableError())
   673  			}
   674  
   675  			// Get `data` argument
   676  
   677  			dataValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
   678  			if !ok {
   679  				panic(errors.NewUnreachableError())
   680  			}
   681  
   682  			invocation.Interpreter.ReportComputation(
   683  				environment.ComputationKindEVMDecodeABI,
   684  				uint(dataValue.Count()),
   685  			)
   686  
   687  			data, err := interpreter.ByteArrayValueToByteSlice(inter, dataValue, locationRange)
   688  			if err != nil {
   689  				panic(err)
   690  			}
   691  
   692  			var arguments gethABI.Arguments
   693  			typesArray.Iterate(
   694  				inter,
   695  				func(element interpreter.Value) (resume bool) {
   696  					typeValue, ok := element.(interpreter.TypeValue)
   697  					if !ok {
   698  						panic(errors.NewUnreachableError())
   699  					}
   700  
   701  					staticType := typeValue.Type
   702  
   703  					gethABITy, ok := gethABIType(staticType, evmAddressTypeID)
   704  					if !ok {
   705  						panic(abiDecodingError{
   706  							Type: staticType,
   707  						})
   708  					}
   709  
   710  					arguments = append(
   711  						arguments,
   712  						gethABI.Argument{
   713  							Type: gethABITy,
   714  						},
   715  					)
   716  
   717  					// continue iteration
   718  					return true
   719  				},
   720  				false,
   721  				locationRange,
   722  			)
   723  
   724  			decodedValues, err := arguments.Unpack(data)
   725  			if err != nil {
   726  				panic(abiDecodingError{})
   727  			}
   728  
   729  			var index int
   730  			values := make([]interpreter.Value, 0, len(decodedValues))
   731  
   732  			typesArray.Iterate(
   733  				inter,
   734  				func(element interpreter.Value) (resume bool) {
   735  					typeValue, ok := element.(interpreter.TypeValue)
   736  					if !ok {
   737  						panic(errors.NewUnreachableError())
   738  					}
   739  
   740  					staticType := typeValue.Type
   741  
   742  					value, err := decodeABI(
   743  						inter,
   744  						locationRange,
   745  						decodedValues[index],
   746  						staticType,
   747  						location,
   748  						evmAddressTypeID,
   749  					)
   750  					if err != nil {
   751  						panic(err)
   752  					}
   753  
   754  					index++
   755  
   756  					values = append(values, value)
   757  
   758  					// continue iteration
   759  					return true
   760  				},
   761  				false,
   762  				locationRange,
   763  			)
   764  
   765  			arrayType := interpreter.NewVariableSizedStaticType(
   766  				inter,
   767  				interpreter.NewPrimitiveStaticType(
   768  					inter,
   769  					interpreter.PrimitiveStaticTypeAnyStruct,
   770  				),
   771  			)
   772  
   773  			return interpreter.NewArrayValue(
   774  				inter,
   775  				locationRange,
   776  				arrayType,
   777  				common.ZeroAddress,
   778  				values...,
   779  			)
   780  		},
   781  	)
   782  }
   783  
   784  func decodeABI(
   785  	inter *interpreter.Interpreter,
   786  	locationRange interpreter.LocationRange,
   787  	value any,
   788  	staticType interpreter.StaticType,
   789  	location common.AddressLocation,
   790  	evmAddressTypeID common.TypeID,
   791  ) (
   792  	interpreter.Value,
   793  	error,
   794  ) {
   795  
   796  	switch staticType {
   797  	case interpreter.PrimitiveStaticTypeString:
   798  		value, ok := value.(string)
   799  		if !ok {
   800  			break
   801  		}
   802  		return interpreter.NewStringValue(
   803  			inter,
   804  			common.NewStringMemoryUsage(len(value)),
   805  			func() string {
   806  				return value
   807  			},
   808  		), nil
   809  
   810  	case interpreter.PrimitiveStaticTypeBool:
   811  		value, ok := value.(bool)
   812  		if !ok {
   813  			break
   814  		}
   815  		return interpreter.BoolValue(value), nil
   816  
   817  	case interpreter.PrimitiveStaticTypeUInt8:
   818  		value, ok := value.(uint8)
   819  		if !ok {
   820  			break
   821  		}
   822  		return interpreter.NewUInt8Value(inter, func() uint8 { return value }), nil
   823  
   824  	case interpreter.PrimitiveStaticTypeUInt16:
   825  		value, ok := value.(uint16)
   826  		if !ok {
   827  			break
   828  		}
   829  		return interpreter.NewUInt16Value(inter, func() uint16 { return value }), nil
   830  
   831  	case interpreter.PrimitiveStaticTypeUInt32:
   832  		value, ok := value.(uint32)
   833  		if !ok {
   834  			break
   835  		}
   836  		return interpreter.NewUInt32Value(inter, func() uint32 { return value }), nil
   837  
   838  	case interpreter.PrimitiveStaticTypeUInt64:
   839  		value, ok := value.(uint64)
   840  		if !ok {
   841  			break
   842  		}
   843  		return interpreter.NewUInt64Value(inter, func() uint64 { return value }), nil
   844  
   845  	case interpreter.PrimitiveStaticTypeUInt128:
   846  		value, ok := value.(*big.Int)
   847  		if !ok {
   848  			break
   849  		}
   850  		return interpreter.NewUInt128ValueFromBigInt(inter, func() *big.Int { return value }), nil
   851  
   852  	case interpreter.PrimitiveStaticTypeUInt256:
   853  		value, ok := value.(*big.Int)
   854  		if !ok {
   855  			break
   856  		}
   857  		return interpreter.NewUInt256ValueFromBigInt(inter, func() *big.Int { return value }), nil
   858  
   859  	case interpreter.PrimitiveStaticTypeInt8:
   860  		value, ok := value.(int8)
   861  		if !ok {
   862  			break
   863  		}
   864  		return interpreter.NewInt8Value(inter, func() int8 { return value }), nil
   865  
   866  	case interpreter.PrimitiveStaticTypeInt16:
   867  		value, ok := value.(int16)
   868  		if !ok {
   869  			break
   870  		}
   871  		return interpreter.NewInt16Value(inter, func() int16 { return value }), nil
   872  
   873  	case interpreter.PrimitiveStaticTypeInt32:
   874  		value, ok := value.(int32)
   875  		if !ok {
   876  			break
   877  		}
   878  		return interpreter.NewInt32Value(inter, func() int32 { return value }), nil
   879  
   880  	case interpreter.PrimitiveStaticTypeInt64:
   881  		value, ok := value.(int64)
   882  		if !ok {
   883  			break
   884  		}
   885  		return interpreter.NewInt64Value(inter, func() int64 { return value }), nil
   886  
   887  	case interpreter.PrimitiveStaticTypeInt128:
   888  		value, ok := value.(*big.Int)
   889  		if !ok {
   890  			break
   891  		}
   892  		return interpreter.NewInt128ValueFromBigInt(inter, func() *big.Int { return value }), nil
   893  
   894  	case interpreter.PrimitiveStaticTypeInt256:
   895  		value, ok := value.(*big.Int)
   896  		if !ok {
   897  			break
   898  		}
   899  		return interpreter.NewInt256ValueFromBigInt(inter, func() *big.Int { return value }), nil
   900  	}
   901  
   902  	switch staticType := staticType.(type) {
   903  	case interpreter.ArrayStaticType:
   904  		array := reflect.ValueOf(value)
   905  
   906  		elementStaticType := staticType.ElementType()
   907  
   908  		size := array.Len()
   909  
   910  		var index int
   911  		return interpreter.NewArrayValueWithIterator(
   912  			inter,
   913  			staticType,
   914  			common.ZeroAddress,
   915  			uint64(size),
   916  			func() interpreter.Value {
   917  				if index >= size {
   918  					return nil
   919  				}
   920  
   921  				element := array.Index(index).Interface()
   922  
   923  				result, err := decodeABI(
   924  					inter,
   925  					locationRange,
   926  					element,
   927  					elementStaticType,
   928  					location,
   929  					evmAddressTypeID,
   930  				)
   931  				if err != nil {
   932  					panic(err)
   933  				}
   934  
   935  				index++
   936  
   937  				return result
   938  			},
   939  		), nil
   940  
   941  	case *interpreter.CompositeStaticType:
   942  		if staticType.TypeID != evmAddressTypeID {
   943  			break
   944  		}
   945  
   946  		addr, ok := value.(gethCommon.Address)
   947  		if !ok {
   948  			break
   949  		}
   950  
   951  		var address types.Address
   952  		copy(address[:], addr.Bytes())
   953  		return NewEVMAddress(
   954  			inter,
   955  			locationRange,
   956  			location,
   957  			address,
   958  		), nil
   959  	}
   960  
   961  	return nil, abiDecodingError{
   962  		Type: staticType,
   963  	}
   964  }
   965  
   966  func NewEVMAddress(
   967  	inter *interpreter.Interpreter,
   968  	locationRange interpreter.LocationRange,
   969  	location common.AddressLocation,
   970  	address types.Address,
   971  ) *interpreter.CompositeValue {
   972  	return interpreter.NewCompositeValue(
   973  		inter,
   974  		locationRange,
   975  		location,
   976  		evmAddressTypeQualifiedIdentifier,
   977  		common.CompositeKindStructure,
   978  		[]interpreter.CompositeField{
   979  			{
   980  				Name:  evmAddressTypeBytesFieldName,
   981  				Value: EVMAddressToAddressBytesArrayValue(inter, address),
   982  			},
   983  		},
   984  		common.ZeroAddress,
   985  	)
   986  }
   987  
   988  const internalEVMTypeRunFunctionName = "run"
   989  
   990  var internalEVMTypeRunFunctionType = &sema.FunctionType{
   991  	Parameters: []sema.Parameter{
   992  		{
   993  			Label:          "tx",
   994  			TypeAnnotation: sema.NewTypeAnnotation(evmTransactionBytesType),
   995  		},
   996  		{
   997  			Label:          "coinbase",
   998  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
   999  		},
  1000  	},
  1001  	// Actually EVM.Result, but cannot refer to it here
  1002  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType),
  1003  }
  1004  
  1005  func newInternalEVMTypeRunFunction(
  1006  	gauge common.MemoryGauge,
  1007  	handler types.ContractHandler,
  1008  ) *interpreter.HostFunctionValue {
  1009  	return interpreter.NewStaticHostFunctionValue(
  1010  		gauge,
  1011  		internalEVMTypeRunFunctionType,
  1012  		func(invocation interpreter.Invocation) interpreter.Value {
  1013  			inter := invocation.Interpreter
  1014  			locationRange := invocation.LocationRange
  1015  
  1016  			// Get transaction argument
  1017  
  1018  			transactionValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1019  			if !ok {
  1020  				panic(errors.NewUnreachableError())
  1021  			}
  1022  
  1023  			transaction, err := interpreter.ByteArrayValueToByteSlice(inter, transactionValue, locationRange)
  1024  			if err != nil {
  1025  				panic(err)
  1026  			}
  1027  
  1028  			// Get coinbase argument
  1029  
  1030  			coinbaseValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1031  			if !ok {
  1032  				panic(errors.NewUnreachableError())
  1033  			}
  1034  
  1035  			coinbase, err := interpreter.ByteArrayValueToByteSlice(inter, coinbaseValue, locationRange)
  1036  			if err != nil {
  1037  				panic(err)
  1038  			}
  1039  
  1040  			// Run
  1041  
  1042  			cb := types.NewAddressFromBytes(coinbase)
  1043  			result := handler.Run(transaction, cb)
  1044  
  1045  			return NewResultValue(handler, gauge, inter, locationRange, result)
  1046  		},
  1047  	)
  1048  }
  1049  
  1050  // dry run
  1051  
  1052  const internalEVMTypeDryRunFunctionName = "dryRun"
  1053  
  1054  var internalEVMTypeDryRunFunctionType = &sema.FunctionType{
  1055  	Parameters: []sema.Parameter{
  1056  		{
  1057  			Label:          "tx",
  1058  			TypeAnnotation: sema.NewTypeAnnotation(evmTransactionBytesType),
  1059  		},
  1060  		{
  1061  			Label:          "from",
  1062  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1063  		},
  1064  	},
  1065  	// Actually EVM.Result, but cannot refer to it here
  1066  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType),
  1067  }
  1068  
  1069  func newInternalEVMTypeDryRunFunction(
  1070  	gauge common.MemoryGauge,
  1071  	handler types.ContractHandler,
  1072  ) *interpreter.HostFunctionValue {
  1073  	return interpreter.NewStaticHostFunctionValue(
  1074  		gauge,
  1075  		internalEVMTypeDryRunFunctionType,
  1076  		func(invocation interpreter.Invocation) interpreter.Value {
  1077  			inter := invocation.Interpreter
  1078  			locationRange := invocation.LocationRange
  1079  
  1080  			// Get transaction argument
  1081  
  1082  			transactionValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1083  			if !ok {
  1084  				panic(errors.NewUnreachableError())
  1085  			}
  1086  
  1087  			transaction, err := interpreter.ByteArrayValueToByteSlice(inter, transactionValue, locationRange)
  1088  			if err != nil {
  1089  				panic(err)
  1090  			}
  1091  
  1092  			// Get from argument
  1093  
  1094  			fromValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1095  			if !ok {
  1096  				panic(errors.NewUnreachableError())
  1097  			}
  1098  
  1099  			from, err := interpreter.ByteArrayValueToByteSlice(inter, fromValue, locationRange)
  1100  			if err != nil {
  1101  				panic(err)
  1102  			}
  1103  
  1104  			// call estimate
  1105  
  1106  			res := handler.DryRun(transaction, types.NewAddressFromBytes(from))
  1107  			return NewResultValue(handler, gauge, inter, locationRange, res)
  1108  		},
  1109  	)
  1110  }
  1111  
  1112  const internalEVMTypeBatchRunFunctionName = "batchRun"
  1113  
  1114  var internalEVMTypeBatchRunFunctionType = &sema.FunctionType{
  1115  	Parameters: []sema.Parameter{
  1116  		{
  1117  			Label:          "txs",
  1118  			TypeAnnotation: sema.NewTypeAnnotation(evmTransactionsBatchBytesType),
  1119  		},
  1120  		{
  1121  			Label:          "coinbase",
  1122  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1123  		},
  1124  	},
  1125  	// Actually [EVM.Result], but cannot refer to it here
  1126  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.NewVariableSizedType(nil, sema.AnyStructType)),
  1127  }
  1128  
  1129  func newInternalEVMTypeBatchRunFunction(
  1130  	gauge common.MemoryGauge,
  1131  	handler types.ContractHandler,
  1132  ) *interpreter.HostFunctionValue {
  1133  	return interpreter.NewStaticHostFunctionValue(
  1134  		gauge,
  1135  		internalEVMTypeBatchRunFunctionType,
  1136  		func(invocation interpreter.Invocation) interpreter.Value {
  1137  			inter := invocation.Interpreter
  1138  			locationRange := invocation.LocationRange
  1139  
  1140  			// Get transactions batch argument
  1141  
  1142  			transactionsBatchValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1143  			if !ok {
  1144  				panic(errors.NewUnreachableError())
  1145  			}
  1146  
  1147  			batchCount := transactionsBatchValue.Count()
  1148  			var transactionBatch [][]byte
  1149  			if batchCount > 0 {
  1150  				transactionBatch = make([][]byte, batchCount)
  1151  				i := 0
  1152  				transactionsBatchValue.Iterate(inter, func(transactionValue interpreter.Value) (resume bool) {
  1153  					t, err := interpreter.ByteArrayValueToByteSlice(inter, transactionValue, locationRange)
  1154  					if err != nil {
  1155  						panic(err)
  1156  					}
  1157  					transactionBatch[i] = t
  1158  					i++
  1159  					return true
  1160  				}, false, locationRange)
  1161  			}
  1162  
  1163  			// Get coinbase argument
  1164  
  1165  			coinbaseValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1166  			if !ok {
  1167  				panic(errors.NewUnreachableError())
  1168  			}
  1169  
  1170  			coinbase, err := interpreter.ByteArrayValueToByteSlice(inter, coinbaseValue, locationRange)
  1171  			if err != nil {
  1172  				panic(err)
  1173  			}
  1174  
  1175  			// Batch run
  1176  
  1177  			cb := types.NewAddressFromBytes(coinbase)
  1178  			batchResults := handler.BatchRun(transactionBatch, cb)
  1179  
  1180  			values := newResultValues(handler, gauge, inter, locationRange, batchResults)
  1181  
  1182  			loc := common.NewAddressLocation(gauge, handler.EVMContractAddress(), ContractName)
  1183  			evmResultType := interpreter.NewVariableSizedStaticType(
  1184  				inter,
  1185  				interpreter.NewCompositeStaticType(
  1186  					nil,
  1187  					loc,
  1188  					evmResultTypeQualifiedIdentifier,
  1189  					common.NewTypeIDFromQualifiedName(
  1190  						nil,
  1191  						loc,
  1192  						evmResultTypeQualifiedIdentifier,
  1193  					),
  1194  				),
  1195  			)
  1196  
  1197  			return interpreter.NewArrayValue(
  1198  				inter,
  1199  				locationRange,
  1200  				evmResultType,
  1201  				common.ZeroAddress,
  1202  				values...,
  1203  			)
  1204  		},
  1205  	)
  1206  }
  1207  
  1208  // newResultValues converts batch run result summary type to cadence array of structs
  1209  func newResultValues(
  1210  	handler types.ContractHandler,
  1211  	gauge common.MemoryGauge,
  1212  	inter *interpreter.Interpreter,
  1213  	locationRange interpreter.LocationRange,
  1214  	results []*types.ResultSummary,
  1215  ) []interpreter.Value {
  1216  	values := make([]interpreter.Value, 0)
  1217  	for _, result := range results {
  1218  		res := NewResultValue(handler, gauge, inter, locationRange, result)
  1219  		values = append(values, res)
  1220  	}
  1221  	return values
  1222  }
  1223  
  1224  func NewResultValue(
  1225  	handler types.ContractHandler,
  1226  	gauge common.MemoryGauge,
  1227  	inter *interpreter.Interpreter,
  1228  	locationRange interpreter.LocationRange,
  1229  	result *types.ResultSummary,
  1230  ) *interpreter.CompositeValue {
  1231  
  1232  	evmContractLocation := common.NewAddressLocation(
  1233  		gauge,
  1234  		handler.EVMContractAddress(),
  1235  		ContractName,
  1236  	)
  1237  
  1238  	deployedContractAddress := result.DeployedContractAddress
  1239  	deployedContractValue := interpreter.NilOptionalValue
  1240  	if deployedContractAddress != nil {
  1241  		deployedContractValue = interpreter.NewSomeValueNonCopying(
  1242  			inter,
  1243  			NewEVMAddress(
  1244  				inter,
  1245  				locationRange,
  1246  				evmContractLocation,
  1247  				*deployedContractAddress,
  1248  			),
  1249  		)
  1250  	}
  1251  
  1252  	fields := []interpreter.CompositeField{
  1253  		{
  1254  			Name: "status",
  1255  			Value: interpreter.NewEnumCaseValue(
  1256  				inter,
  1257  				locationRange,
  1258  				&sema.CompositeType{
  1259  					Location:   evmContractLocation,
  1260  					Identifier: evmStatusTypeQualifiedIdentifier,
  1261  					Kind:       common.CompositeKindEnum,
  1262  				},
  1263  				interpreter.NewUInt8Value(gauge, func() uint8 {
  1264  					return uint8(result.Status)
  1265  				}),
  1266  				nil,
  1267  			),
  1268  		},
  1269  		{
  1270  			Name: "errorCode",
  1271  			Value: interpreter.NewUInt64Value(gauge, func() uint64 {
  1272  				return uint64(result.ErrorCode)
  1273  			}),
  1274  		},
  1275  		{
  1276  			Name: "gasUsed",
  1277  			Value: interpreter.NewUInt64Value(gauge, func() uint64 {
  1278  				return result.GasConsumed
  1279  			}),
  1280  		},
  1281  		{
  1282  			Name:  "data",
  1283  			Value: interpreter.ByteSliceToByteArrayValue(inter, result.ReturnedValue),
  1284  		},
  1285  		{
  1286  			Name:  "deployedContract",
  1287  			Value: deployedContractValue,
  1288  		},
  1289  	}
  1290  
  1291  	return interpreter.NewCompositeValue(
  1292  		inter,
  1293  		locationRange,
  1294  		evmContractLocation,
  1295  		evmResultTypeQualifiedIdentifier,
  1296  		common.CompositeKindStructure,
  1297  		fields,
  1298  		common.ZeroAddress,
  1299  	)
  1300  }
  1301  
  1302  func EVMAddressToAddressBytesArrayValue(
  1303  	inter *interpreter.Interpreter,
  1304  	address types.Address,
  1305  ) *interpreter.ArrayValue {
  1306  	var index int
  1307  	return interpreter.NewArrayValueWithIterator(
  1308  		inter,
  1309  		evmAddressBytesStaticType,
  1310  		common.ZeroAddress,
  1311  		types.AddressLength,
  1312  		func() interpreter.Value {
  1313  			if index >= types.AddressLength {
  1314  				return nil
  1315  			}
  1316  			result := interpreter.NewUInt8Value(inter, func() uint8 {
  1317  				return address[index]
  1318  			})
  1319  			index++
  1320  			return result
  1321  		},
  1322  	)
  1323  }
  1324  
  1325  const internalEVMTypeCallFunctionName = "call"
  1326  
  1327  var internalEVMTypeCallFunctionType = &sema.FunctionType{
  1328  	Parameters: []sema.Parameter{
  1329  		{
  1330  			Label:          "from",
  1331  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1332  		},
  1333  		{
  1334  			Label:          "to",
  1335  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1336  		},
  1337  		{
  1338  			Label:          "data",
  1339  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1340  		},
  1341  		{
  1342  			Label:          "gasLimit",
  1343  			TypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1344  		},
  1345  		{
  1346  			Label:          "value",
  1347  			TypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1348  		},
  1349  	},
  1350  	// Actually EVM.Result, but cannot refer to it here
  1351  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType),
  1352  }
  1353  
  1354  func AddressBytesArrayValueToEVMAddress(
  1355  	inter *interpreter.Interpreter,
  1356  	locationRange interpreter.LocationRange,
  1357  	addressBytesValue *interpreter.ArrayValue,
  1358  ) (
  1359  	result types.Address,
  1360  	err error,
  1361  ) {
  1362  	// Convert
  1363  
  1364  	var bytes []byte
  1365  	bytes, err = interpreter.ByteArrayValueToByteSlice(
  1366  		inter,
  1367  		addressBytesValue,
  1368  		locationRange,
  1369  	)
  1370  	if err != nil {
  1371  		return result, err
  1372  	}
  1373  
  1374  	// Check length
  1375  
  1376  	length := len(bytes)
  1377  	const expectedLength = types.AddressLength
  1378  	if length != expectedLength {
  1379  		return result, errors.NewDefaultUserError(
  1380  			"invalid address length: got %d, expected %d",
  1381  			length,
  1382  			expectedLength,
  1383  		)
  1384  	}
  1385  
  1386  	copy(result[:], bytes)
  1387  
  1388  	return result, nil
  1389  }
  1390  
  1391  func newInternalEVMTypeCallFunction(
  1392  	gauge common.MemoryGauge,
  1393  	handler types.ContractHandler,
  1394  ) *interpreter.HostFunctionValue {
  1395  	return interpreter.NewStaticHostFunctionValue(
  1396  		gauge,
  1397  		internalEVMTypeCallFunctionType,
  1398  		func(invocation interpreter.Invocation) interpreter.Value {
  1399  			inter := invocation.Interpreter
  1400  			locationRange := invocation.LocationRange
  1401  
  1402  			// Get from address
  1403  
  1404  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1405  			if !ok {
  1406  				panic(errors.NewUnreachableError())
  1407  			}
  1408  
  1409  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1410  			if err != nil {
  1411  				panic(err)
  1412  			}
  1413  
  1414  			// Get to address
  1415  
  1416  			toAddressValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1417  			if !ok {
  1418  				panic(errors.NewUnreachableError())
  1419  			}
  1420  
  1421  			toAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, toAddressValue)
  1422  			if err != nil {
  1423  				panic(err)
  1424  			}
  1425  
  1426  			// Get data
  1427  
  1428  			dataValue, ok := invocation.Arguments[2].(*interpreter.ArrayValue)
  1429  			if !ok {
  1430  				panic(errors.NewUnreachableError())
  1431  			}
  1432  
  1433  			data, err := interpreter.ByteArrayValueToByteSlice(inter, dataValue, locationRange)
  1434  			if err != nil {
  1435  				panic(err)
  1436  			}
  1437  
  1438  			// Get gas limit
  1439  
  1440  			gasLimitValue, ok := invocation.Arguments[3].(interpreter.UInt64Value)
  1441  			if !ok {
  1442  				panic(errors.NewUnreachableError())
  1443  			}
  1444  
  1445  			gasLimit := types.GasLimit(gasLimitValue)
  1446  
  1447  			// Get balance
  1448  
  1449  			balanceValue, ok := invocation.Arguments[4].(interpreter.UIntValue)
  1450  			if !ok {
  1451  				panic(errors.NewUnreachableError())
  1452  			}
  1453  
  1454  			balance := types.NewBalance(balanceValue.BigInt)
  1455  			// Call
  1456  
  1457  			const isAuthorized = true
  1458  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1459  			result := account.Call(toAddress, data, gasLimit, balance)
  1460  
  1461  			return NewResultValue(handler, gauge, inter, locationRange, result)
  1462  		},
  1463  	)
  1464  }
  1465  
  1466  const internalEVMTypeCreateCadenceOwnedAccountFunctionName = "createCadenceOwnedAccount"
  1467  
  1468  var internalEVMTypeCreateCadenceOwnedAccountFunctionType = &sema.FunctionType{
  1469  	Parameters: []sema.Parameter{
  1470  		{
  1471  			Label:          "uuid",
  1472  			TypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1473  		},
  1474  	},
  1475  	ReturnTypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1476  }
  1477  
  1478  func newInternalEVMTypeCreateCadenceOwnedAccountFunction(
  1479  	gauge common.MemoryGauge,
  1480  	handler types.ContractHandler,
  1481  ) *interpreter.HostFunctionValue {
  1482  	return interpreter.NewStaticHostFunctionValue(
  1483  		gauge,
  1484  		internalEVMTypeCreateCadenceOwnedAccountFunctionType,
  1485  		func(invocation interpreter.Invocation) interpreter.Value {
  1486  			inter := invocation.Interpreter
  1487  			uuid, ok := invocation.Arguments[0].(interpreter.UInt64Value)
  1488  			if !ok {
  1489  				panic(errors.NewUnreachableError())
  1490  			}
  1491  			address := handler.DeployCOA(uint64(uuid))
  1492  			return EVMAddressToAddressBytesArrayValue(inter, address)
  1493  		},
  1494  	)
  1495  }
  1496  
  1497  const internalEVMTypeDepositFunctionName = "deposit"
  1498  
  1499  var internalEVMTypeDepositFunctionType = &sema.FunctionType{
  1500  	Parameters: []sema.Parameter{
  1501  		{
  1502  			Label:          "from",
  1503  			TypeAnnotation: sema.NewTypeAnnotation(sema.AnyResourceType),
  1504  		},
  1505  		{
  1506  			Label:          "to",
  1507  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1508  		},
  1509  	},
  1510  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.VoidType),
  1511  }
  1512  
  1513  const fungibleTokenVaultTypeBalanceFieldName = "balance"
  1514  
  1515  func newInternalEVMTypeDepositFunction(
  1516  	gauge common.MemoryGauge,
  1517  	handler types.ContractHandler,
  1518  ) *interpreter.HostFunctionValue {
  1519  	return interpreter.NewStaticHostFunctionValue(
  1520  		gauge,
  1521  		internalEVMTypeCallFunctionType,
  1522  		func(invocation interpreter.Invocation) interpreter.Value {
  1523  			inter := invocation.Interpreter
  1524  			locationRange := invocation.LocationRange
  1525  
  1526  			// Get from vault
  1527  
  1528  			fromValue, ok := invocation.Arguments[0].(*interpreter.CompositeValue)
  1529  			if !ok {
  1530  				panic(errors.NewUnreachableError())
  1531  			}
  1532  
  1533  			amountValue, ok := fromValue.GetField(
  1534  				inter,
  1535  				locationRange,
  1536  				fungibleTokenVaultTypeBalanceFieldName,
  1537  			).(interpreter.UFix64Value)
  1538  			if !ok {
  1539  				panic(errors.NewUnreachableError())
  1540  			}
  1541  
  1542  			amount := types.NewBalanceFromUFix64(cadence.UFix64(amountValue))
  1543  
  1544  			// Get to address
  1545  
  1546  			toAddressValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1547  			if !ok {
  1548  				panic(errors.NewUnreachableError())
  1549  			}
  1550  
  1551  			toAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, toAddressValue)
  1552  			if err != nil {
  1553  				panic(err)
  1554  			}
  1555  
  1556  			// NOTE: We're intentionally not destroying the vault here,
  1557  			// because the value of it is supposed to be "kept alive".
  1558  			// Destroying would incorrectly be equivalent to a burn and decrease the total supply,
  1559  			// and a withdrawal would then have to perform an actual mint of new tokens.
  1560  
  1561  			// Deposit
  1562  
  1563  			const isAuthorized = false
  1564  			account := handler.AccountByAddress(toAddress, isAuthorized)
  1565  			account.Deposit(types.NewFlowTokenVault(amount))
  1566  
  1567  			return interpreter.Void
  1568  		},
  1569  	)
  1570  }
  1571  
  1572  const internalEVMTypeBalanceFunctionName = "balance"
  1573  
  1574  var internalEVMTypeBalanceFunctionType = &sema.FunctionType{
  1575  	Purity: sema.FunctionPurityView,
  1576  	Parameters: []sema.Parameter{
  1577  		{
  1578  			Label:          "address",
  1579  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1580  		},
  1581  	},
  1582  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1583  }
  1584  
  1585  // newInternalEVMTypeBalanceFunction returns the Flow balance of the account
  1586  func newInternalEVMTypeBalanceFunction(
  1587  	gauge common.MemoryGauge,
  1588  	handler types.ContractHandler,
  1589  ) *interpreter.HostFunctionValue {
  1590  	return interpreter.NewStaticHostFunctionValue(
  1591  		gauge,
  1592  		internalEVMTypeCallFunctionType,
  1593  		func(invocation interpreter.Invocation) interpreter.Value {
  1594  			inter := invocation.Interpreter
  1595  			locationRange := invocation.LocationRange
  1596  
  1597  			addressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1598  			if !ok {
  1599  				panic(errors.NewUnreachableError())
  1600  			}
  1601  
  1602  			address, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, addressValue)
  1603  			if err != nil {
  1604  				panic(err)
  1605  			}
  1606  
  1607  			const isAuthorized = false
  1608  			account := handler.AccountByAddress(address, isAuthorized)
  1609  
  1610  			return interpreter.UIntValue{BigInt: account.Balance()}
  1611  		},
  1612  	)
  1613  }
  1614  
  1615  const internalEVMTypeNonceFunctionName = "nonce"
  1616  
  1617  var internalEVMTypeNonceFunctionType = &sema.FunctionType{
  1618  	Parameters: []sema.Parameter{
  1619  		{
  1620  			Label:          "address",
  1621  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1622  		},
  1623  	},
  1624  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1625  }
  1626  
  1627  // newInternalEVMTypeNonceFunction returns the nonce of the account
  1628  func newInternalEVMTypeNonceFunction(
  1629  	gauge common.MemoryGauge,
  1630  	handler types.ContractHandler,
  1631  ) *interpreter.HostFunctionValue {
  1632  	return interpreter.NewStaticHostFunctionValue(
  1633  		gauge,
  1634  		internalEVMTypeCallFunctionType,
  1635  		func(invocation interpreter.Invocation) interpreter.Value {
  1636  			inter := invocation.Interpreter
  1637  			locationRange := invocation.LocationRange
  1638  
  1639  			addressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1640  			if !ok {
  1641  				panic(errors.NewUnreachableError())
  1642  			}
  1643  
  1644  			address, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, addressValue)
  1645  			if err != nil {
  1646  				panic(err)
  1647  			}
  1648  
  1649  			const isAuthorized = false
  1650  			account := handler.AccountByAddress(address, isAuthorized)
  1651  
  1652  			return interpreter.UInt64Value(account.Nonce())
  1653  		},
  1654  	)
  1655  }
  1656  
  1657  const internalEVMTypeCodeFunctionName = "code"
  1658  
  1659  var internalEVMTypeCodeFunctionType = &sema.FunctionType{
  1660  	Parameters: []sema.Parameter{
  1661  		{
  1662  			Label:          "address",
  1663  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1664  		},
  1665  	},
  1666  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1667  }
  1668  
  1669  // newInternalEVMTypeCodeFunction returns the code of the account
  1670  func newInternalEVMTypeCodeFunction(
  1671  	gauge common.MemoryGauge,
  1672  	handler types.ContractHandler,
  1673  ) *interpreter.HostFunctionValue {
  1674  	return interpreter.NewStaticHostFunctionValue(
  1675  		gauge,
  1676  		internalEVMTypeCallFunctionType,
  1677  		func(invocation interpreter.Invocation) interpreter.Value {
  1678  			inter := invocation.Interpreter
  1679  			locationRange := invocation.LocationRange
  1680  
  1681  			addressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1682  			if !ok {
  1683  				panic(errors.NewUnreachableError())
  1684  			}
  1685  
  1686  			address, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, addressValue)
  1687  			if err != nil {
  1688  				panic(err)
  1689  			}
  1690  
  1691  			const isAuthorized = false
  1692  			account := handler.AccountByAddress(address, isAuthorized)
  1693  
  1694  			return interpreter.ByteSliceToByteArrayValue(inter, account.Code())
  1695  		},
  1696  	)
  1697  }
  1698  
  1699  const internalEVMTypeCodeHashFunctionName = "codeHash"
  1700  
  1701  var internalEVMTypeCodeHashFunctionType = &sema.FunctionType{
  1702  	Parameters: []sema.Parameter{
  1703  		{
  1704  			Label:          "address",
  1705  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1706  		},
  1707  	},
  1708  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1709  }
  1710  
  1711  // newInternalEVMTypeCodeHashFunction returns the code hash of the account
  1712  func newInternalEVMTypeCodeHashFunction(
  1713  	gauge common.MemoryGauge,
  1714  	handler types.ContractHandler,
  1715  ) *interpreter.HostFunctionValue {
  1716  	return interpreter.NewStaticHostFunctionValue(
  1717  		gauge,
  1718  		internalEVMTypeCallFunctionType,
  1719  		func(invocation interpreter.Invocation) interpreter.Value {
  1720  			inter := invocation.Interpreter
  1721  			locationRange := invocation.LocationRange
  1722  
  1723  			addressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1724  			if !ok {
  1725  				panic(errors.NewUnreachableError())
  1726  			}
  1727  
  1728  			address, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, addressValue)
  1729  			if err != nil {
  1730  				panic(err)
  1731  			}
  1732  
  1733  			const isAuthorized = false
  1734  			account := handler.AccountByAddress(address, isAuthorized)
  1735  
  1736  			return interpreter.ByteSliceToByteArrayValue(inter, account.CodeHash())
  1737  		},
  1738  	)
  1739  }
  1740  
  1741  const internalEVMTypeWithdrawFunctionName = "withdraw"
  1742  
  1743  var internalEVMTypeWithdrawFunctionType = &sema.FunctionType{
  1744  	Parameters: []sema.Parameter{
  1745  		{
  1746  			Label:          "from",
  1747  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1748  		},
  1749  		{
  1750  			Label:          "amount",
  1751  			TypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1752  		},
  1753  	},
  1754  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyResourceType),
  1755  }
  1756  
  1757  func newInternalEVMTypeWithdrawFunction(
  1758  	gauge common.MemoryGauge,
  1759  	handler types.ContractHandler,
  1760  ) *interpreter.HostFunctionValue {
  1761  	return interpreter.NewStaticHostFunctionValue(
  1762  		gauge,
  1763  		internalEVMTypeCallFunctionType,
  1764  		func(invocation interpreter.Invocation) interpreter.Value {
  1765  			inter := invocation.Interpreter
  1766  			locationRange := invocation.LocationRange
  1767  
  1768  			// Get from address
  1769  
  1770  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1771  			if !ok {
  1772  				panic(errors.NewUnreachableError())
  1773  			}
  1774  
  1775  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1776  			if err != nil {
  1777  				panic(err)
  1778  			}
  1779  
  1780  			// Get amount
  1781  
  1782  			amountValue, ok := invocation.Arguments[1].(interpreter.UIntValue)
  1783  			if !ok {
  1784  				panic(errors.NewUnreachableError())
  1785  			}
  1786  
  1787  			amount := types.NewBalance(amountValue.BigInt)
  1788  
  1789  			// Withdraw
  1790  
  1791  			const isAuthorized = true
  1792  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1793  			vault := account.Withdraw(amount)
  1794  
  1795  			ufix, roundedOff, err := types.ConvertBalanceToUFix64(vault.Balance())
  1796  			if err != nil {
  1797  				panic(err)
  1798  			}
  1799  			if roundedOff {
  1800  				panic(types.ErrWithdrawBalanceRounding)
  1801  			}
  1802  
  1803  			// TODO: improve: maybe call actual constructor
  1804  			return interpreter.NewCompositeValue(
  1805  				inter,
  1806  				locationRange,
  1807  				common.NewAddressLocation(gauge, handler.FlowTokenAddress(), "FlowToken"),
  1808  				"FlowToken.Vault",
  1809  				common.CompositeKindResource,
  1810  				[]interpreter.CompositeField{
  1811  					{
  1812  						Name: "balance",
  1813  						Value: interpreter.NewUFix64Value(gauge, func() uint64 {
  1814  							return uint64(ufix)
  1815  						}),
  1816  					},
  1817  					{
  1818  						Name: sema.ResourceUUIDFieldName,
  1819  						Value: interpreter.NewUInt64Value(gauge, func() uint64 {
  1820  							return handler.GenerateResourceUUID()
  1821  						}),
  1822  					},
  1823  				},
  1824  				common.ZeroAddress,
  1825  			)
  1826  		},
  1827  	)
  1828  }
  1829  
  1830  const internalEVMTypeDeployFunctionName = "deploy"
  1831  
  1832  var internalEVMTypeDeployFunctionType = &sema.FunctionType{
  1833  	Parameters: []sema.Parameter{
  1834  		{
  1835  			Label:          "from",
  1836  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1837  		},
  1838  		{
  1839  			Label:          "code",
  1840  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1841  		},
  1842  		{
  1843  			Label:          "gasLimit",
  1844  			TypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1845  		},
  1846  		{
  1847  			Label:          "value",
  1848  			TypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1849  		},
  1850  	},
  1851  	// Actually EVM.Result, but cannot refer to it here
  1852  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType),
  1853  }
  1854  
  1855  func newInternalEVMTypeDeployFunction(
  1856  	gauge common.MemoryGauge,
  1857  	handler types.ContractHandler,
  1858  ) *interpreter.HostFunctionValue {
  1859  	return interpreter.NewStaticHostFunctionValue(
  1860  		gauge,
  1861  		internalEVMTypeCallFunctionType,
  1862  		func(invocation interpreter.Invocation) interpreter.Value {
  1863  			inter := invocation.Interpreter
  1864  			locationRange := invocation.LocationRange
  1865  
  1866  			// Get from address
  1867  
  1868  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1869  			if !ok {
  1870  				panic(errors.NewUnreachableError())
  1871  			}
  1872  
  1873  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1874  			if err != nil {
  1875  				panic(err)
  1876  			}
  1877  
  1878  			// Get code
  1879  
  1880  			codeValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1881  			if !ok {
  1882  				panic(errors.NewUnreachableError())
  1883  			}
  1884  
  1885  			code, err := interpreter.ByteArrayValueToByteSlice(inter, codeValue, locationRange)
  1886  			if err != nil {
  1887  				panic(err)
  1888  			}
  1889  
  1890  			// Get gas limit
  1891  
  1892  			gasLimitValue, ok := invocation.Arguments[2].(interpreter.UInt64Value)
  1893  			if !ok {
  1894  				panic(errors.NewUnreachableError())
  1895  			}
  1896  
  1897  			gasLimit := types.GasLimit(gasLimitValue)
  1898  
  1899  			// Get value
  1900  
  1901  			amountValue, ok := invocation.Arguments[3].(interpreter.UIntValue)
  1902  			if !ok {
  1903  				panic(errors.NewUnreachableError())
  1904  			}
  1905  
  1906  			amount := types.NewBalance(amountValue.BigInt)
  1907  
  1908  			// Deploy
  1909  
  1910  			const isAuthorized = true
  1911  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1912  			result := account.Deploy(code, gasLimit, amount)
  1913  
  1914  			res := NewResultValue(handler, gauge, inter, locationRange, result)
  1915  			return res
  1916  		},
  1917  	)
  1918  }
  1919  
  1920  const internalEVMTypeCastToAttoFLOWFunctionName = "castToAttoFLOW"
  1921  
  1922  var internalEVMTypeCastToAttoFLOWFunctionType = &sema.FunctionType{
  1923  	Purity: sema.FunctionPurityView,
  1924  	Parameters: []sema.Parameter{
  1925  		{
  1926  			Label:          "balance",
  1927  			TypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1928  		},
  1929  	},
  1930  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1931  }
  1932  
  1933  func newInternalEVMTypeCastToAttoFLOWFunction(
  1934  	gauge common.MemoryGauge,
  1935  ) *interpreter.HostFunctionValue {
  1936  	return interpreter.NewStaticHostFunctionValue(
  1937  		gauge,
  1938  		internalEVMTypeCallFunctionType,
  1939  		func(invocation interpreter.Invocation) interpreter.Value {
  1940  			balanceValue, ok := invocation.Arguments[0].(interpreter.UFix64Value)
  1941  			if !ok {
  1942  				panic(errors.NewUnreachableError())
  1943  			}
  1944  			balance := types.NewBalanceFromUFix64(cadence.UFix64(balanceValue))
  1945  			return interpreter.UIntValue{BigInt: balance}
  1946  		},
  1947  	)
  1948  }
  1949  
  1950  const internalEVMTypeCastToFLOWFunctionName = "castToFLOW"
  1951  
  1952  var internalEVMTypeCastToFLOWFunctionType = &sema.FunctionType{
  1953  	Purity: sema.FunctionPurityView,
  1954  	Parameters: []sema.Parameter{
  1955  		{
  1956  			Label:          "balance",
  1957  			TypeAnnotation: sema.NewTypeAnnotation(sema.UIntType),
  1958  		},
  1959  	},
  1960  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1961  }
  1962  
  1963  func newInternalEVMTypeCastToFLOWFunction(
  1964  	gauge common.MemoryGauge,
  1965  ) *interpreter.HostFunctionValue {
  1966  	return interpreter.NewStaticHostFunctionValue(
  1967  		gauge,
  1968  		internalEVMTypeCallFunctionType,
  1969  		func(invocation interpreter.Invocation) interpreter.Value {
  1970  			balanceValue, ok := invocation.Arguments[0].(interpreter.UIntValue)
  1971  			if !ok {
  1972  				panic(errors.NewUnreachableError())
  1973  			}
  1974  			balance := types.NewBalance(balanceValue.BigInt)
  1975  			// ignoring the rounding error and let user handle it
  1976  			v, _, err := types.ConvertBalanceToUFix64(balance)
  1977  			if err != nil {
  1978  				panic(err)
  1979  			}
  1980  			return interpreter.UFix64Value(v)
  1981  		},
  1982  	)
  1983  }
  1984  
  1985  const internalEVMTypeGetLatestBlockFunctionName = "getLatestBlock"
  1986  
  1987  var internalEVMTypeGetLatestBlockFunctionType = &sema.FunctionType{
  1988  	Parameters: []sema.Parameter{},
  1989  	// Actually EVM.Block, but cannot refer to it here
  1990  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyStructType),
  1991  }
  1992  
  1993  func newInternalEVMTypeGetLatestBlockFunction(
  1994  	gauge common.MemoryGauge,
  1995  	handler types.ContractHandler,
  1996  ) *interpreter.HostFunctionValue {
  1997  	return interpreter.NewStaticHostFunctionValue(
  1998  		gauge,
  1999  		internalEVMTypeCallFunctionType,
  2000  		func(invocation interpreter.Invocation) interpreter.Value {
  2001  			inter := invocation.Interpreter
  2002  			locationRange := invocation.LocationRange
  2003  
  2004  			latestBlock := handler.LastExecutedBlock()
  2005  			return NewEVMBlockValue(handler, gauge, inter, locationRange, latestBlock)
  2006  		},
  2007  	)
  2008  }
  2009  
  2010  func NewEVMBlockValue(
  2011  	handler types.ContractHandler,
  2012  	gauge common.MemoryGauge,
  2013  	inter *interpreter.Interpreter,
  2014  	locationRange interpreter.LocationRange,
  2015  	block *types.Block,
  2016  ) *interpreter.CompositeValue {
  2017  	loc := common.NewAddressLocation(gauge, handler.EVMContractAddress(), ContractName)
  2018  	hash, err := block.Hash()
  2019  	if err != nil {
  2020  		panic(err)
  2021  	}
  2022  
  2023  	return interpreter.NewCompositeValue(
  2024  		inter,
  2025  		locationRange,
  2026  		loc,
  2027  		evmBlockTypeQualifiedIdentifier,
  2028  		common.CompositeKindStructure,
  2029  		[]interpreter.CompositeField{
  2030  			{
  2031  				Name:  "height",
  2032  				Value: interpreter.UInt64Value(block.Height),
  2033  			},
  2034  			{
  2035  				Name: "hash",
  2036  				Value: interpreter.NewStringValue(
  2037  					inter,
  2038  					common.NewStringMemoryUsage(len(hash)),
  2039  					func() string {
  2040  						return hash.Hex()
  2041  					},
  2042  				),
  2043  			},
  2044  			{
  2045  				Name: "totalSupply",
  2046  				Value: interpreter.NewIntValueFromBigInt(
  2047  					inter,
  2048  					common.NewBigIntMemoryUsage(common.BigIntByteLength(block.TotalSupply)),
  2049  					func() *big.Int {
  2050  						return block.TotalSupply
  2051  					},
  2052  				),
  2053  			},
  2054  			{
  2055  				Name:  "timestamp",
  2056  				Value: interpreter.UInt64Value(block.Timestamp),
  2057  			},
  2058  		},
  2059  		common.ZeroAddress,
  2060  	)
  2061  }
  2062  
  2063  func NewInternalEVMContractValue(
  2064  	gauge common.MemoryGauge,
  2065  	handler types.ContractHandler,
  2066  	location common.AddressLocation,
  2067  ) *interpreter.SimpleCompositeValue {
  2068  	return interpreter.NewSimpleCompositeValue(
  2069  		gauge,
  2070  		InternalEVMContractType.ID(),
  2071  		internalEVMContractStaticType,
  2072  		InternalEVMContractType.Fields,
  2073  		map[string]interpreter.Value{
  2074  			internalEVMTypeRunFunctionName:                       newInternalEVMTypeRunFunction(gauge, handler),
  2075  			internalEVMTypeBatchRunFunctionName:                  newInternalEVMTypeBatchRunFunction(gauge, handler),
  2076  			internalEVMTypeCreateCadenceOwnedAccountFunctionName: newInternalEVMTypeCreateCadenceOwnedAccountFunction(gauge, handler),
  2077  			internalEVMTypeCallFunctionName:                      newInternalEVMTypeCallFunction(gauge, handler),
  2078  			internalEVMTypeDepositFunctionName:                   newInternalEVMTypeDepositFunction(gauge, handler),
  2079  			internalEVMTypeWithdrawFunctionName:                  newInternalEVMTypeWithdrawFunction(gauge, handler),
  2080  			internalEVMTypeDeployFunctionName:                    newInternalEVMTypeDeployFunction(gauge, handler),
  2081  			internalEVMTypeBalanceFunctionName:                   newInternalEVMTypeBalanceFunction(gauge, handler),
  2082  			internalEVMTypeNonceFunctionName:                     newInternalEVMTypeNonceFunction(gauge, handler),
  2083  			internalEVMTypeCodeFunctionName:                      newInternalEVMTypeCodeFunction(gauge, handler),
  2084  			internalEVMTypeCodeHashFunctionName:                  newInternalEVMTypeCodeHashFunction(gauge, handler),
  2085  			internalEVMTypeEncodeABIFunctionName:                 newInternalEVMTypeEncodeABIFunction(gauge, location),
  2086  			internalEVMTypeDecodeABIFunctionName:                 newInternalEVMTypeDecodeABIFunction(gauge, location),
  2087  			internalEVMTypeCastToAttoFLOWFunctionName:            newInternalEVMTypeCastToAttoFLOWFunction(gauge),
  2088  			internalEVMTypeCastToFLOWFunctionName:                newInternalEVMTypeCastToFLOWFunction(gauge),
  2089  			internalEVMTypeGetLatestBlockFunctionName:            newInternalEVMTypeGetLatestBlockFunction(gauge, handler),
  2090  			internalEVMTypeDryRunFunctionName:                    newInternalEVMTypeDryRunFunction(gauge, handler),
  2091  		},
  2092  		nil,
  2093  		nil,
  2094  		nil,
  2095  	)
  2096  }
  2097  
  2098  const InternalEVMContractName = "InternalEVM"
  2099  
  2100  var InternalEVMContractType = func() *sema.CompositeType {
  2101  	ty := &sema.CompositeType{
  2102  		Identifier: InternalEVMContractName,
  2103  		Kind:       common.CompositeKindContract,
  2104  	}
  2105  
  2106  	ty.Members = sema.MembersAsMap([]*sema.Member{
  2107  		sema.NewUnmeteredPublicFunctionMember(
  2108  			ty,
  2109  			internalEVMTypeRunFunctionName,
  2110  			internalEVMTypeRunFunctionType,
  2111  			"",
  2112  		),
  2113  		sema.NewUnmeteredPublicFunctionMember(
  2114  			ty,
  2115  			internalEVMTypeDryRunFunctionName,
  2116  			internalEVMTypeDryRunFunctionType,
  2117  			"",
  2118  		),
  2119  		sema.NewUnmeteredPublicFunctionMember(
  2120  			ty,
  2121  			internalEVMTypeBatchRunFunctionName,
  2122  			internalEVMTypeBatchRunFunctionType,
  2123  			"",
  2124  		),
  2125  		sema.NewUnmeteredPublicFunctionMember(
  2126  			ty,
  2127  			internalEVMTypeCreateCadenceOwnedAccountFunctionName,
  2128  			internalEVMTypeCreateCadenceOwnedAccountFunctionType,
  2129  			"",
  2130  		),
  2131  		sema.NewUnmeteredPublicFunctionMember(
  2132  			ty,
  2133  			internalEVMTypeCallFunctionName,
  2134  			internalEVMTypeCallFunctionType,
  2135  			"",
  2136  		),
  2137  		sema.NewUnmeteredPublicFunctionMember(
  2138  			ty,
  2139  			internalEVMTypeDepositFunctionName,
  2140  			internalEVMTypeDepositFunctionType,
  2141  			"",
  2142  		),
  2143  		sema.NewUnmeteredPublicFunctionMember(
  2144  			ty,
  2145  			internalEVMTypeWithdrawFunctionName,
  2146  			internalEVMTypeWithdrawFunctionType,
  2147  			"",
  2148  		),
  2149  		sema.NewUnmeteredPublicFunctionMember(
  2150  			ty,
  2151  			internalEVMTypeDeployFunctionName,
  2152  			internalEVMTypeDeployFunctionType,
  2153  			"",
  2154  		),
  2155  		sema.NewUnmeteredPublicFunctionMember(
  2156  			ty,
  2157  			internalEVMTypeCastToAttoFLOWFunctionName,
  2158  			internalEVMTypeCastToAttoFLOWFunctionType,
  2159  			"",
  2160  		),
  2161  		sema.NewUnmeteredPublicFunctionMember(
  2162  			ty,
  2163  			internalEVMTypeCastToFLOWFunctionName,
  2164  			internalEVMTypeCastToFLOWFunctionType,
  2165  			"",
  2166  		),
  2167  		sema.NewUnmeteredPublicFunctionMember(
  2168  			ty,
  2169  			internalEVMTypeBalanceFunctionName,
  2170  			internalEVMTypeBalanceFunctionType,
  2171  			"",
  2172  		),
  2173  		sema.NewUnmeteredPublicFunctionMember(
  2174  			ty,
  2175  			internalEVMTypeNonceFunctionName,
  2176  			internalEVMTypeNonceFunctionType,
  2177  			"",
  2178  		),
  2179  		sema.NewUnmeteredPublicFunctionMember(
  2180  			ty,
  2181  			internalEVMTypeCodeFunctionName,
  2182  			internalEVMTypeCodeFunctionType,
  2183  			"",
  2184  		),
  2185  		sema.NewUnmeteredPublicFunctionMember(
  2186  			ty,
  2187  			internalEVMTypeCodeHashFunctionName,
  2188  			internalEVMTypeCodeHashFunctionType,
  2189  			"",
  2190  		),
  2191  		sema.NewUnmeteredPublicFunctionMember(
  2192  			ty,
  2193  			internalEVMTypeEncodeABIFunctionName,
  2194  			internalEVMTypeEncodeABIFunctionType,
  2195  			"",
  2196  		),
  2197  		sema.NewUnmeteredPublicFunctionMember(
  2198  			ty,
  2199  			internalEVMTypeDecodeABIFunctionName,
  2200  			internalEVMTypeDecodeABIFunctionType,
  2201  			"",
  2202  		),
  2203  		sema.NewUnmeteredPublicFunctionMember(
  2204  			ty,
  2205  			internalEVMTypeGetLatestBlockFunctionName,
  2206  			internalEVMTypeGetLatestBlockFunctionType,
  2207  			"",
  2208  		),
  2209  	})
  2210  	return ty
  2211  }()
  2212  
  2213  var internalEVMContractStaticType = interpreter.ConvertSemaCompositeTypeToStaticCompositeType(
  2214  	nil,
  2215  	InternalEVMContractType,
  2216  )
  2217  
  2218  func newInternalEVMStandardLibraryValue(
  2219  	gauge common.MemoryGauge,
  2220  	handler types.ContractHandler,
  2221  	location common.AddressLocation,
  2222  ) stdlib.StandardLibraryValue {
  2223  	return stdlib.StandardLibraryValue{
  2224  		Name:  InternalEVMContractName,
  2225  		Type:  InternalEVMContractType,
  2226  		Value: NewInternalEVMContractValue(gauge, handler, location),
  2227  		Kind:  common.DeclarationKindContract,
  2228  	}
  2229  }
  2230  
  2231  var internalEVMStandardLibraryType = stdlib.StandardLibraryType{
  2232  	Name: InternalEVMContractName,
  2233  	Type: InternalEVMContractType,
  2234  	Kind: common.DeclarationKindContract,
  2235  }
  2236  
  2237  func SetupEnvironment(
  2238  	env runtime.Environment,
  2239  	handler types.ContractHandler,
  2240  	contractAddress flow.Address,
  2241  ) {
  2242  	location := common.NewAddressLocation(nil, common.Address(contractAddress), ContractName)
  2243  
  2244  	env.DeclareType(
  2245  		internalEVMStandardLibraryType,
  2246  		location,
  2247  	)
  2248  	env.DeclareValue(
  2249  		newInternalEVMStandardLibraryValue(nil, handler, location),
  2250  		location,
  2251  	)
  2252  }
  2253  
  2254  func NewEVMAddressCadenceType(address common.Address) *cadence.StructType {
  2255  	return cadence.NewStructType(
  2256  		common.NewAddressLocation(nil, address, ContractName),
  2257  		evmAddressTypeQualifiedIdentifier,
  2258  		[]cadence.Field{
  2259  			{
  2260  				Identifier: "bytes",
  2261  				Type:       EVMAddressBytesCadenceType,
  2262  			},
  2263  		},
  2264  		nil,
  2265  	)
  2266  }
  2267  
  2268  func NewBalanceCadenceType(address common.Address) *cadence.StructType {
  2269  	return cadence.NewStructType(
  2270  		common.NewAddressLocation(nil, address, ContractName),
  2271  		evmBalanceTypeQualifiedIdentifier,
  2272  		[]cadence.Field{
  2273  			{
  2274  				Identifier: "attoflow",
  2275  				Type:       cadence.UIntType,
  2276  			},
  2277  		},
  2278  		nil,
  2279  	)
  2280  }
  2281  
  2282  func ResultSummaryFromEVMResultValue(val cadence.Value) (*types.ResultSummary, error) {
  2283  	str, ok := val.(cadence.Struct)
  2284  	if !ok {
  2285  		return nil, fmt.Errorf("invalid input: unexpected value type")
  2286  	}
  2287  
  2288  	fields := cadence.FieldsMappedByName(str)
  2289  
  2290  	const expectedFieldCount = 5
  2291  	if len(fields) != expectedFieldCount {
  2292  		return nil, fmt.Errorf(
  2293  			"invalid input: field count mismatch: expected %d, got %d",
  2294  			expectedFieldCount,
  2295  			len(fields),
  2296  		)
  2297  	}
  2298  
  2299  	statusEnum, ok := fields[evmResultTypeStatusFieldName].(cadence.Enum)
  2300  	if !ok {
  2301  		return nil, fmt.Errorf("invalid input: unexpected type for status field")
  2302  	}
  2303  
  2304  	status, ok := cadence.FieldsMappedByName(statusEnum)[sema.EnumRawValueFieldName].(cadence.UInt8)
  2305  	if !ok {
  2306  		return nil, fmt.Errorf("invalid input: unexpected type for status field")
  2307  	}
  2308  
  2309  	errorCode, ok := fields[evmResultTypeErrorCodeFieldName].(cadence.UInt64)
  2310  	if !ok {
  2311  		return nil, fmt.Errorf("invalid input: unexpected type for error code field")
  2312  	}
  2313  
  2314  	gasUsed, ok := fields[evmResultTypeGasUsedFieldName].(cadence.UInt64)
  2315  	if !ok {
  2316  		return nil, fmt.Errorf("invalid input: unexpected type for gas field")
  2317  	}
  2318  
  2319  	data, ok := fields[evmResultTypeDataFieldName].(cadence.Array)
  2320  	if !ok {
  2321  		return nil, fmt.Errorf("invalid input: unexpected type for data field")
  2322  	}
  2323  
  2324  	convertedData := make([]byte, len(data.Values))
  2325  	for i, value := range data.Values {
  2326  		convertedData[i] = byte(value.(cadence.UInt8))
  2327  	}
  2328  
  2329  	var convertedDeployedAddress *types.Address
  2330  
  2331  	deployedAddressField, ok := fields[evmResultTypeDeployedContractFieldName].(cadence.Optional)
  2332  	if !ok {
  2333  		return nil, fmt.Errorf("invalid input: unexpected type for deployed contract field")
  2334  	}
  2335  
  2336  	if deployedAddressField.Value != nil {
  2337  		evmAddress, ok := deployedAddressField.Value.(cadence.Struct)
  2338  		if !ok {
  2339  			return nil, fmt.Errorf("invalid input: unexpected type for deployed contract field")
  2340  		}
  2341  
  2342  		bytes, ok := cadence.SearchFieldByName(evmAddress, evmAddressTypeBytesFieldName).(cadence.Array)
  2343  		if !ok {
  2344  			return nil, fmt.Errorf("invalid input: unexpected type for deployed contract field")
  2345  		}
  2346  
  2347  		convertedAddress := make([]byte, len(bytes.Values))
  2348  		for i, value := range bytes.Values {
  2349  			convertedAddress[i] = byte(value.(cadence.UInt8))
  2350  		}
  2351  		addr := types.Address(convertedAddress)
  2352  		convertedDeployedAddress = &addr
  2353  	}
  2354  
  2355  	return &types.ResultSummary{
  2356  		Status:                  types.Status(status),
  2357  		ErrorCode:               types.ErrorCode(errorCode),
  2358  		GasConsumed:             uint64(gasUsed),
  2359  		ReturnedValue:           convertedData,
  2360  		DeployedContractAddress: convertedDeployedAddress,
  2361  	}, nil
  2362  
  2363  }
  2364  
  2365  func NewEVMBlockCadenceType(address common.Address) *cadence.StructType {
  2366  	return cadence.NewStructType(
  2367  		common.NewAddressLocation(nil, address, ContractName),
  2368  		evmBlockTypeQualifiedIdentifier,
  2369  		[]cadence.Field{
  2370  			{
  2371  				Identifier: "height",
  2372  				Type:       cadence.UInt64Type,
  2373  			},
  2374  			{
  2375  				Identifier: "hash",
  2376  				Type:       cadence.StringType,
  2377  			},
  2378  			{
  2379  				Identifier: "totalSupply",
  2380  				Type:       cadence.IntType,
  2381  			},
  2382  			{
  2383  				Identifier: "timestamp",
  2384  				Type:       cadence.UInt64Type,
  2385  			},
  2386  		},
  2387  		nil,
  2388  	)
  2389  }