Loading...
Loading...

block.timestamp — это время создания текущего блока в формате Unix timestamp (секунды с 1 января 1970 года).Свойство | Тип | Описание | Точность | Ограничения |
|---|---|---|---|---|
block.timestamp | uint256 | Время создания блока в Unix timestamp | ±15 минут | Может быть изменено майнерами |
block.number — порядковый номер текущего блока в блокчейне. В Ethereum блоки создаются примерно каждые 12 секунд.contract BlockTracker { uint256 public startBlock; uint256 public constant BLOCKS_PER_DAY = 7200; // ~24 часа при 12 сек/блок
constructor() { startBlock = block.number; }
function getBlocksSinceStart() public view returns (uint256) { return block.number - startBlock; }
function estimateTimeElapsed() public view returns (uint256) { uint256 blocksPassed = block.number - startBlock; return blocksPassed * 12; // ~12 секунд на блок в Ethereum }
function estimateDaysElapsed() public view returns (uint256) { uint256 blocksPassed = block.number - startBlock; return blocksPassed / BLOCKS_PER_DAY; }}contract TimeLock { mapping(address => uint256) public unlockTime; mapping(address => uint256) public lockedAmount;
event FundsLocked(address indexed user, uint256 amount, uint256 unlockTime); event FundsWithdrawn(address indexed user, uint256 amount);
function lockFunds(uint256 lockDurationMinutes) public payable { require(msg.value > 0, "Нужно отправить эфир");
unlockTime[msg.sender] = block.timestamp + (lockDurationMinutes * 60); lockedAmount[msg.sender] += msg.value;
emit FundsLocked(msg.sender, msg.value, unlockTime[msg.sender]); }
function withdraw() public { require(block.timestamp >= unlockTime[msg.sender], "Средства ещё заблокированы"); require(lockedAmount[msg.sender] > 0, "Нет заблокированных средств");
uint256 amount = lockedAmount[msg.sender]; lockedAmount[msg.sender] = 0; unlockTime[msg.sender] = 0;
payable(msg.sender).transfer(amount);
emit FundsWithdrawn(msg.sender, amount); }
function timeUntilUnlock(address user) public view returns (uint256) { if (block.timestamp >= unlockTime[user]) { return 0; } return unlockTime[user] - block.timestamp; }
function isUnlocked(address user) public view returns (bool) { return block.timestamp >= unlockTime[user]; }}contract TimedVoting { struct Proposal { string description; uint256 startTime; uint256 endTime; uint256 yesVotes; uint256 noVotes; mapping(address => bool) hasVoted; bool executed; }
mapping(uint256 => Proposal) public proposals; uint256 public proposalCount; uint256 public constant VOTING_DURATION = 7 days;
event ProposalCreated(uint256 indexed proposalId, string description, uint256 startTime, uint256 endTime); event VoteCast(uint256 indexed proposalId, address indexed voter, bool support); event ProposalExecuted(uint256 indexed proposalId, bool passed);
function createProposal(string memory description) public { Proposal storage newProposal = proposals[proposalCount]; newProposal.description = description; newProposal.startTime = block.timestamp; newProposal.endTime = block.timestamp + VOTING_DURATION;
emit ProposalCreated(proposalCount, description, newProposal.startTime, newProposal.endTime); proposalCount++; }
function vote(uint256 proposalId, bool support) public { Proposal storage proposal = proposals[proposalId];
require(block.timestamp >= proposal.startTime, "Голосование ещё не началось"); require(block.timestamp <= proposal.endTime, "Голосование завершено"); require(!proposal.hasVoted[msg.sender], "Уже проголосовали");
proposal.hasVoted[msg.sender] = true;
if (support) { proposal.yesVotes++; } else { proposal.noVotes++; }
emit VoteCast(proposalId, msg.sender, support); }
function executeProposal(uint256 proposalId) public { Proposal storage proposal = proposals[proposalId];
require(block.timestamp > proposal.endTime, "Голосование ещё не завершено"); require(!proposal.executed, "Предложение уже исполнено");
proposal.executed = true; bool passed = proposal.yesVotes > proposal.noVotes;
emit ProposalExecuted(proposalId, passed);
if (passed) { // Здесь можно выполнить логику принятого предложения } }
function getProposalStatus(uint256 proposalId) public view returns ( string memory status, uint256 timeRemaining, uint256 yesVotes, uint256 noVotes ) { Proposal storage proposal = proposals[proposalId];
if (proposal.executed) { status = "Executed"; timeRemaining = 0; } else if (block.timestamp < proposal.startTime) { status = "Not Started"; timeRemaining = proposal.startTime - block.timestamp; } else if (block.timestamp <= proposal.endTime) { status = "Active"; timeRemaining = proposal.endTime - block.timestamp; } else { status = "Awaiting Execution"; timeRemaining = 0; }
yesVotes = proposal.yesVotes; noVotes = proposal.noVotes; }}contract TimedAuction { struct Auction { address seller; string itemName; uint256 startTime; uint256 endTime; uint256 highestBid; address highestBidder; bool ended; }
mapping(uint256 => Auction) public auctions; mapping(uint256 => mapping(address => uint256)) public bids; uint256 public auctionCount;
event AuctionCreated(uint256 indexed auctionId, address indexed seller, string itemName, uint256 startTime, uint256 endTime); event BidPlaced(uint256 indexed auctionId, address indexed bidder, uint256 amount); event AuctionEnded(uint256 indexed auctionId, address indexed winner, uint256 winningBid);
function createAuction( string memory itemName, uint256 durationMinutes ) public { auctions[auctionCount] = Auction({ seller: msg.sender, itemName: itemName, startTime: block.timestamp, endTime: block.timestamp + (durationMinutes * 60), highestBid: 0, highestBidder: address(0), ended: false });
emit AuctionCreated(auctionCount, msg.sender, itemName, block.timestamp, auctions[auctionCount].endTime); auctionCount++; }
function placeBid(uint256 auctionId) public payable { Auction storage auction = auctions[auctionId];
require(block.timestamp >= auction.startTime, "Аукцион ещё не начался"); require(block.timestamp <= auction.endTime, "Аукцион завершён"); require(msg.value > auction.highestBid, "Ставка слишком низкая"); require(msg.sender != auction.seller, "Продавец не может делать ставки");
// Возвращаем деньги предыдущему лидеру if (auction.highestBidder != address(0)) { payable(auction.highestBidder).transfer(auction.highestBid); }
auction.highestBid = msg.value; auction.highestBidder = msg.sender; bids[auctionId][msg.sender] = msg.value;
emit BidPlaced(auctionId, msg.sender, msg.value); }
function endAuction(uint256 auctionId) public { Auction storage auction = auctions[auctionId];
require(block.timestamp > auction.endTime, "Аукцион ещё не завершён"); require(!auction.ended, "Аукцион уже завершён"); require( msg.sender == auction.seller || msg.sender == auction.highestBidder, "Только продавец или победитель могут завершить аукцион" );
auction.ended = true;
if (auction.highestBidder != address(0)) { // Переводим деньги продавцу payable(auction.seller).transfer(auction.highestBid); }
emit AuctionEnded(auctionId, auction.highestBidder, auction.highestBid); }
function getAuctionStatus(uint256 auctionId) public view returns ( string memory status, uint256 timeRemaining, uint256 currentHighestBid, address currentLeader ) { Auction memory auction = auctions[auctionId];
if (auction.ended) { status = "Ended"; timeRemaining = 0; } else if (block.timestamp < auction.startTime) { status = "Not Started"; timeRemaining = auction.startTime - block.timestamp; } else if (block.timestamp <= auction.endTime) { status = "Active"; timeRemaining = auction.endTime - block.timestamp; } else { status = "Awaiting End"; timeRemaining = 0; }
currentHighestBid = auction.highestBid; currentLeader = auction.highestBidder; }}contract TokenVesting { struct VestingSchedule { uint256 totalAmount; uint256 startTime; uint256 duration; uint256 released; bool revocable; bool revoked; }
mapping(address => VestingSchedule) public vestingSchedules;
event VestingScheduleCreated(address indexed beneficiary, uint256 totalAmount, uint256 duration); event TokensReleased(address indexed beneficiary, uint256 amount); event VestingRevoked(address indexed beneficiary);
function createVestingSchedule( address beneficiary, uint256 totalAmount, uint256 durationDays, bool revocable ) public payable { require(msg.value == totalAmount, "Неправильная сумма"); require(vestingSchedules[beneficiary].totalAmount == 0, "Уже есть план для этого адреса");
vestingSchedules[beneficiary] = VestingSchedule({ totalAmount: totalAmount, startTime: block.timestamp, duration: durationDays * 1 days, released: 0, revocable: revocable, revoked: false });
emit VestingScheduleCreated(beneficiary, totalAmount, durationDays * 1 days); }
function release() public { VestingSchedule storage schedule = vestingSchedules[msg.sender];
require(schedule.totalAmount > 0, "Нет плана вестинга"); require(!schedule.revoked, "Вестинг отозван");
uint256 releasableAmount = getReleasableAmount(msg.sender); require(releasableAmount > 0, "Нет доступных токенов");
schedule.released += releasableAmount; payable(msg.sender).transfer(releasableAmount);
emit TokensReleased(msg.sender, releasableAmount); }
function getReleasableAmount(address beneficiary) public view returns (uint256) { VestingSchedule memory schedule = vestingSchedules[beneficiary];
if (schedule.revoked) return 0;
uint256 vestedAmount = getVestedAmount(beneficiary); return vestedAmount - schedule.released; }
function getVestedAmount(address beneficiary) public view returns (uint256) { VestingSchedule memory schedule = vestingSchedules[beneficiary];
if (schedule.totalAmount == 0) return 0; if (schedule.revoked) return schedule.released;
if (block.timestamp >= schedule.startTime + schedule.duration) { // Полностью разблокировано return schedule.totalAmount; } else { // Частично разблокировано uint256 timeElapsed = block.timestamp - schedule.startTime; return (schedule.totalAmount * timeElapsed) / schedule.duration; } }
function revokeVesting(address beneficiary) public { VestingSchedule storage schedule = vestingSchedules[beneficiary];
require(schedule.revocable, "Вестинг нельзя отозвать"); require(!schedule.revoked, "Уже отозван");
schedule.revoked = true;
// Возвращаем неразблокированные токены отправителю uint256 unreleased = schedule.totalAmount - schedule.released; if (unreleased > 0) { payable(msg.sender).transfer(unreleased); }
emit VestingRevoked(beneficiary); }}contract TimeValidation { uint256 public lastUpdateTime;
function updateWithValidation() public { // ❌ ПЛОХО: Слишком строгая проверка require(block.timestamp > lastUpdateTime, "Время должно увеличиваться");
// ✅ ХОРОШО: Учитываем возможную неточность require(block.timestamp >= lastUpdateTime - 900, "Время слишком далеко в прошлом"); // 15 минут
lastUpdateTime = block.timestamp; }}contract SafeTimeUsage { uint256 public constant GRACE_PERIOD = 1 hours; // Буферное время
function criticalOperation() public { uint256 deadline = block.timestamp + 1 days;
// ✅ ХОРОШО: Добавляем буферное время для критических операций require(block.timestamp <= deadline - GRACE_PERIOD, "Слишком близко к дедлайну");
// Выполняем критическую операцию }}library TimeUtils { uint256 constant SECONDS_PER_MINUTE = 60; uint256 constant SECONDS_PER_HOUR = 3600; uint256 constant SECONDS_PER_DAY = 86400; uint256 constant SECONDS_PER_WEEK = 604800; uint256 constant SECONDS_PER_YEAR = 31536000;
function minutesToSeconds(uint256 minutes) internal pure returns (uint256) { return minutes * SECONDS_PER_MINUTE; }
function hoursToSeconds(uint256 hours) internal pure returns (uint256) { return hours * SECONDS_PER_HOUR; }
function daysToSeconds(uint256 days) internal pure returns (uint256) { return days * SECONDS_PER_DAY; }
function weeksToSeconds(uint256 weeks) internal pure returns (uint256) { return weeks * SECONDS_PER_WEEK; }
function isExpired(uint256 deadline) internal view returns (bool) { return block.timestamp > deadline; }
function timeUntil(uint256 futureTime) internal view returns (uint256) { if (futureTime <= block.timestamp) return 0; return futureTime - block.timestamp; }
function getDayOfWeek(uint256 timestamp) internal pure returns (uint256) { // 0 = Sunday, 1 = Monday, ..., 6 = Saturday return (timestamp / SECONDS_PER_DAY + 4) % 7; }
function isWeekend(uint256 timestamp) internal pure returns (bool) { uint256 dayOfWeek = getDayOfWeek(timestamp); return dayOfWeek == 0 || dayOfWeek == 6; }}
contract TimeUtilsExample { using TimeUtils for uint256;
function createTimeBasedRestriction() public view returns (bool) { uint256 deadline = block.timestamp + TimeUtils.daysToSeconds(7);
if (TimeUtils.isWeekend(block.timestamp)) { return false; // Не работаем в выходные }
return !deadline.isExpired(); }}block.timestamp и block.number я могу:

