mirror of https://github.com/status-im/EIPs.git
ERC Proxy Identity draft (#1036)
* added ERC725 draft * renamed ERC 725 file * remove author email * fixed link * renamed file
This commit is contained in:
parent
b3fbc3bf3a
commit
ede8c26a77
|
@ -0,0 +1,302 @@
|
|||
---
|
||||
eip: 725
|
||||
title: Proxy Identity
|
||||
author: Fabian Vogelsteller (@frozeman)
|
||||
discussions-to: https://github.com/ethereum/EIPs/issues/725
|
||||
status: Draft
|
||||
type: Standards Track
|
||||
category: ERC
|
||||
created: 2017-10-02
|
||||
---
|
||||
|
||||
## Simple Summary
|
||||
Proxy contract for key management and execution, to establish a Blockchain identity.
|
||||
|
||||
## Abstract
|
||||
The following describes standard functions for a unique identity for humans, groups, objects and machines.
|
||||
This identity can hold keys to sign actions (transactions, documents, logins, access, etc), and claims, which are attested from third parties (issuers) and self attested ([#ERC735](https://github.com/ethereum/EIPs/issues/735)), as well as a proxy function to act directly on the blockchain.
|
||||
|
||||
## Motivation
|
||||
This standardised identity interface will allow Dapps, smart contracts and thirdparties to check the validity of a person, organisation, object or machine through 2 steps as described in the function XXX. Trust is here transfered to the issuers of claims.
|
||||
|
||||
The most important functions to verify an identity are: `XXX`
|
||||
|
||||
The most important functions to manage an identity are: `XXX`
|
||||
|
||||
|
||||
## Definitions
|
||||
|
||||
- `keys`: Keys are public keys from either external accounts, or contract addresses.
|
||||
- `claim issuer`: is another smart contract or external account, which issues claims about this identity. The claim issuer can be an identity contract itself.
|
||||
- `claim`: For details about claims see [#ERC735](https://github.com/ethereum/EIPs/issues/735)
|
||||
|
||||
|
||||
|
||||
## Specification
|
||||
|
||||
|
||||
### Key Management
|
||||
|
||||
Keys are cryptographic public keys, or contract addresses associated with this identity.
|
||||
The structure should be as follows:
|
||||
|
||||
- `key`: A public key owned by this identity
|
||||
- `purpose`: `uint256[]` Array of the key types, like 1 = MANAGEMENT, 2 = ACTION, 3 = CLAIM, 4 = ENCRYPTION
|
||||
- `keyType`: The type of key used, which would be a `uint256` for different key types. e.g. 1 = ECDSA, 2 = RSA, etc.
|
||||
- `key`: `bytes32` The public key. // for non-hex and long keys, its the Keccak256 hash of the key
|
||||
|
||||
|
||||
```js
|
||||
struct Key {
|
||||
uint256[] purposes;
|
||||
uint256 keyType;
|
||||
bytes32 key;
|
||||
}
|
||||
```
|
||||
|
||||
#### getKey
|
||||
|
||||
Returns the full key data, if present in the identity.
|
||||
|
||||
``` js
|
||||
function getKey(bytes32 _key) constant returns(uint256[] purposes, uint256 keyType, bytes32 key);
|
||||
```
|
||||
|
||||
#### keyHasPurpose
|
||||
|
||||
Returns the `TRUE` if a key has is present and has the given purpose. If key is not present it returns `FALSE`.
|
||||
|
||||
``` js
|
||||
function keyHasPurpose(bytes32 _key, uint256 purpose) constant returns(bool exists);
|
||||
```
|
||||
|
||||
|
||||
#### getKeysByPurpose
|
||||
|
||||
Returns an array of public key bytes32 hold by this identity.
|
||||
|
||||
``` js
|
||||
function getKeysByPurpose(uint256 _purpose) constant returns(bytes32[] keys);
|
||||
```
|
||||
|
||||
|
||||
#### addKey
|
||||
|
||||
Adds a `_key` to the identity. The `_purpose` specifies the purpose of key. Initially we propose four purposes:
|
||||
|
||||
- `1`: MANAGEMENT keys, which can manage the identity
|
||||
- `2`: ACTION keys, which perform actions in this identities name (signing, logins, transactions, etc.)
|
||||
- `3`: CLAIM signer keys, used to sign claims on other identities which need to be revokable.
|
||||
- `4`: ENCRYPTION keys, used to encrypt data e.g. hold in claims.
|
||||
|
||||
MUST only be done by keys of purpose `1`, or the identity itself. If its the identity itself, the approval process will determine its approval.
|
||||
|
||||
**Triggers Event:** [KeyAdded](#keyadded)
|
||||
|
||||
``` js
|
||||
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) returns (bool success)
|
||||
```
|
||||
|
||||
|
||||
#### removeKey
|
||||
|
||||
Removes `_key` from the identity.
|
||||
|
||||
MUST only be done by keys of purpose `1`, or the identity itself. If its the identity itself, the approval process will determine its approval.
|
||||
|
||||
**Triggers Event:** [KeyRemoved](#keyremoved)
|
||||
|
||||
``` js
|
||||
function removeKey(bytes32 _key, uint256 _purpose) returns (bool success)
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
### Identity usage
|
||||
|
||||
|
||||
#### execute
|
||||
|
||||
Executes an action on other contracts, or itself, or a transfer of ether.
|
||||
SHOULD require `approve` to be called with one or more keys of purpose `1` or `2` to approve this execution.
|
||||
|
||||
Execute COULD be used as the only accessors for `addKey`, `removeKey` and `replaceKey` and `removeClaim`.
|
||||
|
||||
**Returns `executionId`:** SHOULD be send to the `approve` function, to approve or reject this execution.
|
||||
|
||||
**Triggers Event:** [ExecutionRequested](#executionrequested)
|
||||
**Triggers on direct execution Event:** [Executed](#executed)
|
||||
|
||||
``` js
|
||||
function execute(address _to, uint256 _value, bytes _data) returns (uint256 executionId)
|
||||
```
|
||||
|
||||
|
||||
#### approve
|
||||
|
||||
Approves an execution or claim addition.
|
||||
This SHOULD require `n` of `m` approvals of keys purpose `1`, if the `_to` of the execution is the identity contract itself, to successfull approve an execution.
|
||||
And COULD require `n` of `m` approvals of keys purpose `2`, if the `_to` of the execution is another contract, to successfull approve an execution.
|
||||
|
||||
**Triggers Event:** [Approved](#approved)
|
||||
**Triggers on successfull execution Event:** [Executed](#executed)
|
||||
**Triggers on successfull claim addition Event:** [ClaimAdded](#claimadded)
|
||||
|
||||
``` js
|
||||
function approve(uint256 _id, bool _approve) returns (bool success)
|
||||
```
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
|
||||
### Identity verification
|
||||
|
||||
Requires: [ERC 735](https://github.com/ethereum/EIPs/issues/735)
|
||||
|
||||
##### The following changes to [ERC 735](https://github.com/ethereum/EIPs/issues/735) are REQUIRED:
|
||||
|
||||
#### addClaim
|
||||
|
||||
This SHOULD create a pending claim, which SHOULD to be approved or rejected by `n` of `m` `approve` calls from keys of purpose `1`.
|
||||
|
||||
Only Events:
|
||||
**Triggers if the claim is new Event and approval process exists:** [ClaimRequested](#claimrequested)
|
||||
**Triggers if the claim index existed Event:** [ClaimChanged](https://github.com/ethereum/EIPs/issues/735)
|
||||
|
||||
|
||||
#### removeClaim
|
||||
|
||||
MUST only be done by the `issuer` of the claim, or keys of purpose `1`, or the identity itself. If its the identity itself, the approval process will determine its approval.
|
||||
|
||||
|
||||
--------------------------------------------------------
|
||||
|
||||
|
||||
### Events
|
||||
|
||||
|
||||
#### KeyAdded
|
||||
|
||||
MUST be triggered when `addKey` was successfully called.
|
||||
|
||||
``` js
|
||||
event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType)
|
||||
```
|
||||
|
||||
|
||||
#### KeyRemoved
|
||||
|
||||
MUST be triggered when `removeKey` was successfully called.
|
||||
|
||||
``` js
|
||||
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType)
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### ExecutionRequested
|
||||
|
||||
MUST be triggered when `execute` was successfully called.
|
||||
|
||||
``` js
|
||||
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data)
|
||||
```
|
||||
|
||||
|
||||
#### Executed
|
||||
|
||||
MUST be triggered when `approve` was called and the execution was successfully approved.
|
||||
|
||||
``` js
|
||||
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data)
|
||||
```
|
||||
|
||||
|
||||
#### Approved
|
||||
|
||||
MUST be triggered when `approve` was successfully called.
|
||||
|
||||
``` js
|
||||
event Approved(uint256 indexed executionId, bool approved)
|
||||
```
|
||||
|
||||
##### The following changes to [ERC 735](https://github.com/ethereum/EIPs/issues/735) are REQUIRED:
|
||||
|
||||
#### ClaimRequested
|
||||
|
||||
MUST be triggered when `addClaim` was successfully called.
|
||||
|
||||
|
||||
#### ClaimAdded
|
||||
|
||||
MUST be triggered when `approve` was called and the claim was successfully added.
|
||||
|
||||
|
||||
## Constraints
|
||||
|
||||
- A claim can only be one type per type per issuer.
|
||||
|
||||
|
||||
|
||||
## Rationale
|
||||
This specification was chosen to allow most flexibility and experimention around identity. By having each identity in a separate contract it allows for cross idenity compatibility, but at the same time extra and altered functionality for new use cases.
|
||||
|
||||
The main critic of this standard is the verification where each identity that issues a claim, also should have a separate CLAIM signing key attached. While [#ERC780](https://github.com/ethereum/EIPs/issues/780) uses a standardised registry to assign claims to addresses.
|
||||
Both systems could work in conjunction and should be explored.
|
||||
While also off-chain claims using DID verifiable claims and merkle tries can be added as claims and should be explored.
|
||||
|
||||
The rationale of this standard is to function as an open and veryf flexible container for idenity.
|
||||
|
||||
|
||||
## Implementation
|
||||
|
||||
- [DID resolver specification](https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-spring2018/blob/master/topics-and-advance-readings/DID-Method-erc725.md)
|
||||
- [Implementation by mirceapasoi](https://github.com/mirceapasoi/erc725-735)
|
||||
- [Implementation by Nick Poulden](https://github.com/OriginProtocol/identity-playground), interface at: https://erc725.originprotocol.com/
|
||||
|
||||
|
||||
### Solidity Interface
|
||||
```js
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
contract ERC725 {
|
||||
|
||||
uint256 constant MANAGEMENT_KEY = 1;
|
||||
uint256 constant ACTION_KEY = 2;
|
||||
uint256 constant CLAIM_SIGNER_KEY = 3;
|
||||
uint256 constant ENCRYPTION_KEY = 4;
|
||||
|
||||
event KeyAdded(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
|
||||
event KeyRemoved(bytes32 indexed key, uint256 indexed purpose, uint256 indexed keyType);
|
||||
event ExecutionRequested(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
|
||||
event Executed(uint256 indexed executionId, address indexed to, uint256 indexed value, bytes data);
|
||||
event Approved(uint256 indexed executionId, bool approved);
|
||||
|
||||
struct Key {
|
||||
uint256 purpose; //e.g., MANAGEMENT_KEY = 1, ACTION_KEY = 2, etc.
|
||||
uint256 keyType; // e.g. 1 = ECDSA, 2 = RSA, etc.
|
||||
bytes32 key;
|
||||
}
|
||||
|
||||
function getKey(bytes32 _key) public constant returns(uint256[] purposes, uint256 keyType, bytes32 key);
|
||||
function keyHasPurpose(bytes32 _key, uint256 purpose) constant returns(bool exists);
|
||||
function getKeysByPurpose(uint256 _purpose) public constant returns(bytes32[] keys);
|
||||
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) public returns (bool success);
|
||||
function execute(address _to, uint256 _value, bytes _data) public returns (uint256 executionId);
|
||||
function approve(uint256 _id, bool _approve) public returns (bool success);
|
||||
}
|
||||
```
|
||||
|
||||
## Additional References
|
||||
|
||||
- [Slides of the ERC Identity presentation](https://www.slideshare.net/FabianVogelsteller/erc-725-identity)
|
||||
- [In-contract claim VS claim registry](https://github.com/ethereum/wiki/wiki/ERC-735:-Claim-Holder-Registry-vs.-in-contract)
|
||||
- [Identity related reports](http://www.weboftrust.info/specs.html)
|
||||
- [W3C Verifiable Claims Use Cases](https://w3c.github.io/vc-use-cases/)
|
||||
- [Decentralised Identity Foundation](http://identity.foundation)
|
||||
- [Sovrin Foundation Self Sovereign Identity](https://sovrin.org/wp-content/uploads/2017/06/The-Inevitable-Rise-of-Self-Sovereign-Identity.pdf)
|
||||
|
||||
## Copyright
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
Loading…
Reference in New Issue