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 }