File size: 1,964 Bytes
dfb775d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | // SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.26;
/// @title MindXTrainRegistry
/// @notice Write-once anchoring contract for mindXtrain run receipts.
/// @dev Cypherpunk2048 standard: immutable, no proxy, no Ownable, no admin keys,
/// no pause, no setter. Receipts cannot be overwritten or revoked.
contract MindXTrainRegistry {
struct Receipt {
bytes32 yamlHash;
bytes32 datasetCidHash;
bytes32 checkpointCidHash;
bytes32 evalReportHash;
address publisher;
uint64 timestamp;
}
mapping(bytes32 => Receipt) private _receipts;
event ReceiptAnchored(
bytes32 indexed runId,
address indexed publisher,
bytes32 yamlHash,
bytes32 datasetCidHash,
bytes32 checkpointCidHash,
bytes32 evalReportHash,
uint64 timestamp
);
error ReceiptAlreadyExists(bytes32 runId);
function anchor(
bytes32 runId,
bytes32 yamlHash,
bytes32 datasetCidHash,
bytes32 checkpointCidHash,
bytes32 evalReportHash
) external {
if (_receipts[runId].timestamp != 0) revert ReceiptAlreadyExists(runId);
Receipt memory r = Receipt({
yamlHash: yamlHash,
datasetCidHash: datasetCidHash,
checkpointCidHash: checkpointCidHash,
evalReportHash: evalReportHash,
publisher: msg.sender,
timestamp: uint64(block.timestamp)
});
_receipts[runId] = r;
emit ReceiptAnchored(
runId,
msg.sender,
yamlHash,
datasetCidHash,
checkpointCidHash,
evalReportHash,
r.timestamp
);
}
function get(bytes32 runId) external view returns (Receipt memory) {
return _receipts[runId];
}
function exists(bytes32 runId) external view returns (bool) {
return _receipts[runId].timestamp != 0;
}
}
|