EOS 开发:合约

June 12, 2018

EOS 现在更新非常频繁,之前的命令可能很快就会有变动,于是我新编译了一个版本,不再使用之前的 Docker 环境。

EOS 的合约在 ~/eos/contracts 目录之下,比如 hello 合约为 ~/eos/contracts/hello/hello.cpp

#include <eosiolib/eosio.hpp>
using namespace eosio;

class hello : public eosio::contract {
  public:
      using contract::contract;

      /// @abi action
      void hi( account_name user ) {
         print( "Hello, ", name{user} );
      }
};

EOSIO_ABI( hello, (hi) )

从 CPP 编译成 WebAssembly 文件:

eosiocpp -o hello.wast hello.cpp

生成 abi 文件:

$ eosiocpp -g hello.abi hello.cpp
Generated hello.abi ...

上传合约到账户中(其中 livc 是 account name):

$ cleos --url http://127.0.0.1:8887 set contract livc ~/eos/contracts/hello -p livc
Reading WAST/WASM from /Users/zhao/eos/contracts/hello/hello.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: e35b8ec816d7556fee73f12c31c64e146c8a7af0fa56846a2466b87ef506c7ef  4168 bytes  5181 us
#         eosio <= eosio::setcode               {"account":"livc","vmtype":0,"vmversion":0,"code":"0061736d01000000013b0c60027f7e006000017e60027e7e0...
#         eosio <= eosio::setabi                {"account":"livc","abi":"0e656f73696f3a3a6162692f312e30000102686900010475736572046e616d6501000000000...

$ cleos --url http://127.0.0.1:8887 push action livc hi '["hhhhh"]' --permission livc@active
executed transaction: a193f474503bb79ea6ecafa04419ea851cf4fd5d88c18710f0d8052a2f65e2bb  104 bytes  1269 us
#          livc <= livc::hi                     {"user":"hhhhh"}

其中,-p 代表使用该账户的 active 的授权,cleos 调用了 setcodesetabi 两个函数。

Token 合约

eosio.token 合约是一个 token 标准合约,类似于 ETH 的 ERC20 标准。

eosiocpp -o eosio.bios.wast eosio.bios.cpp

由于目录已存在 abi 文件,不需再次生成。

$ cleos --url http://127.0.0.1:8887 set contract eosio ~/eos/contracts/eosio.bios -p eosio
Reading WAST/WASM from /Users/zhao/eos/contracts/eosio.bios/eosio.bios.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 0fa7093a92ed900c88aaad2cf8b9a0e142d19625731cbd35eb4b5fc87b05cd43  3712 bytes  847 us
#         eosio <= eosio::setcode               {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001621260037f7e7f0060057f7e7e7e7e...
#         eosio <= eosio::setabi                {"account":"eosio","abi":"0e656f73696f3a3a6162692f312e30050c6163636f756e745f6e616d65046e616d650f7065...

创建 eosio.token 账户和合约:

$ cleos create key
(eosio.token owner)
Private key: 5HuTB56H49GP6VnKYk5xHNXQBESfqs8nwBCuhekbbLgS9PPA7mh
Public key: EOS71oCDtXFzjU1p5rn4oBo2VVGh37fSYrXmcusBv53FQyLMwrzEq

$ cleos create key
(eosio.token private)
Private key: 5J9svtsttiFvfHdeHwNruyfRfAF8i9yC1EcSzWUYy6MniuT1SAt
Public key: EOS4xo6bcVrApUY3BGALR29UmvykqdwACeDnzTAgeFNuHiJEMHUFj

$ cleos wallet create -n eosio.token
Creating wallet: eosio.token
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JiCuwwW3qJxU4mj8qvQYsHKGE78FmUtFH8UhJorW2hkmEWrevA"

$ cleos wallet import 5HuTB56H49GP6VnKYk5xHNXQBESfqs8nwBCuhekbbLgS9PPA7mh
imported private key for: EOS71oCDtXFzjU1p5rn4oBo2VVGh37fSYrXmcusBv53FQyLMwrzEq

