pragma solidity ^0.4.23; contract Permissions { // enum and struct declaration enum NodeStatus { NotInList, PendingApproval, Approved, PendingDeactivation, Deactivated, PendingBlacklisting, Blacklisted } enum AccountAccess { FullAccess, ReadOnly, Transact, ContractDeploy } struct NodeDetails { string enodeId; //e.g. 127.0.0.1:20005 string ipAddrPort; string discPort; string raftPort; NodeStatus status; } // use an array to store node details // if we want to list all node one day, mapping is not capable NodeDetails[] private nodeList; // use a mapping of enodeid to array index to track node mapping (bytes32 => uint) private nodeIdToIndex; // keep track of node number uint private numberOfNodes; // use an array to store account details // if we want to list all account one day, mapping is not capable address[] private accountList; // store node approval, deactivation and blacklisting vote status (prevent double vote) mapping (uint => mapping (address => bool)) private voteStatus; // valid vote count mapping (uint => uint) private voteCount; // checks if firts time network boot up has happened or not bool networkBoot = false; // node permission events for new node propose event NodeProposed(string _enodeId); event NodeApproved(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort); event VoteNodeApproval(string _enodeId, address _accountAddress); // node permission events for node decativation event NodePendingDeactivation (string _enodeId); event NodeDeactivated(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort); event VoteNodeDeactivation(string _enodeId, address _accountAddress); // node permission events for node blacklist event NodePendingBlacklist(string _enodeId); event NodeBlacklisted(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort); event VoteNodeBlacklist(string _enodeId, address _accountAddress); // account permission events event AccountAccessModified(address _address, AccountAccess _access); // events related to voting accounts for majority voting event NoVotingAccount(); event VoterAdded(address _address); event VoterRemoved(address _address); // Checks if the given enode exists modifier enodeInList(string _enodeId) { require(nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] != 0, "Enode is not in the list"); _; } // Checks if the given enode does not exists modifier enodeNotInList(string _enodeId) { require(nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] == 0, "Enode is in the list"); _; } // Checks if the account can vote modifier canVote() { bool flag = false; for (uint i=0; i accountList.length / 2){ nodeList[nodeIndex].status = NodeStatus.Approved; emit NodeApproved(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].ipAddrPort, nodeList[nodeIndex].discPort, nodeList[nodeIndex].raftPort); } } function checkNodeDeactivation(string _enodeId) internal { uint nodeIndex = getNodeIndex(_enodeId); if (voteCount[nodeIndex] > accountList.length / 2){ nodeList[nodeIndex].status = NodeStatus.Deactivated; emit NodeDeactivated(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].ipAddrPort, nodeList[nodeIndex].discPort, nodeList[nodeIndex].raftPort); } } function checkNodeBlacklisting(string _enodeId) internal { uint nodeIndex = getNodeIndex(_enodeId); if (voteCount[nodeIndex] > accountList.length / 2){ nodeList[nodeIndex].status = NodeStatus.Blacklisted; emit NodeBlacklisted(nodeList[nodeIndex].enodeId, nodeList[nodeIndex].ipAddrPort, nodeList[nodeIndex].discPort, nodeList[nodeIndex].raftPort); } } }