github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/contracts/chief/src/chief_0.0.2.sol (about) 1 // Copyright 2018 The Smartmesh Chain Authors 2 // This file is part of the Spectrum library. 3 pragma solidity ^0.4.19; 4 5 6 contract TribeChief { 7 8 string vsn = "0.0.2"; 9 10 //配置 >>>> 11 uint epoch = 11520; // 48H 12 mapping(address => bool) genesisSigner; //创世签名节点 13 uint singerLimit = 3; 14 uint volunteerLimit = 4; 15 //配置 <<<< 16 17 uint blockNumber; 18 19 //签名人信息 20 struct SignerInfo { 21 uint score; 22 uint number; 23 } 24 25 address _owner; 26 27 //签名人列表 28 address[] _signerList; 29 30 //候补人列表 31 address[] _volunteerList; 32 33 //签名人分数和变更区块号的映射 34 mapping(address => SignerInfo) signersMap; 35 36 //候选人变更区块号的映射 37 mapping(address => uint) volunteersMap; 38 39 // 删除一个候补志愿者 40 function deleteVolunteer(uint index) private { 41 42 uint vlen = _volunteerList.length; 43 // _signerList >>>> 44 if (index < vlen) { 45 delete volunteersMap[_volunteerList[index]]; 46 for (uint i = index; i < vlen - 1; i++) { 47 _volunteerList[i] = _volunteerList[i + 1]; 48 } 49 _volunteerList.length -= 1; 50 } 51 } 52 53 // 删除一个签名人 54 function deleteSigner(uint index) private { 55 uint slen = _signerList.length; 56 if (index < slen) { 57 delete signersMap[_signerList[index]]; 58 for (uint i = index; i < slen - 1; i++) { 59 _signerList[i] = _signerList[i + 1]; 60 } 61 _signerList.length -= 1; 62 } 63 } 64 65 // 增加一个志愿者 66 function pushVolunteer(address volunteer) private { 67 68 //满员或者已经存在于签名人or候选人则不添加 69 if (_volunteerList.length < volunteerLimit && volunteersMap[volunteer] == 0 && signersMap[volunteer].number == 0) { 70 _volunteerList.push(volunteer); 71 volunteersMap[volunteer] = block.number; 72 } 73 } 74 75 function pushSigner(address signer, uint score) private { 76 77 if (_signerList.length < singerLimit) { 78 _signerList.push(signer); 79 signersMap[signer].score = score; 80 signersMap[signer].number = block.number; 81 } 82 } 83 84 function TribeChief(address[] genesisSigners) public { 85 _owner = msg.sender; 86 uint len = genesisSigners.length; 87 if (len > 0) { 88 for (uint i = 0; i < len; i++) { 89 address g = genesisSigners[i]; 90 genesisSigner[g] = true; 91 pushSigner(g, 3); 92 } 93 } else { 94 // normal default for testing 95 address g1 = 0x4110bd1ff0b73fa12c259acf39c950277f266787; 96 address g2 = 0xca012e2facf405885293d8d3ba3f14fae1e58b71; 97 address g3 = 0xadb3ea3ad356199206ca817b04fd668cc5196df2; 98 99 // nerver delete genesis signer 100 genesisSigner[g1] = true; 101 102 pushSigner(g1, 3); 103 pushSigner(g2, 3); 104 pushSigner(g3, 3); 105 } 106 } 107 108 modifier apply(address _addr) { 109 require(signersMap[_addr].number > 0); 110 _; 111 } 112 modifier owner(address _addr) { 113 require(_addr == _owner); 114 _; 115 } 116 117 function setVolunteerLimit(uint n) public apply(msg.sender) { 118 volunteerLimit = n; 119 } 120 121 function setSingerLimit(uint n) public apply(msg.sender) { 122 singerLimit = n; 123 } 124 125 function update(address volunteer) public apply(msg.sender) { 126 127 blockNumber = block.number; 128 129 // every epoch be clean volunteers 130 if (block.number > epoch && block.number % epoch == 0) { 131 132 uint vlen = _volunteerList.length; 133 for (uint i = 0; i < vlen; i++) { 134 delete volunteersMap[_volunteerList[i]]; 135 } 136 137 delete _volunteerList; 138 } 139 140 // mine 141 // 如果当前块 不是 signers[ blockNumber % signers.length ] 出的,就给这个 signer 减分 142 // 否则恢复成 3 分 143 144 // 序号 145 uint signerIdx = blockNumber % _signerList.length; 146 147 //初始签名人不做处理 148 if (!genesisSigner[_signerList[signerIdx]]) { 149 150 SignerInfo storage signer = signersMap[_signerList[signerIdx]]; 151 152 // 序号对应的不是我,则扣它一分 153 if (msg.sender != _signerList[signerIdx]) { 154 if (signer.score > 1) { 155 signer.score -= 1; 156 signer.number = blockNumber; 157 } else { 158 // 0 分时就删除了 159 deleteSigner(signerIdx); 160 } 161 } else { 162 // 恢复分数 163 signer.score = 3; 164 } 165 } 166 167 // tag 168 if (volunteer != uint160(0)) { 169 pushVolunteer(volunteer); 170 } 171 172 //是否提拔一个人到签名人 173 if (_signerList.length < singerLimit && _volunteerList.length > 0) { 174 175 //将候选人列表首个添加到签名人列表 176 pushSigner(_volunteerList[0], 3); 177 178 //删除该候补志愿者 179 deleteVolunteer(0); 180 } 181 } 182 183 function version() constant returns (string) { 184 return vsn; 185 } 186 function getSignerLimit() constant returns (uint) { 187 return singerLimit; 188 } 189 function getVolunteerLimit() constant returns (uint) { 190 return volunteerLimit; 191 } 192 193 function getStatus() constant returns ( 194 address[] volunteerList, 195 address[] signerList, 196 uint[] memory scoreList, 197 uint[] memory numberList, 198 uint number 199 ) { 200 scoreList = new uint[](_signerList.length); 201 numberList = new uint[](_signerList.length); 202 for (uint i = 0; i < _signerList.length; i ++) { 203 scoreList[i] = signersMap[_signerList[i]].score; 204 numberList[i] = signersMap[_signerList[i]].number; 205 } 206 volunteerList = _volunteerList; 207 signerList = _signerList; 208 number = blockNumber; 209 return; 210 } 211 212 }