公鏈也是一款產品,產品經理和你聊聊公鏈產品如何設計。
一則老新聞,2018年12月19日上午,BetDice、EOSMax相繼發(fā)布公告稱,遭受“回滾攻擊”,其中BetDice損失20萬EOS,EOSMax損失5萬EOS。

隨后,EOS區(qū)塊鏈的開發(fā)團隊甩鍋給DAPP開發(fā)者,大意就是漏洞是因為DAPP開發(fā)者開發(fā)水平爛導致,漏洞與EOSIO無關,并告誡廣大開發(fā)者讀、寫節(jié)點要分離。
但產品經理不以為然,殊不知好的產品不需要思考,要把用戶當傻子,一切用戶的問題都是產品的問題,以下省略一萬字。。。
先說說EOS上這次攻擊是怎么發(fā)生的。
這兩款DAPP都屬于博彩游戲,類似下注猜大猜小,用戶發(fā)送一筆交易,結果要不是贏要不是輸。從公鏈內部看,流程是:
1)DAPP會對接一個API節(jié)點,DAPP構造一筆下注交易后,會先在這個API節(jié)點上預執(zhí)行,校驗這筆交易有效后,這個全節(jié)點一邊修改自己數據庫,一邊將這筆交易廣播給網絡內的其他節(jié)點,包括出塊節(jié)點。注意此時DAPP對接的全節(jié)點只是單方面修改了自己的數據庫,交易結果并沒有上鏈;
2)出塊節(jié)點收到這筆交易后就會發(fā)起共識,共識通過后再將結果廣播給全網節(jié)點,包括DAPP對接的API節(jié)點,此時全網節(jié)點都會修改數據庫,交易結果真正上鏈;
3)DAPP對接的API節(jié)點收到出塊節(jié)點的結果,比對自己的數據庫,如果不一致,就要回滾數據。
黑客就抓住了API節(jié)點和出塊節(jié)點同步時間差的漏洞,黑客發(fā)起一筆交易,并實時查詢API節(jié)點的預執(zhí)行結果。如果結果是黑客贏了,那黑客就不做任何操作,最終上鏈的結果也一定是黑客贏;但如果結果是黑客輸了,那黑客就同時發(fā)送一筆轉賬交易直達當前正出塊的節(jié)點上,讓賬號余額不足以完成先前的那筆輸交易,那么先前的那筆交易就會被廢棄,那么黑客就不會輸了。
為了解決這個問題,EOS開發(fā)團隊提的方案是“讀寫節(jié)點分離”,也就是DAPP需要對接兩個API節(jié)點。一個節(jié)點只有寫的權限,黑客下注的交易在該節(jié)點上預執(zhí)行,但黑客沒辦法查詢到該節(jié)點的預執(zhí)行結果是輸還是贏。另一個節(jié)點只有讀的權限,黑客的交易不會在該節(jié)點上預執(zhí)行。
這個方案其實是一個填坑方案,對于沒踩過坑的開發(fā)者來說,可能還是會翻車。另外,這個方案要求開發(fā)者需要對接兩個API節(jié)點,成本無疑是增加的。
一個好的公鏈,DAPP開發(fā)者的用戶體驗非常重要,最好做到不挖坑。那么從公鏈底層,怎么設計才能避免這個問題呢?
比特幣、ETH 1.0采用的POW共識機制,天生不會發(fā)生這樣的問題。因為POW機制下,出塊節(jié)點是隨機、不確定的,黑客沒辦法用一筆轉賬交易精準的發(fā)到出塊節(jié)點上,提前攔截輸交易。而EOS采用的是PBFT共識算法,出塊節(jié)點是可預測的。
我現在所在的公鏈項目,采用的也是PBFT算法,通過將共識網絡和路由網絡分離來避免“回滾攻擊”??蛻舳俗x、寫數據只能通過最外層的路由網絡與鏈交互,DAPP只需要對接一個路由節(jié)點即可。首先路由節(jié)點收到DAPP交易后不會做任何預執(zhí)行,所以黑客無法在路由節(jié)點上提前查詢到預執(zhí)行的結果是輸還是贏;再則路由節(jié)點會將交易隨機丟給共識網絡中的一些節(jié)點,所以黑客也無法定位到共識節(jié)點查詢預執(zhí)行結果。