如何理解Solidity的Bytecode和Opcode

本篇文章為大家展示了如何理解Solidity的Bytecode和Opcode,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、重慶網(wǎng)站建設(shè)、微信開發(fā)、微信平臺小程序開發(fā)、集團成都企業(yè)網(wǎng)站定制等服務(wù)項目。核心團隊均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗,服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:水處理設(shè)備等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗,同時也獲得了客戶的一致認可!

Solidity的Bytecode和Opcode

隨著我們更深入地編寫智能合約,我們將遇到諸如“ PUSH1”,“ SSTORE”,“ CALLVALUE”等術(shù)語。 他們是什么,我們什么時候應(yīng)該使用到他們?

要了解這些命令,我們必須更深入地了解以太坊虛擬機(EVM)。本文將會嘗試盡可能簡單地解釋一些EVM基礎(chǔ)。希望大家都有所收獲。

像許多其他流行的編程語言一樣,Solidity是一種高級編程語言。 我們可以讀懂,但是機器卻不能夠。 如果大家學過諸如java,c++等編程語言,應(yīng)該會很容易明白這個道理。

當我們安裝諸如geth之類的以太坊客戶端時,它還附帶了以太坊虛擬機,這是專門為運行智能合約而創(chuàng)建的輕量級操作系統(tǒng)。

當我們使用solc編譯器編譯Solidity代碼時,它將代碼轉(zhuǎn)換為只有EVM可以理解的字節(jié)碼。

讓我們以一個非常簡單的合同為例:

pragma solidity ^0.4.26;
contract OpcodeContract {
    uint i = (10 + 2) * 2;
}

如果我們在remix瀏覽器中運行此代碼,然后單擊合同詳細信息,則會看到很多信息。

如何理解Solidity的Bytecode和Opcode

在這種情況下,編譯后的代碼為:

BYTECODE
{
    "linkReferences": {},
    "object": "60806040526018600055348015601457600080fd5b5060358060226000396000f3006080604052600080fd00a165627a7a72305820db1d567e501f1682876df36eea80a02d25a8b2adb186da705e2e98e134b08cc60029",
    "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x18 PUSH1 0x0 SSTORE CALLVALUE DUP1 ISZERO PUSH1 0x14 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x35 DUP1 PUSH1 0x22 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xdb SAR JUMP PUSH31 0x501F1682876DF36EEA80A02D25A8B2ADB186DA705E2E98E134B08CC6002900 ",
    "sourceMap": "25:54:0:-;;;64:12;55:21;;25:54;8:9:-1;5:2;;;30:1;27;20:12;5:2;25:54:0;;;;;;;"
}

其中object就是編譯后的代碼。他們是最終合同的十六進制表示形式,也稱為字節(jié)碼。

在remix瀏覽器的“ Web3 Deploy”部分下,我們看到:

var opcodecontractContract = web3.eth.contract([]);
var opcodecontract = opcodecontractContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x60806040526018600055348015601457600080fd5b5060358060226000396000f3006080604052600080fd00a165627a7a72305820db1d567e501f1682876df36eea80a02d25a8b2adb186da705e2e98e134b08cc60029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

簡單來說,這意味著當我們部署合同時,我們需要將編譯后的16進制碼當成data傳遞,并且建議的gas為4700000。

任何以“ 0x”開頭的內(nèi)容都表示該值采用十六進制格式。 十六進制前面的“ 0x”并不是強制的,因為EVM會將任何值都視為十六進制。

我們還看到了操作代碼(又稱Opcode):

"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x18 PUSH1 0x0 SSTORE CALLVALUE DUP1 ISZERO PUSH1 0x14 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x35 DUP1 PUSH1 0x22 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN STOP PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 0xdb SAR JUMP PUSH31 0x501F1682876DF36EEA80A02D25A8B2ADB186DA705E2E98E134B08CC6002900 ",

操作碼是程序的低級可讀指令。 所有操作碼都具有對應(yīng)的十六進制值,例如“ MSTORE”為“ 0x52”,SSTORE”為“ 0x55”……等等。

具體的操作碼對應(yīng)的數(shù)值可以參考以太坊相關(guān)資料。

EVM虛擬機是一中堆棧虛擬機,所謂堆棧就是后進先出結(jié)構(gòu),用計算機科學術(shù)語來說,我們稱為LIFO。

舉個例子,上面的智能合約,如果在普通算術(shù)中,我們這樣寫方程式:

// Answer is 14. we do multiplication before addition.
10 + 2 * 2

在EVM堆棧虛擬機中,它按照LIFO原理工作,所以我們需要這樣寫:

2 2 * 10 +

這意味著,首先將“ 2”放入堆棧,然后再放入另一個“ 2”,然后再進行乘法運算。 結(jié)果是“ 4”放在在堆棧頂部。 現(xiàn)在在“ 4”的頂部加上數(shù)字“ 10”,最后將兩個數(shù)字加在一起。 堆棧的最終值為14。

