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  }