Spaces:
Running
Running
File size: 4,438 Bytes
963d10b | 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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PureConvo {
// --- 0. BRANDING ---
string public constant name = "PureConvo Research Registry";
string public constant symbol = "CONVO";
// --- 1. IDENTITY & REPUTATION ---
struct Researcher {
bool isRegistered;
uint256 reputationScore;
string role; // "Admin", "Native_Speaker", "Contributor"
}
mapping(address => Researcher) public researchers;
address public labAdmin;
// --- 2. REGISTRY & LICENSING ---
struct DialectEntry {
uint256 id;
string phrase;
string dialect;
string ipfsCid;
address contributor;
string licenseType;
uint256 verificationCount;
bool isVerified;
}
uint256 public entryCounter;
mapping(uint256 => DialectEntry) public entries;
// --- 3. BACKUP SYSTEM ---
struct DataSnapshot {
uint256 timestamp;
string dataType; // "Database_CSV" or "Persona_JSON"
string ipfsCid;
string description;
address uploader;
}
mapping(string => DataSnapshot[]) public backups;
// --- 4. EVENTS (Consolidated) ---
event EntryProposed(uint256 indexed id, string phrase, address indexed proposer);
event EntryVerified(uint256 indexed id, address indexed verifier);
event ReputationMinted(address indexed researcher, uint256 amount);
event BackupCreated(string indexed dataKey, string ipfsCid, uint256 timestamp);
constructor() {
labAdmin = msg.sender;
researchers[msg.sender] = Researcher(true, 100, "Admin");
}
// --- MODIFIERS ---
modifier onlyAdmin() {
require(msg.sender == labAdmin, "Only Lab Admin can do this");
_;
}
modifier onlyRegistered() {
require(researchers[msg.sender].isRegistered, "Must be registered researcher");
_;
}
// --- CORE FUNCTIONS ---
function registerResearcher(address _user, string memory _role) public onlyAdmin {
researchers[_user] = Researcher(true, 10, _role);
}
function proposeEntry(string memory _phrase, string memory _dialect, string memory _ipfsCid, string memory _license) public onlyRegistered {
entryCounter++;
// Clean one-line initialization
entries[entryCounter] = DialectEntry(entryCounter, _phrase, _dialect, _ipfsCid, msg.sender, _license, 0, false);
emit EntryProposed(entryCounter, _phrase, msg.sender);
}
function verifyEntry(uint256 _id) public onlyRegistered {
require(entries[_id].contributor != msg.sender, "Cannot verify own entry");
require(!entries[_id].isVerified, "Already verified");
entries[_id].verificationCount++;
// Simple Consensus: If 2 peers verify, it becomes "Official"
if (entries[_id].verificationCount >= 2) {
entries[_id].isVerified = true;
_mintReputation(entries[_id].contributor, 50);
emit EntryVerified(_id, msg.sender);
}
// Reward the verifier
_mintReputation(msg.sender, 10);
}
function createBackup(string memory _dataKey, string memory _dataType, string memory _ipfsCid, string memory _description) public onlyRegistered {
DataSnapshot memory newSnap = DataSnapshot(block.timestamp, _dataType, _ipfsCid, _description, msg.sender);
backups[_dataKey].push(newSnap);
emit BackupCreated(_dataKey, _ipfsCid, block.timestamp);
}
// --- HELPER & VIEW FUNCTIONS (Restored) ---
// Essential for frontend to find the most recent backup without iterating
function getLatestBackup(string memory _dataKey) public view returns (string memory ipfsCid, uint256 timestamp) {
require(backups[_dataKey].length > 0, "No backups found");
DataSnapshot memory snap = backups[_dataKey][backups[_dataKey].length - 1];
return (snap.ipfsCid, snap.timestamp);
}
// Optional but helpful for quick license checks
function getLicenseInfo(uint256 _id) public view returns (string memory license, address contributor) {
return (entries[_id].licenseType, entries[_id].contributor);
}
// --- INTERNAL ---
function _mintReputation(address _user, uint256 _amount) internal {
researchers[_user].reputationScore += _amount;
emit ReputationMinted(_user, _amount);
}
}
|