/ python / contracts / UsageContract.sol
UsageContract.sol
  1  // SPDX-License-Identifier: MIT
  2  pragma solidity ^0.8.0;
  3  
  4  contract UsageContract {
  5      mapping(address => bool) private developers;
  6      address[] private developerList;
  7      mapping(address => bool) private clients;
  8      mapping(address => uint256) public clientFunding;
  9      mapping(address => uint256) private developerBalances;
 10  
 11      // Voting system for developer registration
 12      mapping(address => bool) private pendingRegistrations;
 13      mapping(address => mapping(address => bool)) private votes;
 14      mapping(address => mapping(address => bool)) private hasVoted;
 15      mapping(address => uint256) private voteCount;
 16  
 17      event DeveloperRegistered(address indexed developer);
 18      event ClientRegistered(address indexed client);
 19      event Funded(address indexed client, uint256 amount);
 20      event Consumed(address indexed client, uint256 amount);
 21  
 22      constructor() {
 23          developers[msg.sender] = true;
 24          developerList.push(msg.sender);
 25          emit DeveloperRegistered(msg.sender);
 26      }
 27  
 28      function requestDeveloperRegistration() external {
 29          require(!developers[msg.sender], "Already registered as developer");
 30          require(!pendingRegistrations[msg.sender], "Registration already pending");
 31  
 32          pendingRegistrations[msg.sender] = true;
 33          // Do not add to developerList or emit event yet - wait for voting
 34      }
 35  
 36      function hasPendingRegistrationRequest(address developer) external view returns (bool) {
 37          return pendingRegistrations[developer];
 38      }
 39  
 40      function voteForDeveloper(address developer, bool approve) external {
 41          require(developers[msg.sender], "Only developers can vote");
 42          require(pendingRegistrations[developer], "No pending registration for this developer");
 43          require(!hasVoted[developer][msg.sender], "Already voted for this developer");
 44  
 45          votes[developer][msg.sender] = approve;
 46          hasVoted[developer][msg.sender] = true;
 47          voteCount[developer]++;
 48  
 49          // Check if all developers have voted
 50          if (voteCount[developer] == developerList.length) {
 51              _finalizeVoting(developer);
 52          }
 53      }
 54  
 55      function _finalizeVoting(address developer) private {
 56          uint256 approvalCount = 0;
 57  
 58          // Count approval votes
 59          for (uint256 i = 0; i < developerList.length; i++) {
 60              if (votes[developer][developerList[i]]) {
 61                  approvalCount++;
 62              }
 63          }
 64  
 65          // Require majority (>50%) approval
 66          bool approved = approvalCount * 2 > developerList.length;
 67  
 68          if (approved) {
 69              developers[developer] = true;
 70              developerList.push(developer);
 71              emit DeveloperRegistered(developer);
 72          }
 73  
 74          // Clean up voting data
 75          pendingRegistrations[developer] = false;
 76          voteCount[developer] = 0;
 77          for (uint256 i = 0; i < developerList.length; i++) {
 78              delete votes[developer][developerList[i]];
 79              delete hasVoted[developer][developerList[i]];
 80          }
 81      }
 82  
 83      function registerClient() external {
 84          clients[msg.sender] = true;
 85          emit ClientRegistered(msg.sender);
 86      }
 87  
 88      function isDeveloper() external view returns (bool) {
 89          return developers[msg.sender];
 90      }
 91  
 92      function isClient(address user) external view returns (bool) {
 93          return clients[user];
 94      }
 95  
 96      function fund() external payable {
 97          require(msg.value > 0, "No funds sent");
 98          clients[msg.sender] = true;
 99          clientFunding[msg.sender] += msg.value;
100          emit Funded(msg.sender, msg.value);
101      }
102  
103      function getClientFunding() external view returns (uint256) {
104          return clientFunding[msg.sender];
105      }
106  
107      function requestPayout() external {
108          require(clients[msg.sender], "Only clients can request payout");
109          require(clientFunding[msg.sender] > 0, "No funds available for payout");
110  
111          uint256 amount = clientFunding[msg.sender];
112  
113          (bool sent, ) = msg.sender.call{value: amount}("");
114          require(sent, "Failed to send payout");
115  
116          clientFunding[msg.sender] = 0;
117      }
118  
119      function consume(uint256 amount) external returns (uint256) {
120          emit Consumed(msg.sender, clientFunding[msg.sender]);
121          require(
122              clientFunding[msg.sender] >= amount,
123              "Insufficient client funding"
124          );
125          require(developerList.length > 0, "No developers registered");
126          clientFunding[msg.sender] -= amount;
127          uint256 share = amount / developerList.length;
128          uint256 remainder = amount % developerList.length;
129          for (uint256 i = 0; i < developerList.length; i++) {
130              developerBalances[developerList[i]] += share;
131          }
132          if (remainder > 0) {
133              developerBalances[developerList[0]] += remainder;
134          }
135          return clientFunding[msg.sender];
136      }
137  
138      function getDeveloperBalance() external view returns (uint256) {
139          require(developers[msg.sender], "Only developers can check their balance");
140          return developerBalances[msg.sender];
141      }
142  
143      function withdrawBalance() external {
144          require(developers[msg.sender], "Only developers can withdraw");
145          uint256 balance = developerBalances[msg.sender];
146          require(balance > 0, "No balance to withdraw");
147  
148          developerBalances[msg.sender] = 0;
149          (bool sent, ) = msg.sender.call{value: balance}("");
150          require(sent, "Failed to withdraw balance");
151      }
152  }