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

Privacy

1. 题目要求

  • 1.1 这个合约的制作者非常小心的保护了敏感区域的 storage.解开这个合约来完成这一关.这些可能有帮助:

    • 理解 storage 的原理
    • 理解 parameter parsing 的原理
    • 理解 casting 的原理
  • 1.2 题目代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Privacy {

bool public locked = true;
uint256 public ID = block.timestamp;
uint8 private flattening = 10;
uint8 private denomination = 255;
uint16 private awkwardness = uint16(block.timestamp);
bytes32[3] private data;

constructor(bytes32[3] memory _data) {
data = _data;
}

function unlock(bytes16 _key) public {
require(_key == bytes16(data[2]));
locked = false;
}

/*
A bunch of super advanced solidity algorithms...

,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`
.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,
*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^ ,---/V\
`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*. ~|__(o.o)
^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*' UU UU
*/
}

2. 分析

  • 2.1 目标:将locked修改为false

    • bool public locked初始化为 true 并保存必须设置为 false 才能赢得挑战的值
    • bytes32[3] private data是存储我们的密钥的变量。我们需要找出data[2]解决挑战的价值
  • 2.2 我们可以将所有其他变量仅视为“存储填充”,以达到我们想要读取的内容 ( data[2]) 以解决挑战。

    • constructor(bytes32[3] memory _data)初始化data变量的值
    • 然后我们只需检查我们传递的输入unlock(bytes16 _key)是否与值匹配。如果比较返回 true,我们就解锁了合约,通过了挑战。byte16 _key``data[2]``true
  • 2.3 data首先,必须检索变量中的数据。这可以通过从区块链上的合约存储中提取数据来完成。在 brownie 中,这可以使用 来完成web3.eth.getStorageAt(),第一个参数是合约的地址,以及要查看的合约存储槽的方向。每个槽的容量为 32 字节(256 位),这意味着实际填满 32 字节槽的数据类型将占用整个槽,因此后续数据类型将滚动到下一个槽。如果数据类型声明为uint256bytes32,它将始终占用一个完整的存储槽,因为这些类型的大小已经是 32 字节。

    在隐私合约的情况下,我们知道相关数据是数组的最后一个元素data。因此,要提取这个,我们必须确定这条数据在哪里,在什么存储槽中。

  • 2.4 参考博客

  • image-20230224230120932

  • 2.5 在浏览器控制台依次执行 web3.eth.getStorageAt() ** ,data.slice(0,34)** 命令

3 .解题

  • 3.1 获取关卡实例地址:0xb6b2910033C8934D4eBf2FBb72EF87cbC09BE4d0

  • 3.2 依次执行如下代码得到 data[2]

  • addr = "0xb6b2910033C8934D4eBf2FBb72EF87cbC09BE4d0"
    '0xb6b2910033C8934D4eBf2FBb72EF87cbC09BE4d0'
    await web3.eth.getStorageAt(addr, 5)
    '0xa9cbb829703de0df913fc95cc78d10df15dc54270f501657492c89ceec732fb2'
    data = "0xa9cbb829703de0df913fc95cc78d10df15dc54270f501657492c89ceec732fb2"
    '0xa9cbb829703de0df913fc95cc78d10df15dc54270f501657492c89ceec732fb2'
    data.slice(0,34)
    '0xa9cbb829703de0df913fc95cc78d10df'
    
  • 3.3 调用实例部署的合约,并查看locked 的值为true

  • image-20230224231829330

  • 3.4 将执行data.slice(0,34) 得到的值传入unlock的形参中,并调用unlock() 函数

  • 3.5 查看locked的值,值由true 变成 false

  • image-20230224232554277

  • 3.6 提交实例

  • image-20230224232656891

  • 3.7 成功!!!!

评论



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