1. 如何處理錯誤?
使用函數(shù) eosio_assert 或者類似的方法用來返回錯誤
2. account_name 如何和字符串相互轉(zhuǎn)換?
account_name 是 uint64_t 類型,EOSIO 提供了一套方式可以將字符串轉(zhuǎn)換成 name, 不過這種方式是有限制條件的:
字符集:".12345abcdefghijklmnopqrstuvwxyz"
字符串不能超過13個字符
涉及相關(guān)函數(shù)是:
::eosio::string_to_name
::eosio::name::to_string
3. asset 是個什么類?
4. asset 如何和字符串相互轉(zhuǎn)換?
asset 類有兩個成員函數(shù) from_string 和 to_string
5. 智能合約是如何實現(xiàn)外部調(diào)用的時候?qū)⒆址D(zhuǎn)換成 account_name 和 asset 的?
針對 asset 類實現(xiàn)了 from_string 和 to_string 在序列化的時候可以通過反射調(diào)用(具體反射流程我還沒有了解清楚)
針對 account_name 程序中有個 eosio::name 類,還有一個 eosio::chain::name 類,我不了解為什么有兩個類存在,但是,后者是通過實現(xiàn)fc::to_variant 和 fc::from_variant 達到序列化和反序列化的目的,前者還不是很清楚轉(zhuǎn)換的邏輯,不過可 以推測前者也是實現(xiàn)了某種轉(zhuǎn)換函數(shù)。
6. 如何編寫一個 Table ?
Table 的編寫受限目前的代碼形式,暫時給個模板,然后說明一下
// @abi table holderinfo i64
struct holderinfo {
uint64_t contract_id;
std::string insurance_holder;
std::string quantity;
uint64_t insurance_num;
std::string insurance_company_id;
std::string insurance_company_name;
std::string download_url;
std::string time;
std::string state;
uint64_t loan_id;
uint64_t primary_key() const { return loan_id; }
EOSLIB_SERIALIZE(
holderinfo, (contract_id)
(insurance_holder)
(quantity)
(insurance_num)
(insurance_company_id)
(insurance_company_name)
(download_url)
(time)
(state)
(loan_id))
};
- 注釋行 “ // @abi table holderinfo i64” 不可少, 其中的 holderinfo 必須是表名稱,表名稱的命令必須符合 name 的定義,另外 i64 也是不可少的,i64 標示主鍵的類型。
- 類的名稱和表名稱保持一致,原則上可以不一致,但是不一致會有一堆的問題。
- primary_key 是不可少的部分,return 語句最好是列字段的變量,原則上可以是列字段對象的某個成員。
- EOSLIB_SERIALIZE 是個表的序列化宏,我不清楚這個宏是不是必須的,初期當成一個必須的部分,需要注意的是,序列化宏必須和類中的字段定義的順序保持一直,否則在 get table 的時候報錯。
- 如果你符合了上述規(guī)則,那么你就可以使用 eosiocpp 工具自動生成 abi 文件,否則 abi 文件需要手動編寫,具體的就是手動編寫表的部分
7. require_auth 是什么?
這個函數(shù)使用來和 -p 選項合作使用的,但是我一直找不到源碼,不知道它是如何工作的。
合約里面如果有如下代碼
require_auth( _self );
說明 -p 選項需要的是合約的名稱,一個一般性的例子如下:
cleos push action token create '["bank", "10000000.0000 FS"]' -p token
其中 token 是合約名稱
8. 如何寫一個 action?
action 是無返回值的,action 的名字要符合 name 的命名規(guī)則, action 最多接受 64 個參數(shù), action 的輸出會以 JSON 的格式返回給客戶端
9. 為什么 action 需要有個 transaction ?
因為 action 可能會執(zhí)行失敗,如果 action 執(zhí)行失敗了, transaction 可以保證原有的數(shù)據(jù)不會受到破壞!transaction 有點類似原子的操作!
10. require_recipient 這個有什么用?
參考What is the purpose of require_recipient?
require_recipient 是一個類似記錄操作記錄,方便后面的針對 account 操作日志的查詢
11. SEND_INLINE_ACTION 這個有什么作用?
這個可以用來發(fā)送同一個合約里面的 action ,舉個例子:
SEND_INLINE_ACTION(*this, transfer, { st.issuer, N(active) }, { st.issuer, to, quantity, memo });
*this:本對象
transfer: inline action
{ st.issuer, N(active) }: 權(quán)限
{ st.issuer, to, quantity, memo }: inline action parameters
12. 一個賬戶能否同時發(fā)布多個合約?一個合約能否同時被多個賬戶發(fā)布?
一個賬戶只能發(fā)布一個合約,一個合約可以被多個賬戶發(fā)布,他們是各自不同的合約。
13. eosio.token 的表是如何設(shè)計的?
對于 EOSIO 中的 TABLE 有幾點需要明確:
- TABLE 的存儲使用的是 fc::datastream 實現(xiàn)的,這個類的具體實現(xiàn)我不太清楚,可以肯定的是應(yīng)該是流存儲方案。
- TABLE 有兩個非常重要的屬性,一個是owner_account_name,一個是 scope_name,前者其實一個account_name, 我們一般設(shè)計的時候使用合約名稱。后者是一個層級結(jié)構(gòu),標識某個scope_name的范圍,這里有一個設(shè)計問題,為什么是二級劃分?
14. 智能合約執(zhí)行時間有什么要求?
智能合約執(zhí)行時間不能太長,具體的沒有試過,不過如果太長會產(chǎn)生 long transaction 的錯誤