使用 RPC 接口新建 EOS 账户
其实这个问题我很早之前就折腾过一遍,只是当时没有做记录,导致现在要用的时候有部分细节记不清楚了,然后现在又重新调试了一次,赶紧记录下来。
废话不多说,直接上实战代码。
首先启动 EOS node,我的 EOS 钱包节点是搭建在 Docker 容器中的,所以我直接通过容器启动,至于如何安装 EOS 钱包节点,请参考我的另一篇博客 EOS 本地开发环境搭建.
# 启动 EOS 容器
docker start eosio
# 启动容器的节点脚本
docker exec -d eosio /run.sh
这里我提一句,我在容器的根目录新建了一个 run.sh 脚本,里面写了启动节点和 ssh-server 服务的脚本
#!/bin/bash
# start ssh-server
/etc/init.d/ssh start
# start EOS node
/root/bin/eos_node_start.sh
eos_node_start.sh 就是 EOS 节点的启动脚本,内容如下:
nodeos -e -p eosio \
--plugin eosio::wallet_api_plugin \
--plugin eosio::wallet_plugin \
--plugin eosio::producer_plugin \
--plugin eosio::history_plugin \
--plugin eosio::chain_api_plugin \
--plugin eosio::history_api_plugin \
--plugin eosio::http_plugin \
-d /data/data \
--config-dir /data/config \
--http-server-address=0.0.0.0:8888 \
--access-control-allow-origin=* --contracts-console
注意:部分参数比如 -d --config-dir 这些参数可能要根据自己的实际情况配置。
好了节点启动好了,我们先使用 curl 测试一下节点是否正常工作:
curl http://127.0.0.1:8888/v1/chain/get_info
得到类似下面的返回,则说明正常
{
"server_version": "ade08c5d",
"chain_id": "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f",
"head_block_num": 50660,
"last_irreversible_block_num": 50659,
"last_irreversible_block_id": "0000c5e39c788cfd805b2400b3b1be0092b8e05f88a90fe42f7b1b7d41eb8db5",
"head_block_id": "0000c5e4a6c55bde666135b175647ead9b65d0b93dca3fc3bce45333065be89c",
"head_block_time": "2018-10-24T10:02:14",
"head_block_producer": "eosio",
"virtual_block_cpu_limit": 200000000,
"virtual_block_net_limit": 1048576000,
"block_cpu_limit": 199900,
"block_net_limit": 1048576
}
接下来我们进入正题,开始实战测试,首先我们需要一个发送 RPC 请求的工具,你可以直接 CURL, 我这里用的是 postman,为什么选它,因为它好用,方便。
# 1. 生成交易二进制代码
请求接口: POST http://127.0.0.1:8888/v1/chain/abi_json_to_bin
请求参数示例:
{
"code": "eosio",
"action": "newaccount",
"args": {
"creator": "eosio",
"name": "ppblock",
"owner": {
"threshold": 1,
"keys": [
{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
},
"active": {
"threshold": 1,
"keys": [
{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
}
}
}
这里有几个参数需要解释一下:
再解释参数之前,先声明一下,EOS 系统中几乎所有的操作都是通过智能合约来完成的,所以你会看到大部分 RPC 接口都有要传入 code, action, args 等这些参数。 其实这些都是智能合约的参数,后面我就不一一介绍了。
参数名称 | 参数说明 |
---|---|
code | 智能合约的名称 |
action | 调用智能合约方法的名称 |
args | 智能合约参数 |
args.creator | 账户的创建者(EOS 创建账户是通过合约调用实现的,而合约调用需要抵押CPU和内存等资源,所以必须指定合约调用人) |
args.name | 新创建的账户名称 |
key | 创建账户的公钥,使用哪个公钥创建账户 |
返回示例:
{
"binargs": "0000000000ea305500000000221a4fad01000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf0100000001000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf01000000"
}
# 2. 获取最新区块号
请求接口:GET http://127.0.0.1:8888/v1/chain/get_info
请求参数: 无
返回报文:
{
"server_version": "ade08c5d",
"chain_id": "cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f",
"head_block_num": 50660,
"last_irreversible_block_num": 50659,
"last_irreversible_block_id": "0000c5e39c788cfd805b2400b3b1be0092b8e05f88a90fe42f7b1b7d41eb8db5",
"head_block_id": "0000c5e4a6c55bde666135b175647ead9b65d0b93dca3fc3bce45333065be89c",
"head_block_time": "2018-10-24T10:02:14",
"head_block_producer": "eosio",
"virtual_block_cpu_limit": 200000000,
"virtual_block_net_limit": 1048576000,
"block_cpu_limit": 199900,
"block_net_limit": 1048576
}
部分返回参数解读:
参数名称 | 参数说明 |
---|---|
server_version | 钱包客户端的版本号 |
chain_id | 网络 ID,我这个本地测试网络,EOS 主网 ID 是: aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906 |
head_block_num | 最新区块号 |
head_block_producer | 出块帐号 |
# 3. 获取最新区块的具体信息
请求接口:POST http://127.0.0.1:8888/v1/chain/get_block
请求参数示例:
{
"block_num_or_id":50174
}
这里的 block_num_or_id 就是上面返回的最新区块号 head_block_num
返回报文:
{
"timestamp": "2018-10-24T09:58:11.000",
"producer": "eosio",
"confirmed": 0,
"previous": "0000c3fda119172e5a5ee1a77340220edf65b7d9afc78abaf89dd6e30f5ab7d2",
"transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000",
"action_mroot": "0202b72cff370d0468ed248783f6fa3c190972d971a1c393e15b27bdf115ed5a",
"schedule_version": 0,
"new_producers": null,
"header_extensions": [],
"producer_signature": "SIG_K1_KBH5MjttdatGy6DADxbedo2Zge8sNeYAYgUZBFFxF1Hx5fKMDWBXBzaZreWS3KQf4GUrUcLE4f29e1yf94ZTNJhKruTpJY",
"transactions": [],
"block_extensions": [],
"id": "0000c3fe106753e86c440c4a07c166a6cdb9f46a9f49957b102162e6d3a7172a",
"block_num": 50174,
"ref_block_prefix": 1242317932
}
这一步是为了获取 ref_block_prefix, 后面签名的时候需要用到
# 4. 解锁钱包
如果你的钱包已经解锁了,这一步可以跳过,请求接口:POST http://127.0.0.1:8888/v1/wallet/unlock
请求参数示例:
["default","PW5J6V6g3jR8NdeNrzPg9PP87z4hWiCEbb8qx2xLqnRFrNhfhZGKx"]
这里只有两个参数,第一个是钱包名称,第二个是钱包密码,如果解锁成功会返回空
{}
5、签名交易,生成交易签名
请求参数示例:
[
{ "ref_block_num": 50174,
"ref_block_prefix": 1242317932,
"expiration": "2018-10-24T10:08:14",
"actions": [
{
"account": "eosio",
"name": "newaccount",
"authorization": [
{
"actor": "eosio",
"permission": "active"
}
],
"data": "0000000000ea305500000000221a4fad01000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf0100000001000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf01000000"
}
],
"signatures": []
},
[
"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"
],
"cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f"
]
部分请求参数解析:
参数名称 | 参数类型 | 参数说明 |
---|---|---|
ref_block_num | number | get_block获得的最新区块号 |
ref_block_prefix | number | get_block获得的最新区块号相关信息 |
expiration | string | 签名过期时间,这个可以把第 3 步的 timestamp 加上 一段时间 ,例如1分钟。 |
account | string | 调用系统智能合约账号名,这里为 eosio |
name | string | 智能合约的方法, 这里为 newaccount |
authorization.actor | string | 执行操作的用户名 |
authorization.permission | string | 执行操作的权限 |
data | string | abi_json_to_bin 序列化后的 值 binargs |
EOS6MR... | string | 创建者的公钥 |
cf057... | string | get_info 获得的网络 ID,这个非常重要,网上很多教程里面都漏掉这个了,会导致后面发送交易的时候报签名错误 |
返回报文:
{
"expiration": "2018-10-24T10:08:14",
"ref_block_num": 50174,
"ref_block_prefix": 1242317932,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [
{
"account": "eosio",
"name": "newaccount",
"authorization": [
{
"actor": "eosio",
"permission": "active"
}
],
"data": "0000000000ea305500000000221a4fad01000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf0100000001000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf01000000"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_K73PhYL44Jg6FVqbrAUnknGyxveNU1ZpazjG2Swdf8qVmxJJpcVYTA6WibzfZbFXUm2cZuFFxGTECbBvkA2bXs7ZGUWodn"
],
"context_free_data": []
}
这一步我们主要是要获取签名(signatures 字段里面的内容)
6、发送交易,执行智能合约,创建账户
请求接口:POST http://127.0.0.1:8888/v1/chain/push_transaction
请求参数示例:
{
"compression": "none",
"transaction": {
"ref_block_num": 50174,
"ref_block_prefix": 1242317932,
"expiration": "2018-10-24T10:08:14",
"actions": [
{
"account": "eosio",
"name": "newaccount",
"authorization": [
{
"actor": "eosio",
"permission": "active"
}
],
"data": "0000000000ea305500000000221a4fad01000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf0100000001000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf01000000"
}
]
},
"signatures": ["SIG_K1_K73PhYL44Jg6FVqbrAUnknGyxveNU1ZpazjG2Swdf8qVmxJJpcVYTA6WibzfZbFXUm2cZuFFxGTECbBvkA2bXs7ZGUWodn"]
}
发送交易请求的参数几乎跟签名的请求参数一样,就多了一个签名字段(signatures)
如果执行成功,就会返回以下类似报文:
{
"transaction_id": "0400904fbdd29b949b6404a4d6a9fca78b05c9ff72aecd5f2ec5599c306b14b1",
"processed": {
"id": "0400904fbdd29b949b6404a4d6a9fca78b05c9ff72aecd5f2ec5599c306b14b1",
"receipt": {
"status": "executed",
"cpu_usage_us": 8956,
"net_usage_words": 25
},
"elapsed": 8956,
"net_usage": 200,
"scheduled": false,
"action_traces": [
{
"receipt": {
"receiver": "eosio",
"act_digest": "b52aed28f45c698133e0ea781b05aa03317c2cfdf4594232124a5f378c3c36e1",
"global_sequence": 50982,
"recv_sequence": 50982,
"auth_sequence": [
[
"eosio",
50982
]
],
"code_sequence": 0,
"abi_sequence": 0
},
"act": {
"account": "eosio",
"name": "newaccount",
"authorization": [
{
"actor": "eosio",
"permission": "active"
}
],
"data": {
"creator": "eosio",
"name": "ppblock",
"owner": {
"threshold": 1,
"keys": [
{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
},
"active": {
"threshold": 1,
"keys": [
{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
}
},
"hex_data": "0000000000ea305500000000221a4fad01000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf0100000001000000010002c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cf01000000"
},
"elapsed": 53,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "0400904fbdd29b949b6404a4d6a9fca78b05c9ff72aecd5f2ec5599c306b14b1",
"inline_traces": []
}
],
"except": null
}
}
返回的报文参数比较多,包括各种交易 hash,区块hash 等。
下面我们来测试一下看看账号是否创建成功,进入 Docker 容器,使用下面命令查看我们创建的账号
cleos get accounts EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
输出信息:
{
"account_names": [
"ppblock",
"xiaoyang333"
]
}
返回两个账号,其中就有我们刚刚新创建的 ppblock
再查看一下详细信息
cleos get account ppblock --json
输出信息:
{
"account_name": "ppblock",
"privileged": false,
"last_code_update": "1970-01-01T00:00:00.000",
"created": "2018-10-24T10:04:54.000",
"ram_quota": -1,
"net_weight": -1,
"cpu_weight": -1,
"net_limit": {
"used": -1,
"available": -1,
"max": -1
},
"cpu_limit": {
"used": -1,
"available": -1,
"max": -1
},
"ram_usage": 2724,
"permissions": [{
"perm_name": "active",
"parent": "owner",
"required_auth": {
"threshold": 1,
"keys": [{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
}
},{
"perm_name": "owner",
"parent": "",
"required_auth": {
"threshold": 1,
"keys": [{
"key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV",
"weight": 1
}
],
"accounts": [],
"waits": []
}
}
],
"total_resources": null,
"self_delegated_bandwidth": null,
"voter_info": null
}
至此,我们已经成功的使用 RPC 接口创建了 EOS 帐号。
本站博文如非注明转载则均属作者原创文章,引用或转载无需申请版权或者注明出处,如需联系作者请加微信: geekmaster01