EVM Opcodes 101

1. Hello Opcodes
2. Opcodes分类
3. 堆栈指令
4. 算数指令
5. 比较指令
6. 位级指令
7. 内存指令
8. 存储指令
9. 控制流指令
10. 区块信息指令
11. 堆栈指令2
12. SHA3指令
13. 账户指令
14. 交易指令
15. Log指令
12. SHA3指令
SHA3指令

我最近在重新学以太坊opcodes,也写一个“WTF EVM Opcodes极简入门”,供小白们使用。

推特:@0xAA_Science

社区:Discord|微信群|官网 wtf.academy

所有代码和教程开源在github: github.com/WTFAcademy/WTF-Opcodes


这一讲,我们将介绍EVM唯一内置的密码学指令--SHA3,你可以用它计算keccak-256哈希。

SHA3指令

在EVM中,计算数据的哈希是一个常见的操作。以太坊使用Keccak算法(SHA-3)计算数据的哈希,并提供了一个专门的操作码SHA3,Solidity中的keccak256()函数就是建立在它之上的。

SHA3(offset, size)指令从堆栈中取出两个参数,起始位置offset和长度size(以字节为单位),然后它从内存中读取起始位置offset开始的size长度的数据,计算这段数据的Keccak-256哈希,并将结果(一个32字节的值)压入堆栈。它的操作码为0x20,gas消耗为30 + 6*数据的字节长度 + 扩展内存成本。

在Python中,我们可以使用pysha3库来实现keccak-256哈希计算。首先你需要安装这个库:

pip install pysha3

下面,让我们在极简EVM中支持SHA3指令:

import sha3

SHA3 = 0x20

def sha3(self):
    if len(self.stack) < 2:
        raise Exception('Stack underflow')
    
    offset = self.pop()
    size = self.pop()
    data = self.memory[offset:offset+size]  # 从内存中获取数据
    hash_value = int.from_bytes(sha3.keccak_256(data).digest(), 'big')  # 计算哈希值
    self.stack.append(hash_value)  # 将哈希值压入堆栈

def run(self):
    while self.pc < len(self.code):
        op = self.next_instruction()

        # ... 其他指令的实现 ...

            elif op == SHA3: # 如果为SHA3
                self.sha3()

我们可以尝试运行一个包含SHA3指令的字节码:0x5F5F20(PUSH0 PUSH0 SHA3)。这个字节码将两个0推入堆栈,然后使用SHA3指令计算0的哈希。

# SHA3
code = b"\x5F\x5F\x20"
evm = EVM(code)
evm.run()
print(hex(evm.stack[-1]))  # 打印出0的keccak256 hash
# output: 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

我们可以在evm.codes上验证结果:

总结

这一讲,我们介绍了EVM中重要的操作符SHA3,它为我们提供了计算数据哈希的功能,这在验证数据或身份时非常重要。目前,我们写的极简EVM已经支持了112/144个操作码,剩下的不多了!

PreviousNext