github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/permission/contract/Permission.sol (about) 1 pragma solidity >=0.4.22 <0.7.0; 2 //约定命名下横线的方法为内部方法 3 //nodeId格式为: 4 //enode://98d1fb92def94a3b8a861c7b1837aa9364126f5f12368db9194f0e152490277da8d5351a3e4796c10faf6c6af16a2185b5cb0a119d05111864eb284875f0bbe9 5 //加入网络:0;剔除网络:1;升级:2;降级:3 6 /** 7 * @title Permission 8 */ 9 contract Permission { 10 //联盟创始节点不允许退出联盟 11 //联盟创始节点 12 uint private constant originator=2; 13 //管理节点 14 uint private constant admin=2; 15 //普通节点 16 uint private constant common=0; 17 //游离节点 18 uint private constant isolated=1; 19 // 0 加入联盟 20 string private constant opJoin="0"; 21 // 1 退出联盟 22 string private constant opExit="1"; 23 // 2 升级为管理节点 24 string private constant opAdmin="2"; 25 // 3 降级成普通节点 26 string private constant opCommon="3"; 27 28 // events related 29 event AddNewNodeNotify(string enodeId, string ip, string port); 30 31 event VerifyNotify(string enodeId,uint opCode,string ip, string port); 32 33 event ApplyByAdminNotify(string enodeId); 34 35 event networkInitComplete(uint number,uint timestamp); 36 37 event isVotedEvent(string _nodeId,string _opCode, string _voterNodeId); 38 39 event isAdminRoleEvent(string _nodeId,address _sender); 40 41 //控制网络初始化的变量,就是整个网络有个初始化的过程,初始化完成之前,admin的节点是随便添加的 42 //初始化完成之后,添加节点都是需要经过投票的。 43 bool private networkStatus = false; 44 45 //管理员的数量 46 uint private adminCount; //administrator count 47 48 struct Node { 49 string nodeId;//节点id 50 string ip;//节点ip地址 51 string port;//节点端口 52 string nodeName;//节点名称 53 address nodeAddress; //节点账号地址 54 bool isOriginator; //是否创始人,联盟创世参与者,创世参与者不允许退出联盟 55 // 0 表示普通节点 56 // 1 表示游离节点 57 // 2 表示管理节点 58 uint role; 59 uint createdAt ; 60 //表示的是纳入管理,就是说要投票加入了,那么就为true,退出网络就为false 61 bool exist ; //存在性标志,添加时设置为true,退出网络时设置为false,这样就可以反复利用 62 } 63 //Used to count votes--统计投票数据 64 struct Statistics { 65 bool exist ; //存在性标志 66 //节点 67 string nodeId; 68 //同意票数 69 uint agree; 70 //不同意票数 71 uint disagree; 72 //发起提案的节点 73 string proposeNodeId; 74 // 0 加入联盟 75 // 1 退出联盟 76 // 2 升级为管理节点 77 // 3 降级成普通节点 78 string opCode; 79 //投票完成状态, 80 // 0:未完成; 81 // 1:已完成 82 uint status; 83 } 84 //投票记录 85 struct VoteRecord { 86 //投票对象 87 string nodeId; 88 //投票人 89 string voterNodeId; 90 //投票人地址 91 address voterAddress; 92 //投票针对的操作 93 string opCode; 94 //投同意票,还是投反对票 95 //赞成:true,反对:false 96 bool auth; 97 } 98 99 //节点都在nodeMap 中(包括游离节点、普通节点、管理节点) 100 //在网络中或曾加入网络的节点信息,key:hash(nodeId) 101 mapping(bytes32 => Node) private nodeMap; 102 103 //存在的节点 104 mapping(bytes32 => bool) private existNodeIds; 105 106 //用来保存节点的id 107 bytes[] private nodeIds;//store nodeId 108 109 address[] private originators; 110 111 //统计票数的记录,key:hash(nodeId+opCode) 112 mapping(bytes32 => Statistics) private statisticsMap; 113 114 //投票记录 115 VoteRecord[] private voteRecords; 116 117 //对于每一次投票,记录投过票的管理员节点,key:hash(nodeId+opCode) 118 //string[] 投票者集合 119 mapping(bytes32 => string[]) private voterMap; 120 121 modifier checkNetworkStatus() { 122 require(!networkStatus, "can not set admin node,initialize finished."); 123 _; 124 } 125 modifier checkInitStatus() { 126 require(networkStatus, "can not invoke method except setAdmin function,initialize have not finished."); 127 _; 128 } 129 //节点移除、节点升级、节点降级 130 //都走这个方法 131 // opCode 3为降级 132 // opCode 2为升级 133 // opCode 1为移除 134 //add node to blacklist application 135 function makeProposeForRoleChange(string memory _nodeId, string memory _opCode,string memory _voterNodeId) checkInitStatus() public payable { 136 require(_isAdminRole(_voterNodeId,msg.sender), "the role is not admin!"); 137 if (_strEqual(_opCode,opExit) || _strEqual(_opCode,opCommon)) {//如果操作类型是剔除网络或者降级 138 bytes32 nodeHash = hash256(bytes(_nodeId)); 139 Node memory nt = nodeMap[nodeHash]; 140 require(!nt.isOriginator, "主节点不允许退出"); 141 } 142 require(_validatePropose(_nodeId, _opCode), "申请失败"); 143 bytes32 statKey = _buildStatMapKey(_nodeId,_opCode); 144 Statistics memory statistics = Statistics(true,_nodeId, 0,0, _voterNodeId, _opCode,uint(0)); 145 statisticsMap[statKey]=statistics; 146 //清空投票信息 147 delete voterMap[statKey]; 148 149 emit ApplyByAdminNotify(_nodeId); 150 } 151 //不允许剔除已被剔除的节点,不允许升级已升级的节点,不允许降级已降级的节点 152 function _validatePropose(string memory _nodeId, string memory _opCode) internal view returns(bool) { 153 if (_strEqual(_opCode, opJoin)) { 154 return false; 155 } 156 bytes32 nodeHash = hash256(bytes(_nodeId)); 157 if (bytes(nodeMap[nodeHash].nodeId).length != 0) { 158 if (nodeMap[nodeHash].role == isolated) { 159 return false; 160 } 161 if (_strEqual(_opCode, opAdmin) && nodeMap[nodeHash].role == admin) { 162 return false; 163 } 164 if (_strEqual(_opCode, opCommon) && nodeMap[nodeHash].role == common) { 165 return false; 166 } 167 } 168 return true; 169 } 170 //投赞成票 171 function voteForRoleChange(string memory _nodeId, string memory _voterNodeId,string memory _opCode) checkInitStatus() public payable { 172 if (!_isAdminRole(_voterNodeId,msg.sender)){ 173 emit isAdminRoleEvent(_voterNodeId,msg.sender); 174 } 175 require(_isAdminRole(_voterNodeId,msg.sender), "the role is must be admin!");//the verify node must be admin role. 176 if (_isVoted(_nodeId, _opCode,_voterNodeId)){ 177 emit isVotedEvent(_nodeId, _opCode,_voterNodeId); 178 } 179 require(!_isVoted(_nodeId, _opCode,_voterNodeId),"已经投过票"); 180 if(_strEqual(_opCode,opAdmin)){ 181 //common=>admin 182 //必须是普通节点才可以升级到管理节点 183 require(_isCommonRole(_nodeId), "the node must be normal role");//if node is not normal role, it cann't upgrade. 184 //更新票数 185 Statistics memory statistics = _updateStatistic(_nodeId, _opCode,_voterNodeId,msg.sender); 186 //获取赞成票数 187 uint count = uint(statistics.agree); 188 //保存投票者信息 189 _insertVoter(_nodeId,_opCode, _voterNodeId); 190 //当满足半数以上规则且投票未结束才可更新节点角色 191 if (count > adminCount / 2 && statistics.status == 0) { 192 //更新投票状态,投票完成 193 bytes32 statKeyHash = hash256(bytes(_strConcat(_nodeId,_opCode))); 194 _finishStatStatus(statKeyHash); 195 delete voterMap[statKeyHash]; 196 //更新角色(common=>admin) 197 bytes32 nodeHash = hash256(bytes(_nodeId)); 198 nodeMap[nodeHash].role = admin; 199 adminCount++; 200 emit VerifyNotify(_nodeId,admin,nodeMap[nodeHash].ip,nodeMap[nodeHash].port); 201 } 202 }else if(_strEqual(_opCode,opCommon)){ 203 bytes32 keyHash=hash256(bytes(_nodeId)); 204 //admin=>common 205 require(isAdmin(keyHash), "the node must be admin!");//the apply node must be admin role. 206 //更新票数 207 Statistics memory statistics = _updateStatistic(_nodeId, _opCode,_voterNodeId,msg.sender); 208 //获取赞成票数 209 uint count = uint(statistics.agree); 210 //保存投票者信息 211 _insertVoter(_nodeId,_opCode, _voterNodeId); 212 if (count > adminCount / 2 && statistics.status == 0) {//当满足半数以上规则且投票未结束才可更新节点角色 213 //更新投票状态,投票完成 214 bytes32 statKeyHash = hash256(bytes(_strConcat(_nodeId,_opCode))); 215 _finishStatStatus(statKeyHash); 216 delete voterMap[statKeyHash]; //删除投票过程 217 //更新角色(admin=>common) 218 bytes32 nodeHash = hash256(bytes(_nodeId)); 219 nodeMap[nodeHash].role = common; 220 adminCount--; 221 emit VerifyNotify(_nodeId,common,nodeMap[nodeHash].ip,nodeMap[nodeHash].port); 222 } 223 224 }else if(_strEqual(_opCode,opExit)){ 225 226 //更新票数 227 Statistics memory statistics = _updateStatistic(_nodeId, _opCode,_voterNodeId,msg.sender); 228 //获取赞成票数 229 uint count = uint(statistics.agree); 230 //保存投票者信息 231 _insertVoter(_nodeId,_opCode, _voterNodeId); 232 //当满足半数以上规则且投票未结束才可更新节点角色 233 if (count > adminCount / 2 && statistics.status == 0) { 234 //更新投票状态 235 bytes32 statKeyHash = hash256(bytes(_strConcat(_nodeId,_opCode))); 236 _finishStatStatus(statKeyHash); 237 delete voterMap[statKeyHash]; //删除投票过程 238 bytes32 nodeHash = hash256(bytes(_nodeId)); 239 if (nodeMap[nodeHash].role == admin) { 240 adminCount--; 241 } 242 //更新角色(admin,common=>isolated) 243 nodeMap[nodeHash].role = isolated; 244 nodeMap[nodeHash].exist=false; 245 emit VerifyNotify(_nodeId,isolated,nodeMap[nodeHash].ip,nodeMap[nodeHash].port); 246 } 247 } 248 } 249 250 251 252 //获取管理员个数 253 function getAdminCount() public view returns (uint) { 254 return adminCount; 255 } 256 //tools function 257 function hash256(bytes memory _hashStr) internal pure returns (bytes32) { 258 return keccak256(_hashStr); 259 } 260 261 function isAdmin(bytes32 _nodeHash) public view returns (bool) { 262 if(nodeMap[_nodeHash].exist){ 263 return nodeMap[_nodeHash].role == admin; 264 } 265 return false; 266 } 267 function _strConcat(string memory _a, string memory _b) internal pure returns (string memory){ 268 bytes memory _ba = bytes(_a); 269 bytes memory _bb = bytes(_b); 270 string memory ret = new string(_ba.length + _bb.length); 271 bytes memory bret = bytes(ret); 272 uint k = 0; 273 for (uint i = 0; i < _ba.length; i++)bret[k++] = _ba[i]; 274 for (uint i = 0; i < _bb.length; i++) bret[k++] = _bb[i]; 275 return string(ret); 276 } 277 278 //设置联盟创始节点 279 function setAdminNode(string memory _nodeId, string memory _ip, string memory _port, string memory _nodeName, address _nodeAddress) public 280 checkNetworkStatus() { 281 bytes32 key = hash256(bytes(_nodeId)); 282 require(!isAdmin(key),"节点已经是联盟创始节点"); 283 nodeMap[key].nodeId = _nodeId; 284 nodeMap[key].ip = _ip; 285 nodeMap[key].port = _port; 286 nodeMap[key].nodeName = _nodeName; 287 nodeMap[key].role = admin; 288 nodeMap[key].nodeAddress = _nodeAddress; 289 nodeMap[key].isOriginator = true;//联盟创始节点 290 nodeMap[key].createdAt=block.timestamp; 291 nodeMap[key].exist=true; 292 nodeIds.push(bytes(_nodeId)); 293 existNodeIds[key]=true; 294 adminCount++; 295 originators.push(_nodeAddress); 296 emit VerifyNotify(_nodeId, admin,nodeMap[key].ip,nodeMap[key].port); 297 } 298 //执行完这个方法以后,就不能再添加联盟创世节点 299 //After this method is executed, it is not allowed to modify the administrator 300 function initFinish() public checkNetworkStatus() { 301 if(adminCount>0){ 302 networkStatus = true; 303 emit networkInitComplete(block.number,block.timestamp); 304 } 305 } 306 function _strEqual(string memory s1, string memory s2) internal pure returns (bool) { 307 return keccak256(abi.encode(s1))== keccak256(abi.encode(s2)); 308 } 309 //check pass 310 //query method 311 //返回同一个类型的节点的nodeId的数组 312 function getNodeByRole(uint _role) public view returns (string memory) { 313 string memory ret = ""; 314 //只有 0 1 2 三个可能值 315 if (_role>2){ 316 return ret; 317 } 318 for (uint i = 0; i < nodeIds.length; i++) { 319 bytes32 key = hash256(nodeIds[i]); 320 string memory nodeId = nodeMap[key].nodeId; 321 uint role = nodeMap[key].role; 322 if (role == _role) { 323 ret = _strConcat(_strConcat(nodeId, ","), ret); 324 } 325 } 326 return ret; 327 } 328 329 //check pass 330 //根据节点nodeId返回节点详细信息 331 function getNodeMap(string memory _nodeId) public view returns (string memory,string memory,string memory,string memory,address, uint,bool,uint) { 332 bytes32 key = hash256(bytes(_nodeId)); 333 Node memory info = nodeMap[key]; 334 return (info.nodeId,info.ip,info.port,info.nodeName,info.nodeAddress,info.role,info.isOriginator,info.createdAt); 335 336 } 337 //check pass 338 //根据节点名称返回节点详细信息 339 function getInfoByName(string memory _nodeName) public view returns (string memory,string memory,string memory,string memory,address, uint,bool,uint) { 340 for (uint i = 0; i < nodeIds.length; i++) { 341 bytes32 key = hash256(nodeIds[i]); 342 if (_strEqual(_nodeName, nodeMap[key].nodeName)) { 343 Node memory info = nodeMap[key]; 344 return (info.nodeId,info.ip,info.port,info.nodeName,info.nodeAddress,info.role,info.isOriginator,info.createdAt); 345 } 346 } 347 return ("","","","",address(0),0,false,0); 348 } 349 //check pass 350 //初始的管理员是否已经完成 351 function isInitFinished() public view returns (bool) { 352 return networkStatus; 353 } 354 //add new node application 355 //申请添加新节点 356 function makeProposeForAddNewNode(string memory _nodeId, string memory _ip, string memory _port, string memory nodeName, address _nodeAddress, string memory _proposeNodeId) checkInitStatus() public payable { 357 358 bytes32 statKey = _buildStatMapKey(_nodeId, opJoin); 359 360 bytes32 nodeHash = hash256(bytes(_nodeId)); 361 362 require(!(nodeMap[nodeHash].exist),"节点已经存在"); 363 364 Statistics memory statistics = Statistics(true,_nodeId, 0,0, _proposeNodeId, opJoin,uint(0)); 365 366 statisticsMap[statKey]=statistics; 367 368 //将节点作为游离节点加入到nodeMap中,isolated表示游离节点 369 _insertNodeMap(_nodeId, _ip, _port, nodeName, _nodeAddress, isolated, nodeHash); 370 //提交事件 371 emit AddNewNodeNotify(_nodeId, _ip, _port); 372 } 373 //给申请的节点投票 374 function voteForNewNodeApply(string memory _nodeId, string memory _voterNodeId)checkInitStatus() public payable { 375 if (!_isAdminRole(_voterNodeId,msg.sender)){ 376 emit isAdminRoleEvent(_voterNodeId,msg.sender); 377 } 378 require(_isAdminRole(_voterNodeId,msg.sender), "the role is not admin!"); 379 380 if (_isVoted(_nodeId, opJoin,_voterNodeId)){ 381 emit isVotedEvent(_nodeId, opJoin,_voterNodeId); 382 } 383 require(!_isVoted(_nodeId, opJoin,_voterNodeId),"已经投过票"); 384 385 Statistics memory statistics = _updateStatistic(_nodeId,opJoin,_voterNodeId,msg.sender); 386 387 _insertVoter(_nodeId, opJoin, _voterNodeId);//保存投票者信息 388 389 uint count = uint(statistics.agree); 390 if (count > adminCount / 2 && statistics.status == 0) {//当满足半数以上规则且投票未结束才可更新节点角色 391 bytes32 statKeyHash = _buildStatMapKey(_nodeId,opJoin); 392 bytes32 nodeHash = hash256(bytes(_nodeId)); 393 _finishStatStatus(statKeyHash);//更新投票状态 394 delete voterMap[statKeyHash]; //删除投票过程 395 //更新节点角色(role) 396 nodeMap[nodeHash].role = common; 397 emit VerifyNotify(_nodeId, common,nodeMap[nodeHash].ip,nodeMap[nodeHash].port); 398 } 399 } 400 //插入nodeMap中 401 function _insertNodeMap(string memory _nodeId, string memory _ip, string memory _port, string memory _nodeName, address _nodeAddress, uint _role, bytes32 _nodeHash) internal { 402 nodeMap[_nodeHash].ip = _ip; 403 nodeMap[_nodeHash].port = _port; 404 nodeMap[_nodeHash].nodeId = _nodeId; 405 nodeMap[_nodeHash].nodeAddress = _nodeAddress; 406 nodeMap[_nodeHash].nodeName = _nodeName; 407 nodeMap[_nodeHash].role = _role; 408 nodeMap[_nodeHash].isOriginator=false; 409 nodeMap[_nodeHash].createdAt=block.timestamp; 410 nodeMap[_nodeHash].exist=true; 411 //保持唯一性 412 if (!existNodeIds[_nodeHash]){ 413 nodeIds.push(bytes(_nodeId)); 414 existNodeIds[_nodeHash]=true; 415 } 416 } 417 418 //检查是否管理角色 419 function _isAdminRole(string memory _nodeId,address _sender) internal view returns (bool) { 420 bytes32 keyHash = hash256(bytes(_nodeId)); 421 if (!isAdmin(keyHash)) 422 { 423 return false; 424 } 425 return nodeMap[keyHash].nodeAddress == _sender; 426 } 427 //检查给定节点是游离节点 428 function _isIsolatedRole(string memory _nodeId) internal view returns (bool) { 429 bytes32 key = hash256(bytes(_nodeId)); 430 bool f1 = existNodeIds[key]; 431 bool f2 = nodeMap[key].role == isolated; 432 return (f1&&f2)||!f1; 433 } 434 435 //检查给定节点是普通节点 436 function _isCommonRole(string memory _nodeId) internal view returns (bool) { 437 bytes32 key = hash256(bytes(_nodeId)); 438 bool f1 = existNodeIds[key]; 439 bool f2 = nodeMap[key].role == common; 440 return (f1&&f2); 441 } 442 443 function _updateStatistic(string memory _nodeId,string memory _opCode, string memory _voterNodeId, address _voterAddress) internal returns (Statistics memory) { 444 bytes32 statKeyHash = _buildStatMapKey(_nodeId, _opCode); 445 VoteRecord memory record=VoteRecord(_nodeId, _voterNodeId, _voterAddress,_opCode,true); 446 voteRecords.push(record); 447 Statistics memory statistics = statisticsMap[statKeyHash]; 448 statistics.agree += 1; 449 statisticsMap[statKeyHash] = statistics; 450 return statistics; 451 } 452 function _buildStatMapKey(string memory _eNodeStr, string memory opCode) internal pure returns (bytes32) { 453 string memory statKey = _strConcat(_eNodeStr, opCode); 454 return hash256(bytes(statKey)); 455 } 456 function _finishStatStatus(bytes32 statKeyHash) internal { 457 Statistics memory statistics = statisticsMap[statKeyHash]; 458 statistics.status = 1; 459 statisticsMap[statKeyHash] = statistics; 460 } 461 function _insertVoter(string memory _nodeId,string memory _opCode, string memory _voterNodeId) internal { 462 bytes32 key = hash256(bytes(_strConcat(_nodeId,_opCode))); 463 voterMap[key].push(_voterNodeId); 464 } 465 //根据state key 获取投票统计信息 466 function getLastStatistics(string memory _nodeId, string memory _opCode) public view returns (uint, uint,string memory, string memory, uint) { 467 string memory key = _strConcat(_nodeId, _opCode); 468 bytes32 nodeHash= hash256(bytes(key)); 469 Statistics memory statistics = statisticsMap[nodeHash]; 470 return (statistics.agree,statistics.disagree,statistics.proposeNodeId,statistics.opCode,statistics.status); 471 } 472 //查询所有投票未完成的记录,返回字符串(enodeId+opType),以逗号分割 473 function getAllStatingRecord() public view returns (string memory) { 474 string memory result = ""; 475 for (uint i=0;i<nodeIds.length;i++) { 476 bytes32 nodeHash = hash256(bytes(nodeIds[i])); 477 string memory record = _getStatingRecord(nodeHash); 478 if (!_strEqual(record, "")) { 479 result = _strConcat(result, _strConcat(",", record)); 480 } 481 } 482 return result; 483 } 484 function _getStatingRecord(bytes32 _nodeHash) internal view returns (string memory) { 485 string memory result = ""; 486 string memory nodeId = nodeMap[_nodeHash].nodeId; 487 string memory tmp = _findStatingStatus(nodeId, opJoin); 488 if (!_strEqual(tmp, "")) { 489 result = tmp; 490 } 491 tmp = _findStatingStatus(nodeId, opExit); 492 if (!_strEqual(tmp, "")) { 493 result = _strConcat(result, _strConcat(",", tmp)); 494 } 495 tmp = _findStatingStatus(nodeId, opAdmin); 496 if (!_strEqual(tmp, "")) { 497 result = _strConcat(result, _strConcat(",", tmp)); 498 } 499 tmp = _findStatingStatus(nodeId, opCommon); 500 if (!_strEqual(tmp, "")) { 501 result = _strConcat(result, _strConcat(",", tmp)); 502 } 503 return result; 504 } 505 function _findStatingStatus(string memory _nodeId, string memory _opCode) internal view returns (string memory) { 506 bytes32 key = _buildStatMapKey(_nodeId, _opCode); 507 if (!statisticsMap[key].exist) { 508 return ""; 509 } 510 Statistics memory statistics = statisticsMap[key]; 511 //投票还在进行中,未完成 512 if (statistics.status == 0) { 513 return _strConcat(_nodeId, _opCode); 514 } 515 return ""; 516 } 517 //投反对票 518 //包括加入,升级,降级,退出 519 function disagree(string memory _nodeId, string memory _voterNodeId,string memory _opCode) checkInitStatus() public payable { 520 require(_isAdminRole(_voterNodeId,msg.sender), "the role must be admin!"); 521 bytes32 statKeyHash = _buildStatMapKey(_nodeId, _opCode); 522 Statistics memory statistics = statisticsMap[statKeyHash]; 523 // 新增投票记录 524 _addDisagreeVote(_nodeId, _voterNodeId,msg.sender,_opCode); 525 526 //增加反对票的数量 527 statistics.disagree += 1; 528 if (uint(statistics.disagree) > adminCount / 2 && statistics.status == 0) { 529 statistics.status = 1; 530 if(_strEqual(_opCode,opJoin)){ 531 nodeMap[hash256(bytes(_nodeId))].exist=false; 532 } 533 delete voterMap[statKeyHash]; //删除投票过程 534 } 535 statisticsMap[statKeyHash] = statistics; 536 } 537 function _addDisagreeVote(string memory _nodeId,string memory _voterNodeId,address _voterNodeAddress,string memory _opCode) internal { 538 VoteRecord memory record; 539 record.nodeId = _nodeId; 540 record.voterNodeId = _voterNodeId; 541 record.voterAddress = _voterNodeAddress; 542 record.opCode=_opCode; 543 record.auth = false; 544 voteRecords.push(record); 545 _insertVoter(_nodeId,_opCode, _voterNodeId); 546 } 547 //更新节点ip和端口信息 548 function updateNodeInfo(string memory _nodeId,string memory _ip,string memory _port) public { 549 bytes32 nodeHash = hash256(bytes(_nodeId)); 550 Node memory node = nodeMap[nodeHash]; 551 require((node.nodeAddress == msg.sender), "账号不匹配"); 552 node.ip = _ip; 553 node.port = _port; 554 nodeMap[nodeHash] = node; 555 } 556 //更新节点的名称 557 function updateNodeName(string memory _nodeId,string memory _nodeName) public { 558 bytes32 nodeHash = hash256(bytes(_nodeId)); 559 Node memory node = nodeMap[nodeHash]; 560 require((node.nodeAddress == msg.sender), "账号不匹配"); 561 node.nodeName = _nodeName; 562 nodeMap[nodeHash] = node; 563 } 564 //退出网络,需要触发断开网络连接的事件,但主节点不允许退出 565 function exit(string memory _nodeId) checkInitStatus() public { 566 bytes32 key = hash256(bytes(_nodeId)); 567 if(nodeMap[key].exist==false){ 568 return ; 569 } 570 //校验是否已经退出网路 571 Node memory nodeTable = nodeMap[key]; 572 require(!nodeTable.isOriginator, "主节点不允许退出"); 573 nodeMap[key].exist=false; 574 emit VerifyNotify(_nodeId, isolated,nodeMap[key].ip,nodeMap[key].port); 575 } 576 //查找该节点是否为本次申请投过票 577 function _isVoted(string memory _nodeId,string memory _opCode, string memory _voterNodeId) internal view returns(bool){ 578 bytes32 key = hash256(bytes(_strConcat(_nodeId,_opCode))); 579 string[] memory ids=voterMap[key]; 580 for(uint i=0;i<ids.length;i++){ 581 if(_strEqual(ids[i],_voterNodeId)){ 582 return true; 583 } 584 } 585 return false; 586 } 587 function getOriginators() public view returns(address[] memory){ 588 return originators; 589 } 590 function nodeExists(string memory _nodeId) public view returns (bool) { 591 bytes32 key = hash256(bytes(_nodeId)); 592 Node memory node = nodeMap[key]; 593 return node.exist; 594 } 595 }