访问私有数据
当我们开始编写智能合约并接触到 public、private 等可见性修饰词时,我们可能会认为,如果你想让某些变量的值可以被公众读取,你需要声明它是公开的,而私有变量除了智能合约本身,任何人都不能读取。
但是,Ethereum 是一个公共区块链。那么,私有数据到底是什么意思?
在这一层次中,我们将看到你如何从任何智能合约中实际读取私有变量的值,同时澄清私有实际上代表什么--这绝对不是私有数据!
私有是什么意思?
函数(和变量)可见性修改器只影响函数的可见性--并不阻止对其值的访问。我们知道,公共函数是那些既可以由用户和智能合约在外部调用,也可以由智能合约本身调用的函数。
同样,内部函数是那些只能由智能合约本身调用的函数,外部用户和智能合约不能调用这些函数。外部函数则相反,它们只能由外部用户和智能合约调用,但不能由拥有该函数的智能合约本身调用。
私有的,类似的,只是影响到谁可以调用该函数。私有的和内部的行为基本类似,只是内部函数也可以被派生合约调用,而私有函数则不可以。
因此,举例来说,如果合约 A 有一个标记为内部的函数 f(),第二个继承合约 A 的合约 B 就会像这样
contract B is A {
...
}
仍然可以调用 f()。
然而,如果合约 A 有一个标记为私有的函数 g(),合约 B 就不能调用 g(),即使它继承了合约 A。
变量也是如此,因为变量基本上只是函数。私有变量只能由智能合约本身访问和修改,甚至派生合约也不能。然而,这并不意味着外部各方不能读取该值。
BUIDL
我们将建立一个简单的合约,以及一个 Hardhat 测试,来证明这一点。我们的合约将尝试将数据存储在私有变量中,希望没有人能够读取它的值。
该合约将在其构造函数中输入密码和用户名,并将它们存储在私有变量中。
用户将能够以某种方式访问这些私有变量。
概念
为了理解这一点,请回顾一下以太坊存储和执行层面,Solidity 中的变量被存储在 32 字节(256 位)的存储槽中,数据根据这些变量的声明顺序,按顺序存储在这些存储槽中。
存储也被优化了,如果一堆变量可以放在一个槽里,它们就会被放在同一个槽里。这被称为变量打包,我们将在后面进一步了解这个问题。
注意 所有这些命令都应该能顺利工作。 如果你在 windows 上,并面临无法读取 null 的属性(读取'pickAlgorithm')等错误,请尝试使用 npm cache clear --force 来清除 NPM 缓存。
新建项目
要建立一个 Hardhat 项目,打开终端并执行这些命令
npm init --yes
npm install --save-dev hardhat
# windows 电脑
# npm install --save-dev @nomicfoundation/hardhat-toolbox @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers
npx hardhat
选择创建一个基本样本项目 对已经指定的 Hardhat 项目根按回车键 在是否要添加.gitignore 的问题上按回车键 在 "是否要用 npm 安装这个样本项目的依赖项(@nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers)? 现在你已经有一个准备好的 hardhat 项目了!