Skip to content

在Moonbeam上使用Substrate API Sidecar

Substrate API Sidecar

概览

Substrate API Sidecar允许应用程序通过REST API访问基于Substrate区块链的区块、账户余额和其他信息。这对于需要在Moonbeam网络上持续追踪账户余额和其他状态更新的交易所、钱包或其他类型的应用程序非常有用。本文将介绍如何为Moonbeam安装和运行Substrate API Sidecar,以及常用API端点。

安装和运行Substrate API Sidecar

有多种方式可以安装和运行Substrate API Sidecar。本教程将介绍通过NPM在本地安装和运行Substrate API Sidecar。通过Docker运行或从源代码构建和运行Substrate API Sidecar,请参考Substrate API Sidecar Github Repository

查看先决条件

通过NPM在本地运行此服务需要先安装node.js。

本教程操作需安装Node.js(我们将使用v15.x)和「npm package manager」。您可通过Node.js下载或自行运行以下代码完成安装

curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -

sudo apt install -y nodejs
# You can use homebrew (https://docs.brew.sh/Installation)
brew install node

# Or you can use nvm (https://github.com/nvm-sh/nvm)
nvm install node

您可以通过请求每个安装包的版本来验证是否安装正确:

node -v
npm -v

安装Substrate API Sidecar

在当前目录下本地安装Substrate API Sidecar服务,请在命令行运行以下命令:

npm install @substrate/api-sidecar@11.3.9

注意事项

如果当前目录还没有Node.js项目结构,则需要先执行mkdir node_modules,手动创建node_modules目录。

Substrate API Sidecar v11.3.9是当前经过测试过可与Moonbeam网络共同使用的稳定版本。您可以通过在安装的根目录运行以下命令来验证是否成功安装:

node_modules/.bin/substrate-api-sidecar --version

设置Substrate API Sidecar

在Sidecar将运行的终端中,导出网络WS端点的环境变量,例如:

export SAS_SUBSTRATE_WS_URL=wss://wss.api.moonbeam.network
export SAS_SUBSTRATE_WS_URL=wss://wss.api.moonriver.moonbeam.network
export SAS_SUBSTRATE_WS_URL=wss://wss.api.moonbase.moonbeam.network
export SAS_SUBSTRATE_WS_URL=ws://127.0.0.1:9944

请参考公共端点页面获取Moonbeam网络端点完整列表。

设置环境变量后,您可以使用echo命令,运行以下命令检查环境变量是否正确设置:

echo $SAS_SUBSTRATE_WS_URL

这将显示您设置的网络端点。

运行Substrate API Sidecar

根据设置的网络端点环境变量,在安装的根目录运行以下命令:

node_modules/.bin/substrate-api-sidecar 

如果安装和配置成功后,您应该在后台看到以下输出:

Successful Output

Substrate API Sidecar端点

常用的Substrate API Sidecar端点包括:

  • GET /blocks/head —— 获取最近确定的区块。可选参数finalized可设置为false以获取最新已知区块(该区块可能尚未被最终确定)
  • GET /blocks/head/header —— 获取最近确定的区块头。可选参数finalized可设置为false以获取最新已知区块头(该区块头可能尚未被最终确定)
  • GET /blocks/{blockId} —— 通过区块的高度或哈希获取该区块
  • GET /accounts/{accountId}/balance-info —— 获取账户的余额信息
  • GET /node/version —— 获取关于Substrates节点实现和版本控制的信息
  • GET /runtime/metadata —— 以解码的JSON格式获取runtime元数据

请参考官方资料库获取Substrate API Sidecar上的可用API端点列表。

区块JSON对象中的EVM字段映射

Substrate API Sidecar将Moonbeam区块作为JSON对象返回。与Moonbeam交易的EVM执行相关信息位于extrinsics顶级字段下,其中个人extrinsics以数字方式组织为嵌套的JSON对象。嵌套结构如下所示:

