簡介
本章將深入源碼骇陈,為大家分析eos的系統(tǒng)合約eosio.token的實現(xiàn)細節(jié)。eosio.token是eos的發(fā)幣合約贱案,這個合約主要實現(xiàn)了EOS代幣的創(chuàng)建魏身、發(fā)行惊橱、轉賬等功能。
主要合約方法
eosio.token系統(tǒng)合約的源碼在eos/contracts/eosio.token中箭昵,eos項目方獨立開了github税朴,負責eosio.token合約的更新和維護。
eosio.token合約家制,在eosio.token.hpp頭文件中正林,主要定義了以下三個合約方法:
- create:負責創(chuàng)建資產(chǎn)
- issue:負責發(fā)行資產(chǎn)
- transfer:負責資產(chǎn)轉賬
下面,將為大家一一介紹各個方法的功能實現(xiàn)細節(jié)
create方法
create方法的實現(xiàn)在eosio.token.cpp中颤殴,需要傳入兩個參數(shù)完成幣種創(chuàng)建:
- issuer:資產(chǎn)發(fā)行賬戶
-?maximum_supply:最大發(fā)行量
ceate方法調用實例如下觅廓,eosio.token合約部署在eosio.token賬戶,資產(chǎn)發(fā)行賬戶為eosio涵但,最大發(fā)行量10億杈绸,幣種精度4帖蔓,幣種符號EOS
cleos push action eosio.token create '[ "eosio", "1000000000.0000 EOS"]' -p eosio.token
深入源碼來看,create方法通過以下步驟完成了資產(chǎn)的創(chuàng)建:
- 獲取eosio.token合約部署賬戶的授權
- 判斷幣種符號 (sysmol name) 是否合法蝇棉,幣種符號必須是大寫字母讨阻,長度小于8位
-?判斷發(fā)行量是否越界且是否為正數(shù),支持的最大發(fā)行量 amount <=?2^62-1
- 查詢statstable表篡殷,判斷代幣符號是否存在,eosio.token支持發(fā)行多資產(chǎn)
- 建表埋涧,將代幣符號板辽、發(fā)行總量、發(fā)行方存入數(shù)據(jù)庫
以上步驟棘催,主要邏輯詳見:eos/contracts/eosiolib/symbol.hpp劲弦、eos/contracts/eosiolib/asset.hpp、eos/contracts/eosiolib/multi_index.hpp
issue方法
create方法的實現(xiàn)在eosio.token.cpp中醇坝,需要傳入兩個參數(shù)完成幣種的發(fā)行:
- to:發(fā)行金額打入的賬戶
-?quantity:發(fā)行金額
- memo:交易備注
issue方法調用實例如下邑跪,資產(chǎn)發(fā)行賬戶eosio授權,將10億EOS打入eosio賬戶中呼猪,備注是test issue
cleos push action eosio.token issue '[ "eosio", "1000000000.0000 EOS", "test issue"]' -p eosio
深入源碼來看画畅,issue方法通過以下步驟完成了資產(chǎn)的發(fā)行:
- 前置檢查:查表判斷幣種是否存在、memo最大長度不能超過256字節(jié)
- 查表獲取幣種信息:發(fā)行賬戶宋距、最大發(fā)行量轴踱、幣種精度、幣種符號
- 獲取發(fā)行賬戶的授權
- 前置檢查:發(fā)行金額為正數(shù)且不超過最大發(fā)行量谚赎、幣種精度校驗
- 更新表淫僻,增加發(fā)行資產(chǎn)的余額
- 如果to賬戶和發(fā)行賬戶不一致,調用內聯(lián)合約轉賬
以上步驟壶唤,主要邏輯詳見:eos/contracts/eosiolib/symbol.hpp雳灵、eos/contracts/eosiolib/asset.hpp、eos/contracts/eosiolib/multi_index.hpp闸盔、eos/contracts/eosiolib/currency.hpp
這里特別要說明最后一個步驟悯辙,內聯(lián)合約的調用。實現(xiàn)邏輯在eos/contracts/eosiolib/currency.hpp
eos智能合約之間蕾殴,通過action通信笑撞,共享數(shù)據(jù)庫存儲。一個智能合約钓觉,可以異步的讀取另一個智能合約的數(shù)據(jù)庫狀態(tài)茴肥。智能合約有兩種通信狀態(tài):
- Inline 內聯(lián)合約。指的是在一個已有的交易里調用其他智能合約的方法荡灾。如果當前交易失敗了瓤狐,內聯(lián)合約的執(zhí)行也不受影響瞬铸,內聯(lián)合約執(zhí)行失敗或成功并沒有通知,但執(zhí)行成功會上鏈
- Deffered 延遲合約础锐。指的是不是立即執(zhí)行嗓节,而是在未來的某個時間計劃去執(zhí)行的合約。當前皆警,可以構造一個交易去發(fā)送延遲合約交易拦宣,也可以發(fā)送一個交易去取消延遲合約。延遲合約也不能保證執(zhí)行成功信姓,執(zhí)行失敗或者成功并沒有通知鸵隧,但執(zhí)行成功會上鏈
在issue方法中,當發(fā)現(xiàn)issuer賬戶和to賬戶不一致時意推,會調用lnline合約豆瘫,觸發(fā)eosio.token合約的transfer方法,將發(fā)行的金額轉入to賬戶菊值。當我們執(zhí)行issue方法后外驱,會發(fā)現(xiàn)除了產(chǎn)生issue的action后,還會有transfer的action:
transfer方法
transfer方法的實現(xiàn)在eosio.token.cpp中腻窒,需要傳入四個參數(shù)完成幣種的轉賬:
- from:出幣賬戶
- to:入金賬戶
-?quantity:轉賬金額
- memo:交易備注
深入源碼來看昵宇,issue方法通過以下步驟完成了資產(chǎn)的轉賬:
- 前置檢查:判斷是否轉賬給自己、判斷to賬戶是否存在
- 獲得from賬戶的授權
- 獲取幣種信息:發(fā)行賬戶定页、最大發(fā)行量趟薄、幣種精度、幣種符號
- 分別通知from典徊、to賬戶合約調用結果
- 前置檢查:轉賬金額為正且不超過最大發(fā)行量杭煎、幣種精度正確、memo長度不大于256
- 加減from和to地址賬戶余額
以上步驟卒落,主要邏輯詳見:eos/contracts/eosiolib/symbol.hpp羡铲、eos/contracts/eosiolib/asset.hpp、eos/contracts/eosiolib/multi_index.hpp儡毕、eos/contracts/eosiolib/currency.hpp
這里特別要說明第四個步驟也切,通知from、to賬戶合約調用結果腰湾。實現(xiàn)邏輯在eos/contracts/eosiolib/action.hpp雷恃、eos/libraries/chain/apply_context.cpp、eos/libraries/chain/transaction_context.cpp
首先倒槐,eosio智能合約的執(zhí)行結果,會分別通知from附井、to讨越、eosio.token两残。我們發(fā)送轉賬交易,會發(fā)現(xiàn)有三條actions把跨,通知所有涉及的賬戶人弓,這是eos系統(tǒng)合約設計的通知機制。大家在執(zhí)行cleos get actions獲取交易結果時着逐,可以通過receiver過濾出發(fā)給自己賬戶的通知崔赌。
receipt的通知詳情滨嘱,調用cleos get actions bp1 -j 獲确灞伞:
后記
本章為大家介紹了eosio.token合約的實現(xiàn)細節(jié),從源碼層面為大家分析了eosio.token如何實現(xiàn)資產(chǎn)的創(chuàng)建太雨、發(fā)行、轉賬的魁蒜。
目前囊扳,基于eos發(fā)行資產(chǎn)的項目方,都會參考eosio.token的實現(xiàn)兜看,去實現(xiàn)自己的發(fā)幣合約锥咸。但是,由于eos是一個剛剛完成主網(wǎng)上線的新項目细移,有許多隱藏的bug有待發(fā)現(xiàn)搏予。例如,我們最后講到的transfer方法的receipt通知機制弧轧,由于實現(xiàn)過于復雜雪侥,前段時間就被慢霧發(fā)現(xiàn)了有嚴重的安全漏洞,會使交易所的提幣賬戶ram被耗盡精绎,詳細issue速缨。
因此,大家在編寫自己的發(fā)幣合約時代乃,務必要檢查好相關邏輯旬牲,以免被惡意攻擊造成資產(chǎn)的損失。eos社區(qū)目前還沒有出合約代碼的標準規(guī)范搁吓,但我相信不久的將來原茅,一定會有詳細的規(guī)范出臺。
接下來的文章堕仔,將繼續(xù)從源碼層面為大家講解eos的系統(tǒng)合約實現(xiàn)細節(jié)擂橘,盡請期待!