github.com/onflow/flow-go@v0.33.17/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  	gethABI "github.com/ethereum/go-ethereum/accounts/abi"
    13  	gethCommon "github.com/ethereum/go-ethereum/common"
    14  	"github.com/onflow/cadence"
    15  	"github.com/onflow/cadence/runtime"
    16  	"github.com/onflow/cadence/runtime/common"
    17  	"github.com/onflow/cadence/runtime/errors"
    18  	"github.com/onflow/cadence/runtime/interpreter"
    19  	"github.com/onflow/cadence/runtime/sema"
    20  	"github.com/onflow/cadence/runtime/stdlib"
    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  //go:embed abiOnlyContract.cdc
    31  var abiOnlyContractCode string
    32  
    33  var flowTokenImportPattern = regexp.MustCompile(`^import "FlowToken"\n`)
    34  
    35  func ContractCode(flowTokenAddress flow.Address, evmAbiOnly bool) []byte {
    36  	if evmAbiOnly {
    37  		return []byte(abiOnlyContractCode)
    38  	}
    39  
    40  	return []byte(flowTokenImportPattern.ReplaceAllString(
    41  		contractCode,
    42  		fmt.Sprintf("import FlowToken from %s", flowTokenAddress.HexWithPrefix()),
    43  	))
    44  }
    45  
    46  const ContractName = "EVM"
    47  const evmAddressTypeBytesFieldName = "bytes"
    48  const evmAddressTypeQualifiedIdentifier = "EVM.EVMAddress"
    49  
    50  const abiEncodingByteSize = 32
    51  
    52  var EVMTransactionBytesCadenceType = cadence.NewVariableSizedArrayType(cadence.TheUInt8Type)
    53  var evmTransactionBytesType = sema.NewVariableSizedType(nil, sema.UInt8Type)
    54  
    55  var evmAddressBytesType = sema.NewConstantSizedType(nil, sema.UInt8Type, types.AddressLength)
    56  var evmAddressBytesStaticType = interpreter.ConvertSemaArrayTypeToStaticArrayType(nil, evmAddressBytesType)
    57  var EVMAddressBytesCadenceType = cadence.NewConstantSizedArrayType(types.AddressLength, cadence.TheUInt8Type)
    58  
    59  // abiEncodingError
    60  type abiEncodingError struct {
    61  	Type interpreter.StaticType
    62  }
    63  
    64  var _ errors.UserError = abiEncodingError{}
    65  
    66  func (abiEncodingError) IsUserError() {}
    67  
    68  func (e abiEncodingError) Error() string {
    69  	var b strings.Builder
    70  	b.WriteString("failed to ABI encode value")
    71  
    72  	ty := e.Type
    73  	if ty != nil {
    74  		b.WriteString(" of type ")
    75  		b.WriteString(ty.String())
    76  	}
    77  
    78  	return b.String()
    79  }
    80  
    81  // abiDecodingError
    82  type abiDecodingError struct {
    83  	Type    interpreter.StaticType
    84  	Message string
    85  }
    86  
    87  var _ errors.UserError = abiDecodingError{}
    88  
    89  func (abiDecodingError) IsUserError() {}
    90  
    91  func (e abiDecodingError) Error() string {
    92  	var b strings.Builder
    93  	b.WriteString("failed to ABI decode data")
    94  
    95  	ty := e.Type
    96  	if ty != nil {
    97  		b.WriteString(" with type ")
    98  		b.WriteString(ty.String())
    99  	}
   100  
   101  	message := e.Message
   102  	if message != "" {
   103  		b.WriteString(": ")
   104  		b.WriteString(message)
   105  	}
   106  
   107  	return b.String()
   108  }
   109  
   110  func reportABIEncodingComputation(
   111  	inter *interpreter.Interpreter,
   112  	values *interpreter.ArrayValue,
   113  	evmAddressTypeID common.TypeID,
   114  	reportComputation func(intensity uint),
   115  ) {
   116  	values.Iterate(inter, func(element interpreter.Value) (resume bool) {
   117  		switch value := element.(type) {
   118  		case *interpreter.StringValue:
   119  			// Dynamic variables, such as strings, are encoded
   120  			// in 2+ chunks of 32 bytes. The first chunk contains
   121  			// the index where information for the string begin,
   122  			// the second chunk contains the number of bytes the
   123  			// string occupies, and the third chunk contains the
   124  			// value of the string itself.
   125  			computation := uint(2 * abiEncodingByteSize)
   126  			stringLength := len(value.Str)
   127  			chunks := math.Ceil(float64(stringLength) / float64(abiEncodingByteSize))
   128  			computation += uint(chunks * abiEncodingByteSize)
   129  			reportComputation(computation)
   130  
   131  		case interpreter.BoolValue,
   132  			interpreter.UInt8Value,
   133  			interpreter.UInt16Value,
   134  			interpreter.UInt32Value,
   135  			interpreter.UInt64Value,
   136  			interpreter.UInt128Value,
   137  			interpreter.UInt256Value,
   138  			interpreter.Int8Value,
   139  			interpreter.Int16Value,
   140  			interpreter.Int32Value,
   141  			interpreter.Int64Value,
   142  			interpreter.Int128Value,
   143  			interpreter.Int256Value:
   144  
   145  			// Numeric and bool variables are also static variables
   146  			// with a fixed size of 32 bytes.
   147  			reportComputation(abiEncodingByteSize)
   148  
   149  		case *interpreter.CompositeValue:
   150  			if value.TypeID() == evmAddressTypeID {
   151  				// EVM addresses are static variables with a fixed
   152  				// size of 32 bytes.
   153  				reportComputation(abiEncodingByteSize)
   154  			} else {
   155  				panic(abiEncodingError{
   156  					Type: value.StaticType(inter),
   157  				})
   158  			}
   159  		case *interpreter.ArrayValue:
   160  			// Dynamic variables, such as arrays & slices, are encoded
   161  			// in 2+ chunks of 32 bytes. The first chunk contains
   162  			// the index where information for the array begin,
   163  			// the second chunk contains the number of bytes the
   164  			// array occupies, and the third chunk contains the
   165  			// values of the array itself.
   166  			computation := uint(2 * abiEncodingByteSize)
   167  			reportComputation(computation)
   168  			reportABIEncodingComputation(inter, value, evmAddressTypeID, reportComputation)
   169  
   170  		default:
   171  			panic(abiEncodingError{
   172  				Type: element.StaticType(inter),
   173  			})
   174  		}
   175  
   176  		// continue iteration
   177  		return true
   178  	})
   179  }
   180  
   181  // EVM.encodeABI
   182  
   183  const internalEVMTypeEncodeABIFunctionName = "encodeABI"
   184  
   185  var internalEVMTypeEncodeABIFunctionType = &sema.FunctionType{
   186  	Parameters: []sema.Parameter{
   187  		{
   188  			Label:      sema.ArgumentLabelNotRequired,
   189  			Identifier: "values",
   190  			TypeAnnotation: sema.NewTypeAnnotation(
   191  				sema.NewVariableSizedType(nil, sema.AnyStructType),
   192  			),
   193  		},
   194  	},
   195  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
   196  }
   197  
   198  func newInternalEVMTypeEncodeABIFunction(
   199  	gauge common.MemoryGauge,
   200  	location common.AddressLocation,
   201  ) *interpreter.HostFunctionValue {
   202  
   203  	evmAddressTypeID := location.TypeID(gauge, evmAddressTypeQualifiedIdentifier)
   204  
   205  	return interpreter.NewHostFunctionValue(
   206  		gauge,
   207  		internalEVMTypeEncodeABIFunctionType,
   208  		func(invocation interpreter.Invocation) interpreter.Value {
   209  			inter := invocation.Interpreter
   210  			locationRange := invocation.LocationRange
   211  
   212  			// Get `values` argument
   213  
   214  			valuesArray, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
   215  			if !ok {
   216  				panic(errors.NewUnreachableError())
   217  			}
   218  
   219  			reportABIEncodingComputation(
   220  				inter,
   221  				valuesArray,
   222  				evmAddressTypeID,
   223  				func(intensity uint) {
   224  					inter.ReportComputation(environment.ComputationKindEVMEncodeABI, intensity)
   225  				},
   226  			)
   227  
   228  			size := valuesArray.Count()
   229  
   230  			values := make([]any, 0, size)
   231  			arguments := make(gethABI.Arguments, 0, size)
   232  
   233  			valuesArray.Iterate(inter, func(element interpreter.Value) (resume bool) {
   234  				value, ty, err := encodeABI(
   235  					inter,
   236  					locationRange,
   237  					element,
   238  					element.StaticType(inter),
   239  					evmAddressTypeID,
   240  				)
   241  				if err != nil {
   242  					panic(err)
   243  				}
   244  
   245  				values = append(values, value)
   246  				arguments = append(arguments, gethABI.Argument{Type: ty})
   247  
   248  				// continue iteration
   249  				return true
   250  			})
   251  
   252  			encodedValues, err := arguments.Pack(values...)
   253  			if err != nil {
   254  				panic(abiEncodingError{})
   255  			}
   256  
   257  			return interpreter.ByteSliceToByteArrayValue(inter, encodedValues)
   258  		},
   259  	)
   260  }
   261  
   262  var gethTypeString = gethABI.Type{T: gethABI.StringTy}
   263  var gethTypeBool = gethABI.Type{T: gethABI.BoolTy}
   264  var gethTypeUint8 = gethABI.Type{T: gethABI.UintTy, Size: 8}
   265  var gethTypeUint16 = gethABI.Type{T: gethABI.UintTy, Size: 16}
   266  var gethTypeUint32 = gethABI.Type{T: gethABI.UintTy, Size: 32}
   267  var gethTypeUint64 = gethABI.Type{T: gethABI.UintTy, Size: 64}
   268  var gethTypeUint128 = gethABI.Type{T: gethABI.UintTy, Size: 128}
   269  var gethTypeUint256 = gethABI.Type{T: gethABI.UintTy, Size: 256}
   270  var gethTypeInt8 = gethABI.Type{T: gethABI.IntTy, Size: 8}
   271  var gethTypeInt16 = gethABI.Type{T: gethABI.IntTy, Size: 16}
   272  var gethTypeInt32 = gethABI.Type{T: gethABI.IntTy, Size: 32}
   273  var gethTypeInt64 = gethABI.Type{T: gethABI.IntTy, Size: 64}
   274  var gethTypeInt128 = gethABI.Type{T: gethABI.IntTy, Size: 128}
   275  var gethTypeInt256 = gethABI.Type{T: gethABI.IntTy, Size: 256}
   276  var gethTypeAddress = gethABI.Type{Size: 20, T: gethABI.AddressTy}
   277  
   278  func gethABIType(staticType interpreter.StaticType, evmAddressTypeID common.TypeID) (gethABI.Type, bool) {
   279  	switch staticType {
   280  	case interpreter.PrimitiveStaticTypeString:
   281  		return gethTypeString, true
   282  	case interpreter.PrimitiveStaticTypeBool:
   283  		return gethTypeBool, true
   284  	case interpreter.PrimitiveStaticTypeUInt8:
   285  		return gethTypeUint8, true
   286  	case interpreter.PrimitiveStaticTypeUInt16:
   287  		return gethTypeUint16, true
   288  	case interpreter.PrimitiveStaticTypeUInt32:
   289  		return gethTypeUint32, true
   290  	case interpreter.PrimitiveStaticTypeUInt64:
   291  		return gethTypeUint64, true
   292  	case interpreter.PrimitiveStaticTypeUInt128:
   293  		return gethTypeUint128, true
   294  	case interpreter.PrimitiveStaticTypeUInt256:
   295  		return gethTypeUint256, true
   296  	case interpreter.PrimitiveStaticTypeInt8:
   297  		return gethTypeInt8, true
   298  	case interpreter.PrimitiveStaticTypeInt16:
   299  		return gethTypeInt16, true
   300  	case interpreter.PrimitiveStaticTypeInt32:
   301  		return gethTypeInt32, true
   302  	case interpreter.PrimitiveStaticTypeInt64:
   303  		return gethTypeInt64, true
   304  	case interpreter.PrimitiveStaticTypeInt128:
   305  		return gethTypeInt128, true
   306  	case interpreter.PrimitiveStaticTypeInt256:
   307  		return gethTypeInt256, true
   308  	case interpreter.PrimitiveStaticTypeAddress:
   309  		return gethTypeAddress, true
   310  	}
   311  
   312  	switch staticType := staticType.(type) {
   313  	case interpreter.CompositeStaticType:
   314  		if staticType.TypeID != evmAddressTypeID {
   315  			break
   316  		}
   317  
   318  		return gethTypeAddress, true
   319  
   320  	case interpreter.ConstantSizedStaticType:
   321  		elementGethABIType, ok := gethABIType(
   322  			staticType.ElementType(),
   323  			evmAddressTypeID,
   324  		)
   325  		if !ok {
   326  			break
   327  		}
   328  
   329  		return gethABI.Type{
   330  			T:    gethABI.ArrayTy,
   331  			Elem: &elementGethABIType,
   332  			Size: int(staticType.Size),
   333  		}, true
   334  
   335  	case interpreter.VariableSizedStaticType:
   336  		elementGethABIType, ok := gethABIType(
   337  			staticType.ElementType(),
   338  			evmAddressTypeID,
   339  		)
   340  		if !ok {
   341  			break
   342  		}
   343  
   344  		return gethABI.Type{
   345  			T:    gethABI.SliceTy,
   346  			Elem: &elementGethABIType,
   347  		}, true
   348  
   349  	}
   350  
   351  	return gethABI.Type{}, false
   352  }
   353  
   354  func goType(
   355  	staticType interpreter.StaticType,
   356  	evmAddressTypeID common.TypeID,
   357  ) (reflect.Type, bool) {
   358  	switch staticType {
   359  	case interpreter.PrimitiveStaticTypeString:
   360  		return reflect.TypeOf(""), true
   361  	case interpreter.PrimitiveStaticTypeBool:
   362  		return reflect.TypeOf(true), true
   363  	case interpreter.PrimitiveStaticTypeUInt8:
   364  		return reflect.TypeOf(uint8(0)), true
   365  	case interpreter.PrimitiveStaticTypeUInt16:
   366  		return reflect.TypeOf(uint16(0)), true
   367  	case interpreter.PrimitiveStaticTypeUInt32:
   368  		return reflect.TypeOf(uint32(0)), true
   369  	case interpreter.PrimitiveStaticTypeUInt64:
   370  		return reflect.TypeOf(uint64(0)), true
   371  	case interpreter.PrimitiveStaticTypeUInt128:
   372  		return reflect.TypeOf((*big.Int)(nil)), true
   373  	case interpreter.PrimitiveStaticTypeUInt256:
   374  		return reflect.TypeOf((*big.Int)(nil)), true
   375  	case interpreter.PrimitiveStaticTypeInt8:
   376  		return reflect.TypeOf(int8(0)), true
   377  	case interpreter.PrimitiveStaticTypeInt16:
   378  		return reflect.TypeOf(int16(0)), true
   379  	case interpreter.PrimitiveStaticTypeInt32:
   380  		return reflect.TypeOf(int32(0)), true
   381  	case interpreter.PrimitiveStaticTypeInt64:
   382  		return reflect.TypeOf(int64(0)), true
   383  	case interpreter.PrimitiveStaticTypeInt128:
   384  		return reflect.TypeOf((*big.Int)(nil)), true
   385  	case interpreter.PrimitiveStaticTypeInt256:
   386  		return reflect.TypeOf((*big.Int)(nil)), true
   387  	case interpreter.PrimitiveStaticTypeAddress:
   388  		return reflect.TypeOf((*big.Int)(nil)), true
   389  	}
   390  
   391  	switch staticType := staticType.(type) {
   392  	case interpreter.ConstantSizedStaticType:
   393  		elementType, ok := goType(staticType.ElementType(), evmAddressTypeID)
   394  		if !ok {
   395  			break
   396  		}
   397  
   398  		return reflect.ArrayOf(int(staticType.Size), elementType), true
   399  
   400  	case interpreter.VariableSizedStaticType:
   401  		elementType, ok := goType(staticType.ElementType(), evmAddressTypeID)
   402  		if !ok {
   403  			break
   404  		}
   405  
   406  		return reflect.SliceOf(elementType), true
   407  	}
   408  
   409  	if staticType.ID() == evmAddressTypeID {
   410  		return reflect.TypeOf(gethCommon.Address{}), true
   411  	}
   412  
   413  	return nil, false
   414  }
   415  
   416  func encodeABI(
   417  	inter *interpreter.Interpreter,
   418  	locationRange interpreter.LocationRange,
   419  	value interpreter.Value,
   420  	staticType interpreter.StaticType,
   421  	evmAddressTypeID common.TypeID,
   422  ) (
   423  	any,
   424  	gethABI.Type,
   425  	error,
   426  ) {
   427  
   428  	switch value := value.(type) {
   429  	case *interpreter.StringValue:
   430  		if staticType == interpreter.PrimitiveStaticTypeString {
   431  			return value.Str, gethTypeString, nil
   432  		}
   433  
   434  	case interpreter.BoolValue:
   435  		if staticType == interpreter.PrimitiveStaticTypeBool {
   436  			return bool(value), gethTypeBool, nil
   437  		}
   438  
   439  	case interpreter.UInt8Value:
   440  		if staticType == interpreter.PrimitiveStaticTypeUInt8 {
   441  			return uint8(value), gethTypeUint8, nil
   442  		}
   443  
   444  	case interpreter.UInt16Value:
   445  		if staticType == interpreter.PrimitiveStaticTypeUInt16 {
   446  			return uint16(value), gethTypeUint16, nil
   447  		}
   448  
   449  	case interpreter.UInt32Value:
   450  		if staticType == interpreter.PrimitiveStaticTypeUInt32 {
   451  			return uint32(value), gethTypeUint32, nil
   452  		}
   453  
   454  	case interpreter.UInt64Value:
   455  		if staticType == interpreter.PrimitiveStaticTypeUInt64 {
   456  			return uint64(value), gethTypeUint64, nil
   457  		}
   458  
   459  	case interpreter.UInt128Value:
   460  		if staticType == interpreter.PrimitiveStaticTypeUInt128 {
   461  			return value.BigInt, gethTypeUint128, nil
   462  		}
   463  
   464  	case interpreter.UInt256Value:
   465  		if staticType == interpreter.PrimitiveStaticTypeUInt256 {
   466  			return value.BigInt, gethTypeUint256, nil
   467  		}
   468  
   469  	case interpreter.Int8Value:
   470  		if staticType == interpreter.PrimitiveStaticTypeInt8 {
   471  			return int8(value), gethTypeInt8, nil
   472  		}
   473  
   474  	case interpreter.Int16Value:
   475  		if staticType == interpreter.PrimitiveStaticTypeInt16 {
   476  			return int16(value), gethTypeInt16, nil
   477  		}
   478  
   479  	case interpreter.Int32Value:
   480  		if staticType == interpreter.PrimitiveStaticTypeInt32 {
   481  			return int32(value), gethTypeInt32, nil
   482  		}
   483  
   484  	case interpreter.Int64Value:
   485  		if staticType == interpreter.PrimitiveStaticTypeInt64 {
   486  			return int64(value), gethTypeInt64, nil
   487  		}
   488  
   489  	case interpreter.Int128Value:
   490  		if staticType == interpreter.PrimitiveStaticTypeInt128 {
   491  			return value.BigInt, gethTypeInt128, nil
   492  		}
   493  
   494  	case interpreter.Int256Value:
   495  		if staticType == interpreter.PrimitiveStaticTypeInt256 {
   496  			return value.BigInt, gethTypeInt256, nil
   497  		}
   498  
   499  	case *interpreter.CompositeValue:
   500  		if value.TypeID() == evmAddressTypeID {
   501  			addressBytesArrayValue := value.GetMember(inter, locationRange, evmAddressTypeBytesFieldName)
   502  			bytes, err := interpreter.ByteArrayValueToByteSlice(
   503  				inter,
   504  				addressBytesArrayValue,
   505  				locationRange,
   506  			)
   507  			if err != nil {
   508  				panic(err)
   509  			}
   510  
   511  			return gethCommon.Address(bytes), gethTypeAddress, nil
   512  		}
   513  
   514  	case *interpreter.ArrayValue:
   515  		arrayStaticType := value.Type
   516  
   517  		arrayGethABIType, ok := gethABIType(arrayStaticType, evmAddressTypeID)
   518  		if !ok {
   519  			break
   520  		}
   521  
   522  		elementStaticType := arrayStaticType.ElementType()
   523  
   524  		elementGoType, ok := goType(elementStaticType, evmAddressTypeID)
   525  		if !ok {
   526  			break
   527  		}
   528  
   529  		var result reflect.Value
   530  
   531  		switch arrayStaticType := arrayStaticType.(type) {
   532  		case interpreter.ConstantSizedStaticType:
   533  			size := int(arrayStaticType.Size)
   534  			result = reflect.Indirect(reflect.New(reflect.ArrayOf(size, elementGoType)))
   535  
   536  		case interpreter.VariableSizedStaticType:
   537  			size := value.Count()
   538  			result = reflect.MakeSlice(reflect.SliceOf(elementGoType), size, size)
   539  		}
   540  
   541  		var index int
   542  		value.Iterate(inter, func(element interpreter.Value) (resume bool) {
   543  
   544  			arrayElement, _, err := encodeABI(
   545  				inter,
   546  				locationRange,
   547  				element,
   548  				element.StaticType(inter),
   549  				evmAddressTypeID,
   550  			)
   551  			if err != nil {
   552  				panic(err)
   553  			}
   554  
   555  			result.Index(index).Set(reflect.ValueOf(arrayElement))
   556  
   557  			index++
   558  
   559  			// continue iteration
   560  			return true
   561  		})
   562  
   563  		return result.Interface(), arrayGethABIType, nil
   564  	}
   565  
   566  	return nil, gethABI.Type{}, abiEncodingError{
   567  		Type: value.StaticType(inter),
   568  	}
   569  }
   570  
   571  // EVM.decodeABI
   572  
   573  const internalEVMTypeDecodeABIFunctionName = "decodeABI"
   574  
   575  var internalEVMTypeDecodeABIFunctionType = &sema.FunctionType{
   576  	Parameters: []sema.Parameter{
   577  		{
   578  			Identifier: "types",
   579  			TypeAnnotation: sema.NewTypeAnnotation(
   580  				sema.NewVariableSizedType(nil, sema.MetaType),
   581  			),
   582  		},
   583  		{
   584  			Label:          "data",
   585  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
   586  		},
   587  	},
   588  	ReturnTypeAnnotation: sema.NewTypeAnnotation(
   589  		sema.NewVariableSizedType(nil, sema.AnyStructType),
   590  	),
   591  }
   592  
   593  func newInternalEVMTypeDecodeABIFunction(
   594  	gauge common.MemoryGauge,
   595  	location common.AddressLocation,
   596  ) *interpreter.HostFunctionValue {
   597  	evmAddressTypeID := location.TypeID(gauge, evmAddressTypeQualifiedIdentifier)
   598  
   599  	return interpreter.NewHostFunctionValue(
   600  		gauge,
   601  		internalEVMTypeDecodeABIFunctionType,
   602  		func(invocation interpreter.Invocation) interpreter.Value {
   603  			inter := invocation.Interpreter
   604  			locationRange := invocation.LocationRange
   605  
   606  			// Get `types` argument
   607  
   608  			typesArray, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
   609  			if !ok {
   610  				panic(errors.NewUnreachableError())
   611  			}
   612  
   613  			// Get `data` argument
   614  
   615  			dataValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
   616  			if !ok {
   617  				panic(errors.NewUnreachableError())
   618  			}
   619  
   620  			invocation.Interpreter.ReportComputation(
   621  				environment.ComputationKindEVMDecodeABI,
   622  				uint(dataValue.Count()),
   623  			)
   624  
   625  			data, err := interpreter.ByteArrayValueToByteSlice(inter, dataValue, locationRange)
   626  			if err != nil {
   627  				panic(err)
   628  			}
   629  
   630  			var arguments gethABI.Arguments
   631  			typesArray.Iterate(inter, func(element interpreter.Value) (resume bool) {
   632  				typeValue, ok := element.(interpreter.TypeValue)
   633  				if !ok {
   634  					panic(errors.NewUnreachableError())
   635  				}
   636  
   637  				staticType := typeValue.Type
   638  
   639  				gethABITy, ok := gethABIType(staticType, evmAddressTypeID)
   640  				if !ok {
   641  					panic(abiDecodingError{
   642  						Type: staticType,
   643  					})
   644  				}
   645  
   646  				arguments = append(
   647  					arguments,
   648  					gethABI.Argument{
   649  						Type: gethABITy,
   650  					},
   651  				)
   652  
   653  				// continue iteration
   654  				return true
   655  			})
   656  
   657  			decodedValues, err := arguments.Unpack(data)
   658  			if err != nil {
   659  				panic(abiDecodingError{})
   660  			}
   661  
   662  			var index int
   663  			values := make([]interpreter.Value, 0, len(decodedValues))
   664  
   665  			typesArray.Iterate(inter, func(element interpreter.Value) (resume bool) {
   666  				typeValue, ok := element.(interpreter.TypeValue)
   667  				if !ok {
   668  					panic(errors.NewUnreachableError())
   669  				}
   670  
   671  				staticType := typeValue.Type
   672  
   673  				value, err := decodeABI(
   674  					inter,
   675  					locationRange,
   676  					decodedValues[index],
   677  					staticType,
   678  					location,
   679  					evmAddressTypeID,
   680  				)
   681  				if err != nil {
   682  					panic(err)
   683  				}
   684  
   685  				index++
   686  
   687  				values = append(values, value)
   688  
   689  				// continue iteration
   690  				return true
   691  			})
   692  
   693  			arrayType := interpreter.NewVariableSizedStaticType(
   694  				inter,
   695  				interpreter.NewPrimitiveStaticType(
   696  					inter,
   697  					interpreter.PrimitiveStaticTypeAnyStruct,
   698  				),
   699  			)
   700  
   701  			return interpreter.NewArrayValue(
   702  				inter,
   703  				locationRange,
   704  				arrayType,
   705  				common.ZeroAddress,
   706  				values...,
   707  			)
   708  		},
   709  	)
   710  }
   711  
   712  func decodeABI(
   713  	inter *interpreter.Interpreter,
   714  	locationRange interpreter.LocationRange,
   715  	value any,
   716  	staticType interpreter.StaticType,
   717  	location common.AddressLocation,
   718  	evmAddressTypeID common.TypeID,
   719  ) (
   720  	interpreter.Value,
   721  	error,
   722  ) {
   723  
   724  	switch staticType {
   725  	case interpreter.PrimitiveStaticTypeString:
   726  		value, ok := value.(string)
   727  		if !ok {
   728  			break
   729  		}
   730  		return interpreter.NewStringValue(
   731  			inter,
   732  			common.NewStringMemoryUsage(len(value)),
   733  			func() string {
   734  				return value
   735  			},
   736  		), nil
   737  
   738  	case interpreter.PrimitiveStaticTypeBool:
   739  		value, ok := value.(bool)
   740  		if !ok {
   741  			break
   742  		}
   743  		return interpreter.BoolValue(value), nil
   744  
   745  	case interpreter.PrimitiveStaticTypeUInt8:
   746  		value, ok := value.(uint8)
   747  		if !ok {
   748  			break
   749  		}
   750  		return interpreter.NewUInt8Value(inter, func() uint8 { return value }), nil
   751  
   752  	case interpreter.PrimitiveStaticTypeUInt16:
   753  		value, ok := value.(uint16)
   754  		if !ok {
   755  			break
   756  		}
   757  		return interpreter.NewUInt16Value(inter, func() uint16 { return value }), nil
   758  
   759  	case interpreter.PrimitiveStaticTypeUInt32:
   760  		value, ok := value.(uint32)
   761  		if !ok {
   762  			break
   763  		}
   764  		return interpreter.NewUInt32Value(inter, func() uint32 { return value }), nil
   765  
   766  	case interpreter.PrimitiveStaticTypeUInt64:
   767  		value, ok := value.(uint64)
   768  		if !ok {
   769  			break
   770  		}
   771  		return interpreter.NewUInt64Value(inter, func() uint64 { return value }), nil
   772  
   773  	case interpreter.PrimitiveStaticTypeUInt128:
   774  		value, ok := value.(*big.Int)
   775  		if !ok {
   776  			break
   777  		}
   778  		return interpreter.NewUInt128ValueFromBigInt(inter, func() *big.Int { return value }), nil
   779  
   780  	case interpreter.PrimitiveStaticTypeUInt256:
   781  		value, ok := value.(*big.Int)
   782  		if !ok {
   783  			break
   784  		}
   785  		return interpreter.NewUInt256ValueFromBigInt(inter, func() *big.Int { return value }), nil
   786  
   787  	case interpreter.PrimitiveStaticTypeInt8:
   788  		value, ok := value.(int8)
   789  		if !ok {
   790  			break
   791  		}
   792  		return interpreter.NewInt8Value(inter, func() int8 { return value }), nil
   793  
   794  	case interpreter.PrimitiveStaticTypeInt16:
   795  		value, ok := value.(int16)
   796  		if !ok {
   797  			break
   798  		}
   799  		return interpreter.NewInt16Value(inter, func() int16 { return value }), nil
   800  
   801  	case interpreter.PrimitiveStaticTypeInt32:
   802  		value, ok := value.(int32)
   803  		if !ok {
   804  			break
   805  		}
   806  		return interpreter.NewInt32Value(inter, func() int32 { return value }), nil
   807  
   808  	case interpreter.PrimitiveStaticTypeInt64:
   809  		value, ok := value.(int64)
   810  		if !ok {
   811  			break
   812  		}
   813  		return interpreter.NewInt64Value(inter, func() int64 { return value }), nil
   814  
   815  	case interpreter.PrimitiveStaticTypeInt128:
   816  		value, ok := value.(*big.Int)
   817  		if !ok {
   818  			break
   819  		}
   820  		return interpreter.NewInt128ValueFromBigInt(inter, func() *big.Int { return value }), nil
   821  
   822  	case interpreter.PrimitiveStaticTypeInt256:
   823  		value, ok := value.(*big.Int)
   824  		if !ok {
   825  			break
   826  		}
   827  		return interpreter.NewInt256ValueFromBigInt(inter, func() *big.Int { return value }), nil
   828  	}
   829  
   830  	switch staticType := staticType.(type) {
   831  	case interpreter.ArrayStaticType:
   832  		array := reflect.ValueOf(value)
   833  
   834  		elementStaticType := staticType.ElementType()
   835  
   836  		size := array.Len()
   837  
   838  		var index int
   839  		return interpreter.NewArrayValueWithIterator(
   840  			inter,
   841  			staticType,
   842  			common.ZeroAddress,
   843  			uint64(size),
   844  			func() interpreter.Value {
   845  				if index >= size {
   846  					return nil
   847  				}
   848  
   849  				element := array.Index(index).Interface()
   850  
   851  				result, err := decodeABI(
   852  					inter,
   853  					locationRange,
   854  					element,
   855  					elementStaticType,
   856  					location,
   857  					evmAddressTypeID,
   858  				)
   859  				if err != nil {
   860  					panic(err)
   861  				}
   862  
   863  				index++
   864  
   865  				return result
   866  			},
   867  		), nil
   868  
   869  	case interpreter.CompositeStaticType:
   870  		if staticType.TypeID != evmAddressTypeID {
   871  			break
   872  		}
   873  
   874  		addr, ok := value.(gethCommon.Address)
   875  		if !ok {
   876  			break
   877  		}
   878  
   879  		var address types.Address
   880  		copy(address[:], addr.Bytes())
   881  		return NewEVMAddress(
   882  			inter,
   883  			locationRange,
   884  			location,
   885  			address,
   886  		), nil
   887  	}
   888  
   889  	return nil, abiDecodingError{
   890  		Type: staticType,
   891  	}
   892  }
   893  
   894  func NewEVMAddress(
   895  	inter *interpreter.Interpreter,
   896  	locationRange interpreter.LocationRange,
   897  	location common.AddressLocation,
   898  	address types.Address,
   899  ) *interpreter.CompositeValue {
   900  	return interpreter.NewCompositeValue(
   901  		inter,
   902  		locationRange,
   903  		location,
   904  		evmAddressTypeQualifiedIdentifier,
   905  		common.CompositeKindStructure,
   906  		[]interpreter.CompositeField{
   907  			{
   908  				Name:  evmAddressTypeBytesFieldName,
   909  				Value: EVMAddressToAddressBytesArrayValue(inter, address),
   910  			},
   911  		},
   912  		common.ZeroAddress,
   913  	)
   914  }
   915  
   916  const internalEVMTypeRunFunctionName = "run"
   917  
   918  var internalEVMTypeRunFunctionType = &sema.FunctionType{
   919  	Parameters: []sema.Parameter{
   920  		{
   921  			Label:          "tx",
   922  			TypeAnnotation: sema.NewTypeAnnotation(evmTransactionBytesType),
   923  		},
   924  		{
   925  			Label:          "coinbase",
   926  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
   927  		},
   928  	},
   929  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.BoolType),
   930  }
   931  
   932  func newInternalEVMTypeRunFunction(
   933  	gauge common.MemoryGauge,
   934  	handler types.ContractHandler,
   935  ) *interpreter.HostFunctionValue {
   936  	return interpreter.NewHostFunctionValue(
   937  		gauge,
   938  		internalEVMTypeRunFunctionType,
   939  		func(invocation interpreter.Invocation) interpreter.Value {
   940  			inter := invocation.Interpreter
   941  			locationRange := invocation.LocationRange
   942  
   943  			// Get transaction argument
   944  
   945  			transactionValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
   946  			if !ok {
   947  				panic(errors.NewUnreachableError())
   948  			}
   949  
   950  			transaction, err := interpreter.ByteArrayValueToByteSlice(inter, transactionValue, locationRange)
   951  			if err != nil {
   952  				panic(err)
   953  			}
   954  
   955  			// Get coinbase argument
   956  
   957  			coinbaseValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
   958  			if !ok {
   959  				panic(errors.NewUnreachableError())
   960  			}
   961  
   962  			coinbase, err := interpreter.ByteArrayValueToByteSlice(inter, coinbaseValue, locationRange)
   963  			if err != nil {
   964  				panic(err)
   965  			}
   966  
   967  			// Run
   968  
   969  			cb := types.NewAddressFromBytes(coinbase)
   970  			handler.Run(transaction, cb)
   971  
   972  			return interpreter.Void
   973  		},
   974  	)
   975  }
   976  
   977  func EVMAddressToAddressBytesArrayValue(
   978  	inter *interpreter.Interpreter,
   979  	address types.Address,
   980  ) *interpreter.ArrayValue {
   981  	var index int
   982  	return interpreter.NewArrayValueWithIterator(
   983  		inter,
   984  		evmAddressBytesStaticType,
   985  		common.ZeroAddress,
   986  		types.AddressLength,
   987  		func() interpreter.Value {
   988  			if index >= types.AddressLength {
   989  				return nil
   990  			}
   991  			result := interpreter.NewUInt8Value(inter, func() uint8 {
   992  				return address[index]
   993  			})
   994  			index++
   995  			return result
   996  		},
   997  	)
   998  }
   999  
  1000  const internalEVMTypeCallFunctionName = "call"
  1001  
  1002  var internalEVMTypeCallFunctionType = &sema.FunctionType{
  1003  	Parameters: []sema.Parameter{
  1004  		{
  1005  			Label:          "from",
  1006  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1007  		},
  1008  		{
  1009  			Label:          "to",
  1010  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1011  		},
  1012  		{
  1013  			Label:          "data",
  1014  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1015  		},
  1016  		{
  1017  			Label:          "gasLimit",
  1018  			TypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1019  		},
  1020  		{
  1021  			Label:          "value",
  1022  			TypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1023  		},
  1024  	},
  1025  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1026  }
  1027  
  1028  func AddressBytesArrayValueToEVMAddress(
  1029  	inter *interpreter.Interpreter,
  1030  	locationRange interpreter.LocationRange,
  1031  	addressBytesValue *interpreter.ArrayValue,
  1032  ) (
  1033  	result types.Address,
  1034  	err error,
  1035  ) {
  1036  	// Convert
  1037  
  1038  	var bytes []byte
  1039  	bytes, err = interpreter.ByteArrayValueToByteSlice(
  1040  		inter,
  1041  		addressBytesValue,
  1042  		locationRange,
  1043  	)
  1044  	if err != nil {
  1045  		return result, err
  1046  	}
  1047  
  1048  	// Check length
  1049  
  1050  	length := len(bytes)
  1051  	const expectedLength = types.AddressLength
  1052  	if length != expectedLength {
  1053  		return result, errors.NewDefaultUserError(
  1054  			"invalid address length: got %d, expected %d",
  1055  			length,
  1056  			expectedLength,
  1057  		)
  1058  	}
  1059  
  1060  	copy(result[:], bytes)
  1061  
  1062  	return result, nil
  1063  }
  1064  
  1065  func newInternalEVMTypeCallFunction(
  1066  	gauge common.MemoryGauge,
  1067  	handler types.ContractHandler,
  1068  ) *interpreter.HostFunctionValue {
  1069  	return interpreter.NewHostFunctionValue(
  1070  		gauge,
  1071  		internalEVMTypeCallFunctionType,
  1072  		func(invocation interpreter.Invocation) interpreter.Value {
  1073  			inter := invocation.Interpreter
  1074  			locationRange := invocation.LocationRange
  1075  
  1076  			// Get from address
  1077  
  1078  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1079  			if !ok {
  1080  				panic(errors.NewUnreachableError())
  1081  			}
  1082  
  1083  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1084  			if err != nil {
  1085  				panic(err)
  1086  			}
  1087  
  1088  			// Get to address
  1089  
  1090  			toAddressValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1091  			if !ok {
  1092  				panic(errors.NewUnreachableError())
  1093  			}
  1094  
  1095  			toAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, toAddressValue)
  1096  			if err != nil {
  1097  				panic(err)
  1098  			}
  1099  
  1100  			// Get data
  1101  
  1102  			dataValue, ok := invocation.Arguments[2].(*interpreter.ArrayValue)
  1103  			if !ok {
  1104  				panic(errors.NewUnreachableError())
  1105  			}
  1106  
  1107  			data, err := interpreter.ByteArrayValueToByteSlice(inter, dataValue, locationRange)
  1108  			if err != nil {
  1109  				panic(err)
  1110  			}
  1111  
  1112  			// Get gas limit
  1113  
  1114  			gasLimitValue, ok := invocation.Arguments[3].(interpreter.UInt64Value)
  1115  			if !ok {
  1116  				panic(errors.NewUnreachableError())
  1117  			}
  1118  
  1119  			gasLimit := types.GasLimit(gasLimitValue)
  1120  
  1121  			// Get balance
  1122  
  1123  			balanceValue, ok := invocation.Arguments[4].(interpreter.UFix64Value)
  1124  			if !ok {
  1125  				panic(errors.NewUnreachableError())
  1126  			}
  1127  
  1128  			balance := types.Balance(balanceValue)
  1129  
  1130  			// Call
  1131  
  1132  			const isAuthorized = true
  1133  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1134  			result := account.Call(toAddress, data, gasLimit, balance)
  1135  
  1136  			return interpreter.ByteSliceToByteArrayValue(inter, result)
  1137  		},
  1138  	)
  1139  }
  1140  
  1141  const internalEVMTypeCreateBridgedAccountFunctionName = "createBridgedAccount"
  1142  
  1143  var internalEVMTypeCreateBridgedAccountFunctionType = &sema.FunctionType{
  1144  	ReturnTypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1145  }
  1146  
  1147  func newInternalEVMTypeCreateBridgedAccountFunction(
  1148  	gauge common.MemoryGauge,
  1149  	handler types.ContractHandler,
  1150  ) *interpreter.HostFunctionValue {
  1151  	return interpreter.NewHostFunctionValue(
  1152  		gauge,
  1153  		internalEVMTypeCreateBridgedAccountFunctionType,
  1154  		func(invocation interpreter.Invocation) interpreter.Value {
  1155  			inter := invocation.Interpreter
  1156  			address := handler.AllocateAddress()
  1157  			return EVMAddressToAddressBytesArrayValue(inter, address)
  1158  		},
  1159  	)
  1160  }
  1161  
  1162  const internalEVMTypeDepositFunctionName = "deposit"
  1163  
  1164  var internalEVMTypeDepositFunctionType = &sema.FunctionType{
  1165  	Parameters: []sema.Parameter{
  1166  		{
  1167  			Label:          "from",
  1168  			TypeAnnotation: sema.NewTypeAnnotation(sema.AnyResourceType),
  1169  		},
  1170  		{
  1171  			Label:          "to",
  1172  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1173  		},
  1174  	},
  1175  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.VoidType),
  1176  }
  1177  
  1178  const fungibleTokenVaultTypeBalanceFieldName = "balance"
  1179  
  1180  func newInternalEVMTypeDepositFunction(
  1181  	gauge common.MemoryGauge,
  1182  	handler types.ContractHandler,
  1183  ) *interpreter.HostFunctionValue {
  1184  	return interpreter.NewHostFunctionValue(
  1185  		gauge,
  1186  		internalEVMTypeCallFunctionType,
  1187  		func(invocation interpreter.Invocation) interpreter.Value {
  1188  			inter := invocation.Interpreter
  1189  			locationRange := invocation.LocationRange
  1190  
  1191  			// Get from vault
  1192  
  1193  			fromValue, ok := invocation.Arguments[0].(*interpreter.CompositeValue)
  1194  			if !ok {
  1195  				panic(errors.NewUnreachableError())
  1196  			}
  1197  
  1198  			amountValue, ok := fromValue.GetField(
  1199  				inter,
  1200  				locationRange,
  1201  				fungibleTokenVaultTypeBalanceFieldName,
  1202  			).(interpreter.UFix64Value)
  1203  			if !ok {
  1204  				panic(errors.NewUnreachableError())
  1205  			}
  1206  
  1207  			amount := types.Balance(amountValue)
  1208  
  1209  			// Get to address
  1210  
  1211  			toAddressValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1212  			if !ok {
  1213  				panic(errors.NewUnreachableError())
  1214  			}
  1215  
  1216  			toAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, toAddressValue)
  1217  			if err != nil {
  1218  				panic(err)
  1219  			}
  1220  
  1221  			// NOTE: We're intentionally not destroying the vault here,
  1222  			// because the value of it is supposed to be "kept alive".
  1223  			// Destroying would incorrectly be equivalent to a burn and decrease the total supply,
  1224  			// and a withdrawal would then have to perform an actual mint of new tokens.
  1225  
  1226  			// Deposit
  1227  
  1228  			const isAuthorized = false
  1229  			account := handler.AccountByAddress(toAddress, isAuthorized)
  1230  			account.Deposit(types.NewFlowTokenVault(amount))
  1231  
  1232  			return interpreter.Void
  1233  		},
  1234  	)
  1235  }
  1236  
  1237  const internalEVMTypeBalanceFunctionName = "balance"
  1238  
  1239  var internalEVMTypeBalanceFunctionType = &sema.FunctionType{
  1240  	Parameters: []sema.Parameter{
  1241  		{
  1242  			Label:          "address",
  1243  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1244  		},
  1245  	},
  1246  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1247  }
  1248  
  1249  // newInternalEVMTypeBalanceFunction returns the Flow balance of the account
  1250  func newInternalEVMTypeBalanceFunction(
  1251  	gauge common.MemoryGauge,
  1252  	handler types.ContractHandler,
  1253  ) *interpreter.HostFunctionValue {
  1254  	return interpreter.NewHostFunctionValue(
  1255  		gauge,
  1256  		internalEVMTypeCallFunctionType,
  1257  		func(invocation interpreter.Invocation) interpreter.Value {
  1258  			inter := invocation.Interpreter
  1259  			locationRange := invocation.LocationRange
  1260  
  1261  			addressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1262  			if !ok {
  1263  				panic(errors.NewUnreachableError())
  1264  			}
  1265  
  1266  			address, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, addressValue)
  1267  			if err != nil {
  1268  				panic(err)
  1269  			}
  1270  
  1271  			const isAuthorized = false
  1272  			account := handler.AccountByAddress(address, isAuthorized)
  1273  
  1274  			return interpreter.UFix64Value(account.Balance())
  1275  		},
  1276  	)
  1277  }
  1278  
  1279  const internalEVMTypeWithdrawFunctionName = "withdraw"
  1280  
  1281  var internalEVMTypeWithdrawFunctionType = &sema.FunctionType{
  1282  	Parameters: []sema.Parameter{
  1283  		{
  1284  			Label:          "from",
  1285  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1286  		},
  1287  		{
  1288  			Label:          "amount",
  1289  			TypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1290  		},
  1291  	},
  1292  	ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.AnyResourceType),
  1293  }
  1294  
  1295  func newInternalEVMTypeWithdrawFunction(
  1296  	gauge common.MemoryGauge,
  1297  	handler types.ContractHandler,
  1298  ) *interpreter.HostFunctionValue {
  1299  	return interpreter.NewHostFunctionValue(
  1300  		gauge,
  1301  		internalEVMTypeCallFunctionType,
  1302  		func(invocation interpreter.Invocation) interpreter.Value {
  1303  			inter := invocation.Interpreter
  1304  			locationRange := invocation.LocationRange
  1305  
  1306  			// Get from address
  1307  
  1308  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1309  			if !ok {
  1310  				panic(errors.NewUnreachableError())
  1311  			}
  1312  
  1313  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1314  			if err != nil {
  1315  				panic(err)
  1316  			}
  1317  
  1318  			// Get amount
  1319  
  1320  			amountValue, ok := invocation.Arguments[1].(interpreter.UFix64Value)
  1321  			if !ok {
  1322  				panic(errors.NewUnreachableError())
  1323  			}
  1324  
  1325  			amount := types.Balance(amountValue)
  1326  
  1327  			// Withdraw
  1328  
  1329  			const isAuthorized = true
  1330  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1331  			vault := account.Withdraw(amount)
  1332  
  1333  			// TODO: improve: maybe call actual constructor
  1334  			return interpreter.NewCompositeValue(
  1335  				inter,
  1336  				locationRange,
  1337  				common.NewAddressLocation(gauge, handler.FlowTokenAddress(), "FlowToken"),
  1338  				"FlowToken.Vault",
  1339  				common.CompositeKindResource,
  1340  				[]interpreter.CompositeField{
  1341  					{
  1342  						Name: "balance",
  1343  						Value: interpreter.NewUFix64Value(gauge, func() uint64 {
  1344  							return uint64(vault.Balance())
  1345  						}),
  1346  					},
  1347  				},
  1348  				common.ZeroAddress,
  1349  			)
  1350  		},
  1351  	)
  1352  }
  1353  
  1354  const internalEVMTypeDeployFunctionName = "deploy"
  1355  
  1356  var internalEVMTypeDeployFunctionType = &sema.FunctionType{
  1357  	Parameters: []sema.Parameter{
  1358  		{
  1359  			Label:          "from",
  1360  			TypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1361  		},
  1362  		{
  1363  			Label:          "code",
  1364  			TypeAnnotation: sema.NewTypeAnnotation(sema.ByteArrayType),
  1365  		},
  1366  		{
  1367  			Label:          "gasLimit",
  1368  			TypeAnnotation: sema.NewTypeAnnotation(sema.UInt64Type),
  1369  		},
  1370  		{
  1371  			Label:          "value",
  1372  			TypeAnnotation: sema.NewTypeAnnotation(sema.UFix64Type),
  1373  		},
  1374  	},
  1375  	ReturnTypeAnnotation: sema.NewTypeAnnotation(evmAddressBytesType),
  1376  }
  1377  
  1378  func newInternalEVMTypeDeployFunction(
  1379  	gauge common.MemoryGauge,
  1380  	handler types.ContractHandler,
  1381  ) *interpreter.HostFunctionValue {
  1382  	return interpreter.NewHostFunctionValue(
  1383  		gauge,
  1384  		internalEVMTypeCallFunctionType,
  1385  		func(invocation interpreter.Invocation) interpreter.Value {
  1386  			inter := invocation.Interpreter
  1387  			locationRange := invocation.LocationRange
  1388  
  1389  			// Get from address
  1390  
  1391  			fromAddressValue, ok := invocation.Arguments[0].(*interpreter.ArrayValue)
  1392  			if !ok {
  1393  				panic(errors.NewUnreachableError())
  1394  			}
  1395  
  1396  			fromAddress, err := AddressBytesArrayValueToEVMAddress(inter, locationRange, fromAddressValue)
  1397  			if err != nil {
  1398  				panic(err)
  1399  			}
  1400  
  1401  			// Get code
  1402  
  1403  			codeValue, ok := invocation.Arguments[1].(*interpreter.ArrayValue)
  1404  			if !ok {
  1405  				panic(errors.NewUnreachableError())
  1406  			}
  1407  
  1408  			code, err := interpreter.ByteArrayValueToByteSlice(inter, codeValue, locationRange)
  1409  			if err != nil {
  1410  				panic(err)
  1411  			}
  1412  
  1413  			// Get gas limit
  1414  
  1415  			gasLimitValue, ok := invocation.Arguments[2].(interpreter.UInt64Value)
  1416  			if !ok {
  1417  				panic(errors.NewUnreachableError())
  1418  			}
  1419  
  1420  			gasLimit := types.GasLimit(gasLimitValue)
  1421  
  1422  			// Get value
  1423  
  1424  			amountValue, ok := invocation.Arguments[3].(interpreter.UFix64Value)
  1425  			if !ok {
  1426  				panic(errors.NewUnreachableError())
  1427  			}
  1428  
  1429  			amount := types.Balance(amountValue)
  1430  
  1431  			// Deploy
  1432  
  1433  			const isAuthorized = true
  1434  			account := handler.AccountByAddress(fromAddress, isAuthorized)
  1435  			address := account.Deploy(code, gasLimit, amount)
  1436  
  1437  			return EVMAddressToAddressBytesArrayValue(inter, address)
  1438  		},
  1439  	)
  1440  }
  1441  
  1442  func NewInternalEVMContractValue(
  1443  	gauge common.MemoryGauge,
  1444  	handler types.ContractHandler,
  1445  	location common.AddressLocation,
  1446  ) *interpreter.SimpleCompositeValue {
  1447  	return interpreter.NewSimpleCompositeValue(
  1448  		gauge,
  1449  		InternalEVMContractType.ID(),
  1450  		internalEVMContractStaticType,
  1451  		InternalEVMContractType.Fields,
  1452  		map[string]interpreter.Value{
  1453  			internalEVMTypeRunFunctionName:                  newInternalEVMTypeRunFunction(gauge, handler),
  1454  			internalEVMTypeCreateBridgedAccountFunctionName: newInternalEVMTypeCreateBridgedAccountFunction(gauge, handler),
  1455  			internalEVMTypeCallFunctionName:                 newInternalEVMTypeCallFunction(gauge, handler),
  1456  			internalEVMTypeDepositFunctionName:              newInternalEVMTypeDepositFunction(gauge, handler),
  1457  			internalEVMTypeWithdrawFunctionName:             newInternalEVMTypeWithdrawFunction(gauge, handler),
  1458  			internalEVMTypeDeployFunctionName:               newInternalEVMTypeDeployFunction(gauge, handler),
  1459  			internalEVMTypeBalanceFunctionName:              newInternalEVMTypeBalanceFunction(gauge, handler),
  1460  			internalEVMTypeEncodeABIFunctionName:            newInternalEVMTypeEncodeABIFunction(gauge, location),
  1461  			internalEVMTypeDecodeABIFunctionName:            newInternalEVMTypeDecodeABIFunction(gauge, location),
  1462  		},
  1463  		nil,
  1464  		nil,
  1465  		nil,
  1466  	)
  1467  }
  1468  
  1469  const InternalEVMContractName = "InternalEVM"
  1470  
  1471  var InternalEVMContractType = func() *sema.CompositeType {
  1472  	ty := &sema.CompositeType{
  1473  		Identifier: InternalEVMContractName,
  1474  		Kind:       common.CompositeKindContract,
  1475  	}
  1476  
  1477  	ty.Members = sema.MembersAsMap([]*sema.Member{
  1478  		sema.NewUnmeteredPublicFunctionMember(
  1479  			ty,
  1480  			internalEVMTypeRunFunctionName,
  1481  			internalEVMTypeRunFunctionType,
  1482  			"",
  1483  		),
  1484  		sema.NewUnmeteredPublicFunctionMember(
  1485  			ty,
  1486  			internalEVMTypeCreateBridgedAccountFunctionName,
  1487  			internalEVMTypeCreateBridgedAccountFunctionType,
  1488  			"",
  1489  		),
  1490  		sema.NewUnmeteredPublicFunctionMember(
  1491  			ty,
  1492  			internalEVMTypeCallFunctionName,
  1493  			internalEVMTypeCallFunctionType,
  1494  			"",
  1495  		),
  1496  		sema.NewUnmeteredPublicFunctionMember(
  1497  			ty,
  1498  			internalEVMTypeDepositFunctionName,
  1499  			internalEVMTypeDepositFunctionType,
  1500  			"",
  1501  		),
  1502  		sema.NewUnmeteredPublicFunctionMember(
  1503  			ty,
  1504  			internalEVMTypeWithdrawFunctionName,
  1505  			internalEVMTypeWithdrawFunctionType,
  1506  			"",
  1507  		),
  1508  		sema.NewUnmeteredPublicFunctionMember(
  1509  			ty,
  1510  			internalEVMTypeDeployFunctionName,
  1511  			internalEVMTypeDeployFunctionType,
  1512  			"",
  1513  		),
  1514  		sema.NewUnmeteredPublicFunctionMember(
  1515  			ty,
  1516  			internalEVMTypeBalanceFunctionName,
  1517  			internalEVMTypeBalanceFunctionType,
  1518  			"",
  1519  		),
  1520  		sema.NewUnmeteredPublicFunctionMember(
  1521  			ty,
  1522  			internalEVMTypeEncodeABIFunctionName,
  1523  			internalEVMTypeEncodeABIFunctionType,
  1524  			"",
  1525  		),
  1526  		sema.NewUnmeteredPublicFunctionMember(
  1527  			ty,
  1528  			internalEVMTypeDecodeABIFunctionName,
  1529  			internalEVMTypeDecodeABIFunctionType,
  1530  			"",
  1531  		),
  1532  	})
  1533  	return ty
  1534  }()
  1535  
  1536  var internalEVMContractStaticType = interpreter.ConvertSemaCompositeTypeToStaticCompositeType(
  1537  	nil,
  1538  	InternalEVMContractType,
  1539  )
  1540  
  1541  func newInternalEVMStandardLibraryValue(
  1542  	gauge common.MemoryGauge,
  1543  	handler types.ContractHandler,
  1544  	location common.AddressLocation,
  1545  ) stdlib.StandardLibraryValue {
  1546  	return stdlib.StandardLibraryValue{
  1547  		Name:  InternalEVMContractName,
  1548  		Type:  InternalEVMContractType,
  1549  		Value: NewInternalEVMContractValue(gauge, handler, location),
  1550  		Kind:  common.DeclarationKindContract,
  1551  	}
  1552  }
  1553  
  1554  var internalEVMStandardLibraryType = stdlib.StandardLibraryType{
  1555  	Name: InternalEVMContractName,
  1556  	Type: InternalEVMContractType,
  1557  	Kind: common.DeclarationKindContract,
  1558  }
  1559  
  1560  func SetupEnvironment(env runtime.Environment, handler types.ContractHandler, service flow.Address) {
  1561  	location := common.NewAddressLocation(nil, common.Address(service), ContractName)
  1562  
  1563  	env.DeclareType(
  1564  		internalEVMStandardLibraryType,
  1565  		location,
  1566  	)
  1567  	env.DeclareValue(
  1568  		newInternalEVMStandardLibraryValue(nil, handler, location),
  1569  		location,
  1570  	)
  1571  }
  1572  
  1573  func NewEVMAddressCadenceType(address common.Address) *cadence.StructType {
  1574  	return cadence.NewStructType(
  1575  		common.NewAddressLocation(nil, address, ContractName),
  1576  		evmAddressTypeQualifiedIdentifier,
  1577  		[]cadence.Field{
  1578  			{
  1579  				Identifier: "bytes",
  1580  				Type:       EVMAddressBytesCadenceType,
  1581  			},
  1582  		},
  1583  		nil,
  1584  	)
  1585  }
  1586  
  1587  func NewBalanceCadenceType(address common.Address) *cadence.StructType {
  1588  	return cadence.NewStructType(
  1589  		common.NewAddressLocation(nil, address, ContractName),
  1590  		"EVM.Balance",
  1591  		[]cadence.Field{
  1592  			{
  1593  				Identifier: "flow",
  1594  				Type:       cadence.UFix64Type{},
  1595  			},
  1596  		},
  1597  		nil,
  1598  	)
  1599  }