-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add demonstration on chain contracts and did method
- Loading branch information
1 parent
5647a69
commit b6a946b
Showing
7 changed files
with
856 additions
and
1 deletion.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/services/common/did/contracts/DIDRegistryOnChain.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.6; | ||
|
||
enum RegistrationState { | ||
Unregistered, | ||
Active, | ||
Deactivated | ||
} | ||
|
||
contract DIDRegistryOnChain { | ||
error INVALID_REQUEST(); | ||
|
||
/** | ||
* @notice Maps ID hash to address for fast verification. | ||
*/ | ||
mapping(bytes32 => uint168) public registry; | ||
|
||
event DIDAttributeChanged(address indexed identity, bytes32 name, bytes value, uint256 validTo, uint256 previousChange); | ||
|
||
/** | ||
* @notice Adds an ID | ||
* | ||
* @param _method ID domain | ||
* @param _id ID address | ||
*/ | ||
function register(string calldata _method, address _id) external { | ||
if (msg.sender != _id) { | ||
revert INVALID_REQUEST(); | ||
} | ||
uint168 record = (uint168(uint160(_id)) << 8) | uint8(RegistrationState.Active); | ||
bytes32 hash = keccak256(abi.encodePacked('did:', _method, ':', _id)); | ||
registry[hash] = record; | ||
emit DIDAttributeChanged(_id, 'isActive', 'true', block.timestamp + 10000, 0); | ||
} | ||
|
||
/** | ||
* @notice Removes an ID | ||
* | ||
* @param _method ID method | ||
* @param _id ID address | ||
*/ | ||
function deactivate(string calldata _method, address _id) external { | ||
if (msg.sender != _id) { | ||
revert INVALID_REQUEST(); | ||
} | ||
bytes32 hash = keccak256(abi.encodePacked('did:', _method, ':', _id)); | ||
uint168 record = registry[hash]; | ||
address recordAddress = address(uint160(record >> 8)); | ||
RegistrationState recordState = RegistrationState(uint8(record)); | ||
|
||
if (recordAddress == _id && recordState == RegistrationState.Active) { | ||
record = uint168((uint160(_id) << 8) | uint8(RegistrationState.Deactivated)); | ||
registry[hash] = record; | ||
|
||
emit DIDAttributeChanged(_id, 'isActive', 'false', block.timestamp + 10000, 0); // TODO: Validity??? | ||
} | ||
} | ||
|
||
function isActive(string calldata _method, address _id) public view returns (bool status) { | ||
bytes32 hash = keccak256(abi.encodePacked('did:', _method, ':', _id)); | ||
uint168 record = registry[hash]; | ||
address recordAddress = address(uint160(record >> 8)); | ||
RegistrationState recordState = RegistrationState(uint8(record)); | ||
|
||
status = recordAddress == _id && recordState == RegistrationState.Active; | ||
} | ||
|
||
function isActiveHash(bytes32 _did) public view returns (bool status) { | ||
uint168 record = registry[_did]; | ||
// address recordAddress = address(uint160(record >> 8)); TODO: should it be compared to decoded address from the _did? | ||
RegistrationState recordState = RegistrationState(uint8(record)); | ||
|
||
status = recordState == RegistrationState.Active; | ||
} | ||
|
||
// TODO: These are copied from the existing registry contract so as to not break stuff | ||
// This needs rework. | ||
function setAttribute( | ||
address identity, | ||
address actor, | ||
bytes32 name, | ||
bytes calldata value, | ||
uint256 validity | ||
) internal { | ||
if (msg.sender != identity) { | ||
revert INVALID_REQUEST(); | ||
} | ||
bytes32 hash = keccak256(abi.encodePacked('did:', 'onyxidentity', ':', identity)); | ||
emit DIDAttributeChanged(identity, name, value, block.timestamp + validity, 0); | ||
//changed[identity] = block.number; | ||
} | ||
|
||
function setAttribute( | ||
address identity, | ||
bytes32 name, | ||
bytes calldata value, | ||
uint256 validity | ||
) public { | ||
setAttribute(identity, msg.sender, name, value, validity); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.6; | ||
|
||
interface IDIDRegistry { | ||
event DIDAttributeChanged(address indexed identity, bytes32 name, bytes value, uint256 validTo, uint256 previousChange); | ||
|
||
function register(string calldata _domain, address _subject) external; | ||
|
||
function deactivate(string calldata _domain, address _subject) external; | ||
|
||
function isActive(string calldata _domain, address _subject) external view returns (bool status); | ||
|
||
function isActiveHash(bytes32 credential) external view returns (bool status); | ||
|
||
function setAttribute( | ||
address identity, | ||
bytes32 name, | ||
bytes calldata value, | ||
uint256 validity | ||
) external; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.6; | ||
|
||
/// Various structs for representing a W3C credential as close to spec as possible given contraints | ||
struct OnChainCredentialSubject { | ||
bytes32 id; | ||
bytes data; | ||
} | ||
|
||
struct OnChainProof { | ||
bytes types; | ||
bytes verificationMethod; | ||
bytes proofValue; | ||
} | ||
|
||
struct OnChainPresentationProof { | ||
bytes types; | ||
bytes verificationMethod; | ||
bytes proofValue; | ||
uint256 nonce; | ||
} | ||
|
||
struct OnChainVerifiableCredential { | ||
bytes32 id; | ||
OnChainCredentialSubject credentialSubject; | ||
bytes32 issuer; | ||
uint256 expirationDate; | ||
uint256 issuanceDate; | ||
bytes types; | ||
OnChainProof proof; | ||
} | ||
|
||
struct OnChainVerifiablePresentation { | ||
bytes32 id; | ||
OnChainVerifiableCredential[] verifiableCredential; | ||
OnChainPresentationProof proof; | ||
} | ||
|
||
/// @notice Interface for Verifier smart contract | ||
interface IVerifier { | ||
event VerificationResult(bytes32 indexed id, bool result, string reason); | ||
|
||
function getNonce(bytes32 _did) external view returns (uint256); | ||
|
||
function verifyChain(OnChainVerifiablePresentation memory presentation, address _presentationSender) external returns (bool); | ||
} |
Oops, something went wrong.