【開發入門】EOSIO智能合約實戰#2
節點專欄
10天前
4036

EOSIO smart contract exericse #2


在上一篇的合約實戰中,提到的 require_recipient() 功能在 EOSIO 設計的方便性, 但是相同地如果沒有處理好,也很容易造成漏洞, 我們來看一下一個真實的攻擊案例。

EOSIO 轉帳的流程


eos-reflex-1.png

上面的圖示是一個正常轉帳的動作。 在 EOS 中所布署的 eosio.token 合約 中,只要使用者發起一筆交易,在 eosio.token 合約中正常執行後,就會自動調用 require_recipient() 來通知發起方 和接收法,所以大部份的博彩遊戲項目方都會以這為起點,也就是當收到使用者下注後,收到轉帳通知,來做後續的動作, 所以,二邊都會收到一動作 (Action) 為 transfer() 的呼叫。



好,那這 require_recipient() 會有什麼問題呢?? 如果說,假設黑客在他的攻擊合約中,布署一個和 Dapp 項目方有同樣名稱的動作(Action)名稱, 再配合著 require_recipient() 的話,就可以發送一個通知到另一端合約,且動作(Action)名稱和攻擊合約是一樣的。 換包話說,黑客可以經由 GET ABI 來得知智能合約所公開的 ABI 界面, 並去猜測那些可能是開獎或是發放金額給玩家, 那就有機會達成無本獲利動作, 如下圖中, 在 check() 中使用了 require_recipient()。





eos-reflex-2.png




到此為此,那我們該怎麼預防呢 ?? 其實很簡單, 只要確定合約中的加上如下圖的檢查, 意思是說,假設我們的合約內 check() 動作只充許被本身的合約所調用,那就加上 code == receiver 的檢查即可。


螢幕快照 2019-03-11 下午18.35.52 下午.png


還有另一個早期的攻擊 (但是在寫這篇文章時,還是有新的項目方被攻擊),也是利用了轉帳通知,但是不是轉了真正 EOS ,而可能是其它的代幣(token)。 但是,問題是,要怎麼檢查,我們收到的代幣是主網上真正的 EOS 還是其它人發行的 「假 EOS」, 或是其它代幣呢?? 很簡單,因為在 EOS 主網上, 是利用 eosio.token 合約做 EOS 的代幣發行, 所以, 我們只要去檢查 code == "eosio.token"_n / N(eosio.token) 即可得知發送轉帳通知的合約是不是主網唯一的 「eosio.token」 所發出的。 如下圖所示。

螢幕快照 2019-03-11 下午18.37.49 下午.png



快速總結一下這一篇的要點。

(A) code 變數會因為被調用的合約不同,而有不同的值,請根據自已的合約設計,是否只充許內部調用,適合加上檢查。

(B) 轉帳也有可能是假代幣, 如果不想被白白損失真正 EOS 代幣,也請檢查轉帳通知中的代幣是不是非 eosio.token 發行的代幣。


Chester,eosCity.io 共同創辦人、Novogo 共同創辦人、CLE 中文計劃成員。 早期挖礦玩家,開源碼貢獻者,近年致力於深度學習和區塊鏈整合,期望可以再度以複雜科技解決現實問題。
新聞排行
熱門新聞

© blocktimes——專業的區塊鏈媒體平臺