访问 EVM 帐户

⚠️ Update Notice:

Please read Substrate to Polkadot SDK page first.


本教程说明了如何使用来自Frontier项目的crates来构建与以太坊兼容的区块链,该区块链可以访问基于以太坊的帐户并执行基于 Solidity 的智能合约。Frontier 项目的两个主要目标是使您能够执行以下操作:

  • 使用本地 Substrate 节点无修改地运行以太坊去中心化应用程序。
  • 从以太坊主网导入状态。

本教程使用预定义的节点模板来提供工作环境。 该模板是使用Frontier 发行指南中的说明生成的。

如果您想自己生成独立模板,则可以使用solo-template-node-release.sh模板生成脚本。 如果您使用frontier存储库或模板生成脚本构建自己的节点,请注意 Frontier 使用其自身的 Substrate crates版本,您可能需要更新Cargo文件中的依赖项以匹配项目中的依赖项。

开始之前

在尝试本教程之前,您应该已完成以下 Substrate 教程:

从这些教程中,您应该熟悉如何执行以下任务:

  • 启动 Substrate 区块链节点。
  • 在运行时添加、删除和配置模块。
  • 通过使用 Polkadot-JS 或其他前端连接到节点来提交事务。

在开始本教程之前,您还应该熟悉以下内容:

  • 以太坊核心概念和术语
  • 以太坊虚拟机 (EVM) 基础知识
  • 去中心化应用程序和智能合约
  • 模块设计原则

创世配置

frontier-solo-template-node中的开发链规范定义了一个创世块,该块已预先配置了alice帐户的 EVM 帐户。 当您以开发模式启动此节点时,alice的 EVM 帐户将获得默认数量的以太币。 您将使用此帐户来查看 EVM 帐户详细信息并调用以太坊智能合约。 启动节点后,您将能够使用Polkadot-JS 应用程序查看alice的 EVM 帐户的详细信息。

编译 Frontier 节点

Frontier 节点模板提供了一个可工作的开发环境,以便您可以立即开始在 Substrate 上构建。

要编译 Frontier 节点模板:

  1. 在您的计算机上打开终端 shell。
  2. 通过运行以下命令克隆节点模板存储库:

    git clone https://github.com/substrate-developer-hub/frontier-solo-template-node.git
  3. 通过运行以下命令更改到节点模板目录的根目录:

    cd frontier-solo-template-node
  4. 通过运行以下命令编译节点模板:

    cargo build --release

连接到节点

节点编译完成后,您必须启动节点才能开始浏览预配置的 EVM 帐户。

要启动本地 Substrate 节点:

  1. 根据需要在本地计算机上打开终端 shell。
  2. 更改到您编译frontier-solo-template-node的根目录。
  3. 通过运行以下命令以开发模式启动节点:

    ./target/release/frontier-template-node --dev

    --dev命令行选项指定节点使用预定义的development链规范运行,该规范包括alice的预定义 EVM 帐户以及其他用于测试的帐户。

  4. 通过查看终端中显示的输出,验证您的节点是否已成功启动并运行。

    终端应显示类似于此的输出:

    2022-07-08 10:06:42 Frontier Node
    2022-07-08 10:06:42 ✌️  version 0.0.0-1b6bff4-x86_64-macos
    2022-07-08 10:06:42 ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2021-2022
    2022-07-08 10:06:42 📋 Chain specification: Development
    2022-07-08 10:06:42 🏷  Node name: flippant-boat-0444
    2022-07-08 10:06:42 👤 Role: AUTHORITY
    ...
  5. 使用Polkadot-JS 应用程序连接到本地节点。
  6. 点击设置,然后点击开发者

    开发者设置
  7. 定义以下帐户信息以创建 EVM Account类型并使帐户能够发送事务和检查区块。

    要发送事务,您必须定义AddressLookupSource设置。
    要检查区块,您必须定义TransactionSignature设置。

    {
      "Address": "MultiAddress",
      "LookupSource": "MultiAddress",
      "Account": {
         "nonce": "U256",
         "balance": "U256"
      },
      "Transaction": {
         "nonce": "U256",
         "action": "String",
         "gas_price": "u64",
         "gas_limit": "u64",
         "value": "U256",
         "input": "Vec<u8>",
         "signature": "Signature"
      },
      "Signature": {
         "v": "u64",
         "r": "H256",
         "s": "H256"
      }
    }
  8. 点击保存

使用 RPC 查询余额

配置 EVM 帐户的设置后,您可以使用 Polkadot-JS 应用程序查看有关alice的 EVM 帐户的信息。

  1. 验证您的节点是否仍在运行,并且Polkadot-JS 应用程序已连接到节点。
  2. 点击开发者,然后选择RPC 调用
  3. 提交选项卡上,选择eth作为要调用的端点。
  4. 从要调用的函数列表中选择getBalance(address, number)
  5. 为地址指定alice帐户的 EVM 帐户标识符。

    预定义的帐户地址为0xd43593c715fdd31c61141abd04a99fd6822c8558。 帐户的地址是使用Substrate EVM 实用程序根据alice帐户的公钥计算得出的。

  6. 点击提交 RPC 调用

    该调用应返回类似于以下内容的输出:

    2: eth.getBalance: U256
    340,282,366,920,938,463,463,374,607,431,768,210,955

部署智能合约

