微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取 Solidity 映射的密钥

如何解决获取 Solidity 映射的密钥

我试图在 solidity 合同中获取映射到特定合同(不完全是)的明星名称和地址的键

mapping(string=>address) nameOfAccounts;

我期待的是一种类似于 Javascript 中的 Object.keys(nameOfAccounts)方法。有没有类似的方法?。或者我应该使用额外的 array。额外的 Array 可能会导致额外的 gas 成本(这不是我喜欢的选择)。请分享一些见解

我想知道如果无法获得钥匙,是否还有其他方法可以做?

解决方法

简短回答:如果合同没有提供地图的对象键列表,您将无法获得。

长答案:

但是由于区块链是公开的东西,你可以得到任何东西。 要获取地图的所有键,您需要执行以下操作:

  • 设置存档节点并启用跟踪(您将需要 9 TB 的磁盘,带有 SSD 缓存)
  • 获取对合约的所有调用的跟踪并搜索 SSTORE 操作码(指令)
  • SSTORE 指令从堆栈中弹出 2 个参数,Loc(位置)和 Val(值)。位置是您正在寻找的关键。

如果你没有存档节点的预算,可以试试Etherscan的API

SO 上有关于如何读取合同存储的答案,可能会有用。

还有一个选项,反编译合约,并检查其输入,输入会有密钥,然后扫描该合约的所有交易,并通过处理输入提取密钥(输入是tx.Data()场地)。如果您对合同有一些了解,或者如果您有来源,则此选项会更容易,这将是最简单的事情(处理输入)

StateDB 对象类型中还有一个函数,称为 ForEachStorage()。它没有来自 RPC api 的前端,但是您可以通过一些努力实现自己的 RPC 函数来访问它并将其放在完整节点上。这个函数接受合约的地址和一个闭包函数,它会遍历整个合约的存储。来源:https://github.com/ethereum/go-ethereum/blob/0a3993c558616868e35f9730e92c704ac16ee437/core/state/statedb.go#L634 您唯一需要知道的是密钥是如何构建的,而这只能从合约源中得知。

,

迭代键的最佳方法是,当添加一个键时,您还会发出一个 Solidity 事件。

您从事件日志中获取密钥。这可以在客户端(JavaScript、Python)完成,但不能在 Solidity 内部完成,因为 EVM 无法访问事件数据。

由于执行受限环境中的效率原因,Solidity/EVM 不存储可迭代键。

More informationn here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。