[eos7]智能合约开发-数据持久化
https://developers.eos.io/eosio-home/docs/data-persistence
本篇主要是见识下eos的类似关系型数据库的东东,关键技术:multi_index。
本篇通过一个address book为例来说明。
1、流程
创建标准的合约文件
创建表(table)结构
配置multi_index table结构
实现构造器
实现新增/修改一条记录的方法(即合约的action)
实现删除一条记录的方法(即合约的action)
添加action,table等声明,为生成abi文件准备
实现李嘉图合约(可选)
实现李嘉图条款(可选)
编译合约
创建账号并部署合约
测试合约
2、关键点
2.1 创建表(table)结构
Next, define a primary_key method. Every multi_index struct requires a primary key to be set. Behind the scenes, this method is used according to the index specification of your multi_index instantiation. EOSIO wraps boost::multi_index
必须为每个multi_index结构体指定一个primary_key函数。eosio封装了boost:multi_index
struct [[eosio::table]] person {
name key;
std::string first_name;
std::string last_name;
std::string street;
std::string city;
std::string state;
uint64_t primary_key() const { return key.value;}
};
本例中,主键的定义强制每个用户只有一条记录。name的类型本质上就是uint64_t。
2.2 配置multi_index table
之前只是定义了表的结构,例如有多少列,哪个是主键等。现在需要定义这个表:
typedef eosio::multi_index<"people"_n, person> address_index;
这段代码包含以下几个信息:
1、表名:people(_n操作符表示eosio::name类型)
2、表结构:person
3、multi_index名字:address_index
2.3 实现新增/修改一条记录的方法(即合约的action)
大体上,要做的事情就行初始化address_index,即表对象,然后检测这条记录是否已经在表中存在,不存在则插入(使用multi_index的emplace函数),存在则根据内容修改(使用multi_index的modify函数)。
唯一有权利修改记录的账号就是user自己。即只有自己可以修改自己的记录。由于name的类型本质上就是uint64_t,所以name这个类型就是primary_key的理想类型。
需要先初始化multi_index table,即address_index,需要两个参数:
1)code:表示这个表的所有者。这里用get_self将会获得合约(即账号?)的名字
2)scope:确保这个table在这个合约上的唯一性。
代码如下:
void upsert(name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
require_auth( user );
address_index addresses(get_self(), get_first_receiver().value);
auto iterator = addresses.find(user.value);
if( iterator == addresses.end() )
{
addresses.emplace(user, [&]( auto& row ) {
row.key = user;
row.first_name = first_name;
row.last_name = last_name;
row.street = street;
row.city = city;
row.state = state;
});
}
else {
addresses.modify(iterator, user, [&]( auto& row ) {
row.key = user;
row.first_name = first_name;
row.last_name = last_name;
row.street = street;
row.city = city;
row.state = state;
});
}
}
2.4 实现李嘉图合约/条款(可选)
md格式文件,名字必须和智能合约的名字一样。
李嘉图合约主要用来说明各个action的功能
李嘉图条款用来说明合约的功能