EOS 系统级智能合约 - eosio.token
本文介绍了 EOS 的系统级智能合约 eosio.token,主要是编译、部署、交互等方面。源代码层面的注释请参考本人相关的源代码专栏。
本文参考了官网上的示例 Deploy, Issue and Transfer Tokens。
Step 1. 获取合约源代码
$ cd ~/bitbucket/zblockchain/eoscodes/contracts
git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch
cd eosio.contracts/eosio.token
Step 2: 创建测试账户
必须先创建相应的账户,才能部署合约 eosio.token。这里我们使用与账户 eosio 相同的密钥创建账户 eosio.token。
$ cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
Step 3: 编译合约
$ eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen
Step 4: 部署合约
采用相对路径部署
$ cd ~/bitbucket/zblockchain/eoscodes/contracts/eosio.contracts
$ cleos set contract eosio.token eosio.token --abi eosio.token.abi -p eosio.token@active
当然也可以采用绝对路径部署。
$ cleos set contract eosio.token ~/bitbucket/zblockchain/eoscodes/contracts/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active
执行上述命令,产生如下输出
Reading WASM from ...
Publishing contract...
executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us
# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f...
# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61...
warning: transaction executed locally, but may not be confirmed by the network yet ]
Step 5: 创建代币
执行下面的命令创建一个新的代币 SYS。
$ cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active
其中:
- eosio.token 为代币合约
- create 为合约中的 action 名称,用于创建代币
- 参数 "eosio" 为新创建代币的创建者,拥有此代币的所有控制权限,包括 issue 等。
- 参数 "1000000000.0000" SYS 为代币符号,同时指定了最大代币数量。
- -p eosio.token@active 是对代币合约 eosio.token 交易的授权
上述命令执行结果如下
executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles
# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"}
下面的命令和上面的一样,只是采用了命名参数,而非位置参数。
$ cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active
Step 6: 释放代币
代币释放者可以释放代币到任意指定账户,比如之前创建的账户 "alice"。
$ cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active
注意,这里的授权是 eosio@active 而非 eosio.token@active。这是因为这里的授权是对代币 "4 SYS" 进行的,而代币 "4 SYS" 的释放者是 eosio。
执行上述命令,输出如下
executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles
# eosio.token <= eosio.token::issue {"to":"alice","quantity":"100.0000 SYS","memo":"memo"}
>> issue
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"alice","quantity":"100.0000 SYS","memo":"memo"}
>> transfer
# eosio <= eosio.token::transfer {"from":"eosio","to":"alice","quantity":"100.0000 SYS","memo":"memo"}
# alice <= eosio.token::transfer {"from":"eosio","to":"alice","quantity":"100.0000 SYS","memo":"memo"}
这次输出包含几个不同的 action:一个 issue 和三个 transfer。虽然授权的唯一 action 是 issue,但 action issue 执行 “inline transfer”,“inline transfer” 通知 sender 和 receiver 帐户。输出指示被调用的所有 action 处理程序,调用它们的顺序以及 action 是否生成任何输出。
Technically, the eosio.token contract could have skipped the inline transfer and opted to just modify the balances directly. However, in this case the eosio.token contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals.
从技术上讲,合约 eosio.token 可能已跳过内联转移,并选择直接修改余额。但是,在这种情况下,合约 eosio.token 遵循我们的代币约定,该约定要求所有帐户余额可以通过引用它们的传输操作的总和来推导。它还要求通知资金的发送方和接收方,以便它们可以自动处理存款和取款。
要检查交易,请尝试使用 -d -j 选项,它们表示“不要广播”和“将事务返回为 json”,在开发过程中会发现这些选项很有用。
$ cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j
本人的专栏 eosio.cleos 中会有专题介绍交易。
Step 7: 传输代币
现在帐户 alice 中已经被释放了相应的代币,可以将其中一些转移到帐户 bob。之前曾表示 alice 使用参数 -p alice@active 授权此操作。
$ cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active
执行上述命令,输出结果如下
executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles
# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"}
>> transfer
# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"}
# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"}
现在,使用命令 cleos get currency balance 检查账户 “bob” 是否获得相应数量的代币。
$ cleos get currency balance eosio.token bob SYS
25.00 SYS
再检查账户 “alice” 的余额,注意从帐户中扣除了相应数量的代币。
$ cleos get currency balance eosio.token alice SYS
75.00 SYS
完美,至此你已经成功创建了你自己的代币,并能够进行正常的释放和转账等操作。
Reference
- Deploy, Issue and Transfer Tokens, https://developers.eos.io/eosio-home/docs/token-contract
项目源代码
项目源代码会逐步上传到 Github,地址为:
- https://github.com/windstamp/blockchain
- https://github.com/windstamp/eoscodes
- https://github.com/windstamp/installscripts
Contributor
- Windstamp, https://github.com/windstamp