RESPONSE JSON Block Object:
    |--extrinsics
        |--{extrinsic number}
            |--method
                |--pallet: "ethereum"
                |--method: "transact"
            |--signature:
            |--nonce: 
            |--args
                |--transaction
                    |--{transaction type}
            |--hash
            |--events
                |--{event number}
                    |--method
                        |--pallet: "ethereum"
                        |--method: "Executed"
                    |--data
                        |--0
                        |--1
                        |--2
                        |--3
    ...

Moonbeam EVM交易可以通过在当前extrinsic对象下的method字段进行验证,method字段可设置为:

{extrinsic number}.method.pallet = "ethereum"
{extrinsic number}.method.method = "transact"

交易类型和负载

Moonbeam EVM目前支持3种交易标准:legacyeip1559eip2930。这些对应上述JSON对象示意图中的transaction type字段。每个交易类型的交易负载包含以下字段:

    ...
    |--eip1559
        |--chainId
        |--nonce
        |--maxPriorityFeePerGas
        |--maxFeePerGas
        |--gasLimit
        |--action
        |--value
        |--input
        |--accessList
        |--oddYParity
        |--r
        |--s      
    ...
    ...
    |--legacy
        |--nonce
        |--gasPrice
        |--gasLimit
        |--action
        |--value
        |--input
        |--signature       
    ...
    ...
    |--eip2930
        |--chainId
        |--nonce
        |--gasPrice
        |--gasLimit
        |--action
        |--value
        |--input
        |--accessList 
        |--oddYParity
        |--r
        |--s      
    ...

想要获取关于新的EIP1559EIP2930交易类型更多信息,及其每个字段的含义,请参考各自的官方以太坊提案。

交易字段映射

要获取EVM发送方地址、接收方地址,以及任何EVM交易类型的EVM哈希,检查在当前extrinsic对象下的events字段并验证method字段已设置为:

{event number}.method.pallet: "ethereum"
{event number}.method.method: "Executed" 

然后将EVM字段映射总结为如下所示:

EVM Field Block JSON Field
Chain ID extrinsics.{extrinsic number}.args.transaction.eip1559.chainId
Nonce extrinsics.{extrinsic number}.args.transaction.eip1559.nonce
Max Priority Fee Per Gas extrinsics.{extrinsic number}.args.transaction.eip1559.maxPriorityFeePerGas
Max Fee Per Gas extrinsics.{extrinsic number}.args.transaction.eip1559.maxFeePerGas
Gas Limit extrinsics.{extrinsic number}.args.transaction.eip1559.gasLimit
Access List extrinsics.{extrinsic number}.args.transaction.eip1559.accessList
Signature extrinsics.{extrinsic number}.args.transaction.eip1559.oddYParity/r/s
Sender Address extrinsics.{extrinsic number}.events.{event number}.data.0
Recipient Address extrinsics.{extrinsic number}.events.{event number}.data.1
EVM Hash extrinsics.{extrinsic number}.events.{event number}.data.2
EVM Execution Status extrinsics.{extrinsic number}.events.{event number}.data.3
EVM Field Block JSON Field
Nonce extrinsics.{extrinsic number}.args.transaction.legacy.nonce
Gas Price extrinsics.{extrinsic number}.args.transaction.legacy.gasPrice
Gas Limit extrinsics.{extrinsic number}.args.transaction.legacy.gasLimit
Value extrinsics.{extrinsic number}.args.transaction.legacy.value
Signature extrinsics.{extrinsic number}.args.transaction.legacy.signature
Sender Address extrinsics.{extrinsic number}.events.{event number}.data.0
Recipient Address extrinsics.{extrinsic number}.events.{event number}.data.1
EVM Hash extrinsics.{extrinsic number}.events.{event number}.data.2
EVM Execution Status extrinsics.{extrinsic number}.events.{event number}.data.3
EVM Field Block JSON Field
Chain ID extrinsics.{extrinsic number}.args.transaction.eip2930.chainId
Nonce extrinsics.{extrinsic number}.args.transaction.eip2930.nonce
GasPrice extrinsics.{extrinsic number}.args.transaction.eip2930.gasPrice
GasLimit extrinsics.{extrinsic number}.args.transaction.eip2930.gasLimit
Value extrinsics.{extrinsic number}.args.transaction.eip2930.value
Access List extrinsics.{extrinsic number}.args.transaction.eip2930.accessList
Signature extrinsics.{extrinsic number}.args.transaction.eip2930.oddYParity/r/s
Sender Address extrinsics.{extrinsic number}.events.{event number}.data.0
Recipient Address extrinsics.{extrinsic number}.events.{event number}.data.1
EVM Hash extrinsics.{extrinsic number}.events.{event number}.data.2
EVM Execution Status extrinsics.{extrinsic number}.events.{event number}.data.3

