github.com/onflow/flow-go@v0.33.17/fvm/evm/stdlib/contract.cdc (about)

     1  import "FlowToken"
     2  
     3  access(all)
     4  contract EVM {
     5  
     6      /// EVMAddress is an EVM-compatible address
     7      access(all)
     8      struct EVMAddress {
     9  
    10          /// Bytes of the address
    11          access(all)
    12          let bytes: [UInt8; 20]
    13  
    14          /// Constructs a new EVM address from the given byte representation
    15          init(bytes: [UInt8; 20]) {
    16              self.bytes = bytes
    17          }
    18  
    19          /// Deposits the given vault into the EVM account with the given address
    20          access(all)
    21          fun deposit(from: @FlowToken.Vault) {
    22              InternalEVM.deposit(
    23                  from: <-from,
    24                  to: self.bytes
    25              )
    26          }
    27  
    28          /// Balance of the address
    29          access(all)
    30          fun balance(): Balance {
    31              let balance = InternalEVM.balance(
    32                  address: self.bytes
    33              )
    34  
    35              return Balance(flow: balance)
    36          }
    37      }
    38  
    39      access(all)
    40      struct Balance {
    41  
    42          /// The balance in FLOW
    43          access(all)
    44          let flow: UFix64
    45  
    46          /// Constructs a new balance, given the balance in FLOW
    47          init(flow: UFix64) {
    48              self.flow = flow
    49          }
    50  
    51          // TODO:
    52          // /// Returns the balance in terms of atto-FLOW.
    53          // /// Atto-FLOW is the smallest denomination of FLOW inside EVM
    54          // access(all)
    55          // fun toAttoFlow(): UInt64
    56      }
    57  
    58      access(all)
    59      resource BridgedAccount {
    60  
    61          access(self)
    62          let addressBytes: [UInt8; 20]
    63  
    64          init(addressBytes: [UInt8; 20]) {
    65             self.addressBytes = addressBytes
    66          }
    67  
    68          /// The EVM address of the bridged account
    69          access(all)
    70          fun address(): EVMAddress {
    71              // Always create a new EVMAddress instance
    72              return EVMAddress(bytes: self.addressBytes)
    73          }
    74  
    75          /// Get balance of the bridged account
    76          access(all)
    77          fun balance(): Balance {
    78              return self.address().balance()
    79          }
    80  
    81          /// Deposits the given vault into the bridged account's balance
    82          access(all)
    83          fun deposit(from: @FlowToken.Vault) {
    84              self.address().deposit(from: <-from)
    85          }
    86  
    87          /// Withdraws the balance from the bridged account's balance
    88          access(all)
    89          fun withdraw(balance: Balance): @FlowToken.Vault {
    90              let vault <- InternalEVM.withdraw(
    91                  from: self.addressBytes,
    92                  amount: balance.flow
    93              ) as! @FlowToken.Vault
    94              return <-vault
    95          }
    96  
    97          /// Deploys a contract to the EVM environment.
    98          /// Returns the address of the newly deployed contract
    99          access(all)
   100          fun deploy(
   101              code: [UInt8],
   102              gasLimit: UInt64,
   103              value: Balance
   104          ): EVMAddress {
   105              let addressBytes = InternalEVM.deploy(
   106                  from: self.addressBytes,
   107                  code: code,
   108                  gasLimit: gasLimit,
   109                  value: value.flow
   110              )
   111              return EVMAddress(bytes: addressBytes)
   112          }
   113  
   114          /// Calls a function with the given data.
   115          /// The execution is limited by the given amount of gas
   116          access(all)
   117          fun call(
   118              to: EVMAddress,
   119              data: [UInt8],
   120              gasLimit: UInt64,
   121              value: Balance
   122          ): [UInt8] {
   123               return InternalEVM.call(
   124                   from: self.addressBytes,
   125                   to: to.bytes,
   126                   data: data,
   127                   gasLimit: gasLimit,
   128                   value: value.flow
   129              )
   130          }
   131      }
   132  
   133      /// Creates a new bridged account
   134      access(all)
   135      fun createBridgedAccount(): @BridgedAccount {
   136          return <-create BridgedAccount(
   137              addressBytes: InternalEVM.createBridgedAccount()
   138          )
   139      }
   140  
   141      /// Runs an a RLP-encoded EVM transaction, deducts the gas fees,
   142      /// and deposits the gas fees into the provided coinbase address.
   143      ///
   144      /// Returns true if the transaction was successful,
   145      /// and returns false otherwise
   146      access(all)
   147      fun run(tx: [UInt8], coinbase: EVMAddress) {
   148          InternalEVM.run(tx: tx, coinbase: coinbase.bytes)
   149      }
   150  
   151      access(all)
   152      fun encodeABI(_ values: [AnyStruct]): [UInt8] {
   153          return InternalEVM.encodeABI(values)
   154      }
   155  
   156      access(all)
   157      fun decodeABI(types: [Type], data: [UInt8]): [AnyStruct] {
   158          return InternalEVM.decodeABI(types: types, data: data)
   159      }
   160  
   161      access(all)
   162      fun encodeABIWithSignature(
   163          _ signature: String,
   164          _ values: [AnyStruct]
   165      ): [UInt8] {
   166          let methodID = HashAlgorithm.KECCAK_256.hash(
   167              signature.utf8
   168          ).slice(from: 0, upTo: 4)
   169          let arguments = InternalEVM.encodeABI(values)
   170  
   171          return methodID.concat(arguments)
   172      }
   173  
   174      access(all)
   175      fun decodeABIWithSignature(
   176          _ signature: String,
   177          types: [Type],
   178          data: [UInt8]
   179      ): [AnyStruct] {
   180          let methodID = HashAlgorithm.KECCAK_256.hash(
   181              signature.utf8
   182          ).slice(from: 0, upTo: 4)
   183  
   184          for byte in methodID {
   185              if byte != data.removeFirst() {
   186                  panic("signature mismatch")
   187              }
   188          }
   189  
   190          return InternalEVM.decodeABI(types: types, data: data)
   191      }
   192  }