欢迎订阅专栏:3分钟Solidity--智能合约--Web3区块链技术必学
如需获取本内容的最新版本,请参见 Cyfrin.io 上的“块时间戳作(代码示例)”
漏洞
block.timestamp可能会被矿工操纵,但有以下限制:
- 它不能比其父区块的时间戳更早
- 它不能设定为太远的未来时间
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
/*
轮盘赌是一种游戏,如果你能在特定时机提交交易,就能赢得合约中的所有以太币。
玩家需要发送10个以太币,如果区块时间戳模15等于0,即可获胜。
*/
/*
1. 用10个以太坊部署轮盘赌
2. Eve运行着一个强大的矿工,可以操纵区块时间戳。
3. Eve将block.timestamp设置为未来能被15整除的数字,并找到目标区块哈希。
4. Eve的区块成功被纳入链中,Eve赢得了轮盘赌游戏。
*/
contract Roulette {
uint256 public pastBlockTime;
constructor() payable {}
function spin() external payable {
require(msg.value == 10 ether); // 必须发送10个以太币才能参与
require(block.timestamp != pastBlockTime); // 每个区块仅限一笔交易
pastBlockTime = block.timestamp;
if (block.timestamp % 15 == 0) {
(bool sent,) = msg.sender.call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
}
}
预防性技术
- 不要使用
block.timestamp作为熵源和随机数