EVM入门
Opcodes
Opcodes(操作码)是以太坊智能合约的基本单元。我们写的Solidity智能合约会被编译为字节码(bytecode),然后才能在EVM(以太坊虚拟机)上运行。而字节码就是由一系列Opcodes组成的。当用户在EVM中调用这个智能合约的函数时,EVM会解析并执行这些Opcodes,以实现合约逻辑。
常见的Opcodes
PUSH1
: 将一个字节的数据压入堆栈。例如,PUSH1 0x60 就是将 0x60 压入堆栈。DUP1
: 复制堆栈顶部的一个元素。SWAP1
: 交换堆栈顶部的前两个元素。
例如:下面是一个简单的Solidity智能合约,它只有一个add()函数,计算1+1的结果并返回。
// SPDX-License-Identifier: MIT |
将合约编译后,我们可以得到合约对应的bytecode:60806040523480156100…
通过bytecode,我们可以得到合约对应的opcodes为:PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 …
我认为需要特别记忆的基本Opcodes:
PUSH1:将一个长度为1字节的数据压入堆栈顶部。同理可知:PUSH2就是压入长度为俩个字节的数据进入栈堆顶部
ADD:会弹出堆栈顶部的两个元素,计算它们的和,然后将结果压入堆栈。
PUSH0:就是将0压入栈堆
MUL: 会弹出堆栈顶部的两个元素,计算它们的乘,然后将结果压入堆栈。
SUB: 会弹出堆栈顶部的两个元素,第二个元素减去第一个元素,然后将结果压入堆栈
DUPx:就是复制第x个元素到栈顶
LT:从堆栈中弹出两个元素,比较第二个元素是否小于第一个元素。如果是,那么将1推入堆栈,否则将0推入堆栈。如果堆栈元素不足两个,那么会抛出异常。
GT:从堆栈中弹出两个元素,比较第二个元素是否大于第一个元素。如果是,那么将1推入堆栈,否则将0推入堆栈。如果堆栈元素不足两个,那么会抛出异常。
EQ:从堆栈中弹出两个元素,比较第二个元素是否等于第一个元素。如果是,那么将1推入堆栈,否则将0推入堆栈。如果堆栈元素不足两个,那么会抛出异常。
AND:从栈堆中弹出俩个元素,比较位级,如2(0000 0010)和3(0000 0011),则入栈的是2
OR:从栈堆中弹出俩个元素,比较位级,如2(0000 0010)和3(0000 0011),则入栈的是3
XOR:它是异或运算,,如2(0000 0010)和3(0000 0011),则入栈的是1(0000 0001),就是比较依次它们2进制的数,俩个0相遇或者俩个1相遇就为0,不同的相遇就为1
SHL:指令执行左移位操作,从堆栈中弹出两个元素,将第二个元素左移第一个元素位数,然后将结果推回栈顶。将2(0000 0010)和3(0000 0011)推入堆栈,然后将2左移3位,结果应该为16(0001 0000)。
SHR:同上,只不过向右移,字节码将16(0001 0000)和3(0000 0011)推入堆栈,然后将16右移3位,结果应该为2(0000 0010)。
MSTORE:指令用于将一个256位(32字节)的值存储到内存中。它从堆栈中弹出两个元素,第一个元素为内存的地址(偏移量 offset),第二个元素为存储的值(value)。
STOP:它的作用是停止当前上下文的执行,并成功退出。
JUMP:用于无条件跳转到一个新的程序计数器位置。它从堆栈中弹出一个元素,将这个元素设定为新的程序计数器(pc)的值。搭配JUMPDEST(标记一个有效的跳转目标位置)使用
JUMP1:用于条件跳转,它从堆栈中弹出两个元素,如果第二个元素(条件,condition)不为0,那么将第一个元素(目标,destination)设定为新的pc的值。
SWAP:交换,如SWAP1,交换栈顶与次栈顶,swap2,交换栈顶与第三个元素
CALLDATALOAD:从交易或合约调用的data字段加载数据。它从堆栈中弹出calldata的偏移量(offset),然后从calldata的offset位置读取32字节的数据并压入堆栈。如果calldata剩余不足32字节,则补0。
CALLDATASIZE:获取交易或合约调用的data字段的字节长度,并压入堆栈。
CALLDATACOPY:将data中的数据复制到内存中。它会从堆栈中弹出3个参数(mem_offset, calldata_offset, length),分别对应写到内存的偏移量,读取calldata的偏移量和长度。
CODESIZE:获取当前合约代码的字节长度,然后压入堆栈。
EVM基础
以太坊虚拟机(EVM)是以太坊区块链中的关键组件,充当开发人员的虚拟计算机或软件平台。这项创新允许创建和部署去中心化应用程序(DApp)以及在以太坊网络上执行智能合约。 EVM 由Vitalik Buterin于 2013 年提出概念,成为以太坊网络的核心,强调了其在决定以太坊区块链中每个区块的状态方面的基础作用。
EVM就是一个运行环境,就如同Java的运行环境一样,含义,分类都差不多,它包括了堆栈,内存,存储,EVM字节码,有一点编程基础的都知道堆栈,这种先进后出的结构,反正就是一个类似于JVM一样机器,它主要就是运行一些操作符opcode,真正的要理解熟悉opcode操作符,144个,点击学习,更多的详细指令参考WTF,我就不一一讲了,接下来就是大白话:
优点
- 跨区块链支持:EVM 支持字节码兼容的智能合约的能力使其能够跨各种区块链。 Polygon 和 Avalanche 等多个区块链都利用了此功能,使它们能够利用 EVM 强大的生态系统。
- 隔离沙箱环境:EVM 在同一计算机网络内单独操作每个代码段,确保一个应用程序的执行不会影响区块链的其余部分或节点计算机上存储的数据。这种隔离有利于快速高效的开发。
- 灵活的开发能力:EVM 擅长执行复杂且定制的智能合约,这对于包括 dApp、 DeFi平台、游戏和NFT在内的各种应用程序至关重要。此外,EVM 周围有一个庞大的开发人员社区,简化了软件构建过程。
- 跨操作系统的交叉兼容性:由于区块链网络中 MacOS、Windows 等操作系统的多样性,开发兼容软件可能具有挑战性。 EVM 通过标准化并支持跨多个操作系统执行程序来解决这个问题,而无需单独的代码库。
缺点
- 高交易成本(Gas 费) :使用 EVM 最显着的缺点之一是加密 Gas费成本高昂。由于 EVM 的可扩展性限制,这些费用可能会迅速增加,尤其是在网络流量较高的时期。
- 可扩展性挑战:EVM 每秒只能处理有限数量的事务。这种限制可能会导致网络拥塞加剧,进一步推高汽油费。
部署智能合约的成本:以太坊的流行性质意味着部署自定义智能合约或更大的应用程序可能会成本高昂。开发人员必须优化其合约以提高效率,消除冗余代码或不必要的功能,并且还必须考虑以太坊区块链上的高存储成本。 - 智能合约的不可逆性:一旦部署,区块链上的智能合约就无法更改。如果在部署后发现错误或漏洞,则这种不变性会带来挑战,需要重新部署整个合约,这可能会产生额外的成本。