Contract Name:
EthereumDIDRegistry
Contract Source Code:
File 1 of 1 : EthereumDIDRegistry
pragma solidity ^0.4.4;
contract EthereumDIDRegistry {
mapping(address => address) public owners;
mapping(address => mapping(bytes32 => mapping(address => uint))) public delegates;
mapping(address => uint) public changed;
mapping(address => uint) public nonce;
modifier onlyOwner(address identity, address actor) {
require (actor == identityOwner(identity));
_;
}
event DIDOwnerChanged(
address indexed identity,
address owner,
uint previousChange
);
event DIDDelegateChanged(
address indexed identity,
bytes32 delegateType,
address delegate,
uint validTo,
uint previousChange
);
event DIDAttributeChanged(
address indexed identity,
bytes32 name,
bytes value,
uint validTo,
uint previousChange
);
function identityOwner(address identity) public view returns(address) {
address owner = owners[identity];
if (owner != 0x0) {
return owner;
}
return identity;
}
function checkSignature(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 hash) internal returns(address) {
address signer = ecrecover(hash, sigV, sigR, sigS);
require(signer == identityOwner(identity));
nonce[identity]++;
return signer;
}
function validDelegate(address identity, bytes32 delegateType, address delegate) public view returns(bool) {
uint validity = delegates[identity][keccak256(delegateType)][delegate];
return (validity > now);
}
function changeOwner(address identity, address actor, address newOwner) internal onlyOwner(identity, actor) {
owners[identity] = newOwner;
emit DIDOwnerChanged(identity, newOwner, changed[identity]);
changed[identity] = block.number;
}
function changeOwner(address identity, address newOwner) public {
changeOwner(identity, msg.sender, newOwner);
}
function changeOwnerSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, address newOwner) public {
bytes32 hash = keccak256(byte(0x19), byte(0), this, nonce[identityOwner(identity)], identity, "changeOwner", newOwner);
changeOwner(identity, checkSignature(identity, sigV, sigR, sigS, hash), newOwner);
}
function addDelegate(address identity, address actor, bytes32 delegateType, address delegate, uint validity) internal onlyOwner(identity, actor) {
delegates[identity][keccak256(delegateType)][delegate] = now + validity;
emit DIDDelegateChanged(identity, delegateType, delegate, now + validity, changed[identity]);
changed[identity] = block.number;
}
function addDelegate(address identity, bytes32 delegateType, address delegate, uint validity) public {
addDelegate(identity, msg.sender, delegateType, delegate, validity);
}
function addDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 delegateType, address delegate, uint validity) public {
bytes32 hash = keccak256(byte(0x19), byte(0), this, nonce[identityOwner(identity)], identity, "addDelegate", delegateType, delegate, validity);
addDelegate(identity, checkSignature(identity, sigV, sigR, sigS, hash), delegateType, delegate, validity);
}
function revokeDelegate(address identity, address actor, bytes32 delegateType, address delegate) internal onlyOwner(identity, actor) {
delegates[identity][keccak256(delegateType)][delegate] = now;
emit DIDDelegateChanged(identity, delegateType, delegate, now, changed[identity]);
changed[identity] = block.number;
}
function revokeDelegate(address identity, bytes32 delegateType, address delegate) public {
revokeDelegate(identity, msg.sender, delegateType, delegate);
}
function revokeDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 delegateType, address delegate) public {
bytes32 hash = keccak256(byte(0x19), byte(0), this, nonce[identityOwner(identity)], identity, "revokeDelegate", delegateType, delegate);
revokeDelegate(identity, checkSignature(identity, sigV, sigR, sigS, hash), delegateType, delegate);
}
function setAttribute(address identity, address actor, bytes32 name, bytes value, uint validity ) internal onlyOwner(identity, actor) {
emit DIDAttributeChanged(identity, name, value, now + validity, changed[identity]);
changed[identity] = block.number;
}
function setAttribute(address identity, bytes32 name, bytes value, uint validity) public {
setAttribute(identity, msg.sender, name, value, validity);
}
function setAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 name, bytes value, uint validity) public {
bytes32 hash = keccak256(byte(0x19), byte(0), this, nonce[identity], identity, "setAttribute", name, value, validity);
setAttribute(identity, checkSignature(identity, sigV, sigR, sigS, hash), name, value, validity);
}
function revokeAttribute(address identity, address actor, bytes32 name, bytes value ) internal onlyOwner(identity, actor) {
emit DIDAttributeChanged(identity, name, value, 0, changed[identity]);
changed[identity] = block.number;
}
function revokeAttribute(address identity, bytes32 name, bytes value) public {
revokeAttribute(identity, msg.sender, name, value);
}
function revokeAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 name, bytes value) public {
bytes32 hash = keccak256(byte(0x19), byte(0), this, nonce[identity], identity, "revokeAttribute", name, value);
revokeAttribute(identity, checkSignature(identity, sigV, sigR, sigS, hash), name, value);
}
}