eth-address-index/solidity/AddressDeclarator.sol

130 lines
3.6 KiB
Solidity

pragma solidity >0.6.11;
// SPDX-License-Identifier: GPL-3.0-or-later
contract AddressDeclarator {
mapping( address => address[] ) declarationIndex;
mapping( bytes32 => uint256 ) declarationContentIndex; // the _latest_ content pointer for the declarator to subject mapping
mapping( address => address[] ) declarator;
mapping( address => address[] ) declaratorReverse;
mapping( bytes32 => bool ) declarationExistIndex;
bytes32[][] public contents;
event DeclarationAdded(address _declarator, address _subject, bytes32 _proof);
constructor(bytes32 _initialDescription) public {
bytes32[] memory foundation;
contents.push(foundation);
contents[contents.length-1].push(blockhash(block.number));
addDeclaration(msg.sender, _initialDescription);
}
function toReference(address _declarator, address _subject) private pure returns ( bytes32 ) {
bytes32 k;
bytes memory signMaterial = new bytes(40);
bytes memory addrBytes = abi.encodePacked(_declarator);
for (uint256 i = 0; i < 20; i++) {
signMaterial[i] = addrBytes[i];
}
addrBytes = abi.encodePacked(_subject);
for (uint256 i = 0; i < 20; i++) {
signMaterial[i+20] = addrBytes[i];
}
k = sha256(signMaterial);
return k;
}
function toReference(address _declarator, address _subject, bytes32 _proof) private pure returns ( bytes32[2] memory ) {
bytes32 k;
bytes32[2] memory ks;
bytes memory signMaterial = new bytes(64);
k = toReference(_declarator, _subject);
for (uint256 i = 0; i < 32; i++) {
signMaterial[i] = k[i];
}
for (uint256 i = 0; i < 32; i++) {
signMaterial[i+32] = _proof[i];
}
ks[0] = k;
ks[1] = sha256(signMaterial);
return ks;
}
// Implements Declarator
function declaratorCount(address _subject) public view returns ( uint256 ) {
return declarator[_subject].length;
}
// Implements Declarator
function declaratorAddressAt(address _subject, uint256 _idx) public view returns ( address ) {
return declarator[_subject][_idx];
}
// Implements Declarator
function addDeclaration(address _subject, bytes32 _proof) public returns ( bool ) {
bytes32[2] memory ks;
bytes32[] memory declarationContents;
uint256 idx;
ks = toReference(tx.origin, _subject, _proof);
idx = declarationContentIndex[ks[0]];
if (idx == 0) { // This also works for the constructor :)
declarator[_subject].push(tx.origin);
contents.push(declarationContents);
declarationIndex[tx.origin].push(_subject);
}
idx = contents.length-1;
declarationContentIndex[ks[0]] = idx;
contents[idx].push(_proof);
declarationExistIndex[ks[1]] = true;
return true;
}
// Implements Declarator
function declaration(address _declarator, address _subject) public view returns ( bytes32[] memory ) {
bytes32 k;
uint256 idx;
k = toReference(_declarator, _subject);
idx = declarationContentIndex[k];
return contents[idx];
}
// Implements Declarator
function haveDeclaration(address _declarator, address _subject, bytes32 _proof) public view returns (bool) {
bytes32[2] memory ks;
ks = toReference(_declarator, _subject, _proof);
return declarationExistIndex[ks[1]];
}
// Implements Declarator
function declarationCount(address _declarator) public view returns ( uint256 ) {
return declarationIndex[_declarator].length;
}
// Implements Declarator
function declarationAddressAt(address _declarator, uint256 _idx) public view returns ( address ) {
return declarationIndex[_declarator][_idx];
}
// Implements EIP165
function supportsInterface(bytes4 _sum) public pure returns (bool) {
if (_sum == 0x27beb910) { // Implements Declarator
return true;
}
if (_sum == 0x01ffc9a7) { // EIP165
return true;
}
return false;
}
}