EOS智能合约的开发、编译、部署与交互。
## 运行示例代码
### 1、启动节点服务
在1#终端启动nodeos,建议先清除历史数据:
```
~$ rm -rf ~/.local/share/eosio/nodeos/data
~$ nodeos
```
在2#终端启动keosd:
```
~$ keosd
```
### 2、初始化钱包和账户
进入3#终端,执行以下脚本初始化默认钱包,并创建三个账户:
```
~$ init-wallet.sh
~$ new-account.sh sodfans
~$ new-account.sh jack
~$ new-account.sh pony
```
### 3、基本计数器合约
在3#终端进入~/repo/chapter4目录,执行以下脚本构建并部署合约:
```
~$ cd ~/repo/chapter4
~/repo/chapter4$ build-contract.sh counter.cpp
~/repo/chapter4$ deploy-contract.sh sodfans build/counter
```
使用cleos与计数器合约交互:
```
~/repo/chapter4$ cleos push action sodfans increase '[]' -p sodfans
```
### 4、识别交易执行者
执行以下脚本构建并部署合约:
```
~/repo/chapter4$ build-contract.sh counter-with-id.cpp
~/repo/chapter4$ deploy-contract.sh sodfans build/counter-with-id
```
使用cleos与计数器合约交互:
```
~/repo/chapter4$ cleos push action sodfans increase '["sodfans"]' -p sodfans
```
### 5、计数状态持久化
执行以下脚本构建并部署合约:
```
~/repo/chapter4$ build-contract.sh counter-with-table.cpp
~/repo/chapter4$ deploy-contract.sh sodfans build/counter-with-table
```
使用cleos与计数器合约交互:
```
~/repo/chapter4$ cleos push action sodfans increase '["sodfans"]' -p sodfans
```
### 6、使用scope隔离不同账户的状态
执行以下脚本构建并部署合约:
```
~$ cd ~/repo/chapter4
~/repo/chapter4$ build-contract.sh counter-with-scope.cpp
~/repo/chapter4$ deploy-contract.sh sodfans build/counter-with-scope
```
使用cleos与计数器合约交互:
```
~/repo/chapter4$ cleos push action sodfans increase '["jack"]' -p jack
~/repo/chapter4$ cleos push action sodfans increase '["pony"]' -p pony
```
## 文件目录组织
- counter.cpp:基本计数器合约,无持久化状态
#include <eosiolib/eosio.hpp>
class counter_contract:eosio::contract{
public:
counter_contract(account_name self):eosio::contract(self){}
void increase(){
eosio::print("INCREASE => ",value++);
}
void decrease(){
eosio::print("DECREASE => ",value--);
}
private:
uint64_t value;
};
EOSIO_ABI(counter_contract,(increase)(decrease))
- counter-with-id.cpp:检测交易执行账户的计数器合约
#include <eosiolib/eosio.hpp>
class counter_contract:eosio::contract{
public:
counter_contract(account_name self):eosio::contract(self){}
void increase(account_name actor){
eosio::require_auth(actor);
eosio::print(eosio::name{actor} , " INCREASE => ",value++);
}
void decrease(account_name actor){
eosio::print(eosio::name{actor} , " DECREASE => ",value--);
}
private:
uint64_t value;
};
EOSIO_ABI(counter_contract,(increase)(decrease))
- counter-with-table.cpp:具有持久化状态的计数器合约
#include <eosiolib/eosio.hpp>
//@abi table
struct counter{
uint64_t actor;
uint64_t value;
uint64_t primary_key() const { return actor; }
};
typedef eosio::multi_index<N(counter),counter> counter_table;
class counter_contract:eosio::contract{
public:
counter_contract(account_name self):eosio::contract(self){}
void increase(account_name actor){
eosio::require_auth(actor);
value = get_value(actor);
eosio::print(eosio::name{actor} , " INCREASE => ",value++);
update_value(actor,value);
}
void decrease(account_name actor){
eosio::print(eosio::name{actor} , " DECREASE => ",value--);
}
private:
uint64_t value;
uint64_t get_value(account_name actor){
counter_table c(_self,_self);
auto iter = c.find(actor);
if(iter != c.end()) return iter->value;
c.emplace(actor,[&](auto& record){
record.actor = actor;
record.value = 0;
});
return 0;
}
void update_value(account_name actor,uint64_t value){
counter_table c(_self,_self);
auto iter = c.find(actor);
c.modify(iter,actor,[&](auto& record){
record.value = value;
});
}
};
EOSIO_ABI(counter_contract,(increase)(decrease))
- counter-with-scope.cpp:使用数据域隔离不同账户状态的计数器合约
#include <eosiolib/eosio.hpp>
//@abi table
struct counter{
uint64_t actor;
uint64_t value;
uint64_t primary_key() const { return actor; }
};
typedef eosio::multi_index<N(counter),counter> counter_table;
class counter_contract:eosio::contract{
public:
counter_contract(account_name self):eosio::contract(self){}
void increase(account_name actor){
eosio::require_auth(actor);
value = get_value(actor);
eosio::print(eosio::name{actor} , " INCREASE => ",value++);
update_value(actor,value);
}
void decrease(account_name actor){
eosio::print(eosio::name{actor} , " DECREASE => ",value--);
}
private:
uint64_t value;
uint64_t get_value(account_name actor){
counter_table c(_self,actor);
auto iter = c.find(actor);
if(iter != c.end()) return iter->value;
c.emplace(actor,[&](auto& record){
record.actor = actor;
record.value = 0;
});
return 0;
}
void update_value(account_name actor,uint64_t value){
counter_table c(_self,actor);
auto iter = c.find(actor);
c.modify(iter,actor,[&](auto& record){
record.value = value;
});
}
};
EOSIO_ABI(counter_contract,(increase)(decrease))