注意事项

EVM交易号和签名字段位于extrinsics.{extrinsic number}.args.transaction.{transaction type},而extrinsics.{extrinsic number}下的noncesignature字段是Substrate交易号和签名,需为EVM交易设置为null

成功执行的EVM交易将在"EVM Execution Status"字段下返回succeed: "Stopped"succeed: "Returned"

ERC-20代币转账

智能合约(例如部署在Moonbeam上的ERC-20合约)发出的事件可以从Sidecar区块的JSON对象中解码。它的嵌套结构如下:

RESPONSE JSON Block Object:
    |--extrinsics
        |--{extrinsic number}
            |--method
                |--pallet: "ethereum"
                |--method: "transact"
            |--signature:
            |--nonce: 
            |--args
                |--transaction
                    |--{transaction type}
            |--hash
            |--events
                |--{event number}
                    |--method
                        |--pallet: "evm"
                        |--method: "Log"
                    |--data
                        |--0
                            |-- address
                            |-- topics
                                |--0
                                |--1
                                |--2
                            |-- data
            ...
    ...

Moonbeam ERC-20代币转账所发出的Transfer事件,可解码如下:

交易信息 对应JSON字段
ERC-20合约地址 extrinsics.{extrinsic number}.events.{event number}.data.0.address
事件签名哈希 extrinsics.{extrinsic number}.events.{event number}.data.0.topics.0
发送人地址 extrinsics.{extrinsic number}.events.{event number}.data.0.topics.1
接纳人地址 extrinsics.{extrinsic number}.events.{event number}.data.0.topics.2
数额 extrinsics.{extrinsic number}.events.{event number}.data.0.data

EVM智能合约发出的其他事件也可以以类似的方式进行解码,但事件主题和JSON字段的内容将根据事件的定义而改变。

注意事项

转账金额以Wei和十六进制格式给出。

计算Gas花费

要计算EVM交易执行期间的Gas花费或费用,可使用以下计算公式:

Gas Used =(Base Fee + Max Priority Fee Per Gas) * Transaction Weight / 25000
Gas Used = Gas Price * Transaction Weight / 25000
Gas Used = Gas Price * Transaction Weight / 25000

适用交易类型的Gas PriceMax Priority Fee Per Gas数值可以根据上述表格从区块中读取。

EIP 1559引入的Base Fee由网络自身决定。EIP1559类型交易的Base Fee目前在Moonbeam网络上为固定值,如下所示:

变量
Base Fee 100 Gwei
变量
Base Fee 1 Gwei
变量
Base Fee 1 Gwei

Transaction Weight是一种Substrate机制,用于管理验证区块所需的时间。对于所有的交易类型,Transaction Weight可以通过在相关extrinsic事件下的method进行如下设置以检索获得:

pallet: "system", method: "ExtrinsicSuccess" 

随后,Transaction Weight将映射至区块JSON对象的以下字段:

extrinsics.{extrinsic number}.events.{event number}.data.0.weight