开始学习智能合约
开始前请安装 install EOSIO
Step 1:安装Contract Development Toolkit(CDT)
EOSIO Contract Development Toolkit - 跟随安装指示进行. 编译合约以及生成ABI文件的eosio-cpp
工具包含在此工具包中.
首先,clone:
git clone --recursive https://github.com/eosio/eosio.cdt --branch v1.2.1 --single-branch
cd eosio.cdt
然后运行build.sh并为EOSIO区块链提供一个将要部署去哪的core symbol.
./build.sh <CORE_SYMBOL>
最后,安装 build
This install will install the core to /usr/local/eosio.cdt and symlinks to the top level tools (compiler, ld, etc.) to /usr/local/bin
$ sudo ./install.sh
Step 2:打开你的Node
如果你使用docker并且你的容器没有运行,执行:
docker start eosio
如果你想在本地运行nodeos
来开启你自己的single-node区块链,使用这一命令:
$ nodeos -e -p eosio --plugin eosio::chain_api_plugin \
--plugin eosio::history_api_plugin
这一命令设置了一些标记并将加载了一些我们将在后面教程使用的插件.如果没出问题,你能看到每0.5秒生成一个区块.
docker logs --tail 25 eosio
Result:
...
3165501ms thread-0 producer_plugin.cpp:944 produce_block ] Produced block 00000a4c898956e0... #2636 @ 2018-05-25T16:52:45.500 signed by eosio [trxs: 0, lib: 2635, confirmed: 0]
3166004ms thread-0 producer_plugin.cpp:944 produce_block ] Produced block 00000a4d2d4a5893... #2637 @ 2018-05-25T16:52:46.000 signed by eosio [trxs: 0, lib: 2636, confirmed: 0]
...
Step 3:创建钱包
钱包是给行为授权以进入区块链的私钥仓库.这些密钥通过一个为你生成的密码加密存储在硬盘上.这个密码应该被妥善保管好,例如安全的密码软件或抄写下来.
$ cleos wallet create --to-console
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5JuBXoXJ8JHiCTXf...."
你的钱包会在一段时间后自动锁定,你可以这样解锁:
$ cleos wallet unlock
password:
为了安全,如果你不使用钱包的时候请把它锁上.在不关闭nodeos
的情况下锁定钱包可以这样做:
cleos wallet lock
Locked: default
你需要解锁你的钱包以继续后面的教程.
加载教程密钥
上述步骤中启动的私有区块链是使用默认初始密钥创建的,必须将其加载到钱包中(如下所示):
$ cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
imported private key for: EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
Step4:加载BIOS合约
Now that we have a wallet with the key for the eosio
account loaded, we can set a default system contract. For the purposes of development, the default eosio.bios
contract can be used. This contract enables you to have direct control over the resource allocation of other accounts and to access other privileged API calls. In a public blockchain, this contract will manage the staking and unstaking of tokens to reserve bandwidth for CPU and network activity, and memory for contracts.
The eosio.bios
contract can be found in the contracts/eosio.bios
folder of your EOSIO source code. The command sequence below assumes it is being executed from the root of the EOSIO source, but you can execute it from anywhere by specifying the full path to ${EOSIO_SOURCE}/build/contracts/eosio.bios
.
If you're using docker, the command is:
$ cleos set contract eosio contracts/eosio.bios -p eosio@active
Reading WAST...
Assembling WASM...
Publishing contract...
executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 4068 bytes 10000 cycles
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ab011960037f7e7f0060057f7e7e7e...
# eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n...
If you built from source, the command is:
$ cleos set contract eosio build/contracts/eosio.bios -p eosio@active
Reading WAST...
Assembling WASM...
Publishing contract...
executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 4068 bytes 10000 cycles
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ab011960037f7e7f0060057f7e7e7e...
# eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n...
The result of this command sequence is that cleos
generated a transaction with two actions, eosio::setcode
and eosio::setabi
.
The code defines how the contract runs and the abi describes how to convert between binary and json representations of the arguments. While an abi is technically optional, all of the EOSIO tooling depends upon it for ease of use.
Any time you execute a transaction you will see output like:
executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 4068 bytes 10000 cycles
# eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ab011960037f7e7f0060057f7e7e7e...
# eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n...
This can be read as: The action setcode
as defined by eosio
was executed by eosio
contract with {args...}
.
# ${executor} <= ${contract}:${action} ${args...}
> console output from this execution, if any
As we will see in a bit, actions can be processed by more than one contract.
The last argument to this call was -p eosio@active
. This tells cleos
to sign this action with the active authority of the eosio
account, i.e., to sign the action using the private key for the eosio
account that we imported earlier.
Step 5: Create Accounts
Now that we have setup the basic system contract, we can start to create our own accounts. We will create two accounts, user
and tester
, and we will need to associate a key with each account. In this example, the same key will be used for both accounts.
To do this we first generate a key for the accounts.
$ cleos create key --to-console
Private key: 5Jmsawgsp1tQ3GD6JyGCwy1dcvqKZgX6ugMVMdjirx85iv5VyPR
Public key: EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
Then we import this key into our wallet:
$ cleos wallet import --private-key 5Jmsawgsp1tQ3GD6JyGCwy1dcvqKZgX6ugMVMdjirx85iv5VyPR
imported private key for: EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
NOTE: Be sure to use the actual key value generated by the cleos
command and not the one shown in the example above!
Keys are not automatically added to a wallet, so skipping this step could result in losing control of your account.
Create Two User Accounts
Next we will create two accounts, user
and tester
, using the key we created and imported above.
$ cleos create account eosio user EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
executed transaction: 8aedb926cc1ca31642ada8daf4350833c95cbe98b869230f44da76d70f6d6242 364 bytes 1000 cycles
# eosio <= eosio::newaccount {"creator":"eosio","name":"user","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxentZZ...
$ cleos create account eosio tester EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 366 bytes 1000 cycles
# eosio <= eosio::newaccount {"creator":"eosio","name":"tester","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxentZZ...
NOTE: The create account
subcommand requires two keys, one for the OwnerKey (which in a production environment should be kept highly secure) and one for the ActiveKey. In this tutorial example, the same key is used for both.
Because we are using the eosio::history_api_plugin
we can query all accounts that are controlled by our key:
$ cleos get accounts EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4
{
"account_names": [
"tester",
"user"
]
}