$ cleos wallet import 5J9svtsttiFvfHdeHwNruyfRfAF8i9yC1EcSzWUYy6MniuT1SAt
imported private key for: EOS4xo6bcVrApUY3BGALR29UmvykqdwACeDnzTAgeFNuHiJEMHUFj

$ cleos --url http://127.0.0.1:8887 create account eosio eosio.token EOS71oCDtXFzjU1p5rn4oBo2VVGh37fSYrXmcusBv53FQyLMwrzEq EOS4xo6bcVrApUY3BGALR29UmvykqdwACeDnzTAgeFNuHiJEMHUFj
executed transaction: b4ea4231f9cdcc5c97d9777bdf4a0d67a49a3312674fe62571e8de76a43aa803  200 bytes  621 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"eosio.token","owner":{"threshold":1,"keys":[{"key":"EOS71oCDtXFzjU1p5rn4o...

$ cleos --url http://127.0.0.1:8887 set contract eosio.token ~/eos/contracts/eosio.token -p eosio.token
Reading WAST/WASM from /Users/zhao/eos/contracts/eosio.token/eosio.token.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: effb485662fe1003b00a872aca556e5f16f6715c872ce61657302a09d3d87b0a  8112 bytes  1124 us
#         eosio <= eosio::setcode               {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d01000000017e1560037f7e7f0060057f7e...
#         eosio <= eosio::setabi                {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d65...

$ cleos --url http://127.0.0.1:8887 push action eosio.token create '["eosio","1000000000.0000 EOS",0,0,0]' -p eosio.token
executed transaction: f5e3a7f3138f03c8dcac789e40bc8af2ac76750581aa9f97ab241edbdee8b4c8  120 bytes  1460 us
#   eosio.token <= eosio.token::create          {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS"}

创建一个账户 bob 并给他转账:

$ cleos create key
(bob owner)
Private key: 5JPZkcPwVfRAZYjD2CkLLf1TwsaWk7JGJcUZJM9Vtw4XQuVXsh1
Public key: EOS7URUGippnvXCifEao2quScqHGanjzLqxGdPyrgVTuMCe5PGQxb

$ cleos create key
(bob private)
Private key: 5Jg1Y9u8HDsMzo7WtSXHXkRwAbdy9hBsgTMf1gSoZDRbp76G4Ge
Public key: EOS6MyaP2sPpgbXARnHkSkVPU5rid7YTTP44Xsr7vnKVZCxwxJSY1

$ cleos wallet create -n bobwallet
Creating wallet: bobwallet
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5J1SNSox7ozdETfnDeFFQYYrGjCwsV7trcoyX4GbCtcjtfpwqny"

$ cleos wallet import 5JPZkcPwVfRAZYjD2CkLLf1TwsaWk7JGJcUZJM9Vtw4XQuVXsh1
imported private key for: EOS7URUGippnvXCifEao2quScqHGanjzLqxGdPyrgVTuMCe5PGQxb

$ cleos wallet import 5Jg1Y9u8HDsMzo7WtSXHXkRwAbdy9hBsgTMf1gSoZDRbp76G4Ge
imported private key for: EOS6MyaP2sPpgbXARnHkSkVPU5rid7YTTP44Xsr7vnKVZCxwxJSY1

$ cleos --url http://127.0.0.1:8887 create account eosio bob EOS7URUGippnvXCifEao2quScqHGanjzLqxGdPyrgVTuMCe5PGQxb EOS6MyaP2sPpgbXARnHkSkVPU5rid7YTTP44Xsr7vnKVZCxwxJSY1
executed transaction: 32269bbfa553468ee798e5c2f70df1262258eecfa241eabe800d2bae2651775e  200 bytes  232 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"bob","owner":{"threshold":1,"keys":[{"key":"EOS7URUGippnvXCifEao2quScqHGa...

$ cleos --url http://127.0.0.1:8887 push action eosio.token issue '[ "bob", "100.0000 EOS", "memo" ]' -p eosio
executed transaction: 39d7ba273c549db9ba1746a74938b026b57b8a3f0bf49919529b25119498767d  128 bytes  1622 us
#   eosio.token <= eosio.token::issue           {"to":"bob","quantity":"100.0000 EOS","memo":"memo"}
#   eosio.token <= eosio.token::transfer        {"from":"eosio","to":"bob","quantity":"100.0000 EOS","memo":"memo"}
#         eosio <= eosio.token::transfer        {"from":"eosio","to":"bob","quantity":"100.0000 EOS","memo":"memo"}
#           bob <= eosio.token::transfer        {"from":"eosio","to":"bob","quantity":"100.0000 EOS","memo":"memo"}

再创建一个账号 Mary,从 Bob 给 Mary 转账:

$ cleos create key
Private key: 5K4ooajerHnUikiQG1pfrAxsveoBg7Zs7BMkrgeyBZLTszmL4R2
Public key: EOS8jxG15Zd4MGGrb5aNo3ZoBGEx9v7uCvaXxeWqni7HraMGtshiw

$ cleos create key
Private key: 5JS9VHiHgpjC5P1bFjjGDumANoR3nhibFwJpDrmqg25Jk4EQU75
Public key: EOS537AH7wwzYRHc4sUjnXDsJ4pu8rSxCJLrNp2XdtcHrCE34DZ8X

$ cleos wallet create -n marywallet
Creating wallet: marywallet
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5J2gAWRz7hqcT8ASU66XeRsEDHnfrAqj8djYyXs8vNBWf6Th2Fr"

$ cleos wallet import 5K4ooajerHnUikiQG1pfrAxsveoBg7Zs7BMkrgeyBZLTszmL4R2
imported private key for: EOS8jxG15Zd4MGGrb5aNo3ZoBGEx9v7uCvaXxeWqni7HraMGtshiw

$ cleos wallet import 5JS9VHiHgpjC5P1bFjjGDumANoR3nhibFwJpDrmqg25Jk4EQU75
imported private key for: EOS537AH7wwzYRHc4sUjnXDsJ4pu8rSxCJLrNp2XdtcHrCE34DZ8X

$ cleos --url http://127.0.0.1:8887 create account eosio mary EOS8jxG15Zd4MGGrb5aNo3ZoBGEx9v7uCvaXxeWqni7HraMGtshiw EOS537AH7wwzYRHc4sUjnXDsJ4pu8rSxCJLrNp2XdtcHrCE34DZ8X
executed transaction: 1d0aac267f86a645f278910a20c527b73fda20832e315f26b82d6b388986a144  200 bytes  469 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"mary","owner":{"threshold":1,"keys":[{"key":"EOS8jxG15Zd4MGGrb5aNo3ZoBGEx...

$ cleos --url http://127.0.0.1:8887 push action eosio.token transfer '[ "bob", "mary", "25.0000 EOS", "m" ]' -p bob
executed transaction: cb664fc62c5bbf480aa73ab8ae19aecd85c68b09d9fdd70f0e7ee0e83a7ee433  128 bytes  976 us
#   eosio.token <= eosio.token::transfer        {"from":"bob","to":"mary","quantity":"25.0000 EOS","memo":"m"}
#           bob <= eosio.token::transfer        {"from":"bob","to":"mary","quantity":"25.0000 EOS","memo":"m"}
#          mary <= eosio.token::transfer        {"from":"bob","to":"mary","quantity":"25.0000 EOS","memo":"m"}

检查余额:

$ cleos --url http://127.0.0.1:8887 get currency balance eosio.token mary
25.0000 EOS

$ cleos --url http://127.0.0.1:8887 get currency balance eosio.token bob
75.0000 EOS

Reference


Profile picture

Written by Armin Li , a venture capitalist. [Weibo] [Subscribe]