如何读取Ganache指定区块中存储的智能合约变量历史值
智能合约区块存储逻辑及历史值读取方法
一、EVM 链上数据存储逻辑
- 每个智能合约在EVM中拥有独立的持久化存储空间,状态变量按声明顺序依次分配固定的存储槽(slot),你示例中第一个声明的
uint public value对应存储槽0。 - 每个区块会记录当前链的全局状态根,对应该区块生成完成时所有合约的存储状态快照,区块生成后状态根不可篡改。
- 你部署合约生成Block-1时,slot 0的初始值为0;调用
inputData(43)生成Block-2时,slot 0的值被修改为43并对应Block-2的状态根;调用inputData(57)生成Block-3时,slot 0的值更新为57对应Block-3的状态根。
二、读取Block-2中value历史值的方法
Ganache默认开启全历史状态存储,无需修改合约即可直接查询历史区块的状态,常用方法如下:
方法1:通过SDK调用标准RPC接口
使用Web3.js/Ethers.js等开发SDK调用eth_getStorageAt接口,指定三个参数:合约地址、存储槽编号、目标区块高度:
// Ethers v6 示例 const targetBlockNumber = 2; // Block-2的区块高度 const slotNumber = 0; // value对应的存储槽 const historicalValue = await provider.getStorage("你的合约地址", slotNumber, targetBlockNumber); console.log(Number(historicalValue)); // 输出 43
// Web3.js 示例 const historicalValue = await web3.eth.getStorageAt("你的合约地址", 0, 2); console.log(Number(historicalValue)); // 输出 43
方法2:通过Remix直接查询
在Remix的Deploy & Run Transactions面板选中你部署的合约,调用自动生成的value()查询方法时,面板顶部可选择查询的区块高度,选择Block-2对应的高度后执行调用即可直接返回43。
内容的提问来源于stack exchange,提问作者Mr. Jack
相关产品推荐
相关产品推荐

