pragma solidity ^0.8.13; contract BlockhashReceiptAnchor { struct Receipt { uint64 blockNumber; address signer; bytes32 parentHash; } mapping(bytes32 => Receipt) private receipts; event Anchored( bytes32 indexed receiptId, address indexed signer, bytes32 payload, bytes32 parentHash, uint256 blockNumber ); function pin(bytes32 payload) external { bytes32 parentHash = blockhash(block.number - 1); require(parentHash != bytes32(0)); bytes32 receiptId = keccak256(abi.encodePacked(block.chainid, msg.sender, payload, parentHash)); require(receipts[receiptId].parentHash == bytes32(0)); receipts[receiptId] = Receipt(uint64(block.number), msg.sender, parentHash); emit Anchored(receiptId, msg.sender, payload, parentHash, block.number); } }