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