<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>

          Solidity智能合約庫:區(qū)塊鏈工程師的隨身工具箱

          共 10511字,需瀏覽 22分鐘

           ·

          2021-04-22 11:36

          區(qū)塊鏈技術在經(jīng)歷了十余年的發(fā)展后,漸呈“燎原之勢”,不斷在各行業(yè)落地生根。但同時,從技術的角度看,區(qū)塊鏈應用開發(fā)仍然有著較高的門檻,存在不少痛點。為了提升應用開發(fā)各環(huán)節(jié)的用戶體驗,微眾銀行將自主研發(fā)的區(qū)塊鏈應用開發(fā)組件WeBankBlockchain-SmartDev全面開源,多維度提速區(qū)塊鏈應用開發(fā)效率。開源公告詳見《區(qū)塊鏈應用開發(fā)組件:助力低代碼開發(fā)》。

          WeBankBlockchain-SmartDev所包含的智能合約庫組件,涵蓋了從基礎類型到上層業(yè)務的常見Solidity庫代碼,用戶可根據(jù)實際需要進行參考、復用。該智能合約庫已經(jīng)集成到國家信息中心頂層設計的區(qū)塊鏈服務網(wǎng)絡BSN、微眾銀行自主研發(fā)的區(qū)塊鏈中間件平臺WeBASE中,并在供應鏈金融、存證、農牧溯源等多個業(yè)務場景中廣泛應用。我們期待區(qū)塊鏈技術愛好者和開源社區(qū)的伙伴們,一同參與共建,協(xié)力推動Solidity智能合約庫向更成熟的技術、更完善的生態(tài)上發(fā)展。

            智能合約庫簡介

          作為一門實現(xiàn)了圖靈完備的智能合約編程語言,Solidity編程語言的開發(fā)、設計、迭代、演化的邏輯完全基于區(qū)塊鏈,并在區(qū)塊鏈領域具有廣泛的影響力和詳盡的文檔,被眾多區(qū)塊鏈底層平臺所支持,其中就包括FISCO BCOS。

          但是,Solidity編程語言也存在若干挑戰(zhàn)。首先,受區(qū)塊鏈昂貴的資源限制,Solidity舍去了諸多在其他語言中常見的特性,例如高級的語法等。其次,流行的Solidity智能合約庫多為公有鏈所開發(fā),與FISCO BCOS存在兼容性的問題。最后,智能合約編程的安全性要求高,且較難對合約進行升級,一旦存在安全漏洞,后果不堪設想。

          為了解決上述問題,WeBankBlockchain-SmartDev-Contract智能合約庫應運而生,包含了基礎類型、數(shù)據(jù)結構、通用功能、上層業(yè)務等智能合約庫。用戶可根據(jù)實際需求進行參考、復用。智能合約庫的設計初衷是提供場景化、通用化、可插拔的智能合約代碼,從而最大程度地節(jié)約開發(fā)智能合約的時間,改變智能合約工具庫匱乏的局面。

          SmartDev-Contract智能合約庫是一個“麻雀雖小,五臟俱全”的智能合約的工具類庫,通過Solidity的library封裝,旨在幫助Solidity開發(fā)者提升開發(fā)體驗,避免重復造輪子,讓編寫Solidity語言也可以如編寫Python語言那樣“絲滑順暢”。

          SmartDev-Contract智能合約庫的每個合約文件都來自于微眾銀行區(qū)塊鏈工程師的細致打磨,來自于實際使用場景的“聚沙成塔”,覆蓋了業(yè)務場景開發(fā)中的各種“犄角旮旯”,是開發(fā)智能合約的“10倍工程師”的不二法門。

          從功能上來看,SmartDev-Contract智能合約庫涵蓋了從基礎類型到上層業(yè)務的常見代碼,用戶可根據(jù)實際需要進行參考、復用。具體如下:


            痛點及解決方式

          以在Solidity語言中將address類型轉為string為例。

          過去:
          打開搜索引擎或github->搜索關鍵字“Solidity address convert to string”->找到相關的搜索結果->拷貝相關的代碼->粘貼到自己的智能合約代碼中。
          如果無法搜索到相關的代碼,開發(fā)者必須重新造輪子,耗時耗力的同時,還可能引入新的風險。

          現(xiàn)在:
          直接下載智能合約代碼庫->解壓->找到相關的庫合約->引入代碼->調用相關函數(shù)。智能合約代碼庫地址:
          https://github.com/WeBankBlockchain/SmartDev-Contract/archive/refs/tags/V1.0.0.zip
          pragma solidity ^0.4.25;import "./LibAddress.sol" contract Demo { ... address addr = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9; bytes memory bs = LibAddress.addressToBytes(addr);}

          開發(fā)者引入或拷貝網(wǎng)絡上未知來源的代碼可能出現(xiàn)重大的bug。同樣的,自己重新編寫的代碼可能因為缺乏測試或實踐檢驗,更易出現(xiàn)風險。智能合約庫提供了方便、成熟、安全、低成本的解決方案。

          痛點一:計算可能溢出

          在智能合約的開發(fā)中,數(shù)值計算問題不可避免。但是,Solidity內置的運算機制不夠安全,因計算問題導致的智能合約安全事故屢見不鮮。

          SmartDev-Contract智能合約庫提供了安全計算的代碼類庫。以uint256數(shù)據(jù)類型為例,LibSafeMathForUint256Utils提供了Uint256類型的相關計算操作,且保證數(shù)據(jù)的正確性和安全性,包括加法、減法、乘法、除法、取模、乘方、最大值、最小值和平均數(shù)等操作。其他的數(shù)值類型可以自行參考實現(xiàn)。

          1、加減乘除運算
          function f() public view { uint256 a = 25; uint256 b = 20; // a + b uint256 c = LibSafeMathForUint256Utils.add(a,b); // a - b uint256 d = LibSafeMathForUint256Utils.sub(a,b); // a * b uint256 e = LibSafeMathForUint256Utils.mul(a,b); // a/b uint256 f = LibSafeMathForUint256Utils.div(a,b);}

          2、取模運算、乘方運算
          function f() public view { uint256 a = 25; uint256 b = 20; // a % b uint256 c = LibSafeMathForUint256Utils.mod(a,b); // a ^ b uint256 d = LibSafeMathForUint256Utils.power(a,b);}
          3、最大值、最小值、平均數(shù)運算
          function f() public view { uint256 a = 25; uint256 b = 20; // max(a, b) uint256 c= LibSafeMathForUint256Utils.max(a,b); // min(a, b) uint256 d = LibSafeMathForUint256Utils.min(a,b); // average(a, b) uint256 e = LibSafeMathForUint256Utils.average(a,b);}

          痛點二:轉換不夠便捷

          數(shù)值轉換工具

          基礎數(shù)據(jù)類型轉換是編程語言的剛需。LibConverter提供各類Solidity數(shù)據(jù)基本類型的轉換,開發(fā)者可以根據(jù)此工具擴展為其他的數(shù)值轉換類型和函數(shù)。

          1、數(shù)值類型向下轉換,例如uint256轉換為uint8。
          function f() public view{ uint256 a = 25; uint8 b = LibConverter.toUint8(a);}

          2、數(shù)值類型轉bytes
          function f() public view{ uint256 a = 25; bytes memory b = LibConverter.uintToBytes(a);}

          3、bytes轉數(shù)值類型
          function f() public view{ bytes memory a = "25"; int b = LibConverter.bytesToInt(a);}

          address轉換工具

          address類型是Solidity特有的數(shù)據(jù)類型之一。在日常的程序運行邏輯中,常常會涉及到address與bytes和string類型的互轉。LibAddress實現(xiàn)了上述的轉換功能。

          address轉bytes
          address addr = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9;bytes memory bs = LibAddress.addressToBytes(addr);

          bytes轉address
          bytes memory bs = newbytes(20);address addr = LibAddress.bytesToAddress(bs);

          address轉string
          address addr = 0xE0f5206BBD039e7b0592d8918820024e2a7437b9;string memory addrStr = LibAddress.addressToString(addr);

          string轉address
          string memory str="0xE0f5206BBD039e7b0592d8918820024e2a7437b9";address addr = LibAddress.stringToAddress(str);

          痛點三:數(shù)組操作不夠豐富

          在Solidity中原生支持的數(shù)組類型,不支持排序、查找、比較、移除、添加、翻轉、合并、去重等眾多常用的功能。

          SmartDev-Contract智能合約庫基于動態(tài)數(shù)組的結構封裝了“LibArrayForUint256Utils”的常用工具函數(shù)實現(xiàn)。開發(fā)者也可根據(jù)自身需要的數(shù)據(jù)結構,自行封裝相關的工具類。

          1、添加不重復的元素
          uint[] private array;function f() public view { array=new uint[](0); // array add element 2 LibArrayForUint256Utils.addValue(array,2); // array: {2}}

          2、合并兩個數(shù)組
          uint[] private array1;uint[] private array1;function f() public view { array1=new uint[](2); array2=new uint[](2); LibArrayForUint256Utils.extend(array1,array2); // array1 length 4}

          3、對數(shù)組去重
          uint[] private array;function f() public view { array=new uint[](2); array[0]=2; array[1]=2; LibArrayForUint256Utils.distinct(array); // array: {2}}

          4、對數(shù)組升序排序
          uint[] private array;function f() public view { array=new uint[](3); array[0]=3; array[1]=2; array[2]=1; LibArrayForUint256Utils.qsort(array); // array: {1,2,3}}

          5、二分查找

          基于已排序的數(shù)組,支持二分查找,提升查找的效率。
          uint[] private array;function f() public view { array=new uint[](3); array[0]=3; array[1]=2; array[2]=1; uint256 key=3; LibArrayForUint256Utils.binarySearch(array,key); // array: {true, 1}}

          6、刪除元素
          uint[] private array;function f() public view { array=new uint[](3); array[0]=3; array[1]=2; array[2]=1; LibArrayForUint256Utils.removeByValue(array,2); // array: {3, 1}}

          痛點四:不提供字符串內置操作

          對字符串的操作是開發(fā)中較為常見的操作,例如獲取字符串長度、大小寫轉換等。在其他開發(fā)語言中,通常會提供一些內置的字符串處理類庫。但Solidity本身沒有提供字符串內置操作,因此,這部分需求可通過使用SmartDev-Contract智能合約庫來滿足。

          在SmartDev-Contract智能合約庫中,對于字符串,我們提供了豐富的功能,這里列舉三個比較常見的函數(shù)。

          1、獲取字符串長度

          下面的示例中,分別示意了獲取字符串長度、字符串字節(jié)數(shù):
          pragma solidity ^0.4.25;import "./LibString.sol";contract Test { function f() public{ string memory str = "你好"; uint256 lenOfChars = LibString.lenOfChars(str); uint256 lenOfBytes = LibString.lenOfBytes(str); require(lenOfChars == 2); require(lenOfBytes == 6); }}

          2、大小寫轉換

          下面示例中,將大寫轉換為小寫:
          pragma solidity ^0.4.25;import "./LibString.sol";contract Test { function f() public view returns(string memory) { string memory c = LibString.toUppercase("abcd");// Expected to be ABCD return c; }}

          3、相等比較
          pragma solidity ^0.4.25;import "./LibString.sol";contract Test { function f() public view { bool r = LibString.equal("abcd","abcd");//Expected to be true require(r); }}

          4、字符串前綴比較
          pragma solidity ^0.4.25;import "./LibString.sol";contract Test { function f() public view { bool r = LibString.startWith("abcd","ab");//Expected to be true require(r); }}

          痛點五:高級數(shù)據(jù)結構不完備

          作為一門面向區(qū)塊鏈的語言,Solidity為了節(jié)省資源,在數(shù)據(jù)結構層面砍掉了許多特性,這使得和常規(guī)語言相比,其在使用上存在較大差異。一方面,Solidity內部僅提供了數(shù)組、mapping等數(shù)據(jù)結構,如果存在其他需求,需自助實現(xiàn);另一方面,對于mapping,其內部的鍵僅保存了哈希值,無法獲取鍵的原值。

          綜上所述,我們在SmartDev-Contract智能合約庫中提供了對數(shù)據(jù)結構的增強支持,以資參考、使用。

          Mapping映射

          在下面這個例子中,定義了一個Map,然后向里面存放了三個鍵值對。再通過迭代的方式將key取出,存放在事件里。
          pragma solidity ^0.4.25;import "./LibBytesMap.sol";
          contract Test { using LibBytesMap for LibBytesMap.Map; LibBytesMap.Map private map; event Log(bytes key, uint256 index); function f() public { string memory k1 = "k1"; string memory k2 = "k2"; string memory k3 = "k3"; string memory v1 = "v1"; string memory v2 = "v2"; string memory v3 = "v3"; map.put(bytes(k1),bytes(v1)); map.put(bytes(k2),bytes(v2)); map.put(bytes(k3),bytes(v3)); // 開始迭代 uint256 i = map.iterate_start(); while(map.can_iterate(i)){ emit Log(map.getKeyByIndex(i), i); i = map.iterate_next(i); } }}

          address set集合

          作為多數(shù)高級編程語言標配的數(shù)據(jù)結構,set是一種集合的數(shù)據(jù)結構,其中每個獨特屬性的元素都是唯一的。

          SmartDev-Contract智能合約庫依托動態(tài)數(shù)組和mapping,實現(xiàn)了一個基礎的set集合。此外,由于Solidity不支持泛型機制,開發(fā)者可以參考此工具,實現(xiàn)其他元素的set集合。
          pragma solidity ^0.4.25;
          import "./LibAddressSet.sol";
          contract Test { using LibAddressSet for LibAddressSet.AddressSet; LibAddressSet.AddressSet private addressSet; event Log(uint256 size); function testAddress() public { //添加元素; addressSet.add(address(1)); // {1} // 查詢set容器數(shù)量 uint256 size = addressSet.getSize(); require(size == 1); // 獲取指定index的元素 address addr = addressSet.get(0); require(addr == address(1)); // 返回set中所有的元素 addressSet.getAll(); // {0x1} // 判斷元素是否存在 bool contains = addressSet.contains(address(1)); require(contains== true); // 刪除元素 addressSet.remove(address(1)); }}
          除了LibBytesMap和LibAddressSet之外,SmartDev-Contract智能合約庫還包含了堆、棧、單向隊列、雙向隊列、雙向鏈表等實用的數(shù)據(jù)結構。

            業(yè)務場景的合約模板

          針對上層的業(yè)務場景,我們選擇聯(lián)盟鏈落地中最常見、典型的存證和積分業(yè)務場景,提供智能合約代碼實例。開發(fā)者可以基于自身的實際業(yè)務場景修改智能合約代碼,也可以參考場景中的部分代碼,進行擴展和裁剪。

          場景一:存證場景

          電子數(shù)據(jù)存證是記錄“用戶身份驗證-數(shù)據(jù)創(chuàng)建-存儲-傳輸”全過程的方式,應用一系列安全技術全方位確保電子數(shù)據(jù)的真實性、完整性、安全性,在司法上具備完整的法律效力。

          使用區(qū)塊鏈智能合約進行數(shù)據(jù)存在,具有以下優(yōu)勢:
          • 區(qū)塊鏈技術完善的防篡改機制:使用區(qū)塊鏈技術保全證據(jù),進一步加強了證據(jù)不可篡改性。

          • 證據(jù)效力得到機構認可:司法機構作為鏈上節(jié)點,對鏈數(shù)據(jù)參與認可和簽名,事后可從鏈上確認數(shù)據(jù)的真實有效性。

          • 服務持續(xù)有效:數(shù)據(jù)被多方共識上鏈后,即使有部分共識方退出也不會造成數(shù)據(jù)的丟失或失效。


          簡要業(yè)務流程

          • 在存證場景中可以抽象出三類典型用戶:存證方、審核方和取證方。存證方提交需要存證的申請。

          • 審核方基于內容,對存證數(shù)據(jù)進行審核和簽名確認。實際業(yè)務場景中,審核方可能會涉及投票和多方審核的多簽過程。

          • 當存證上鏈后,取證方可隨時查詢存證者地址、時間戳和審核詳情等相關信息進行核驗。




          合約概要設計

          首先,代碼設計了邏輯和數(shù)據(jù)層分離。因為Solidity智能合約語言沒有獨立數(shù)據(jù)層,為便于合約后續(xù)擴展、升級,需要將邏輯和數(shù)據(jù)層分離,體現(xiàn)在下圖中就是將數(shù)據(jù)層和控制層區(qū)分開。

          其次,依據(jù)合約單一職責原理,代碼中引入了權限層。在一條聯(lián)盟鏈上所有節(jié)點可以自由訪問鏈上數(shù)據(jù),智能合約提供了一種修飾器機制,可控制合約給指定授權用戶訪問。


          具體的結構如下:
          • Authentication:權限合約,用于提供基礎的權限控制功能。

          • EvidenceRepository:存證數(shù)據(jù)倉庫,它繼承了權限合約,所有存證數(shù)據(jù)都被保存到數(shù)據(jù)合約里。這樣可以起到統(tǒng)一存儲、統(tǒng)一管理的效果。

          • RequestRepository:請求數(shù)據(jù)倉庫,存儲了存證數(shù)據(jù)和投票請求信息等。存證方開始提交存證數(shù)據(jù)并不會直接被寫入存證倉庫中,而是經(jīng)過審核方簽名完成后才會真正提交,審核方可以為多方。

          • EvidenceController:控制器,引入了兩個數(shù)據(jù)倉庫合約,可以完成所有用戶接口的交互。包含了創(chuàng)建存證請求,審核人根據(jù)請求進行投票的功能。



          場景二:積分場景

          區(qū)塊鏈積分場景是指多個獨立對等的零售商組成聯(lián)盟,利用公眾聯(lián)盟鏈為消費者提供真正意義上的全渠道綜合消費體驗。

          在積分場景中引入?yún)^(qū)塊鏈,具有以下優(yōu)勢:
          • 區(qū)塊鏈技術可以增加品牌曝光度:多個機構組成積分聯(lián)盟,積分可有效通兌,實現(xiàn)客戶資源引流,提升營銷效果。
          • 保證積分安全性:所有積分的生成和流轉過程保存到鏈上,防止商戶篡改和抵賴。
          • 提升用戶體驗:不同商戶和用戶之間實現(xiàn)積分流轉、互通,更加便利。


          簡要業(yè)務流程

          基于區(qū)塊鏈技術,多個商家組成積分聯(lián)盟,實現(xiàn)積分通存通兌、客戶資源相互引流等。管理者部署和管理合約。商家有發(fā)行積分、拉入其他商家、撤銷發(fā)行者身份的權限。消費者有開戶、銷戶、消費積分和積分轉賬的權限。


          合約概要設計

          在存證合約中,我們引入了數(shù)據(jù)和邏輯分離的思想;在積分合約中,我們引入管理、數(shù)據(jù)和邏輯分離的思想。

          引入了管理合約后,就實現(xiàn)了類似控制反轉的效果,控制合約和數(shù)據(jù)合約都由管理合約來創(chuàng)建;同時,管理合約還可以隨時設置數(shù)據(jù)合約中控制合約的地址。這樣,控制合約就可以隨時實現(xiàn)平滑的業(yè)務邏輯升級;將管理合約分離出來,還有利于鏈上權限治理。

          • Admin:管理并生成合約,控制訪問Data合約的地址

          • Controller:合約層對外暴露服務的控制器

          • Data:存儲業(yè)務合約相關的數(shù)據(jù)

          • BasicAuth、IssuerRole:權限、角色的工具合約

          • LibRoles、LibSafeMath:權限mapping,數(shù)值計算的庫



            即刻體驗

          上述優(yōu)化及功能所涉及的最新代碼和技術文檔已同步更新,歡迎體驗和 star 支持。如需咨詢技術問題,歡迎關注本公眾號,對話框回復【小助手】進技術交流群。

          文檔地址: 
          https://smartdev-doc.readthedocs.io/zh_CN/latest/docs/WeBankBlockchain-SmartDev-Contract/index.html
          GitHub代碼庫地址:
          https://github.com/WeBankBlockchain/SmartDev-Contract
          gitee代碼庫地址:
          https://gitee.com/WeBankBlockchain/SmartDev-Contract

          歡迎參與WeBankBlockchain的社區(qū)建設:
          • 如項目對您有幫助,歡迎點亮我們的小星星(點擊項目左上方Star按鈕)。

          • 歡迎提交代碼(Pull requests)。

          • 提問和提交BUG。

          • 如果發(fā)現(xiàn)代碼存在安全漏洞,可通過以下地址上報:

            https://security.webank.com/




          FISCO BCOS的代碼完全開源且免費

          下載地址↓↓↓

          https://github.com/FISCO-BCOS/FISCO-BCOS



          瀏覽 233
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  青娱乐免费少妇 | 性视频午夜男女 | 色婷婷综合激情国产日韩 | 一区国产好的作爱视 | 四虎国产精品成人久久 |