pragma solidity ^0.8.13; contract ReceiptMint { event Receipt(address indexed minter, bytes32 indexed payload, address indexed receiptAddress); mapping(address => uint256) public receiptBlock; error Exists(); error Create2Failed(); function mint(bytes32 payload) external returns (address receiptAddress) { bytes32 salt = keccak256(abi.encodePacked(block.chainid, msg.sender, payload)); bytes memory init = hex"60016000f3"; bytes32 initHash = keccak256(init); receiptAddress = address(uint160(uint256(keccak256(abi.encodePacked( hex"ff", address(this), salt, initHash ))))); if (receiptAddress == address(0) || receiptAddress.code.length != 0) revert Exists(); address deployed; assembly { deployed := create2(0, add(init, 0x20), mload(init), salt) } if (deployed != receiptAddress) revert Create2Failed(); receiptBlock[deployed] = block.timestamp; emit Receipt(msg.sender, payload, deployed); } }