1. 程式人生 > >死磕以太坊原始碼分析之EVM指令集

死磕以太坊原始碼分析之EVM指令集

> 死磕以太坊原始碼分析之EVM指令集 > > 配合以下程式碼進行閱讀:https://github.com/blockchainGuide/ > > 寫文不易,給個小關注,有什麼問題可以指出,便於大家交流學習。 > > 以下指令集持續更新,最新文章請參考上面 ![f4a720afd869d70c3d1d2149980ba0e9](https://tva1.sinaimg.cn/large/008eGmZEgy1gn1z0rqeqaj31c00u0k20.jpg) ## EVM 指令集概念 **EVM執行的是位元組碼**。由於操作碼被限制在一個位元組以內,所以EVM指令集最多隻能容納**256**條指令。目前EVM已經定義了`100`多條指令,還有**100**多條指令可供以後擴充套件。**這100多條指令包括算術運算指令,比較操作指令,按位運算指令,密碼學計算指令,棧、memory、storage操作指令,跳轉指令,區塊、智慧合約相關指令等**。 ## EVM指令集 ### 算數運算指令集 > *0x0* ``` STOP: "STOP", ADD: "ADD", //加法運算 MUL: "MUL", //乘法運算 SUB: "SUB", //減法運算 DIV: "DIV", //無符號整除運算 SDIV: "SDIV", //有符號整除運算 MOD: "MOD", //無符號取模運算 SMOD: "SMOD", //有符號取模運算 EXP: "EXP", //指數運算 NOT: "NOT", //從棧頂彈出兩個元素,進行比較, //然後把結果(1表示true,0表示false)推入棧頂。 //其中LT和GT把彈出的元素解釋為無符號整數進行比較, //SLT和SGT把彈出的元素解釋為有符號數進行比較,EQ不關心符號 LT: "LT", //無符號小於比較 GT: "GT", //無符號大於比較 SLT: "SLT", //有符號小於比較 SGT: "SGT", //有符號大於比較 EQ: "EQ", // 等於比較 //SZERO指令從棧頂彈出一個元素,判斷它是否為0,如果是,則把1推入棧頂,否則把0推入棧頂 ISZERO: "ISZERO", //布林取反 //SIGNEXTEND指令從棧頂依次彈出k和x,並 //把x解釋為k+1(0 <= k <= 31)位元組有符號整數,然 //後把x符號擴充套件至32位元組。比如x是二進位制10000000,k是0, //則符號擴充套件之後,結果為二進位制1111…10000000(共249個1) SIGNEXTEND: "SIGNEXTEND" //符號位擴充套件 ``` ### 位運算指令集 > *0x10* ``` //AND、OR、XOR指令從棧頂彈出兩個元素,進行按位運算,然後把結果推入棧頂 AND: "AND", OR: "OR", XOR: "XOR", //BYTE指令先後從棧頂彈出n和x,取x的第n個位元組並推入棧頂。 //由於EVM的字長是32個位元組,所以n在[0, 31]區間內才有意義, //否則BYTE的運算結果就是0。另外,位元組是從左到右數的,因此第0個位元組佔據字的最高位8個位元 BYTE: "BYTE", //這三條指令都是先後從棧頂彈出兩個數n和x, //其中x是要進行位移操作頂數,n是位移位元數,然後把結果推入棧頂 SHL: "SHL", //SHR和SAR的區別在於,前者執行邏輯右移(空缺補0),後者執行算術右移(空缺補符號位) SHR: "SHR", SAR: "SAR", ADDMOD: "ADDMOD", //MULMOD指令依次從棧頂彈出x、y、z三個數, //先計算x和y的乘積(不受溢位限制),再計算乘積和z的模,最後把結果推入棧頂 //假定乘積不會溢位,那麼MULMOD(x, y, z)等價於x * y % z MULMOD: "MULMOD", ``` ### 加密指令集 > *0x20* ``` SHA3: "SHA3" ``` ### 關閉狀態指令集 > *0x30* ``` ADDRESS: "ADDRESS", BALANCE: "BALANCE", ORIGIN: "ORIGIN", CALLER: "CALLER", CALLVALUE: "CALLVALUE", CALLDATALOAD: "CALLDATALOAD", CALLDATASIZE: "CALLDATASIZE", CALLDATACOPY: "CALLDATACOPY", CODESIZE: "CODESIZE", CODECOPY: "CODECOPY", GASPRICE: "GASPRICE", EXTCODESIZE: "EXTCODESIZE", EXTCODECOPY: "EXTCODECOPY", RETURNDATASIZE: "RETURNDATASIZE", RETURNDATACOPY: "RETURNDATACOPY", EXTCODEHASH: "EXTCODEHASH", ``` ### 塊操作指令集 >*0x40* ``` BLOCKHASH: "BLOCKHASH", COINBASE: "COINBASE", TIMESTAMP: "TIMESTAMP", NUMBER: "NUMBER", DIFFICULTY: "DIFFICULTY", GASLIMIT: "GASLIMIT", CHAINID: "CHAINID", SELFBALANCE: "SELFBALANCE" ``` ### 儲存和執行指令集 > *0x50* ``` POP: "POP", // 棧頂彈出元素 MLOAD: "MLOAD", MSTORE: "MSTORE", MSTORE8: "MSTORE8", SLOAD: "SLOAD", //先取出棧頂元素x,然後在storage中取以x為鍵的值(storage[x])存入棧頂 SSTORE: "SSTORE", //儲存storage是一個鍵值儲存,可將256位字對映到256位字 JUMP: "JUMP", JUMPI: "JUMPI", PC: "PC", MSIZE: "MSIZE", GAS: "GAS", JUMPDEST: "JUMPDEST" ``` ### Push指令集 > *0x60* ``` // PUSH系列指令把緊跟在指令後面的N(1 ~ 32)位元組元素推入棧頂 PUSH1: "PUSH1", ... PUSH32: "PUSH32", //DUP系列指令複製從棧頂開始數的第N(1 ~ 16)個元素,並把複製後的元素推入棧頂 DUP1: "DUP1", DUP2: "DUP2", ... DUP16: "DUP16", //SWAP系列指令把棧頂元素和從棧頂開始數的第N(1 ~ 16)+ 1 個元素進行交換。 SWAP1: "SWAP1", ... SWAP16: "SWAP16", LOG0: "LOG0", ... LOG4: "LOG4", ``` ## 參考 > https://mindcarver.cn > > https://github.com/blockchainGui