Edit me

运行本地节点

pct@Chandler:~/workspace/eos/eos/build/programs/nodeos$ nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin 
181308ms thread-0 chain_plugin.cpp:200 plugin_initialize ] initializing chain plugin
181308ms thread-0 chain_plugin.cpp:351 plugin_initialize ] Starting up fresh blockchain with default genesis state.
181683ms thread-0 http_plugin.cpp:285 plugin_initialize ] configured http to listen on 127.0.0.1:8888
181683ms thread-0 net_plugin.cpp:2814 plugin_initialize ] Initialize net plugin
181684ms thread-0 net_plugin.cpp:2835 plugin_initialize ] host: 0.0.0.0 port: 9876 
181684ms thread-0 net_plugin.cpp:2907 plugin_initialize ] my node_id is 5f1d469db56b6fc4ffd6993ebb43611f9f3f7c48260222da16d53bd1d865c6c3
181684ms thread-0 main.cpp:104 main ] nodeos version aecf0890
181684ms thread-0 main.cpp:105 main ] eosio root is /home/pct/.local/share
181684ms thread-0 controller.cpp:1146 startup ] No head block in fork db, perhaps we need to replay
181684ms thread-0 controller.cpp:307 initialize_fork_db ] Initializing new blockchain with genesis state         
182500ms thread-0 producer_plugin.cpp:689 start_block ] Not producing block because the irreversible block is too old [age:8103782s, max:1800s]        

运行失败需先清空本地账本:

pct@Chandler:~/workspace/eos/eos/build/programs/nodeos$ rm -rf ~/.local/share/eosio/

需要执行两次,再次执行就会出块:

pct@Chandler:~/workspace/eos/eos/build/programs/nodeos$ nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin 
188683ms thread-0 chain_plugin.cpp:200 plugin_initialize ] initializing chain plugin
188743ms thread-0 block_log.cpp:123 open ] Log is nonempty
188743ms thread-0 block_log.cpp:136 open ] my->head->block_num(): 2 
188743ms thread-0 block_log.cpp:142 open ] Index is nonempty
188753ms thread-0 http_plugin.cpp:285 plugin_initialize ] configured http to listen on 127.0.0.1:8888
188753ms thread-0 net_plugin.cpp:2814 plugin_initialize ] Initialize net plugin
188753ms thread-0 net_plugin.cpp:2835 plugin_initialize ] host: 0.0.0.0 port: 9876 
188753ms thread-0 net_plugin.cpp:2907 plugin_initialize ] my node_id is 43ffec6e659a8ded2258494f4a4dd2bac9af8a757c6bdcbf18231c8bb51c6920
188753ms thread-0 main.cpp:104 main ] nodeos version aecf0890
188753ms thread-0 main.cpp:105 main ] eosio root is /home/pct/.local/share
188753ms thread-0 chain_plugin.cpp:406 plugin_startup ] starting chain in read/write mode
188753ms thread-0 chain_plugin.cpp:411 plugin_startup ] Blockchain started; head block is #3, genesis timestamp is 2018-03-02T12:00:00.000
188753ms thread-0 http_plugin.cpp:323 plugin_startup ] start listening for http requests
188754ms thread-0 chain_api_plugin.cpp:75 plugin_startup ] starting chain_api_plugin
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/abi_bin_to_json
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/abi_json_to_bin
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_account
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_block
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_code
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_currency_balance
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_currency_stats
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_info
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_producers
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_required_keys
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/get_table_rows
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/push_block
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/push_transaction
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/chain/push_transactions
188754ms thread-0 history_api_plugin.cpp:38 plugin_startup ] starting history_api_plugin
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/history/get_actions
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/history/get_controlled_accounts
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/history/get_key_accounts
188754ms thread-0 http_plugin.cpp:369 add_handler ] add api url: /v1/history/get_transaction
188754ms thread-0 net_plugin.cpp:2919 plugin_startup ] starting listener, max clients is 25
188754ms thread-0 producer_plugin.cpp:509 plugin_startup ] producer plugin: plugin_startup() begin
188754ms thread-0 producer_plugin.cpp:524 plugin_startup ] Launching block production for 1 producers at 2018-06-04T07:03:08.754.
188754ms thread-0 producer_plugin.cpp:536 plugin_startup ] producer plugin: plugin_startup() end
189000ms thread-0 producer_plugin.cpp:987 produce_block ] Produced block 00000004d79211b6... #4 @ 2018-06-04T07:03:09.000 signed by eosio [trxs: 0, lib: 3, confirmed: 0]

创建账户

创建钱包:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ mkdir ~/eosio-wallet
pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos wallet create
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5KSfG7tEpdYshJWoXs8AXaQHcEMPWE8Wm7ABgY3zkFKt5HSEmxb"

