访问私人数据|破解Solidity

  • Solidity通过槽(Slot)系统存储合约中定义的变量,即使变量被标记为私有(private),区块链的透明性仍允许任何人读取这些数据,因此存储敏感信息(如密码)是不安全的。

  • 文章通过一个Vault Contract示例展示了如何利用Truffle工具和web3.eth.getStorageAt方法访问私有变量,包括bytes32类型的密码和Users结构数组中的数据。

  • 演示了如何从特定槽索引读取数据,并将十六进制转换为ASCII码以获取明文密码,以及如何通过哈希计算访问数组中的后续元素。

  • 最终强调区块链的透明性本质决定了敏感信息不应直接存储在链上,开发者需避免此类设计漏洞。

总结

在开始之前,我们需要了解状态变量是如何通过SLOTS以稳定方式存储的。

Slot System

Solidity通过槽存储合约中定义的变量。

                     访问说明符(私有)

当为基于区块链的应用程序(dApps)编写代码时,你可以定义一个变量为公共或私有。定义私有变量的目的是防止其他合约修改它。但是,区块链应该是透明的,这意味着不管变量是私有的还是公共的,每个人都可以读取它。因此,存储像密码这样的敏感信息是一个非常糟糕的主意。

通过例子来理解

Vault Contract定义了各种各样的变量,但最有趣的是bytes32密码,存储id和密码的 struct Users数组。

addUsers函数将其他用户推送到Users结构数组中。

合约已经部署在Ropsten TestNet地址:0x3505a02BCDFbb225988161a95528bfDb279faD6b

让我们使用truffle来学习如何与插槽交互,并最终提取密码。

Truffle Demo

让我们连接到Ropsten并初始化到我们拥有的合约地址。

          truffle — 连接到Ropsten 

如果你正在查看上面的合约,我已经标记了哪些变量存储在哪些槽中。

//Syntax to access the data stored in the slots web3.eth.getStorageAt(contractAddress, slotIndex, console.log)

在下面的例子中,我们读取slotIndex=0的数据,然后将十六进制转换为十进制。

在本例中,我们试图读取slotIndex=2的内容,即密码变量。输出为bytes32,可以通过web3.utils.toAscii转换为Ascii码。

           读取私有bytes32密码变量

最后,读取用户id和密码。第一个getStorageAt调用输出数组长度。soliditySha3返回第一个数组元素存储的哈希值。

访问下一个存储项。我们需要将哈希值增加1。因此,3f - >40。

           读取struct Users数组中的数据

解决方案

区块链在设计上是透明的,所以不要将敏感信息存储在区块链上。

Source:https://zuhaibmd.medium.com/accessing-private-data-hack-solidity-4-f94d479432c7

分享至:

作者:去中心化金融社区

本文为PANews入驻专栏作者的观点,不代表PANews立场,不承担法律责任。

文章及观点也不构成投资意见

图片来源:去中心化金融社区如有侵权,请联系作者删除。

关注PANews官方账号,一起穿越牛熊
推荐阅读
6小时前
8小时前
9小时前
2026-01-15 12:00
2026-01-15 10:10
2026-01-15 07:00

热门文章

行业要闻
市场热点
精选读物

精选专题

App内阅读