1. 链一财经首页
  2. 资讯

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

                                          QQ截图20180514094223.png

之前我们在对 EOS 代码进行了编译和测试,陆续发布了三份《EOS 编译、测试指南》,详细介绍了 EOS 的入门知识、基本结构,帮助开发人员学习、研究 EOS。基于EOS 刚刚推出的 Dawn 1.0,进行了测试,本次将以代币的发行为例,详细介绍 EOS 上 WASM 的数据库机制和智能合约的数据库 API,基于此开发人员可以在 EOS 上发行自己的代币和开发钱包应用。

EOS.IO 的架构目标,是成为一个高效的消息分发平台,消息被分发到 account(合约)中然后被高效地并发执行。

EOS 底层需要一个高效的沙盒运行环境。沙盒中,底层的脚本语言,执行环境都是可以被替换的。在白皮书中,EOS 宣传支持 EVM 和 WASM 两种沙盒运行环境。目前所知,WASM 的运行效率比 EVM 高很多,这点为 EOS 提供了有力的竞争条件。高效的执行环境,提供了更快的交易反馈时间,从而在单个出块周期处理更多的业务,可以运行更大规模的运算。

一、智能合约的数据库 API

EOS 的合约执行依赖于 WASM 的沙盒运行环境。

上一份指南中,我们分析了 block 数据结构的存储,EOS 使用boost::interprocess,将 block 信息通过文件映射存储到磁盘上。

而在 EOS 合约执行过程中,所有的 account 状态都存储在沙盒的运行内存中。EOS 对 account 的操作,通过调用 contract/eoslib/db.hpp 的 table 模版类,进行类似于传统的增删查改操作。db.hpp 通过一个 c 接口,接入 WASM 沙盒环境,实现了跨平台的储存机制。WASM 对数据存储的具体实现,依赖 chainbase.hpp 中,database 类实现的 mmap 数据存储接口。

account 的状态数据,均存储在一个 table 的数据结构中,我们可以在 db.hpp中可以看到对其的实现:

template<uint64_t scope, uint64_t code, uint64_t table, typename Record, typename PrimaryType, typename SecondaryType = void>

struct Table {

}

struct Table<scope,code,table,Record,PrimaryType,void>

{

}

由此可见智能合约的数据结构大致如下:

– **scope** – an account where the data is stored

– **code** – the account name which has write permission

– **table** – a name for the table that is being stored

– **record** – a row in the table

– **PrimaryType** – primary key in one record

– **SecondaryType** – secondary key in one record

开发者使用 db.hpp 调用中 C 或 C++包装的 api,来实现数据存取。

在每一条交易信息中会使用 scope 指定哪些账号需要对该消息读、写。code决定了对应 account 可以采取的操作,这种操作权限和代码分离的设计提升了安全性。同时,如果修改了不在 scope 中的 account 的信息或者执行了非 code 的操作,会直接导致该交易失败。

以代币的发行实例来看 (代码部分参见 contract/currency.cpp),代币的所有账户都以 Table 的形式存储:

using Accounts = Table<N(currency),N(currency),N(account),Account,uint64_t>;

合约文件中,提供了初始化代币和代币转账接口,当代币合约被存储时,各节点会自动执行一次合约中的 init 接口。当每次合约被调用,将调用合约中的apply 接口:

extern “C” {

void init() {

storeAccount(N(currency),Account( CurrencyTokens(1000ll*1000ll*1000ll) ) );

}

void apply( uint64_t code, uint64_t action ) {

if( code == N(currency) ) {

if( action == N(transfer) )

currency::apply_currency_transfer(currentMessage<

TOKEN_NAME::Transfer >() );

}

}

}

table 将不同 scope/code/table 的 account 数据,存储到了不同的内存映射中。在 currency.cpp 合约中,eos 使用 table 实现了代币账户下各种业务逻辑。

当用户发行 currency 合约时,会用工具把 cpp 生成 currency.wast.cpp 文件,同时需要一个 abi 文件作为第三方输入到合约的数据接口,接着 wasm-jit 会把wast 代码,连同 abi 接口,一起存储到 tx 的 message 中,让其他节点验证并存储此合约,等待合约被调用。

以下代码中,实现了打包 currency 合约到 transaction 中的流程:

types::setcode handler;

handler.account = “currency”;

auto wasm = assemble_wast( currency_wast ); handler.code.resize(wasm.size());

memcpy( handler.code.data(), wasm.data(), wasm.size() );

eos::chain::SignedTransaction trx;

trx.scope = {“currency”};

trx.messages.resize(1);

trx.messages[0].code = config::EosContractName;

trx.messages[0].authorization.emplace_back(types::AccountPermission{“currenc y”,”active”});

transaction_set_message(trx, 0, “setcode”, handler);

trx.expiration = chain.head_block_time() + 100;

transaction_set_reference_block(trx, chain.head_block_id());

chain.push_transaction(trx);

chain.produce_blocks(1);

文章原标题:[区块链研究实验室]EOS 智能合约数据结构 API(一)作者:链三丰

根据国家《关于防范代币发行融资风险的公告》,大家应警惕代币发行融资与交易的风险隐患。

本文来自LIANYI转载,不代表链一财经立场,转载请联系原作者。

发表评论

登录后才能评论

联系我们

微信:kkyves

邮件:kefu@lianyi.com

时间:7x24,节假日bu休息

QR code