EOS智能合約存儲實例
智能合約中的基礎功能之一是token在某種規則下轉移。以EOS提供的token.cpp為例,定義了eos token的數據結構:typedef eos::token<uint_t,N(eos)>Tokens;
以Currency合約為例。該合約中,也用類token模板類生成了代幣currency:typedef eos::token<uint_t,N(currency)>CurrencyTokens;
有了 eos token和我們發行的子代幣,我們就能編寫智能合約,讓用戶使用不同的代幣進行交易。在currency.cpp或者exchange.cpp中,eos實現了發行代幣、代幣流通、兌換功能。
struct Transfer{
AccountName from;
AccountName to;
Tokens quantity;
};
這樣,在轉賬時,調用currency.cpp中實現的api傳入Transfer結構表明想要轉賬的token數量:
Transfer MeToYou;
MeToYou.form=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.banlance-=transfer.quantituy;
to.banlance+=transfer.quantituy;
assertion storeAccount(transfer.from,from);
storeAccount(transfer.to,to);
}
最終存儲結果將保存到沙盒的內存中。
EOS智能合約數據庫的持久化
在沙盒機制中,當我們運行一個合約、發行一個代幣時,EOS為我們提供的一些基礎運行框架。其中最重要的兩個:第一,實現了平台無關的account存儲機制;第二,提供了一個account間結算的業務平台。同時EOS會將沙盒里面的數據存儲接口存儲在具體物理設備上來,實現數據的持久化。
在chain/wasm_interface.cpp中,對接了wasm的context,並使用context獲取到db.php中實現的數據存儲接口,然后將這些接口實現到了message_handing_contexts.hpp中。
這樣后面的處理流程就比較清晰了。當合約在讀取數據時,將調用message_handing_contexte.hpp中的load_record接口:
template<typename IndexType,typename Scope>
int32_t load_record(Name scope,Name code,Name table,typename IndexType::value_type::key_type* keys,char* value,unit32_t valuelen){
const auto& idx=db.get_index<IndexType,Scope>();
auto tuple = load_record_tuple<typename IndexType::value_type,Scope>: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_.php中提供了一種從數據庫讀取table的方法
get_table_rows_result get_table_rows( const get_table_rows_params¶ms)const;
利用這個開發者就能讀取到合約目前的所有狀態,開發自己的錢包了。
總結:
EOS.IO發布的版本已經提供了開發智能合約的基本API,本次從數據庫到持久化方法介紹了EOS智能合約的數據庫API。
基於這些API,開發者就可以開發出自己的錢包。