欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

怎么使用以太坊的預(yù)編譯合約

這篇文章主要講解了“怎么使用以太坊的預(yù)編譯合約”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么使用以太坊的預(yù)編譯合約”吧!

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供霍林郭勒網(wǎng)站建設(shè)、霍林郭勒做網(wǎng)站、霍林郭勒網(wǎng)站設(shè)計(jì)、霍林郭勒網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、霍林郭勒企業(yè)網(wǎng)站模板建站服務(wù),10年霍林郭勒做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

以太坊包含了一些用于密碼學(xué)計(jì)算的預(yù)編譯合約,可以用來實(shí)現(xiàn)高級隱私保護(hù)功能。在這個(gè)教程中我們將了解以太坊提供的預(yù)編譯合約清單,并通過bn256ScalarMulbigModExp這兩個(gè)實(shí)例學(xué)習(xí)以太坊預(yù)編譯合約的使用方法。

1、以太坊虛擬機(jī)基本概念

在繼續(xù)下面的教程之前,我們需要對以太坊和Solidity有一些基本的了解。我們關(guān)心的重點(diǎn)在于,以太坊有一個(gè)分布式的虛擬機(jī)即EVM,EVM提供了一組指令可以用于在區(qū)塊鏈上執(zhí)行交易并更新狀態(tài)。關(guān)于EVM的一些基本概念如下:

  • storage:可以永久在鏈上存儲(chǔ)信息

  • memory:EVM虛擬機(jī)的工作內(nèi)存,用于保存計(jì)算過程中的變量內(nèi)容

  • uint:uint256類型的別名,可保存256位,完美匹配橢圓曲線坐標(biāo)的要求

  • public:用來聲明函數(shù)位公開可調(diào)用

  • view:用來告訴編譯器,所裝飾的函數(shù)不會(huì)修改合約狀態(tài)

  • pure:表示所裝飾的函數(shù)不涉及合約狀態(tài)的讀寫

2、以太坊預(yù)編譯合約清單

以太坊Geth客戶端的預(yù)編譯合約清單看起來像這樣:

var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{     
  common.BytesToAddress([]byte{1}): &ecrecover{}, 
  common.BytesToAddress([]byte{2}): &sha256hash{}, 
  common.BytesToAddress([]byte{3}): &ripemd160hash{}, 
  common.BytesToAddress([]byte{4}): &dataCopy{}, 
  common.BytesToAddress([]byte{5}): &bigModExp{}, 
  common.BytesToAddress([]byte{6}): &bn256Add{}, 
  common.BytesToAddress([]byte{7}): &bn256ScalarMul{}, 
  common.BytesToAddress([]byte{8}): &bn256Pairing{},
}

上述代碼中的映射結(jié)構(gòu)記錄了預(yù)編譯合約的地址,是最后4個(gè)是新增的預(yù)編譯 合約:

bigModExp:地址0x05,執(zhí)行操作:b^e mod m。bigModExp預(yù)編譯合約的輸入為: 底數(shù)長度、指數(shù)長度、模長度、底數(shù)即b的值、指數(shù)即e的值、模即m的值

bn256Add:地址0x06,執(zhí)行操作:(x1, y1) + (x2, y2),其中x1, y1, x2, y2 都是256位的域成員,因此 (x1, y1)和 (x2, y2)都是bn256曲線上的有效點(diǎn),滿足公式y^2 = x^3 + 3 mod fieldOrder。 bn256預(yù)編譯合約的輸入就是x1, y1, x2, y2。

bn256ScalarMul:地址0x07,執(zhí)行操作:k * (x, y),其中k屬于群,(x,y)是曲線上的有效點(diǎn)。 bn256scalarMul的輸入是x, y, k。

bn256Pairing:地址0x08,執(zhí)行操作:配對檢查e(g1, g2) = e(-h2, h3,其中g(shù)1和h2屬于群G1, g2和h3屬于群G2。bn256Pairing可以接收任意多對橢圓曲線上的點(diǎn)。群G1上的點(diǎn)形式為(x,y),群 G2上的點(diǎn)形式為(ai + b, ci + d),其中a, b, c, d (依次為虛部、實(shí)部、虛部、實(shí)部) 需要在預(yù)編譯 調(diào)用時(shí)傳入。bn256Pairing代碼首先檢查已經(jīng)送出6的倍數(shù)個(gè)成員,然后執(zhí)行配對檢查。

x, y, a, b, c, d的值都是域成員,因此都會(huì)按域大小取模。在bn256ScalarMul中使用的k的值,則是按橢圓曲線群的階取模。

下面我們將要學(xué)習(xí)兩個(gè)主要的示例:bn256ScalarMul和bigModExp。bn256ScalarMul操作和bn256Add非常類似,而bn256Pairing操作則更像bigModExp,因?yàn)檫@兩者都接受可變長度的輸入,因此調(diào)用時(shí)需要指定輸入大小。下面是調(diào)用bn256ScalarMul的代碼:

function ecmul(uint ax, uint ay, uint k) public view returns(uint[2] memory p) { uint[3] memory input;
 input[0] = ax;
 input[1] = ay;
 input[2] = k;

 assembly {
   if iszero(staticcall(gas, 0x07, input, 0x60, p, 0x40)) {
       revert(0,0)
   }
 }
 return p;
}

