首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

EOS 智能合约数据结构 API(二)

区块链研究实验室

技术开发 | 咨询 | 孵化 | 资本对接

回来继续学习数据结构 API下部分的内容,

二、智能合约数据存储实例

智能合约中基础的功能之一是 token 在某种规则下的转移。以 EOS 提供的token.cpp 为例,定义了 eos token 的数据结构:typedef eos::tokenTokens;

以 currency 合约为例。合约中,也用类 token 模版类生成了代币 currency:typedef eos::tokenCurrencyTokens;

有了 eos token 和我们发行的子代币,我们就能编写合约,让用户使用不同的代币进行交易。在 currency.cpp 或 exchange.cpp 中,eos 实现了发行代币、代币流通、兑换功能。

eos 和自定义 currency 在流通时,都使用一个类似的 Transfer 结构体:

struct Transfer{

AccountName from;

AccountName to;

Tokens quantity;

};

这样,在转账时,调用 currency.cpp 中实现的 abi 接口,传入 Transfer 结构表明想要转账的 token 数量:

Transfer MeToYou;

MeToYou.from = N(Me);

MeToYou.to = N(You);

MeToYou.quantity = Tokens(100);

当 eos 的合约处理接收到这样的请求时,会调用相关流程完成对对应 token的处理。

void apply_transfer( const Transfer& transfer ) {

auto from = getAccount( transfer.from );

auto to= getAccount( transfer.to );

from.balance -= transfer.quantity;

to.balance+= transfer.quantity;

assertion storeAccount( transfer.from, from );

storeAccount( transfer.to, to );

}

最终存储结果将保存到沙盒的内存中。

三、智能合约数据库的持久化

在沙盒机制中,当我们运行一个合约、发行一个代币时,EOS 为我们提供的一些基础运行框架。其中最重要的两个:第一,实现了平台无关的 account 存储机制;第二,提供了一个 account 间结算的业务平台。同时 EOS 会将沙盒里面的数据存储接口储存在具体物理设备上来,实现数据的持久化。

在 chain/wasm_interface.cpp 中,对接了 wasm 的 context,并使用 context 获取 到 db.hpp 中 实 现 的 数 据 存 储 接 口 , 然 后 将 这 些 接 口 实 现 到 了message_handing_contexts.hpp 中。

chain/wasm_interface.cpp:

#define DEFINE_RECORD_UPDATE_FUNCTIONS(OBJTYPE, INDEX) \

DEFINE_INTRINSIC_FUNCTION4(env,store_##OBJTYPE,store_##OBJTYPE,i32,i64,scop e,i64,table,i32,valueptr,i32,valuelen) {

\UPDATE_RECORD(store_record, INDEX, valuelen); \

} \

DEFINE_INTRINSIC_FUNCTION4(env,update_##OBJTYPE,update_##OBJTYPE,i32,i64,s cope,i64,table,i32,valueptr,i32,valuelen) {

\UPDATE_RECORD(update_record, INDEX, valuelen); \

} \

DEFINE_INTRINSIC_FUNCTION3(env,remove_##OBJTYPE,remove_##OBJTYPE,i32,i64, scope,i64,table,i32,valueptr) { \

UPDATE_RECORD(remove_record, INDEX, sizeof(typename INDEX::value_type::key_type)*INDEX::value_type::number_of_keys); \

}

message_handing_contexts.hpp:

int32_t update_record( Name scope, Name code, Name table, typename ObjectType::key_type *keys, char* value, uint32_t valuelen )

int32_t remove_record( Name scope, Name code, Name table, typename ObjectType::key_type* keys, char* value, uint32_t valuelen )

int32_t load_record( Name scope, Name code, Name table, typename IndexType::value_type::key_type* keys, char* value, uint32_t valuelen )

这样后面的处理流程就比较清晰了。当合约在读取数据时,将调用message_handing_contexts.hpp 的 load_recod 接口:

template

int32_t load_record( Name scope, Name code, Name table, typename IndexType::value_type::key_type* keys, char* value, uint32_t valuelen ) {

const auto& idx = db.get_index();

auto tuple = load_record_tuple::get(scope, code, table, keys);

auto itr = idx.lower_bound(tuple);

}

上面 load_record 代码中,调用了 db.get_index 方法。此处的 db 也就是 chainbase/chainbase.hpp 中实现的 database 类。database 中使用了 boost 的managed_mapped_file,实现了对数据的存储和读取的接口。

在 EOS 提供的插件 plugins/chain_plugin/chain_plugin.hpp 中提供了一种从数据库读取 table 的方法:

get_table_rows_result get_table_rows( const get_table_rows_params& params )const;

利用这个方法开发者就能读取到合约目前的所有状态,开发属于自己的钱包了。

四、总结

EOS.IO 发布的 Dawn 1.0 版本已经提供了开发智能合约的基本 API,本次我们从数据库结构到持久化方法介绍了 EOS 智能合约的数据库 API。基于这些 API,开发者就可以开发出自己的钱包。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180515A077K600?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券