<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Neo核心開發(fā)者:我為N3開發(fā)的第一個智能合約|Neo專欄

          共 4288字,需瀏覽 9分鐘

           ·

          2021-09-10 20:38

          上一篇Neo專欄中

          作者為我們揭秘了引入隨機(jī)數(shù)的具體困難有哪些

          以及Neo在隨機(jī)數(shù)算法領(lǐng)域究竟有何發(fā)展目標(biāo)??


          本篇Neo專欄,

          Neo核心開發(fā)者廖京輝???♂?

          帶您走近他「為N3開發(fā)的第一個智能合約」

          在此過程中遇到的困難和解決方案

          及對N3區(qū)塊鏈開發(fā)平臺的理解與想法??


          快來一起看看吧??

          前兩篇文章里介紹了為N3引入安全隨機(jī)數(shù)的事情,雖然最終版本的隨機(jī)數(shù)算法還在不斷的開發(fā)迭代中,但是現(xiàn)有的N3的區(qū)塊內(nèi)已經(jīng)引入了一個由議長生成的隨機(jī)數(shù),可以用來測試相關(guān)合約。因此,我開發(fā)了一個剪刀石頭布的游戲。一是用來學(xué)習(xí)N3的合約開發(fā),二來是測試一下運(yùn)行時隨機(jī)數(shù)。合約源碼地??https://github.com/Liaojinghui/RPC

          這個剪刀石頭布的游戲很簡單,設(shè)計如下:

          剪刀石頭布

          用戶轉(zhuǎn)GAS給RPC合約,同時傳入一個手勢(以0,1,2 來代表)。


          RPC合約在收到GAS之后就會觸發(fā)OnNEP17Payment 方法并將手勢傳進(jìn)來。


          在OnNEP17Payment 中,RPC會調(diào)用運(yùn)行時的隨機(jī)數(shù)算法來生成一個隨機(jī)數(shù),并將其值約束在0、1、2的范圍內(nèi),之后與用戶手勢進(jìn)行比較。


          如果用戶獲勝,則合約給用戶反向轉(zhuǎn)賬,如果合約獲勝,合約拿走用戶的轉(zhuǎn)賬,如果平手,則交易FAULT。

          用戶每輪的投注需要大于1個GAS,同時需要小于之前合約從用戶那里贏走的錢。也就是說用戶不能期待一把回本,否則合約幾乎永遠(yuǎn)都是輸家。

          在別的平臺如果開發(fā)這樣的合約,在沒有可靠的運(yùn)行時隨機(jī)數(shù)的前提下,用戶需要先將手勢的摘要信息發(fā)送到合約里,然后等待下一個區(qū)塊取某種線上數(shù)據(jù)作為隨機(jī)數(shù),再等待一個區(qū)塊才能將用戶手勢的明文發(fā)送到合約里。為了完成一個簡單的小游戲,這樣的操作不可謂不繁瑣復(fù)雜。而在N3里,只需要一筆交易,所有的過程都可以直接在一個區(qū)塊內(nèi)完成。

          工具方法

          為了方便合約開發(fā),我把常用的權(quán)限控制整理成了OwnerOnly()方法,將條件控制邏輯整理成了Require()方法。

          OwnerOnly()方法是為了對合約接口的調(diào)用權(quán)限進(jìn)行約束。我們把只允許管理員進(jìn)行調(diào)用的接口稱為管理員接口,標(biāo)記為***I_owner***。通常,我們需要對合約調(diào)用的交易的簽名進(jìn)行驗證,只有來自合約擁有者,也就是在合約里標(biāo)記的Owner賬戶的簽名才能合法調(diào)用I_owner接口。這樣的驗證邏輯通常是一致的代碼邏輯,因此,為了方便合約開發(fā),對其進(jìn)行代碼進(jìn)行歸納整理為:

          private static void OwnerOnly() { if (!Verify()) throw new Exception("No authorization."); }

          Require() 方法則是因為各種合約方法內(nèi)部都需要對條件進(jìn)行非常繁瑣的驗證,為了合約安全,我們通常希望合約的驗證越完善越好。但是驗證的過程一般需要引入if語句,而為了邏輯清晰,我們又不能將所有的條件整理成一種。當(dāng)大量的if語句堆疊到一起的時候,代碼就會變得臃腫。

          因此,為了讓合約在進(jìn)行邏輯和條件檢查的時候能更加“優(yōu)雅”,我定義了private static void Require(bool isTrue, string msg = "Invalid")(后文稱Require())。Require() 接收兩個參數(shù),第一個參數(shù)為條件或者條件語句,第二個為可選的錯誤信息。當(dāng)?shù)谝粋€參數(shù)的結(jié)果不是true的時候,Require()就會拋出異常,F(xiàn)AULT這筆交易。同時用戶可以通過第二個參數(shù)來自定義異常信息。方法實(shí)現(xiàn)為:

          private static void Require(bool isTrue, string msg = "Invalid") { if (!isTrue) throw new Exception($"RPC::{msg}"); }

          此外,為了減少由方法調(diào)用而增加的額外開銷,我將這兩個方法都設(shè)置為了內(nèi)聯(lián)函數(shù)。因此兩個方法的最終實(shí)現(xiàn)版本為:

          [MethodImpl(MethodImplOptions.AggressiveInlining)]private static void Require(bool isTrue, string msg = "Invalid") { if (!isTrue) throw new Exception($"RPC::{msg}"); } 


          [MethodImpl(MethodImplOptions.AggressiveInlining)]private static void OwnerOnly() { if (!Verify()) throw new Exception("No authorization."); }

          細(xì)粒度安全要求與嚴(yán)格的安全校驗

          雖然開發(fā)這個小游戲的代碼量并不大,邏輯更是非常簡單,但是為了給以后的合約開發(fā)者積累更多的經(jīng)驗,我還是按照最高標(biāo)準(zhǔn)來去實(shí)現(xiàn)了這個合約的每一個功能。對于合約來說,最高的標(biāo)準(zhǔn)就是安全標(biāo)準(zhǔn)——這一點(diǎn)是毫無爭議的。我始終認(rèn)為合約的開發(fā)應(yīng)該在最小的單位——方法里,就對安全要求進(jìn)行定義并且驗證。并且每個單位應(yīng)該有自己完全獨(dú)立的安全邏輯,比如參數(shù)的驗證一定要在方法內(nèi)部獨(dú)立完成,不能對上層的calling方法傳入的參數(shù)進(jìn)行任何形式的假設(shè),否則肯定會增加的重復(fù)驗證的開銷。但是,對于合約來說,安全大過天,為了保證安全,合約有時不得不“臃腫”。搭乘過飛機(jī)的小伙伴肯定都知道坐飛機(jī)有非常繁瑣的安檢流程,尤其是跨國轉(zhuǎn)機(jī),幾乎每次中轉(zhuǎn)都要重新安檢。這就是為了排除各種風(fēng)險。而合約的開發(fā)就需要這樣對安全認(rèn)真嚴(yán)謹(jǐn)?shù)膽B(tài)度,在每一個最小節(jié)點(diǎn)里定義安全行為,引入安全檢查。

          在該合約里,我是在每個方法的注釋里加入Security Requirements 內(nèi)容來對方法的安全進(jìn)行文字層面的約束,主要就是定義一下參數(shù)的范圍,方法權(quán)限等等。然后在開發(fā)的時候逐一對安全要求進(jìn)行確認(rèn)。再在合約部署在測試網(wǎng)之后對每一個安全要求進(jìn)行測試網(wǎng)上實(shí)際交易的檢驗,當(dāng)檢驗通過時再進(jìn)行最終的確認(rèn)標(biāo)記。也就是在功能測試之外,獨(dú)立進(jìn)行安全測試。舉個例子,合約里的OnNEP17Payment回調(diào)方法:

          OnNEP17Payment回調(diào)方法

          方法的注釋里有四條安全約束,這四條安全約束都在代碼中進(jìn)行了體現(xiàn),具體到代碼所在的行:

          // <2> -- confirmed by jinghuiRequire(!Paused());


           // <3> -- yet to confirmRequire(Runtime.CallingScriptHash == GAS.Hash, "Script format error.");//Require(Runtime.EntryScriptHash == GAS.Hash, "Runtime.EntryScriptHash == ((Transaction)Runtime.ScriptContainer).Hash");if (((Transaction)Runtime.ScriptContainer).Script.Length > 96)    throw new Exception("RPC::Transaction script length error. No wrapper contract or extra script allowed.");// should not be called from a contract// --confirmedRequire(ContractManagement.GetContract(from) is null, "ContractManagement.GetContract(from) is null");


           // <1> -- confirmed by jinghuiRequire(move == 0 || move == 1 || move == 2, "Invalid move."); 


           // <0> -- confirmed by jinghuiRequire(amount >= 1_0000_0000, "Please at least bet 1 GAS.");

          雖然這樣的方式不能排除合約存在漏洞的可能,但是卻可以強(qiáng)制合約開發(fā)者對合約安全進(jìn)行思考并予以約束,進(jìn)而為合約提供最低限度的安全保障。

          最后,特別感謝NGD的陳志同同學(xué)和鴨脖小朋友提供的大量幫助和指點(diǎn)。這個合約部署在N3的測試網(wǎng)上??https://neo3.testnet.neotube.io/contract/0x9c01a8640dff7c086dca99758d71645f57164d7c。感興趣的朋友可以去試試。不過調(diào)用合約最好不要用Neo-cli,這個里面的send命令有點(diǎn)問題,必須傳from字段才能傳data,而且data還只能是string類型。建議大家用別的工具來進(jìn)行調(diào)用。

          合約代碼開源且完全授權(quán),任何同學(xué)都可以對其進(jìn)行任何形式的更改,進(jìn)行任何方式的使用。希望能夠幫助到想要進(jìn)行N3合約開發(fā)的同學(xué)。

          - 推薦閱讀 -

          All in One · All in Neo

          Neo是一個由社區(qū)驅(qū)動的開源平臺。利用區(qū)塊鏈技術(shù)與數(shù)字身份,開發(fā)者可以通過智能合約實(shí)現(xiàn)資產(chǎn)管理數(shù)字化與自動化。Neo致力于通過分布式網(wǎng)絡(luò)建設(shè)下一代互聯(lián)網(wǎng)基礎(chǔ)設(shè)施,為區(qū)塊鏈技術(shù)大規(guī)模落地奠定基礎(chǔ),以實(shí)現(xiàn)智能經(jīng)濟(jì)的宏大愿景。

          自2016年上線至今,Neo主網(wǎng)已穩(wěn)定運(yùn)行超過四年。全新版本Neo N3已于2021年發(fā)布,能夠提供更高吞吐量、更強(qiáng)穩(wěn)定性與安全性,帶來優(yōu)化的智能合約系統(tǒng)及功能豐富的基礎(chǔ)設(shè)施集合,賦能開發(fā)者并加速企業(yè)級區(qū)塊鏈創(chuàng)新。

          瀏覽 53
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本岛国视频在线观看一区二区三区 | 婷婷五月伊人 | 欧美婷婷六月丁香综合色 | 免费无码婬片AAAA片直播表情 | 久久久久久AV少妇 |