HackingLab 创新关 第一题 说明

为了能够更好的模拟真实的攻击环境,我们将题目部署到了以太坊测试网,在进入以太网测试网之前,您必须有一个钱包,这个钱包就是你到个人身份,在这里十分推荐使用MetaMask,MetaMask是一个Chrome浏览器插件,在Chrome商店搜索即可下载得到。
以下为第一题代码,我们到目标是调用guessAnswer函数,并传入正确到答案,但是由于区块链网络上你发送的交易,别人也可以看到,因此有些人可以窃取你的答案。为此,我们增加了HackingLabTools,在你发送答案前,先将答案做哈希计算(keccak256)然后再跟你的钱包地址一起做哈希计算,这样别人很难破解得到你的答案,而且也不可以通过重放的方式来通关。

为了能够更方便的得到你要发送的哈希值,我们提供了一个getAddressAnswerKeccak256函数,通过call该函数即可得到哈希后的答案,然后再发送交易到guess函数即可通关。但是第一题可能对于新手来说很难理解,所以guessAnswer函数也设计成了constant,即不需要发送交易也可以调用,所以只要call一下guess函数即可验证你的答案是否有效,如果返回true则说明答案正确,此时可以将未经哈希的答案提交到Hackinglab即可通关。

pragma solidity ^0.4.25;
contract Owned {
address public owner;
constructor() public payable{
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function setOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}
}

contract HackingLabTools{
//Welcome To HackingLab.cn
//TXkgV2VjaGF0IGlzIENwbHVzSHVhLCBubyBuZWVkIHRvIGhlc2l0YXRlLCBhZGQgbWUgbm93IQ==
function answerCompare(uint256 _answer, bytes32 _user_answer) public constant returns (bool){
bytes32 system_answer = keccak256(keccak256(_answer), abi.encodePacked(msg.sender));
if(system_answer == _user_answer){
return true;
}
return false;
}

//1. 如果你有了一个答案,先调用这个函数获得你到哈希值
function getAddressAnswerKeccak256(uint256 _answer)public constant returns (bytes32){
bytes32 system_answer = keccak256(keccak256(_answer), abi.encodePacked(msg.sender));
return system_answer;
}
}

contract AnswerToWin is Owned,HackingLabTools {
uint256 private answer;

function setAnswer(uint256 _answer) public onlyOwner{
answer = _answer;
}
//2. 提交你通过第一步获取到的哈希值,如果返回true,则说明你的答案正确,此时可以到Hackinglab提交答案
function guessAnswer(bytes32 _user_answer) public constant returns (bool){
require(msg.value <= 5000000000 wei);
return answerCompare(answer,_user_answer);
}
function transfer(address _to, uint256 _value) public onlyOwner{
_to.transfer(_value);
}

}