Copyright © 2022-2025 aizws.net · 网站版本: v1.2.6·内部版本: v1.25.2·
页面加载耗时 0.00 毫秒·物理内存 117.2MB ·虚拟内存 1372.9MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
stateOject中有两个Storage类型的变量,是用来缓存智能合约中所有变量的值的。这个Storage类型的定义如下:
type Storage map[common.Hash]common.Hash
就是一个map,key跟value都是common.Hash类型,其实就是[]byte。这个map只有在EVM执行SSTORE指令时候会赋值,用于记录变量的值。那么这里面的key跟value具体是什么内容呢?经研究,结果如下:

可以使用browser-solidity查看编译出来的EVM指令:
https://ethereum.github.io/browser-solidity
在编辑器中写测试代码:
pragma solidity ^0.4.0;
contract Demo {
int a;
int x;
mapping(address => int) b;
function myfunc() public {
a = 8;
x = 9;
b[123] = 1;
}
}
点击右边的“Start to compile”,然后点击“Details”就可以查看编译出来的EVM指令。以map为例,逐条分析指令就可以看出SSTORE具体存储的key和value是如何生成的:
// 压栈返回值
PUSH 1 1
stack [1]
// 压栈变量position
PUSH 2 b
stack [2 1]
// 压栈内存存储起点
PUSH 0 b[123]
stack [0 2 1]
// 压栈map索引值(即123)
PUSH 7B 123
stack [7B 0 2 1]
// 压栈mask
PUSH FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF b[123]
stack [FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 7B 0 2 1]
// 索引值 & mask,弹出2个值,压栈与的结果
AND b[123]
stack [7B 0 2 1]
// 复制第二个值并压栈
DUP2 b[123]
stack [0 7B 0 2 1]
// 在内存0位置存储7B(即map索引值),弹出2个值
MSTORE b[123]
stack [0 2 1]
store {7B}
// 压栈内存偏移,0x20 = 32字节
PUSH 20 b[123]
stack [20 0 2 1]
store {7B}
// 计算内存偏移,弹出2个值,压栈相加的结果
ADD b[123]
stack [20 2 1]
store {7B}
// 交换栈顶2个值
SWAP1 b[123]
stack [2 20 1]
store {7B}
// 复制第二个值并压栈
DUP2 b[123]
stack [20 2 20 1]
store {7B}
// 在内存0x20位置存储2(即变量position)
MSTORE b[123]
stack [20 1]
store {7B 2}
// 压栈内存偏移,0x20 = 32字节
PUSH 20 b[123]
stack [20 20 1]
store {7B 2}
// 计算内存偏移,弹出2个值,压栈相加的结果
ADD b[123]
stack [40 1]
store {7B 2}
// 压栈数据读取offset
PUSH 0 b[123]
stack [0 40 1]
store {7B 2}
// offset=0, size=0x40,也就是从store中读取2个32字节的值,
// 然后计算SHA3,结果压栈
KECCAK256 b[123]
stack [sha3(0x0000007B00000002) 1]
store {7B 2}
// 复制第二个值(即要赋的值)并压栈
DUP2 b[123] = 1
stack [1 sha3 1]
store {7B 2}
// 交换栈顶2个值
SWAP1 b[123] = 1
stack [sha3 1 1]
store {7B 2}
// 以sha3为key,1为value,存入StateDB,同时弹栈
SSTORE b[123] = 1
stack [1]
store {7B 2}
// 弹出返回值
POP b[123] = 1
stack []
store {7B 2}
以太坊挖矿流程的基本框架参见下图:其中涉及到的组件之间的关系可以参见下面的UML图:1. Miner启动打包在eth Service初始化的时候,会创建一个Miner实例:eth.miner = miner.New(e ...