跳到主要内容

WTF Opcodes极简入门: 12. 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个操作码,剩下的不多了!