// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; contract QuantumMaintenanceRecord1155 is ERC1155, AccessControl { bytes32 public constant ISSUER_ROLE = keccak256("ISSUER_ROLE"); struct MaintenanceRecord { string publicId; string referenceCode; string recordHash; string traceabilityHash; string metadataURI; uint256 impactWh; uint64 periodStart; uint64 periodEnd; bool exists; } string public name = "Quantum Maintenance Record"; string public symbol = "QMR"; uint256 public nextTokenId = 1; mapping(uint256 => MaintenanceRecord) public records; mapping(string => uint256) public tokenIdByPublicId; event MaintenanceRecordMinted( uint256 indexed tokenId, address indexed to, string publicId, string referenceCode, uint256 impactWh ); constructor(address admin, string memory baseURI) ERC1155(baseURI) { _grantRole(DEFAULT_ADMIN_ROLE, admin); _grantRole(ISSUER_ROLE, admin); } function mintRecord( address to, string calldata publicId, string calldata referenceCode, string calldata recordHash, string calldata traceabilityHash, string calldata metadataURI, uint256 impactWh, uint64 periodStart, uint64 periodEnd ) external onlyRole(ISSUER_ROLE) returns (uint256 tokenId) { require(bytes(publicId).length > 0, "publicId required"); require(bytes(referenceCode).length > 0, "referenceCode required"); require(bytes(recordHash).length > 0, "recordHash required"); require(periodEnd > periodStart, "invalid period"); require(tokenIdByPublicId[publicId] == 0, "publicId already minted"); tokenId = nextTokenId++; records[tokenId] = MaintenanceRecord({ publicId: publicId, referenceCode: referenceCode, recordHash: recordHash, traceabilityHash: traceabilityHash, metadataURI: metadataURI, impactWh: impactWh, periodStart: periodStart, periodEnd: periodEnd, exists: true }); tokenIdByPublicId[publicId] = tokenId; _mint(to, tokenId, 1, ""); emit MaintenanceRecordMinted(tokenId, to, publicId, referenceCode, impactWh); } function uri(uint256 tokenId) public view override returns (string memory) { require(records[tokenId].exists, "token does not exist"); return records[tokenId].metadataURI; } }