這種算術(shù)類型稱為后綴表示法。

將數(shù)據(jù)放入堆棧的動作稱為“ PUSH”指令,將數(shù)據(jù)從堆棧中刪除的動作稱為“ POP”指令。 很明顯,我們在上面的示例中看到的最常見的操作碼是“ PUSH1”,這意味著將1個字節(jié)的數(shù)據(jù)放入堆棧中。
因此,此指令:

PUSH1 0x80

表示將1字節(jié)值“ 0x80”放入堆棧中。 “ PUSH1”的十六進制值恰是“ 0x60”。 刪除非強制性的“ 0x”,我們可以將此邏輯以字節(jié)碼形式寫為“ 6080”。
讓我們更進一步。

PUSH1 0x80 PUSH1 0x40 MSTORE

再次查看以太坊的操作碼圖表,我們看到MSTORE(0x52)接受2個輸入,但不產(chǎn)生任何輸出。 上面的操作碼表示:
PUSH1(0x60):將0x80放入堆棧。
PUSH1(0x40):將0x40放入堆棧。
MSTORE(0x52):分配0x80的內(nèi)存空間并移至0x40的位置。
結(jié)果字節(jié)碼為:

6080604052

實際上,在任何固定字節(jié)碼的開頭,我們總會看到這個魔術(shù)數(shù)字“ 6080604052”,因為它是智能合約引導的方式。

請注意,這里不能將0x40或0x60解釋為實數(shù)40或60。由于它們是十六進制,所以40實際上等于十進制的64(16 x 4),而80等于十進制的128(16 x 8)。

簡而言之,“ PUSH1 0x80 PUSH1 0x40 MSTORE”正在做的是分配128個字節(jié)的內(nèi)存并將指針移到第64個字節(jié)的開頭。現(xiàn)在,我們有64個字節(jié)用于暫存空間,而64個字節(jié)用于臨時內(nèi)存存儲。

在EVM中,有3個地方可以存儲數(shù)據(jù)。首先,在堆棧中,按照上面的示例,我們剛剛使用了“ PUSH”操作碼在此處存儲數(shù)據(jù)。其次,在使用“ MSTORE”操作碼的內(nèi)存(RAM)中,最后在使用“ SSTORE”存儲數(shù)據(jù)的磁盤存儲中。將數(shù)據(jù)存儲到磁盤存儲所需的gas最昂貴,而將數(shù)據(jù)存儲到堆棧中的gas則最便宜。

我們在Solidity中的智能合約中,有時候也會用到Assembly Language,這個Assembly Language就是使用這樣的匯編Opcode來操作EVM字節(jié)碼。他理解起來比較難,但是通過使用它可以節(jié)省燃料和做一些無法通過Solidity完成的事情。

上述內(nèi)容就是如何理解Solidity的Bytecode和Opcode,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁標題:如何理解Solidity的Bytecode和Opcode
鏈接URL:http://m.kartarina.com/article36/jedspg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站商城網(wǎng)站App設(shè)計網(wǎng)站內(nèi)鏈手機網(wǎng)站建設(shè)網(wǎng)站收錄

廣告

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

外貿(mào)網(wǎng)站建設(shè)
主站蜘蛛池模板: 国产精品无码无卡无需播放器| 久久精品九九热无码免贵| 18禁无遮挡无码国产免费网站| 中文无码久久精品| 精品无码免费专区毛片| 东京热HEYZO无码专区| 国产高清无码毛片| 亚洲Av无码国产一区二区| 国产精品无码素人福利不卡| 无码福利一区二区三区| 国产网红主播无码精品| 亚洲午夜无码久久久久小说| 亚洲中文字幕无码一区二区三区| 亚洲精品中文字幕无码A片老| 精品久久久无码中文字幕| 亚洲综合无码一区二区痴汉| 亚洲啪啪AV无码片| 国产精品无码无片在线观看3D| 久久精品中文字幕无码绿巨人| heyzo专区无码综合| 人妻少妇看A偷人无码精品| 无码人妻一区二区三区免费看| 国产成人亚洲综合无码| 无翼乌工口肉肉无遮挡无码18| 91久久精品无码一区二区毛片| 性无码专区无码片| 国产品无码一区二区三区在线蜜桃 | 一本色道无码不卡在线观看| 亚洲精品无码日韩国产不卡av| 国产在线无码一区二区三区视频| 免费人妻无码不卡中文字幕18禁| 亚洲中文字幕无码爆乳app| 日韩乱码人妻无码中文字幕| 亚洲VA中文字幕无码毛片| 亚洲Aⅴ无码一区二区二三区软件| 无码精品国产va在线观看dvd| 免费无码中文字幕A级毛片| 国产精品无码素人福利免费| 色欲香天天综合网无码| 激情无码亚洲一区二区三区| 无码国产精品久久一区免费|