现在您已经了解了如何查询以太坊地址的余额,您可能希望探索如何部署和调用以太坊智能合约以及测试相关功能。 本教程使用Truffle示例合约,该合约定义了一个ERC-20 代币。您还可以使用 Polkadot JS SDK 和Typescript创建 ERC-20 代币合约。

  1. 创建 ERC-20 合约。

    为方便起见,您可以使用MyToken.json中代币合约的已编译bytecode来在 Substrate 区块链上部署合约。

  2. 验证您的节点是否仍在运行,并且Polkadot-JS 应用程序已连接到节点。
  3. 点击开发者,然后选择外部函数
  4. 选择ALICE开发帐户作为用于提交交易的帐户。
  5. 选择evm
  6. 选择create函数。
  7. 配置函数的参数。

    此处指定此内容
    source0xd43593c715fdd31c61141abd04a99fd6822c8558
    init来自MyToken.json的原始bytecode十六进制值
    value0
    gasLimit4294967295
    maxFeePerGas100000000

    您可以将可选参数留空。 nonce的值将递增源帐户的已知 nonce,从0x0开始。 根据您选择的函数,您可能需要删除未使用的参数。

  8. 点击提交事务
  9. 点击签名并提交以授权交易。

查看智能合约

提交交易后,合约将在网络上部署,您可以使用Polkadot-JS 应用程序查看有关它的信息。

  1. 验证您的节点是否仍在运行,并且Polkadot-JS 应用程序已连接到节点。
  2. 点击网络,然后选择资源管理器
  3. 点击evm.Created事件以验证新创建的合约的地址是否为0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f

    成功创建合约事件

    您还可以使用浏览器开发者工具中的控制台查看有关交易的详细信息。

    由于 EVM 合约地址由合约创建者的帐户标识符和 nonce 确定,因此部署合约的地址是使用众所周知的帐户标识符0xd43593c715fdd31c61141abd04a99fd6822c8558alice帐户的 nonce 0x0计算得出的。

  4. 点击开发者,然后选择链状态
  5. 选择evm作为要查询的状态和accountCodes
  6. alice帐户指定帐户标识符0xd43593c715fdd31c61141abd04a99fd6822c8558,并注意帐户代码为空(0x)。
  7. 为您使用alice开发帐户部署的合约指定合约地址0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f,并注意合约帐户代码是来自 Solidity 合约的字节码。

查看帐户存储

您部署的 ERC-20 合约基于OpenZeppelin ERC-20 实现。 此合约包含一个构造函数,该构造函数会铸造最大数量的代币并将它们存储在与合约创建者关联的帐户中。

要查询与智能合约关联的帐户存储:

  1. 在链状态中,将evm作为要查询的状态,选择accountStorages
  2. 将 ERC-20 合约地址0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f指定为第一个参数。
  3. 将要读取的存储槽指定为第二个参数0x045c0350b9cf0df39c4b40400c965118df2dca5ce0fbcf0de4aafc099aea4a14

    地址的存储槽是使用Substrate EVM 实用程序根据槽 0 和帐户标识符0xd43593c715fdd31c61141abd04a99fd6822c8558计算得出的。

    返回的值应为0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

    如果您在部署合约后检查alice帐户的余额,您会看到已从帐户中提取费用,并且getBalance(address, number)调用返回类似于以下内容的值:

    340,282,366,920,938,463,463,374,603,530,233,757,803

转移代币

到目前为止,您只使用了alice开发帐户。 下一步是使用已部署的合约将代币转移到另一个帐户。

  1. 验证您的节点是否仍在运行,并且Polkadot-JS 应用程序已连接到节点。
  2. 点击开发者,然后选择外部函数
  3. 选择ALICE开发帐户作为用于提交交易的帐户。
  4. 选择evm
  5. 选择call以在 ERC-20 合约上调用transfer(address, uint256)函数。
  6. 配置函数的参数。

    此处指定此内容
    source0xd43593c715fdd31c61141abd04a99fd6822c8558
    target0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f
    input0xa9059cbb0000000000000000000000008eaf04151687736326c9fea17e25fc528761369300000000000000000000000000000000000000000000000000000000000000dd
    value0
    gasLimit4294967295
    maxFeePerGas100000000

    source代表持有代币的帐户。 在本例中,sourcealice的 EVM 帐户,即合约创建者。 target是用于从alicebob转移代币的合约地址。

    input参数是一个 EVM ABI 编码的函数调用,该调用指定要执行的函数调用(0xa9059cbb)以及函数所需的参数。 对于此函数,参数是bobEVM 帐户标识符(0x8eaf04151687736326c9fea17e25fc5287613693)和要转移的代币数量(221 或十六进制中的0xdd)。

    本教程中的输入值是使用Remix web IDE计算得出的。

  7. 点击提交事务
  8. 点击签名并提交以授权交易。

验证代币转移

提交交易后,您可以使用Polkadot-JS 应用程序验证代币转移。

  1. 验证您的节点是否仍在运行,并且Polkadot-JS 应用程序已连接到节点。
  2. 点击网络,然后选择资源管理器
  3. 点击evm.Executed事件以验证已执行合约的地址是否为0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f

    成功执行事件
  4. 点击开发者,然后选择链状态
  5. 选择evm作为要查询的状态和accountStorages
  6. 检查合约地址0x8a50db1e0f9452cfd91be8dc004ceb11cb08832f和存储槽0x045c0350b9cf0df39c4b40400c965118df2dca5ce0fbcf0de4aafc099aea4a14的存储。

    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff22

    如果您在部署合约后检查alice帐户的余额,您会看到已从帐户中提取费用,并且getBalance(address, number)调用返回类似于以下内容的值:

    340,282,366,920,938,463,463,374,603,530,233,366,411

下一步