目前內(nèi)聯(lián)匯編已經(jīng)支持if語句,調(diào)用時(shí)設(shè)置gas數(shù)量也比以前簡單 —— 在調(diào)用時(shí)使用gas,就表示利用所有可用gas,這避免了我們自己猜測需要的gas數(shù)量。

revert操作碼將回滾所有的狀態(tài)變化,起作用是在gas不足時(shí)或?qū)︻A(yù)編譯合約的調(diào)用發(fā)生故障后,可以回滾部分完成的狀態(tài)更新。

3、調(diào)用bn256ScalarMul預(yù)編譯合約

每個(gè)地址關(guān)聯(lián)的持久化內(nèi)存被稱為存儲(chǔ)(Storage),這時(shí)一個(gè)key-value庫,實(shí)現(xiàn)從256位到256位數(shù)據(jù)的映射。在合約內(nèi)這個(gè)鍵值庫沒有辦法枚舉,合約也不能訪問其他地址關(guān)聯(lián)的存儲(chǔ)。

如果采用如下形式初始化變量:uint256 blah,那么就會(huì)將變量blah保存到持久化存儲(chǔ)。uint是uint256的別名,如果需要更細(xì)粒度的管理,可以使用uint8,uint16等等。

EVM有一個(gè)虛擬棧可以保存256位的值。選擇256位的目的是與密碼學(xué)操作保持兼容。所有的EVM操作都是利用這個(gè)虛擬棧完成的,它最多可以容納1024個(gè)成員。你可以拷貝棧頂16個(gè)成員之一,或者兩兩交換。所有其他的操作碼都利用棧頂特定位置的成員作為輸入并將結(jié)果壓入棧。

對于每一個(gè)消息調(diào)用,易失內(nèi)存都被復(fù)位,內(nèi)存以32字節(jié)為單位分配,使用gas支付內(nèi)存利用的成本。我們需要調(diào)用預(yù)編譯合約的值保持在這個(gè)內(nèi)存的頂部。

我們可以將之前保存在持久化存儲(chǔ)中的變量賦值給內(nèi)存,方式如下:

uint256[2] memory inputToPrecompile;
input[0] = somePreviouslyStoredValue;
input[1] = someOtherPreviouslyStoredValue;

這實(shí)際上就是我們在ecmul中的開始4行的操作。我們將值ax,ay,k壓入虛擬棧的頂部。然后通過調(diào)用bn256ScalarMul預(yù)編譯合約的地址就完成調(diào)用了。看下一部分的代碼:

assembly {
   if iszero(staticcall(gas, 0x07, input, 0x60, p, 0x40)) {
       revert(0,0)
   }
 }

staticcall操作碼的調(diào)用形式如下:

staticcall(gasLimit, to, inputOffset, inputSize, outputOffset, outputSize)

可以看到在上面的調(diào)用bn256ScalarMul的代碼中,我們:

  • 在扣除2000后,發(fā)送當(dāng)前可用的gas

  • 調(diào)用地址0x07的預(yù)編譯合約,這對應(yīng)bn256ScalarMul

  • 使用內(nèi)存變量input作為輸入偏移參數(shù)

  • 將輸入大小聲明為0x60,這對應(yīng)3個(gè)256位數(shù)值,表示一個(gè)橢圓曲線點(diǎn)和一個(gè)256位標(biāo)量

  • 將輸出保存在p中

  • 輸出大小為0x40,對應(yīng)要返回的橢圓曲線點(diǎn)

這樣就完成了對以太坊預(yù)編譯合約bn256ScalarMul的調(diào)用,ecmul函數(shù)的返回值現(xiàn)在就是bn256ScalarMul預(yù)編譯合約的返回值!

4、調(diào)用bigModExp預(yù)編譯合約

下面的代碼調(diào)用bigModExp預(yù)編譯合約:

function expmod(uint base, uint e, uint m) public view returns (uint o) {
  
  assembly {
   // define pointer
   let p := mload(0x40)
   // store data assembly-favouring ways
   mstore(p, 0x20)             // Length of Base
   mstore(add(p, 0x20), 0x20)  // Length of Exponent
   mstore(add(p, 0x40), 0x20)  // Length of Modulus
   mstore(add(p, 0x60), base)  // Base
   mstore(add(p, 0x80), e)     // Exponent
   mstore(add(p, 0xa0), m)     // Modulus
   if iszero(staticcall(sub(gas, 2000), 0x05, p, 0xc0, p, 0x20)) {
     revert(0, 0)
   }
   // data
   o := mload(p)
  }}

需要注意的是,0x40始終是空閑內(nèi)存,因此可以使用p:=mload(0x40)來初始化內(nèi)存指針。

感謝各位的閱讀,以上就是“怎么使用以太坊的預(yù)編譯合約”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么使用以太坊的預(yù)編譯合約這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

分享題目:怎么使用以太坊的預(yù)編譯合約
網(wǎng)頁URL:http://www.chinadenli.net/article30/piisso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)網(wǎng)站建設(shè)Google全網(wǎng)營銷推廣營銷型網(wǎng)站建設(shè)移動(dòng)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作