2018-05-02 17:58:45 +00:00
---
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
2018-09-24 11:18:21 +00:00
A proxy contract for key management and execution, to establish a Blockchain identity.
2018-05-02 17:58:45 +00:00
## Abstract
The following describes standard functions for a unique identity for humans, groups, objects and machines.
2018-09-24 11:18:21 +00:00
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.
2018-05-02 17:58:45 +00:00
## Motivation
2018-09-24 11:18:21 +00:00
This standardized identity interface will allow Dapps, smart contracts and third parties to check the validity of a person, organization, object or machine through 2 steps as described in the function XXX. Trust is here transferred to the issuers of claims.
2018-05-02 17:58:45 +00:00
The most important functions to verify an identity are: `XXX`
The most important functions to manage an identity are: `XXX`
## Definitions
2018-09-24 11:18:21 +00:00
- `keys` : Keys are public keys from either external accounts, or contracts' addresses.
2018-05-02 17:58:45 +00:00
- `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
2018-11-13 07:39:44 +00:00
- `purpose` : `uint256` The key purpose. e.g., 1 = MANAGEMENT, 2 = ACTION, 3 = CLAIM, 4 = ENCRYPTION
2018-05-02 17:58:45 +00:00
- `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 {
2018-11-13 07:39:44 +00:00
uint256 purpose;
2018-05-02 17:58:45 +00:00
uint256 keyType;
bytes32 key;
}
```
#### getKey
Returns the full key data, if present in the identity.
``` js
2018-11-13 07:39:44 +00:00
function getKey(bytes32 _key) constant returns(uint256 purpose, uint256 keyType, bytes32 key);
2018-05-02 17:58:45 +00:00
```
#### keyHasPurpose
2018-09-29 22:02:46 +00:00
Returns `TRUE` if a key is present and has the given purpose. If the key is not present it returns `FALSE` .
2018-05-02 17:58:45 +00:00
``` js
function keyHasPurpose(bytes32 _key, uint256 purpose) constant returns(bool exists);
```
#### getKeysByPurpose
2018-09-29 22:02:46 +00:00
Returns an array of public key bytes32 held by this identity.
2018-05-02 17:58:45 +00:00
``` js
function getKeysByPurpose(uint256 _purpose) constant returns(bytes32[] keys);
```
#### addKey
2018-09-24 11:18:21 +00:00
Adds a `_key` to the identity. The `_purpose` specifies the purpose of the key. Initially, we propose four purposes:
2018-05-02 17:58:45 +00:00
- `1` : MANAGEMENT keys, which can manage the identity
2018-09-29 22:02:46 +00:00
- `2` : ACTION keys, which perform actions in this identity's name (signing, logins, transactions, etc.)
2018-09-24 11:18:21 +00:00
- `3` : CLAIM signer keys, used to sign claims on other identities which need to be revocable.
2018-05-02 17:58:45 +00:00
- `4` : ENCRYPTION keys, used to encrypt data e.g. hold in claims.
2018-09-29 22:02:46 +00:00
MUST only be done by keys of purpose `1` , or the identity itself. If it's the identity itself, the approval process will determine its approval.
2018-05-02 17:58:45 +00:00
**Triggers Event:** [KeyAdded ](#keyadded )
``` js
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) returns (bool success)
```
#### removeKey
Removes `_key` from the identity.
2018-09-29 22:02:46 +00:00
MUST only be done by keys of purpose `1` , or the identity itself. If it's the identity itself, the approval process will determine its approval.
2018-05-02 17:58:45 +00:00
**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.
2018-09-24 11:18:21 +00:00
Execute COULD be used as the only accessor for `addKey` , `removeKey` and `replaceKey` and `removeClaim` .
2018-05-02 17:58:45 +00:00
2018-09-24 11:18:21 +00:00
**Returns `executionId` :** SHOULD be sent to the `approve` function, to approve or reject this execution.
2018-05-02 17:58:45 +00:00
**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.
2018-09-24 11:18:21 +00:00
This SHOULD require `n` of `m` approvals of keys purpose `1` , if the `_to` of the execution is the identity contract itself, to successfully approve an execution.
And COULD require `n` of `m` approvals of keys purpose `2` , if the `_to` of the execution is another contract, to successfully approve an execution.
2018-05-02 17:58:45 +00:00
**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
2018-09-24 11:18:21 +00:00
This SHOULD create a pending claim, which SHOULD be approved or rejected by `n` of `m` `approve` calls from keys of purpose `1` .
2018-05-02 17:58:45 +00:00
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
2018-09-29 22:02:46 +00:00
MUST only be done by the `issuer` of the claim, or keys of purpose `1` , or the identity itself. If it's the identity itself, the approval process will determine its approval.
2018-05-02 17:58:45 +00:00
--------------------------------------------------------
### 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
2018-09-24 11:18:21 +00:00
This specification was chosen to allow most flexibility and experimentation around identity. By having each identity in a separate contract it allows for cross identity compatibility, but at the same time extra and altered functionality for new use cases.
2018-05-02 17:58:45 +00:00
2018-09-24 11:18:21 +00:00
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 standardized registry to assign claims to addresses.
2018-05-02 17:58:45 +00:00
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.
2018-08-28 12:57:47 +00:00
The rationale of this standard is to function as an open and very flexible container for identity.
2018-05-02 17:58:45 +00:00
## 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;
}
2018-11-13 07:39:44 +00:00
function getKey(bytes32 _key) public constant returns(uint256 purpose, uint256 keyType, bytes32 key);
2018-08-28 14:49:11 +00:00
function keyHasPurpose(bytes32 _key, uint256 _purpose) public constant returns (bool exists);
function getKeysByPurpose(uint256 _purpose) public constant returns (bytes32[] keys);
2018-05-02 17:58:45 +00:00
function addKey(bytes32 _key, uint256 _purpose, uint256 _keyType) public returns (bool success);
2018-08-28 14:49:11 +00:00
function removeKey(bytes32 _key, uint256 _purpose) public returns (bool success);
2018-05-02 17:58:45 +00:00
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 )
2019-03-09 07:56:08 +00:00
- [Identity related reports ](https://www.weboftrust.info/specs.html )
2018-05-02 17:58:45 +00:00
- [W3C Verifiable Claims Use Cases ](https://w3c.github.io/vc-use-cases/ )
2019-03-09 07:56:08 +00:00
- [Decentralised Identity Foundation ](https://identity.foundation )
2018-05-02 17:58:45 +00:00
- [Sovrin Foundation Self Sovereign Identity ](https://sovrin.org/wp-content/uploads/2017/06/The-Inevitable-Rise-of-Self-Sovereign-Identity.pdf )
## Copyright
2018-08-28 12:57:47 +00:00
Copyright and related rights waived via [CC0 ](https://creativecommons.org/publicdomain/zero/1.0/ ).