EIPs/EIPS/eip-725.md

179 lines
6.9 KiB
Markdown

---
eip: 725
title: Proxy Account
author: Fabian Vogelsteller (@frozeman), Tyler Yasaka (@tyleryasaka)
discussions-to: https://github.com/ethereum/EIPs/issues/725
status: Draft
type: Standards Track
category: ERC
created: 2017-10-02
---
## Simple Summary
A standard interface for a simple proxy account.
## Abstract
The following describes standard functions for a unique identifiable proxy account to be used by humans, groups, organisations, objects and machines. The proxy has 2 abilities: (1) it can execute arbitrary contract calls, and (2) it can hold arbitrary data through a generic key/value store. One of these keys should hold the owner of the contract. The owner may be an address or a key manager contract for more complex management logic. Most importantly, this contract should be the reference point for a long-lasting identifiable profiles.
## Motivation
Standardizing a minimal interface for an proxy account allows third parties to interact with various proxy accounts contracts in a consistent manner.
the benefit is a persistent account that is independent from single keys and can attach an arbitrary amount of information to verifiy, or enhance the accounts purpose.
## Specification
### Methods
#### owner
Returns the current owner
```js
address public owner;
```
#### changeOwner
Changes the current owner. MUST only be called by the current owner of the contract.
```js
function changeOwner(address _owner);
```
**Triggers Event:** [OwnerChanged](#ownerchanged)
#### getData
Returns the data at the specified key.
```js
function getData(bytes32 _key) external view returns (bytes _value);
```
#### setData
Sets the data at a specific key. MUST only be called by the current owner of the contract.
**Triggers Event:** [DataChanged](#datachanged)
```js
function setData(bytes32 _key, bytes _value) external;
```
#### execute
Executes an action on other contracts or a transfer of the blockchains native cryptocurrency. MUST only be called by the current owner of the contract.
```js
function execute(uint256 _operationType, address _to, uint256 _value, bytes _data) external;
```
The `operationType` should represent the assembly operation as follows:
- `0` for `call`
- `1` for `create`
Others may be added in the future. Inspired by [ERC1077](https://eips.ethereum.org/EIPS/eip-1077) and [Gnosis](https://github.com/gnosis/safe-contracts/blob/master/contracts/Enum.sol#L7)
### Events
#### DataChanged
MUST be triggered when `setData` was successfully called.
```js
event DataChanged(bytes32 indexed key, bytes value);
```
#### ContractCreated
MUST be triggered when `execute` creates a new contract using the `_operationType` `1`.
```js
event ContractCreated(address indexed contractAddress);
```
#### OwnerChanged
MUST be triggered when `changeOwner` was successfully called.
```js
event OwnerChanged(address indexed ownerAddress);
```
### Ownership
This contract is controlled by the owner. The owner can be a smart contract or an address, or itself.
### Data keys
Data keys, should be the keccak256 hash of a type name.
e.g. `myNewKeyType` is `0xa94996022594f93c34a730df0ae89d1ecd69dff98c17d0387e69ce58346323a4`
#### Multiple keys of the same type
Multiple keys for the same key type must add a `keyTypeName-1` at the end of the key type.
This would looks as follows for `myNewKeyType`:
version 0 `myNewKeyType`: `0xa94996022594f93c34a730df0ae89d1ecd69dff98c17d0387e69ce58346323a4`
version 1 `myNewKeyType-1`: `0xb6dace1ed14874742c4d1b8cd9b270305176f769e0ae22118a02c2db4e620f29`
version 2 `myNewKeyType-2`: `0x6cc96a01de588f4550e8c3a821aed065ae7897f8dfb61836c78c0389e499d9ed`
...
Anyone that would like to standardize a new data key should make a pull request to update the table below.
| Name | Description | Key | value |
| --- | --- | --- | --- |
| owner | The owner of the proxy account | 0x0000000000000000000000000000000000000000000000000000000000000000 | left padded owner address, e.g. `0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe` |
| 735 | The proxy accounts claim holder contract (per [ERC735](https://github.com/ethereum/EIPs/issues/735)) | 0xb0f23aea7d77ce19f9393243a7b50a3bcaac893c7d68a5a309dea7cacf035fd0 | left padded address of the claim holder contract, e.g. `0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe` |
| 780 | The proxy accounts claim holder contract (per [ERC735](https://github.com/ethereum/EIPs/issues/735)) | 0xdaf52dba5981246bcf8fd7c6b00dce587fdcf5e2a95b281eea95dcd1376afdcd | left padded address of the claim registry contract, e.g. `0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe` |
## Rationale
The purpose of an identity proxy is to allow an entity to exist as a first-class citizen in Ethereum, with the ability to execute arbitrary contract calls. At that same time the proxy account should be managed by an arbitrary simple or complex logic.
It also opens up the possibility of [meta transactions](https://medium.com/@austin_48503/ethereum-meta-transactions-90ccf0859e84), where a third party can send a transaction to the owner contract, that then verifies the execution permission based on a signed message.
It further allows any information to be attached to that proxy accounts which can be in the forms of claims via [ERC735](https://github.com/ethereum/EIPs/issues/735) or [ERC780](https://github.com/ethereum/EIPs/issues/780), or any arbitrary new systems and protocols.
This specification was chosen to allow the most flexibility and experimentation around verifiable manageable accounts.
## Implementation
- [Implementation by ERC725Alliance](https://github.com/ERC725Alliance/erc725/tree/master/contracts/contracts)
### Solidity Interface
```js
pragma solidity ^0.5.4;
interface ERC725 {
event DataChanged(bytes32 indexed key, bytes32 indexed value);
event OwnerChanged(address indexed ownerAddress);
event ContractCreated(address indexed contractAddress);
// address public owner;
function changeOwner(address _owner) external;
function getData(bytes32 _key) external view returns (bytes32 _value);
function setData(bytes32 _key, bytes32 _value) external;
function execute(uint256 _operationType, address _to, uint256 _value, bytes calldata _data) external;
}
```
## 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](https://www.weboftrust.info/specs.html)
- [W3C Verifiable Claims Use Cases](https://w3c.github.io/vc-use-cases/)
- [Decentralised Identity Foundation](https://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/).