您好,登錄后才能下訂單哦!
對于普通的solidity智能合約來說,通過solc編譯器的優(yōu)化操作,將源代碼轉(zhuǎn)換為以太坊能夠識別的二進制文件。但是solc編譯器不是萬能的,在某些情況下,例如循環(huán)操作的時候,并不能達到最佳的執(zhí)行方式。通過在solidity智能合約中內(nèi)嵌匯編代碼,可以阻止編譯器的優(yōu)化,在某些時候能夠到達節(jié)約gas的作用。同時,內(nèi)嵌匯編代碼可以增加solidity語言的功能。例如在判斷賬戶地址為合約地址還是外部地址的時候,只能夠通過匯編代碼來實現(xiàn)。
1 | assembly{ |
let指令定義變量。
add函數(shù)是內(nèi)聯(lián)匯編中內(nèi)置的加法操作,solidity內(nèi)聯(lián)匯編中有很多內(nèi)置的函數(shù)。jumpi為跳轉(zhuǎn)函數(shù),跳轉(zhuǎn)到loop語句執(zhí)行。
It函數(shù)為小于函數(shù),lt(i,9)判斷i是否小于9
1 | function nativeLoop() public returns(uint _r){ |
1 | function nativeConditional(uint _v) returns(uint _r){ |
下面的合約中,msize()代表的是當前已經(jīng)使用的memory空間的最大位置。加1之后,代表的是可用的指針所在的位置。
mstore代表將值_v賦值給_ptr。 return (ptr,0x20)代表的是從位置_ptr開始,往下讀取0x20也就是32個字節(jié)
1 | function asmReturens(uint _v) public returns(uint){ |
mload(40)代表獲取0x40位置往下32個字節(jié)存儲的數(shù)據(jù)。0x40位置非常特殊,其存儲的是最小的可用的memory內(nèi)存的地址。
例如為0x80.
mstore(add(freemem_pointer,0x00),“36e5236fcd4c610449678014f0d085”) 存儲字符串到"36e5236fcd4c610449678014f0d085" 到0x80往下32個字節(jié)的空間中。
mstore(add(freemem_pointer,0x20),“36e5236fcd4c610449678014f0d086”) 首先將0x80加上32個字節(jié),變?yōu)榱?xa0。之后便加上32個字節(jié),存儲字符串"36e5236fcd4c610449678014f0d086" 到0xa0往下32個字節(jié)的空間中。
let arr1:=mload(freemem_pointer)定義了變量arr1. 獲取freemem_pointer往下32個字節(jié)。由于freemem_pointer當前仍然為0x80,因此arr1的值為字符串"36e5236fcd4c610449678014f0d085"。 最后的語句mstore(add(freemem_pointer,0x40),arr1)。存儲了arr1到0xc0地址往下的32個字節(jié)的空間中。
1 | pragma solidity ^0.4.23; |
下面的函數(shù),實現(xiàn)了將地址轉(zhuǎn)換為動態(tài)字節(jié)數(shù)組的操作。
let m := mload(0x40)獲取0x40位置往下32個字節(jié)存儲的數(shù)據(jù)。0x40位置非常特殊,其存儲的是最小的可用的memory內(nèi)存的地址。例如為0x80. add(m, 20) 將0x80加上了20個字節(jié)(0x14),到達0x94.
xor為位運算的異或操作。相等為0,不等為1。0x140000000000000000000000000000000000000000的長度為168位,幣地址多了6位。假設地址為0xca35b7d915458ef540ade6068dfe2f44e8fa733c。那么異或之后,變?yōu)榱?x14ca35b7d915458ef540ade6068dfe2f44e8fa733c,一共有21個字節(jié)。填充為32個字節(jié)之后變?yōu)榱?x000000000000000000000014ca35b7d915458ef540ade6068dfe2f44e8fa733c,通過mstore存儲到0x94地址之后的32個字節(jié)中。
在memory空間中
0x80 0x0000000000000000000000000000000000000000000000000000000000000014
0xa0 0xca35b7d915458ef540ade6068dfe2f44e8fa733c000000000000000000000000
從而14代表長度為20個字節(jié)。其后面是地址。將0x80的地址賦值給動態(tài)長度字節(jié)變量b。由于動態(tài)長度字節(jié)數(shù)組首先32個字節(jié)存儲長度,后面存儲內(nèi)容。因此將地址轉(zhuǎn)換為了動態(tài)長度數(shù)組。
1 | contract dog{ |
本文鏈接: https://dreamerjonson.com/2018/11/24/solidity-50-assembly/
版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY 4.0 CN協(xié)議 許可協(xié)議。轉(zhuǎn)載請注明出處!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。