为账户部署合约,需要执行两次才能成功:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos set contract eosio ../../contracts/eosio.bios -p eosio
Reading WAST/WASM from ../../contracts/eosio.bios/eosio.bios.wasm...
Using already assembled WASM...
Publishing contract...
Error 3080006: transaction took too long
Error Details:
deadline exceeded
pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos set contract eosio ../../contracts/eosio.bios -p eosio
Reading WAST/WASM from ../../contracts/eosio.bios/eosio.bios.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 3dc2d6b3b4ef037a796ec1adfaa97f6476b1e4e211acbea860d13bd1c52dfad3 3704 bytes 815 us
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001621260037f7e7f0060057f7e7e7e7e...
# eosio <= eosio::setabi {"account":"eosio","abi":"0e656f73696f3a3a6162692f312e30050c6163636f756e745f6e616d65046e616d650f7065...
warning: transaction executed locally, but may not be confirmed by the network yet

创建两个公私钥对:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create key
Private key: 5HrLmXt57CMFh6NyG9gX6D5SeJdoB4iLYe2G2TRa4NdKe9u9odT
Public key: EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo
pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create key
Private key: 5K1A4VgFMkEqjJ9UNXM8hTx3Td1bqUiGQTi9KD648z13GD89M7e
Public key: EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW

导入钱包:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos wallet import 5HrLmXt57CMFh6NyG9gX6D5SeJdoB4iLYe2G2TRa4NdKe9u9odT
imported private key for: EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo
pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos wallet import 5K1A4VgFMkEqjJ9UNXM8hTx3Td1bqUiGQTi9KD648z13GD89M7e
imported private key for: EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW

