一个蜜罐合约的解析
合约地址在: etherscan
网上的讨论地址 reddit 源码如下:
contract defi_game {
function Try(string memory _response) public payable {
if (
answerHash == keccak256(abi.encode(_response)) &&
msg.value > 1 ether
) {
payable(msg.sender).transfer(address(this).balance);
}
}
string public question;
bytes32 answerHash;
mapping(bytes32 => bool) admin;
function Start(string calldata _question, string calldata _response)
public
payable
isAdmin
{
if (answerHash == 0x0) {
answerHash = keccak256(abi.encode(_response));
question = _question;
}
}
function New(string calldata _question, bytes32 _answerHash) public payable isAdmin {
question = _question;
answerHash = _answerHash;
}
function Stop() public payable isAdmin {
payable(msg.sender).transfer(address(this).balance);
}
constructor(bytes32[] memory admins) {
for (uint256 i = 0; i < admins.length; i++) {
admin[admins[i]] = true;
}
}
modifier isAdmin() {
require(admin[keccak256(abi.encodePacked(msg.sender))]);
_;
}
fallback() external {}
}
分别是部署合约(constructor),开始游戏(Start),尝试(Try),停止游戏(Stop) 从代码来看,整个代码就是,猜谜游戏,start出题、设置答案,Try解题,对了就转账给对的人。 从交易记录来看,出题人,一下转了2个eth进去,Try需要至少1个eth才能进行。 结果就是合约部署人,在constructor的时候把自己账号的 keccak256(abi.encodePacked(msg.sender)给设置进去
for (uint256 i = 0; i < admins.length; i++) {
admin[admins[i]] = true;
}
Start的时候设置问题,
answerHash = keccak256(abi.encode(_response)); question = _question;
这个地方question是一个public变量,所以你能在链上面看到问题,通过Start的参数,你可以看到答案,但是这不是真的答案, try一下你就知道,try一下就至少一个ETH
我把合约本地部署了一下,调用参数一样,Try可以成功,套路挺深的。 所以那个源码可能不是真的源码。 反汇编代码还是挺累,所以这个坑,后面有时间再填。 如果自己要部署合约,先这样:
function getadmin() public {
address addr = address(0x9BEF5148fD530244a14830f4984f2B76BCa0dC58);
bytes32 kca = keccak256(abi.encodePacked(addr));
emit log_bytes32(kca);//0x8d3dfe9abb5f4b094c84ab5dc2fa239c318e4985fd30286fff6150ea6963222f
}
await defi_game.deploy(["0x0000000000000000000000000000000000000000000000000000000000000020", "0x0000000000000000000000000000000000000000000000000000000000000002",
"0x8d3dfe9abb5f4b094c84ab5dc2fa239c318e4985fd30286fff6150ea6963222f"])
0x9BEF5148fD530244a14830f4984f2B76BCa0dC58 是 Ganache的默认账号。
只是技术探讨,大家可以交流一下。
后面又反汇编了一下代码,发现代码确实是这个。
经过群友Miller的提醒,感谢Miller,ethscan上面合约调用合约显示是有问题的 这个里可以明确看到,New调用
另一个区块链浏览器 这样就完整了,我一直当ethscan是什么都能看到的,疑惑了几天,看来分析问题得多看几个区块链浏览器。
所以流程如下:
1,部署合约, 2,调用New设置答案hash 3,开始Start,投入2个eth 4,有人Try,投入至少1个eth 5,Stop 收入,转回自己的钱包。
后续,没讲完的 一个蜜罐合约的解析(二)调用隐藏 | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!