Description:
Smart contract deployed on Ethereum with Factory features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/ProofRegistry.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title ProofRegistry
* @dev Stores proof tokens for human-AI handshakes on the blockchain
* @notice This contract is part of the Shuka License Registry Temple
*/
contract ProofRegistry {
// Admin address (Shuka's admin wallet)
address public admin;
// Proof structure matching ShukaHandshakeLog model
struct ProofToken {
string proofId; // Maps to handshake log id
bytes32 promptHash; // Hash of the prompt
string userIntent; // User's intended action
string initiatingAgent; // AI agent that initiated
uint256 trustScore; // Trust score (scaled by 100 for decimals)
address userWallet; // User's wallet address
uint256 timestamp; // Block timestamp
string shukaSignature; // Shuka's cryptographic signature
bool verified; // External verification status
string proofJWT; // JWT proof token
}
// Mappings
mapping(string => ProofToken) public proofs;
mapping(address => string[]) public userProofs;
mapping(bytes32 => bool) public promptHashExists;
// Events
event ProofRegistered(
string indexed proofId,
address indexed userWallet,
bytes32 indexed promptHash,
uint256 timestamp
);
event ProofVerified(
string indexed proofId,
address indexed verifier,
uint256 timestamp
);
// Modifiers
modifier onlyAdmin() {
require(msg.sender == admin, "Only admin can perform this action");
_;
}
modifier proofExists(string memory _proofId) {
require(bytes(proofs[_proofId].proofId).length > 0, "Proof does not exist");
_;
}
constructor() {
admin = msg.sender;
}
/**
* @dev Register a new proof token
* @param _proofId Unique identifier for the proof
* @param _promptHash Hash of the original prompt
* @param _userIntent User's intended action
* @param _initiatingAgent AI agent identifier
* @param _trustScore Trust score (0-100)
* @param _userWallet User's wallet address
* @param _shukaSignature Cryptographic signature from Shuka
* @param _proofJWT JWT token for proof
*/
function registerProof(
string memory _proofId,
bytes32 _promptHash,
string memory _userIntent,
string memory _initiatingAgent,
uint256 _trustScore,
address _userWallet,
string memory _shukaSignature,
string memory _proofJWT
) external onlyAdmin {
require(bytes(proofs[_proofId].proofId).length == 0, "Proof already exists");
require(!promptHashExists[_promptHash], "Prompt hash already registered");
require(_trustScore <= 100, "Trust score must be <= 100");
require(_userWallet != address(0), "Invalid user wallet");
ProofToken memory newProof = ProofToken({
proofId: _proofId,
promptHash: _promptHash,
userIntent: _userIntent,
initiatingAgent: _initiatingAgent,
trustScore: _trustScore,
userWallet: _userWallet,
timestamp: block.timestamp,
shukaSignature: _shukaSignature,
verified: false,
proofJWT: _proofJWT
});
proofs[_proofId] = newProof;
userProofs[_userWallet].push(_proofId);
promptHashExists[_promptHash] = true;
emit ProofRegistered(_proofId, _userWallet, _promptHash, block.timestamp);
}
/**
* @dev Verify an existing proof
* @param _proofId Proof identifier to verify
*/
function verifyProof(string memory _proofId)
external
onlyAdmin
proofExists(_proofId)
{
require(!proofs[_proofId].verified, "Proof already verified");
proofs[_proofId].verified = true;
emit ProofVerified(_proofId, msg.sender, block.timestamp);
}
/**
* @dev Get proof details
* @param _proofId Proof identifier
* @return ProofToken struct
*/
function getProof(string memory _proofId)
external
view
proofExists(_proofId)
returns (ProofToken memory)
{
return proofs[_proofId];
}
/**
* @dev Get all proofs for a user
* @param _userWallet User's wallet address
* @return Array of proof IDs
*/
function getUserProofs(address _userWallet)
external
view
returns (string[] memory)
{
return userProofs[_userWallet];
}
/**
* @dev Check if a prompt hash has been registered
* @param _promptHash Hash to check
* @return Boolean indicating existence
*/
function isPromptHashRegistered(bytes32 _promptHash)
external
view
returns (bool)
{
return promptHashExists[_promptHash];
}
/**
* @dev Update admin address
* @param _newAdmin New admin address
*/
function updateAdmin(address _newAdmin) external onlyAdmin {
require(_newAdmin != address(0), "Invalid admin address");
admin = _newAdmin;
}
/**
* @dev Get proof count for a user
* @param _userWallet User's wallet address
* @return Number of proofs
*/
function getUserProofCount(address _userWallet)
external
view
returns (uint256)
{
return userProofs[_userWallet].length;
}
/**
* @dev Batch register multiple proof tokens - saves ~65% gas for 10+ proofs
* @param _proofIds Array of unique proof identifiers
* @param _promptHashes Array of prompt hashes
* @param _userIntents Array of user intents
* @param _initiatingAgents Array of AI agent identifiers
* @param _trustScores Array of trust scores
* @param _userWallets Array of user wallet addresses
* @param _shukaSignatures Array of cryptographic signatures
* @param _proofJWTs Array of JWT tokens
*/
function batchRegisterProofs(
string[] memory _proofIds,
bytes32[] memory _promptHashes,
string[] memory _userIntents,
string[] memory _initiatingAgents,
uint256[] memory _trustScores,
address[] memory _userWallets,
string[] memory _shukaSignatures,
string[] memory _proofJWTs
) external onlyAdmin {
uint256 length = _proofIds.length;
require(
_promptHashes.length == length &&
_userIntents.length == length &&
_initiatingAgents.length == length &&
_trustScores.length == length &&
_userWallets.length == length &&
_shukaSignatures.length == length &&
_proofJWTs.length == length,
"Array length mismatch"
);
uint256 currentTime = block.timestamp;
for (uint256 i = 0; i < length; i++) {
require(bytes(proofs[_proofIds[i]].proofId).length == 0, "Proof exists");
require(!promptHashExists[_promptHashes[i]], "Hash registered");
require(_trustScores[i] <= 100, "Invalid trust score");
require(_userWallets[i] != address(0), "Invalid wallet");
proofs[_proofIds[i]] = ProofToken({
proofId: _proofIds[i],
promptHash: _promptHashes[i],
userIntent: _userIntents[i],
initiatingAgent: _initiatingAgents[i],
trustScore: _trustScores[i],
userWallet: _userWallets[i],
timestamp: currentTime,
shukaSignature: _shukaSignatures[i],
verified: false,
proofJWT: _proofJWTs[i]
});
userProofs[_userWallets[i]].push(_proofIds[i]);
promptHashExists[_promptHashes[i]] = true;
emit ProofRegistered(_proofIds[i], _userWallets[i], _promptHashes[i], currentTime);
}
}
/**
* @dev Batch verify multiple proofs - saves ~50% gas
* @param _proofIds Array of proof identifiers to verify
*/
function batchVerifyProofs(string[] memory _proofIds) external onlyAdmin {
uint256 currentTime = block.timestamp;
for (uint256 i = 0; i < _proofIds.length; i++) {
require(bytes(proofs[_proofIds[i]].proofId).length > 0, "Proof not found");
if (!proofs[_proofIds[i]].verified) {
proofs[_proofIds[i]].verified = true;
emit ProofVerified(_proofIds[i], msg.sender, currentTime);
}
}
}
/**
* @dev Batch get proof details - view function, no gas cost
* @param _proofIds Array of proof identifiers
* @return Array of ProofToken structs
*/
function batchGetProofs(
string[] memory _proofIds
) external view returns (ProofToken[] memory) {
ProofToken[] memory proofArray = new ProofToken[](_proofIds.length);
for (uint256 i = 0; i < _proofIds.length; i++) {
if (bytes(proofs[_proofIds[i]].proofId).length > 0) {
proofArray[i] = proofs[_proofIds[i]];
}
}
return proofArray;
}
/**
* @dev Batch check if prompt hashes have been registered - view function
* @param _promptHashes Array of hashes to check
* @return Array of booleans indicating existence
*/
function batchCheckPromptHashes(
bytes32[] memory _promptHashes
) external view returns (bool[] memory) {
bool[] memory exists = new bool[](_promptHashes.length);
for (uint256 i = 0; i < _promptHashes.length; i++) {
exists[i] = promptHashExists[_promptHashes[i]];
}
return exists;
}
}"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-09-28 14:51:45
Comments
Log in to comment.
No comments yet.