创建两个用户账户:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create account eosio user EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo
executed transaction: 03e5da242a0f19b801f96454b73bab5e333b35d956617ccbda4248fcaae8eb93 200 bytes 150 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"user","owner":{"threshold":1,"keys":[{"key":"EOS5LXo8zVfUcLAk6DSTqjWMbVUg...
warning: transaction executed locally, but may not be confirmed by the network yet
pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create account eosio tester EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW
executed transaction: b5f75300da61641ddbb4c296bf3f4745d7bd07671bcab87777be4e9ab866c34e 200 bytes 164 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"tester","owner":{"threshold":1,"keys":[{"key":"EOS5ppEozqEDyXcXLPR6my9Jxr...
warning: transaction executed locally, but may not be confirmed by the network yet

创建账号需要遵守规范,必须使用指定范围的字符(.12345abcdefghijklmnopqrstuvwxyz):

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create account eosio eager7 EOS4zKgCGgQoCBhmARRARE256eXpFE7y4KpECL8TV6ursYh45j2oq EOS7LKabEK3DLPeErMr2R4HDzuq86Rx5nenQYC85VGmT7JtVJ4J9q
Error 3010001: Invalid name
Name should be less than 13 characters and only contains the following symbol .12345abcdefghijklmnopqrstuvwxyz
Error Details:
Name not properly normalized (name: eager7, normalized: eager) 

如下是合法的:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create account eosio baidu.com EOS4zKgCGgQoCBhmARRARE256eXpFE7y4KpECL8TV6ursYh45j2oq EOS7LKabEK3DLPeErMr2R4HDzuq86Rx5nenQYC85VGmT7JtVJ4J9q
executed transaction: 6737598fa0e6e5240e7e7608b3a8f5071fb5d2c36ac98ff9fc978c459024ad29  200 bytes  634 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"baidu.com","owner":{"threshold":1,"keys":[{"key":"EOS4zKgCGgQoCBhmARRARE2...
warning: transaction executed locally, but may not be confirmed by the network yet

这样设计的原因和域名有点相似,RFC883中有部分定义,不区分大小写,不过域名中支持6789数字,这里这样设计主要还是出于编码的考虑:

Loss of case sensitive data must be minimized. Thus while data for x.y and X.Y may both be stored under x.y, data for a.x and B.X can be stored as a.x and B.x, but not A.x, A.X, b.x, or b.X. In general, this prevents the first component of a domain name from loss of case information.

创建一个合约账号:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos create account eosio eosio.token EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW
executed transaction: fee63b9af9956ef629576cae6b9c94a7849df78029de5cc235d76a4327155966 200 bytes 158 us
# eosio <= eosio::newaccount {"creator":"eosio","name":"eosio.token","owner":{"threshold":1,"keys":[{"key":"EOS5LXo8zVfUcLAk6DSTq...
warning: transaction executed locally, but may not be confirmed by the network yet

查看账户信息:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos get account eosio.token
privileged: false
permissions: 
     owner 1: 1 EOS5LXo8zVfUcLAk6DSTqjWMbVUgokr7DMzUjeyEPHikrCv72KBNo
        active 1: 1 EOS5ppEozqEDyXcXLPR6my9JxrEuyW8tyhpx2Sj1qFjedjdTzLvAW
memory: 
     quota: -1 bytes used: 2.66 Kb   
net bandwidth: (averaged over 3 days)
     used: -1 bytes
     available: -1 bytes
     limit: -1 bytes
cpu bandwidth: (averaged over 3 days)
     used: -1 us   
     available: -1 us   
     limit: -1 us

部署合约:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos set contract eosio.token ../../contracts/eosio.token -p eosio.token
Reading WAST/WASM from ../../contracts/eosio.token/eosio.token.wasm...
Using already assembled WASM...
Publishing contract...
executed transaction: 7cfd72d458b9d1308e4efbca161e32450a1b3c44f678718acad4af5b22987071 8104 bytes 935 us
# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d01000000017e1560037f7e7f0060057f7e...
# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d65...
warning: transaction executed locally, but may not be confirmed by the network yet

调用合约生成代币:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token
executed transaction: c2d506fa1f02fd51b0912cca8b142800320858626420a5d3b87128f168954599 120 bytes 8785 us
# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"}
warning: transaction executed locally, but may not be confirmed by the network yet

函数源码为:

void token::create( account_name issuer,
                    asset maximum_supply )
{
    require_auth( _self );
    auto sym = maximum_supply.symbol;
    eosio_assert( sym.is_valid(), "invalid symbol name" );
    eosio_assert( maximum_supply.is_valid(), "invalid supply");
    eosio_assert( maximum_supply.amount > 0, "max-supply must be positive");
    stats statstable( _self, sym.name() );
    auto existing = statstable.find( sym.name() );
    eosio_assert( existing == statstable.end(), "token with symbol already exists" );
    statstable.emplace( _self, [&]( auto& s ) {
       s.supply.symbol = maximum_supply.symbol;
       s.max_supply = maximum_supply;
       s.issuer = issuer;
    });
}

测试issue发行:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos push action eosio.token issue '[ "user", "100.0000 SYS", "memo" ]' -p eosio
executed transaction: 83ec0a9ffe55f6b5fe54d4d949fb3a5b0cd04d56135991086e1e746e5f1ed322 128 bytes 603 us
# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"}
# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"}
# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"}
# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"}
warning: transaction executed locally, but may not be confirmed by the network yet

函数源码为:

void token::issue( account_name to, asset quantity, string memo )
{
    auto sym = quantity.symbol;
    eosio_assert( sym.is_valid(), "invalid symbol name" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
    auto sym_name = sym.name();
    stats statstable( _self, sym_name );
    auto existing = statstable.find( sym_name );
    eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
    const auto& st = *existing;
    require_auth( st.issuer );
    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must issue positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
    statstable.modify( st, 0, [&]( auto& s ) {
       s.supply += quantity;
    });
    add_balance( st.issuer, quantity, st.issuer );
    if( to != st.issuer ) {
       SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} );
    }
}

测试转账:

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos push action eosio.token transfer '[ "user", "tester", "25.0000 SYS", "m" ]' -p user
executed transaction: c42acae5718c4001b38f74f92a7cd2a2de8e0b5e41311b536b12be295e87dba6 128 bytes 553 us
# eosio.token <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 SYS","memo":"m"}
# user <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 SYS","memo":"m"}
# tester <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 SYS","memo":"m"}
warning: transaction executed locally, but may not be confirmed by the network yet

函数源码为:

void token::transfer( account_name from,
                      account_name to,
                      asset quantity,
                      string memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    require_auth( from );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );
    require_recipient( from );
    require_recipient( to );
    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
    sub_balance( from, quantity );
    add_balance( to, quantity, from );
}

获取区块消息

pct@Chandler:~/workspace/eos/eos/build/programs/cleos$ ./cleos -u http://localhost:8888 get info
{
  "server_version": "aecf0890",
  "chain_id": "706a7ddd808de9fc2b8879904f3b392256c83104c1d544b38302cc07d9fca477",
  "head_block_num": 88,
  "last_irreversible_block_num": 87,
  "last_irreversible_block_id": "00000057acf18fb9740dcbcabec689b39cabba6a3918db7b5e35a942dafcea8d",
  "head_block_id": "000000585b22d2cae37d99f2b70866e1ba434a393930256f9ded43ef8536c941",
  "head_block_time": "2018-06-04T09:00:55",
  "head_block_producer": "eosio",
  "virtual_block_cpu_limit": 218145,
  "virtual_block_net_limit": 1143890,
  "block_cpu_limit": 199900,
  "block_net_limit": 1048576
}
Tags: