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);
    }
}