AddressDeclarator.sol (3850B)
1 pragma solidity >=0.8.0; 2 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 5 contract AddressDeclarator { 6 7 mapping( address => address[] ) declarationIndex; 8 mapping( bytes32 => uint256 ) declarationContentIndex; // the _latest_ content pointer for the declarator to subject mapping 9 mapping( address => address[] ) declarator; 10 mapping( address => address[] ) declaratorReverse; 11 12 bytes32[][] contents; 13 14 // Implements Declarator 15 event DeclarationAdded(address indexed _declarator, address indexed _subject, bytes32 indexed _topic, bytes32 _proof); 16 17 constructor(bytes32 _initial) { 18 addDeclaration(address(this), _initial); 19 } 20 21 // Create a digest reference for a declarator and subject pair 22 function toReference(address _declarator, address _subject) private pure returns ( bytes32 ) { 23 bytes32 k; 24 bytes memory addrMaterial = new bytes(40); 25 bytes memory addrBytes = abi.encodePacked(_declarator); 26 for (uint256 i = 0; i < 20; i++) { 27 addrMaterial[i] = addrBytes[i]; 28 } 29 addrBytes = abi.encodePacked(_subject); 30 for (uint256 i = 0; i < 20; i++) { 31 addrMaterial[i+20] = addrBytes[i]; 32 } 33 k = sha256(addrMaterial); 34 return k; 35 } 36 37 // Create a digest reference for a declarator and subject pair on top of the given digest 38 function toReference(address _declarator, address _subject, bytes32 _digest) private pure returns ( bytes32[2] memory ) { 39 bytes32 k; 40 bytes32[2] memory ks; 41 bytes memory signMaterial = new bytes(64); 42 43 k = toReference(_declarator, _subject); 44 for (uint256 i = 0; i < 32; i++) { 45 signMaterial[i] = k[i]; 46 } 47 for (uint256 i = 0; i < 32; i++) { 48 signMaterial[i+32] = _digest[i]; 49 } 50 51 ks[0] = k; 52 ks[1] = sha256(signMaterial); 53 54 return ks; 55 } 56 57 // Implements Declarator 58 function declaratorCount(address _subject) public view returns ( uint256 ) { 59 return declarator[_subject].length; 60 } 61 62 // Implements Declarator 63 function declaratorAddressAt(address _subject, uint256 _idx) public view returns ( address ) { 64 return declarator[_subject][_idx]; 65 } 66 67 // Implements Declarator 68 function addDeclaration(address _subject, bytes32 _proof, bytes32 _topic) public returns ( bool ) { 69 bytes32[2] memory ks; 70 bytes32[] memory declarationContents; 71 uint256 idx; 72 ks = toReference(tx.origin, _subject, _topic); 73 idx = declarationContentIndex[ks[1]]; 74 if (idx == 0) { // This also works for the constructor :) 75 declarator[_subject].push(tx.origin); 76 contents.push(declarationContents); 77 declarationIndex[tx.origin].push(_subject); 78 idx = contents.length-1; 79 } 80 81 declarationContentIndex[ks[1]] = idx; 82 contents[idx].push(_proof); 83 84 return true; 85 } 86 87 // Implements Declarator 88 function addDeclaration(address _subject, bytes32 _proof) public returns ( bool ) { 89 return addDeclaration(_subject, _proof, bytes32(0)); 90 } 91 92 // Implements Declarator 93 function declaration(address _declarator, address _subject) public view returns ( bytes32[] memory ) { 94 return declaration(_declarator, _subject, bytes32(0)); 95 } 96 97 // Implements Declarator 98 function declaration(address _declarator, address _subject, bytes32 _topic) public view returns ( bytes32[] memory ) { 99 bytes32[2] memory k; 100 uint256 idx; 101 k = toReference(_declarator, _subject, _topic); 102 idx = declarationContentIndex[k[1]]; 103 return contents[idx]; 104 } 105 106 // Implements Declarator 107 function declarationCount(address _declarator) public view returns ( uint256 ) { 108 return declarationIndex[_declarator].length; 109 } 110 111 // Implements Declarator 112 function declarationAddressAt(address _declarator, uint256 _idx) public view returns ( address ) { 113 return declarationIndex[_declarator][_idx]; 114 } 115 116 // Implements EIP165 117 function supportsInterface(bytes4 _sum) public pure returns (bool) { 118 if (_sum == 0x21b7493b) { // Implements Declarator 119 return true; 120 } 121 if (_sum == 0x01ffc9a7) { // EIP165 122 return true; 123 } 124 return false; 125 } 126 }