1. 前言
前面我们使用cleos
完成过转账的功能,这篇文章我们尝试使用RPC API的方式进行转账。在测试网络/主网络转账EOS,在测试网络转账代币。
官方文档:https://github.com/EOSBlock/EOS-Tutorials/blob/master/EN/transfer-tokens-using-RPC.md
2. 大致流程
使用RPC API转账的流程如下:
abi_json_to_bin
将转账信息由json
格式序列化为bin
格式字符串get_info
获取当前最新的区块编号get_block
根据区块编号获取区块详情get_required_keys
(可省略) 传入当前拥有的公钥、bin
字符串,区块等信息,筛选出签署交易需要的公钥sign_transaction
传入上面获取的相关参数,通过钱包中私钥对交易进行签署push_transaction
根据第五步获取的签名信息,将交易提交到区块链上
3. 详细流程
3.1 在测试网络转账EOS
3.1.1 查看余额
先查看两个交易账号的EOS余额:
api
http://jungle.cryptolions.io:18888/v1/chain/get_currency_balance
params
{"code":"eosio.token", "account":"testnetyy111", "symbol":"eos"}
{"code":"eosio.token", "account":"testneths111", "symbol":"eos"}
return
testnetyy111
[
"9641.6587 EOS"
]
testneths111
[
"0.0000 EOS"
]
3.1.2 将交易信息由JSON格式序列化为BIN格式字符串
从testnetyy111
转100
EOS给testneths111
:
api
http://jungle.cryptolions.io:18888/v1/chain/abi_json_to_bin
params
{"code":"eosio.token","action":"transfer","args":{"from":"testnetyy111","to":"testneths111","quantity":"100.0000 EOS", "memo":"hi there"}}
return
{
"binargs": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
}
获取到binargs
3.1.3 获取当前最新的区块编号
api
http://jungle.cryptolions.io:18888/v1/chain/get_info
params
无
return
{
"server_version": "cc9decff",
"chain_id": "038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca",
"head_block_num": 13800828,
"last_irreversible_block_num": 13800496,
"last_irreversible_block_id": "00d29430d9809c633ddf3cc5c01613b58105394502e9846515c87274765c6d05",
"head_block_id": "00d2957ccb42d63c2d643c0a1b0b98da69c462b94a62ed434a0e565035bab90b",
"head_block_time": "2018-09-11T05:39:10.000",
"head_block_producer": "lioninjungle",
"virtual_block_cpu_limit": 200000000,
"virtual_block_net_limit": 1048576000,
"block_cpu_limit": 199900,
"block_net_limit": 1048576,
"server_version_string": "v1.2.4-dirty"
}
获取到head_block_num
3.1.4 根据区块编号获取区块详情
api
http://jungle.cryptolions.io:18888/v1/chain/get_block
params
{"block_num_or_id":"13800828"}
return
{
"timestamp": "2018-09-11T05:39:10.000",
"producer": "lioninjungle",
"confirmed": 0,
"previous": "00d2957b0e343f2ffa7640591ac1f27ed0ac89d2869e0a9c0576f065a31ee1cc",
"transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000",
"action_mroot": "22546c1e4c12d53a55c60d0ccb7196baa0afb05993612d2cf0591d7bf8fd8d34",
"schedule_version": 219,
"new_producers": null,
"header_extensions": [],
"producer_signature": "SIG_K1_KXFvmHtXMnDhp8V7CpHuGoYch3whWorL2Fr7nArevzTmC2tXsKRXHCkHiF9myRpbbx3cTShba64jWveKATr49k3Bonp7aw",
"transactions": [],
"block_extensions": [],
"id": "00d2957ccb42d63c2d643c0a1b0b98da69c462b94a62ed434a0e565035bab90b",
"block_num": 13800828,
"ref_block_prefix": 171729965
}
获取到timestamp
和ref_block_prefix
3.1.5 筛选出签署交易需要的公钥
钱包中可能有很多公钥存在,调用此方法可以筛选出完成此次交易需要的公钥。如果已明确应该使用的公钥,那可以省略
此方法。
首先调用API打开并解锁钱包,然后获取所有的公钥。这部分内容在EOS开发(八)RPC API都有使用介绍。
参数说明:
available_keys
钱包中的公钥account
合约名称。这里是转账EOS,使用的是eosio.token
actor
调用者。这里相当于转账方permission
使用的权限类型data
之前生成的bin
字符串name
调用的合约方法。这里调用的是转账方法transfer
expiration
过期时间。这里将timestamp
加上了20分钟。可以根据需要来增加时长ref_block_num
前面获取的最新区块号ref_block_prefix
前面获取的ref_block_prefix
api
http://jungle.cryptolions.io:18888/v1/chain/get_required_keys
params
{
"available_keys": [
"EOS6cnhSLTn4eSUEqS4nC8frYTsVsjeH2M3hos1TUeCgme2Yim5Q5",
"EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc",
"EOS7RkP6aevKjN1CiKSqo44Gi1HhPYBczGFgSduBXBD7uHUFhg2qC",
"EOS7sGb8DfutGgpuMmnDhG1d2stVETfpkrHQ6HhVRJJaPXRqLay2E"
],
"transaction": {
"actions": [
{
"account": "eosio.token",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265",
"name": "transfer"
}
],
"context_free_actions": [
],
"context_free_data": [
],
"delay_sec": 0,
"expiration": "2018-09-11T05:59:10.000",
"max_kcpu_usage": 0,
"max_net_usage_words": 0,
"ref_block_num": 13800828,
"ref_block_prefix": 171729965,
"signatures": [
]
}
}
return
{
"required_keys": [
"EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc"
]
}
获取到实际需要的公钥EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc
3.1.6 签署交易
参数说明:
ref_block_num
前面获取的最新区块号ref_block_prefix
前面获取的ref_block_prefix
expiration
过期时间。这里将timestamp
加上了20分钟。可以根据需要来增加时长account
合约名称。这里是转账EOS,使用的是eosio.token
name
调用的合约方法。这里调用的是转账方法transfer
actor
调用者。这里相当于转账方permission
使用的权限类型data
之前生成的bin
字符串EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc
签署此交易的公钥。实际上是由钱包中对应的私钥来签038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca
链id。注明当前处于主网/测试网/私有网络。这里显示的为测试网络
api
http://127.0.0.1:8888/v1/wallet/sign_transaction
params
[{
"ref_block_num": 13800828,
"ref_block_prefix": 171729965,
"expiration": "2018-09-11T05:59:10.000",
"actions": [{
"account": "eosio.token",
"name": "transfer",
"authorization": [{
"actor": "testnetyy111",
"permission": "active"
}],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
}],
"signatures": []
},
["EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc"], "038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca"
]
return
{
"expiration": "2018-09-11T05:59:10",
"ref_block_num": 38268,
"ref_block_prefix": 171729965,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [
{
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_K9eDsXiqEMkJs8wPwEjiN6hL1h2Bm3gGQtUheidFczWNdBmDF24AUuPmiosi9CwtEW3jPFPao7HYWLJ63ic3TggjnoKtJF"
],
"context_free_data": []
}
获取到signatures
3.1.7 提交交易
参数说明:
expiration
过期时间。这里将timestamp
加上了20分钟。可以根据需要来增加时长ref_block_num
前面获取的最新区块号ref_block_prefix
前面获取的ref_block_prefix
account
合约名称。这里是转账EOS,使用的是eosio.token
name
调用的合约方法。这里调用的是转账方法transfer
actor
调用者。这里相当于转账方permission
使用的权限类型data
之前生成的bin
字符串signatures
签署交易后生成的签名字符串
api
http://jungle.cryptolions.io:18888/v1/chain/push_transaction
params
{
"compression": "none",
"transaction": {
"expiration": "2018-09-11T05:59:10.000",
"ref_block_num": 13800828,
"ref_block_prefix": 171729965,
"context_free_actions": [],
"actions": [
{
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
}
],
"transaction_extensions": []
},
"signatures": [
"SIG_K1_K9eDsXiqEMkJs8wPwEjiN6hL1h2Bm3gGQtUheidFczWNdBmDF24AUuPmiosi9CwtEW3jPFPao7HYWLJ63ic3TggjnoKtJF"
]
}
return
{
"transaction_id": "4efb2687ef59c9a677da68264eb409d71aca66d7e3df4b35ee34f59e13783ffc",
"processed": {
"id": "4efb2687ef59c9a677da68264eb409d71aca66d7e3df4b35ee34f59e13783ffc",
"receipt": {
"status": "executed",
"cpu_usage_us": 1537,
"net_usage_words": 17
},
"elapsed": 1537,
"net_usage": 136,
"scheduled": false,
"action_traces": [
{
"receipt": {
"receiver": "eosio.token",
"act_digest": "45d232c72b5ca003627bc411ff9881286fd411239ceac528b98e6fb33a50919e",
"global_sequence": 32142292,
"recv_sequence": 1716642,
"auth_sequence": [
[
"testnetyy111",
37
]
],
"code_sequence": 3,
"abi_sequence": 3
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": {
"from": "testnetyy111",
"to": "testneths111",
"quantity": "100.0000 EOS",
"memo": "hi there"
},
"hex_data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
},
"elapsed": 942,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "4efb2687ef59c9a677da68264eb409d71aca66d7e3df4b35ee34f59e13783ffc",
"inline_traces": [
{
"receipt": {
"receiver": "testnetyy111",
"act_digest": "45d232c72b5ca003627bc411ff9881286fd411239ceac528b98e6fb33a50919e",
"global_sequence": 32142293,
"recv_sequence": 16,
"auth_sequence": [
[
"testnetyy111",
38
]
],
"code_sequence": 3,
"abi_sequence": 3
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": {
"from": "testnetyy111",
"to": "testneths111",
"quantity": "100.0000 EOS",
"memo": "hi there"
},
"hex_data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
},
"elapsed": 100,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "4efb2687ef59c9a677da68264eb409d71aca66d7e3df4b35ee34f59e13783ffc",
"inline_traces": []
},
{
"receipt": {
"receiver": "testneths111",
"act_digest": "45d232c72b5ca003627bc411ff9881286fd411239ceac528b98e6fb33a50919e",
"global_sequence": 32142294,
"recv_sequence": 7,
"auth_sequence": [
[
"testnetyy111",
39
]
],
"code_sequence": 3,
"abi_sequence": 3
},
"act": {
"account": "eosio.token",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": {
"from": "testnetyy111",
"to": "testneths111",
"quantity": "100.0000 EOS",
"memo": "hi there"
},
"hex_data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004454f5300000000086869207468657265"
},
"elapsed": 23,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "4efb2687ef59c9a677da68264eb409d71aca66d7e3df4b35ee34f59e13783ffc",
"inline_traces": []
}
]
}
],
"except": null
}
}
3.1.8 查询转账完成后的余额
testnetyy111 "9541.6587 EOS"
testneths111 "100.0000 EOS"
3.2 在测试网络转账代币
3.2.1 先查询余额
api
http://jungle.cryptolions.io:18888/v1/chain/get_currency_balance
params
{"code":"testnetyy111", "account":"testnetyy111", "symbol":"ray"}
{"code":"testnetyy111", "account":"testneths111", "symbol":"ray"}
return
testnetyy111
[
"99999800.0000 RAY"
]
testneths111
[
"200.0000 RAY"
]
3.2.2 将交易信息由JSON格式序列化为BIN格式字符串
从testnetyy111
转100
RAY给testneths111
:
api
http://jungle.cryptolions.io:18888/v1/chain/abi_json_to_bin
params
{"code":"testnetyy111","action":"transfer","args":{"from":"testnetyy111","to":"testneths111","quantity":"100.0000 RAY", "memo":"hello there"}}
return
{
"binargs": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
}
3.2.3 获取当前最新的区块编号
api
http://jungle.cryptolions.io:18888/v1/chain/get_info
params
无
return
{
"server_version": "cc9decff",
"chain_id": "038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca",
"head_block_num": 13807658,
"last_irreversible_block_num": 13807329,
"last_irreversible_block_id": "00d2aee1e209a3a21f0c1bf3a9b3b79322c27cb48353d9e28f17286b0daaa58b",
"head_block_id": "00d2b02afdedb3e0f487026946a7a56be8f331aecebb8b04faff03cf566a0fb6",
"head_block_time": "2018-09-11T06:36:50.000",
"head_block_producer": "astraealions",
"virtual_block_cpu_limit": 200000000,
"virtual_block_net_limit": 1048576000,
"block_cpu_limit": 199900,
"block_net_limit": 1048576,
"server_version_string": "v1.2.4-dirty"
}
3.2.4 根据区块编号获取区块详情
api
http://jungle.cryptolions.io:18888/v1/chain/get_block
params
{"block_num_or_id":"13807658"}
return
{
"timestamp": "2018-09-11T06:36:50.000",
"producer": "astraealions",
"confirmed": 0,
"previous": "00d2b029ac9a6eb269c6ea4f8bb3f2961d948f1f0ca3cd0cc4640ceadc95d37b",
"transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000",
"action_mroot": "0b1b4f510e0cdd272052fe0f3f9b1e74c7c6f83253409d943c3394eefbb7762e",
"schedule_version": 219,
"new_producers": null,
"header_extensions": [],
"producer_signature": "SIG_K1_KZZ4giS7WxbSt3i6rcdZqgBWGzpE9XXq8A88kkSDDt9s8MbB2Vs1VEdMDoGYAeqTVUqX25xszU2cBwfHkbEvooPnZSm5FR",
"transactions": [],
"block_extensions": [],
"id": "00d2b02afdedb3e0f487026946a7a56be8f331aecebb8b04faff03cf566a0fb6",
"block_num": 13807658,
"ref_block_prefix": 1761773556
}
3.2.5 筛选出签署交易需要的公钥
这里省略这一步了,因为我们明确知道需要的公钥为EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc
3.2.6 签署交易
这里的参数
account
变为testnetyy111
,因为其是代币合约
api
http://127.0.0.1:8888/v1/wallet/sign_transaction
params
[{
"ref_block_num": 13807658,
"ref_block_prefix": 1761773556,
"expiration": "2018-09-11T06:56:50.000",
"actions": [{
"account": "testnetyy111",
"name": "transfer",
"authorization": [{
"actor": "testnetyy111",
"permission": "active"
}],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
}],
"signatures": []
},
["EOS6Z7mUQeFC2cQTT3xMyZh2wsLQoHih1bTMgRhr3dbichprTi7Rc"], "038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca"
]
return
{
"expiration": "2018-09-11T06:56:50",
"ref_block_num": 45098,
"ref_block_prefix": 1761773556,
"max_net_usage_words": 0,
"max_cpu_usage_ms": 0,
"delay_sec": 0,
"context_free_actions": [],
"actions": [
{
"account": "testnetyy111",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
}
],
"transaction_extensions": [],
"signatures": [
"SIG_K1_KXFAydwhD6u74pxQcTakiGCjtSuUw9PBsFb7ETxh1ULqjFkXqfyaoL34TkEmZi7iBTgUQZqUJRcVYYkrLWZxbVybRUArNX"
],
"context_free_data": []
}
3.2.7 提交交易
api
http://jungle.cryptolions.io:18888/v1/chain/push_transaction
params
{
"compression": "none",
"transaction": {
"expiration": "2018-09-11T06:56:50.000",
"ref_block_num": 13807658,
"ref_block_prefix": 1761773556,
"context_free_actions": [],
"actions": [
{
"account": "testnetyy111",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
}
],
"transaction_extensions": []
},
"signatures": [
"SIG_K1_KXFAydwhD6u74pxQcTakiGCjtSuUw9PBsFb7ETxh1ULqjFkXqfyaoL34TkEmZi7iBTgUQZqUJRcVYYkrLWZxbVybRUArNX"
]
}
return
{
"transaction_id": "27c120548fee4e0ca31bc779ba85eb61ea4a2c5204043b696800d6cdb11da48b",
"processed": {
"id": "27c120548fee4e0ca31bc779ba85eb61ea4a2c5204043b696800d6cdb11da48b",
"receipt": {
"status": "executed",
"cpu_usage_us": 1176,
"net_usage_words": 17
},
"elapsed": 1176,
"net_usage": 136,
"scheduled": false,
"action_traces": [
{
"receipt": {
"receiver": "testnetyy111",
"act_digest": "28d41460e20878bc412281b80c4d46ce174a4a48e8c7caf9ef28a13383e72d9e",
"global_sequence": 32149270,
"recv_sequence": 17,
"auth_sequence": [
[
"testnetyy111",
40
]
],
"code_sequence": 1,
"abi_sequence": 1
},
"act": {
"account": "testnetyy111",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": {
"from": "testnetyy111",
"to": "testneths111",
"quantity": "100.0000 RAY",
"memo": "hello there"
},
"hex_data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
},
"elapsed": 782,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "27c120548fee4e0ca31bc779ba85eb61ea4a2c5204043b696800d6cdb11da48b",
"inline_traces": [
{
"receipt": {
"receiver": "testneths111",
"act_digest": "28d41460e20878bc412281b80c4d46ce174a4a48e8c7caf9ef28a13383e72d9e",
"global_sequence": 32149271,
"recv_sequence": 8,
"auth_sequence": [
[
"testnetyy111",
41
]
],
"code_sequence": 1,
"abi_sequence": 1
},
"act": {
"account": "testnetyy111",
"name": "transfer",
"authorization": [
{
"actor": "testnetyy111",
"permission": "active"
}
],
"data": {
"from": "testnetyy111",
"to": "testneths111",
"quantity": "100.0000 RAY",
"memo": "hello there"
},
"hex_data": "1042f03eab99b1ca1042c02dab99b1ca40420f000000000004524159000000000b68656c6c6f207468657265"
},
"elapsed": 14,
"cpu_usage": 0,
"console": "",
"total_cpu_usage": 0,
"trx_id": "27c120548fee4e0ca31bc779ba85eb61ea4a2c5204043b696800d6cdb11da48b",
"inline_traces": []
}
]
}
],
"except": null
}
}
3.2.8 查询转账完成后的余额
testnetyy111 "99999700.0000 RAY"
testneths111 "300.0000 RAY"
3.3 在主网络转账EOS和代币
在主网和测试网络转账基本一样,需要注意节点地址,以及账户名称的差异。我已经试过是可用的,这里就不再演示了。