1. 如何處理錯(cuò)誤疚脐?
使用函數(shù) eosio_assert 或者類似的方法用來(lái)返回錯(cuò)誤
2. account_name 如何和字符串相互轉(zhuǎn)換碧囊?
account_name 是 uint64_t 類型蚓土,EOSIO 提供了一套方式可以將字符串轉(zhuǎn)換成 name肖粮, 不過(guò)這種方式是有限制條件的:
字符集:".12345abcdefghijklmnopqrstuvwxyz"
字符串不能超過(guò)13個(gè)字符
涉及相關(guān)函數(shù)是:
::eosio::string_to_name
::eosio::name::to_string
3. asset 是個(gè)什么類革半?
4. asset 如何和字符串相互轉(zhuǎn)換砂蔽?
asset 類有兩個(gè)成員函數(shù) from_string 和 to_string
5. 智能合約是如何實(shí)現(xiàn)外部調(diào)用的時(shí)候?qū)⒆址D(zhuǎn)換成 account_name 和 asset 的洼怔?
針對(duì) asset 類實(shí)現(xiàn)了 from_string 和 to_string 在序列化的時(shí)候可以通過(guò)反射調(diào)用(具體反射流程我還沒(méi)有了解清楚)
針對(duì) account_name 程序中有個(gè) eosio::name 類,還有一個(gè) eosio::chain::name 類左驾,我不了解為什么有兩個(gè)類存在镣隶,但是,后者是通過(guò)實(shí)現(xiàn)fc::to_variant 和 fc::from_variant 達(dá)到序列化和反序列化的目的诡右,前者還不是很清楚轉(zhuǎn)換的邏輯安岂,不過(guò)可 以推測(cè)前者也是實(shí)現(xiàn)了某種轉(zhuǎn)換函數(shù)。
6. 如何編寫一個(gè) Table 稻爬?
Table 的編寫受限目前的代碼形式嗜闻,暫時(shí)給個(gè)模板,然后說(shuō)明一下
// @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 標(biāo)示主鍵的類型翠肘。
- 類的名稱和表名稱保持一致檐束,原則上可以不一致,但是不一致會(huì)有一堆的問(wèn)題束倍。
- primary_key 是不可少的部分被丧,return 語(yǔ)句最好是列字段的變量,原則上可以是列字段對(duì)象的某個(gè)成員绪妹。
- EOSLIB_SERIALIZE 是個(gè)表的序列化宏甥桂,我不清楚這個(gè)宏是不是必須的,初期當(dāng)成一個(gè)必須的部分邮旷,需要注意的是黄选,序列化宏必須和類中的字段定義的順序保持一直,否則在 get table 的時(shí)候報(bào)錯(cuò)婶肩。
- 如果你符合了上述規(guī)則办陷,那么你就可以使用 eosiocpp 工具自動(dòng)生成 abi 文件,否則 abi 文件需要手動(dòng)編寫律歼,具體的就是手動(dòng)編寫表的部分
7. require_auth 是什么民镜?
這個(gè)函數(shù)使用來(lái)和 -p 選項(xiàng)合作使用的,但是我一直找不到源碼险毁,不知道它是如何工作的制圈。
合約里面如果有如下代碼
require_auth( _self );
說(shuō)明 -p 選項(xiàng)需要的是合約的名稱,一個(gè)一般性的例子如下:
cleos push action token create '["bank", "10000000.0000 FS"]' -p token
其中 token 是合約名稱
8. 如何寫一個(gè) action辱揭?
action 是無(wú)返回值的离唐,action 的名字要符合 name 的命名規(guī)則, action 最多接受 64 個(gè)參數(shù)问窃, action 的輸出會(huì)以 JSON 的格式返回給客戶端
9. 為什么 action 需要有個(gè) transaction 亥鬓?
因?yàn)?action 可能會(huì)執(zhí)行失敗,如果 action 執(zhí)行失敗了域庇, transaction 可以保證原有的數(shù)據(jù)不會(huì)受到破壞嵌戈!transaction 有點(diǎn)類似原子的操作!
10. require_recipient 這個(gè)有什么用听皿?
參考What is the purpose of require_recipient?
require_recipient 是一個(gè)類似記錄操作記錄熟呛,方便后面的針對(duì) account 操作日志的查詢
11. SEND_INLINE_ACTION 這個(gè)有什么作用?
這個(gè)可以用來(lái)發(fā)送同一個(gè)合約里面的 action 尉姨,舉個(gè)例子:
SEND_INLINE_ACTION(*this, transfer, { st.issuer, N(active) }, { st.issuer, to, quantity, memo });
*this:本對(duì)象
transfer: inline action
{ st.issuer, N(active) }: 權(quán)限
{ st.issuer, to, quantity, memo }: inline action parameters
12. 一個(gè)賬戶能否同時(shí)發(fā)布多個(gè)合約庵朝?一個(gè)合約能否同時(shí)被多個(gè)賬戶發(fā)布?
一個(gè)賬戶只能發(fā)布一個(gè)合約,一個(gè)合約可以被多個(gè)賬戶發(fā)布九府,他們是各自不同的合約椎瘟。
13. eosio.token 的表是如何設(shè)計(jì)的?
對(duì)于 EOSIO 中的 TABLE 有幾點(diǎn)需要明確:
- TABLE 的存儲(chǔ)使用的是 fc::datastream 實(shí)現(xiàn)的侄旬,這個(gè)類的具體實(shí)現(xiàn)我不太清楚肺蔚,可以肯定的是應(yīng)該是流存儲(chǔ)方案。
- TABLE 有兩個(gè)非常重要的屬性儡羔,一個(gè)是owner_account_name宣羊,一個(gè)是 scope_name,前者其實(shí)一個(gè)account_name, 我們一般設(shè)計(jì)的時(shí)候使用合約名稱汰蜘。后者是一個(gè)層級(jí)結(jié)構(gòu)仇冯,標(biāo)識(shí)某個(gè)scope_name的范圍,這里有一個(gè)設(shè)計(jì)問(wèn)題族操,為什么是二級(jí)劃分赞枕?
14. 智能合約執(zhí)行時(shí)間有什么要求?
智能合約執(zhí)行時(shí)間不能太長(zhǎng)坪创,具體的沒(méi)有試過(guò),不過(guò)如果太長(zhǎng)會(huì)產(chǎn)生 long transaction 的錯(cuò)誤