// SPDX-License-Identifier: MIT pragma solidity 0.8.29; /** * @title SokoGuestbook * @notice Simple guestbook: anyone can write a message stored with their address and timestamp. * @dev Minimal and gas-conscious. Uses calldata for input and stores timestamp as uint64. */ contract SokoGuestbook { /// @dev Single guestbook entry struct Entry { address author; uint64 timestamp; string message; } /// @dev All entries are stored in this dynamic array Entry[] private entries; /// @notice Emitted when a new message is written event NewMessage(address indexed author, uint64 timestamp, string message); /// @notice Write a message to the guestbook /// @param message The message to store function writeMessage(string calldata message) external { // Store entry with compact timestamp type entries.push(Entry({author: msg.sender, timestamp: uint64(block.timestamp), message: message})); emit NewMessage(msg.sender, uint64(block.timestamp), message); } /// @notice Get number of messages stored /// @return count Number of entries function count() external view returns (uint256) { return entries.length; } /// @notice Read all messages /// @dev Returns three parallel arrays (authors, timestamps, messages) /// @return authors Array of message authors /// @return timestamps Array of timestamps (uint64) /// @return messages Array of messages function getAll() external view returns (address[] memory authors, uint64[] memory timestamps, string[] memory messages) { uint256 len = entries.length; authors = new address[](len); timestamps = new uint64[](len); messages = new string[](len); for (uint256 i = 0; i < len; ++i) { Entry storage e = entries[i]; authors[i] = e.author; timestamps[i] = e.timestamp; messages[i] = e.message; } } }