使用RPC接口与EOS智能合约交互。
示例代码依赖于eosio.token系统合约。
运行示例代码
1、启动节点服务
在1#终端启动nodeos,建议启动前先清除历史数据:
~$ rm -rf ~/.local/share/eosio/nodeos/data
~$ nodeos
或者使用方便脚本:
~$ clean-nodeos.sh
在2#终端启动keosd:
~$ keosd
2、初始化钱包和账户
在3#终端执行以下脚本初始化默认钱包,然后创建3个账号:
~$ init-wallet.sh
~$ new-account.sh eosio.token
~$ new-account.sh tommy
~$ new-account.sh jerry
3、部署代币合约并发行代币
在3#终端执行以下脚本部署系统代币合约:
~$ deply-contract.sh eosio.token ~/eos/build/contracts/eosio.token
系统代币合约部署成功后,执行以下脚本注册总量100万个HAPY代币,并向tommy发行100个:
~$ new-token.sh
4、使用rpc调用转账
tommy向jerry转账2个HAPY代币。
在3#终端进入~/repo/chapter6,然后执行以下脚本:
~$ cd ~/repo/chapter6
~/repo/chapter6$ ./rpc-transfer.sh
5、使用eosjs转账
tommy向jerry转账2个HAPY代币。
在3#终端运行transfer.js:
~/repo/chapter6$ node transfer.js
6、在eosjs中使用keosd签名交易
tommy向jerry转账2个HAPY代币。
在3#终端运行transfer-with-keosd.js:
~/repo/chapter6$ node transfer-with-keosd.js
文件目录组织
- rpc-transfer.sh:使用curl通过rpc调用实现代币转账
-
#!/bin/bash API_BASE=http://127.0.0.1:8888/v1 WALLET_BASE=http://127.0.0.1:8900/v1 TOOLS_HOME=$HOME/repo/tools PUBLIC_KEY=`cat $TOOLS_HOME/artifacts/tommy/activePublicKey` WALLET_PASS=`cat $TOOLS_HOME/artifacts/defaultWalletPassword` serialize(){ payload='{ "code":"eosio.token", "action":"transfer", "args":{ "from":"tommy", "to":"jerry", "quantity":"2.00 HAPY", "memo":"take care" } }' API=chain/abi_json_to_bin echo $(curl $API_BASE/$API -X POST -s -d "$payload" | jq ".binargs") #curl $API_BASE/$API -X POST -s -d "$payload" } get_info(){ API=chain/get_info curl $API_BASE/$API -X POST -s| jq ".head_block_num,.chain_id" } get_block_info(){ payload='{"block_num_or_id":'$1'}' API=chain/get_block curl $API_BASE/$API -X POST -s -d "$payload" | jq ".block_num,.ref_block_prefix,.timestamp" } unlock_wallet(){ payload='["default","'$WALLET_PASS'"]' echo $payload API=wallet/unlock curl $WALLET_BASE/$API -X POST -s -d "$payload" | jq } # params: ref_block_num,ref_block_prefix,timestamp,data sign_transaction(){ payload='[ { "ref_block_num": '$1', "ref_block_prefix": '$2', "expiration": '$3', "actions": [ { "account": "eosio.token", "name": "transfer", "authorization": [{ "actor": "tommy", "permission": "active" }], "data": '$4' } ], "signatures": [] }, ["'$PUBLIC_KEY'"], '$5' ]' API=wallet/sign_transaction curl $WALLET_BASE/$API -X POST -s -d "$payload" | jq ".signatures[0]" } show_table(){ payload='{ "code": "eosio.token", "scope": "tommy", "table": "accounts", "json": "true" }' API=chain/get_table_rows curl $API_BASE/$API -X POST -s -d "$payload" | jq } #params: r push_transaction(){ payload='{ "compression": "none", "transaction": { "expiration": '$3', "ref_block_num": '$1', "ref_block_prefix": '$2', "context_free_actions": [], "actions": [ { "account": "eosio.token", "name": "transfer", "authorization": [ { "actor": "tommy", "permission": "active" } ], "data": '$4' } ], "transaction_extensions": [] }, "signatures": ['$5'] }' API=chain/push_transaction curl $API_BASE/$API -X POST -s -d "$payload" | jq ".transaction_id" } txdata=$(serialize) info=($(get_info)) head_block_num=${info[0]} chain_id=${info[1]} block_info=($(get_block_info $head_block_num)) expired=\"`date -d next-hour "+%Y-%m-%dT%H:%M:%S.999"`\" signature=`sign_transaction ${block_info[0]} ${block_info[1]} ${expired} $txdata ${chain_id}` push_transaction ${block_info[0]} ${block_info[1]} ${expired} $txdata $signature show_table
- transfer.js:使用eosjs进行代币转账
-
const Eos = require('eosjs') const fs = require('fs') prvkey = fs.readFileSync('/home/user/repo/tools/artifacts/tommy/activePrivateKey','utf-8').trim() const config = { httpEndpoint: 'http://localhost:8888', keyProvider: [prvkey] } const nodeos = Eos(config) nodeos.contract("eosio.token") .then(contract => contract.transfer("tommy","jerry","2.00 HAPY",{authorization:["tommy"]})) .then(rsp => console.log(rsp.transaction_id)) .then(() => nodeos.getTableRows(true,"eosio.token","tommy","accounts")) .then(rsp => console.log(rsp)) .catch(err => console.log(err))
- transfer-with-keosd.js:在eosjs中使用keosd进行交易签名的代币转账
-
const Eos = require('eosjs') const fs = require('fs') const ecc = require('eosjs-ecc') const WalletApi = require('./WalletApi') const pubkey = fs.readFileSync('/home/user/repo/tools/artifacts/tommy/activePublicKey','utf-8').trim() const chain_id = 'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f' const keosd = WalletApi({ httpEndpoint: 'http://localhost:8900' }) const keosdSigner = function({transaction}){ const data = [ transaction, [pubkey], chain_id ] return keosd.signTransaction(data) .then(ret => ret.signatures[0]) } const config = { httpEndpoint: 'http://localhost:8888', signProvider: keosdSigner } const nodeos = Eos(config) nodeos.contract("eosio.token") .then(contract => contract.transfer("tommy","jerry","2.00 HAPY",{authorization:["tommy"]})) .then(rsp => console.log(rsp.transaction_id)) .then(() => nodeos.getTableRows(true,"eosio.token","tommy","accounts")) .then(rsp => console.log(rsp)) .catch(err => console.log(err))
- WalletApi.js:keosd的RPC API封装
const apiGen = require('eosjs-api/lib/apigen')
const processArgs = require('eosjs-api/lib/process-args')
const api = {
"wallet": {
"list_wallets": {
"params": null,
"results": "string[]"
},
"sign_transaction":{
"params": "array",
"results": "signed_transaction"
}
}
}
const WalletApi = function(config) {
return apiGen('v1', api, config)
}
Object.assign(
WalletApi,
{
processArgs,
api
}
)
module.exports = WalletApi