Skip to content

Commit

Permalink
Automatically merged updates to draft EIP(s) 725 (ethereum#3110)
Browse files Browse the repository at this point in the history
Hi, I'm a bot! This change was automatically merged because:

 - It only modifies existing Draft or Last Call EIP(s)
 - The PR was approved or written by at least one author of each modified EIP
 - The build is passing
  • Loading branch information
frozeman authored and Arachnid committed Mar 6, 2021
1 parent 46cb6c4 commit aab0982
Showing 1 changed file with 109 additions and 77 deletions.
186 changes: 109 additions & 77 deletions EIPS/eip-725.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,90 @@
---
eip: 725
title: Proxy Account
title: ERC-725 Smart Contract Based Account
author: Fabian Vogelsteller (@frozeman), Tyler Yasaka (@tyleryasaka)
discussions-to: https://github.com/ethereum/EIPs/issues/725
status: Draft
type: Standards Track
category: ERC
requires: 165, 173
created: 2017-10-02
---


## Simple Summary
A standard interface for a simple proxy account.
A standard interface for a smart contract based account with attachable key value store.

## 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.
The following describes standard functions for a unique smart contract based account that can be used by humans,
groups, organisations, objects and machines.

The standard is divided into two sub standards:

`ERC725X`:
Can execute arbitrary smart contracts using and deploy other smart contracts.

`ERC725Y`:
Can hold arbitrary data through a generic key/value store.

## 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.
Standardizing a minimal interface for a smart contract based account allows any interface to operate through these account types.
Smart contact based accounts following this standard have the following advantages:

- can hold any asset (native token, e.g. ERC20 like tokens)
- can execute any smart contract and deploy smart contracts
- have upgradeable security (through owner change, e.g. to a gnosis safe)
- are basic enough to work for for a long time
- are extensible though additional standardisation of the key/value data.
- can function as an owner/controller or proxy of other smart contracts


## Specification

### ERC725X

### Methods
ERC165 identifier: `0x44c028fe`

#### owner
#### execute

Returns the current owner
Executes a call on any other smart contracts, transfers the blockchains native token, or deploys a new smart contract.
MUST only be called by the current owner of the contract.

```js
address public owner;
function execute(uint256 operationType, address to, uint256 value, bytes data)
```

#### changeOwner
The `operationType` can execute the following operations:
- `0` for `call`
- `1` for `delegatecall`
- `2` for `create2`
- `3` for `create`

Others may be added in the future.

**Triggers Event:** [ContractCreated](#contractcreated) if a contract was created

### Events

#### ContractCreated

Changes the current owner. MUST only be called by the current owner of the contract.
MUST be triggered when `execute` creates a new contract using the `_operationType` `1`.

```js
function changeOwner(address _owner);
event ContractCreated(address indexed contractAddress)
```

**Triggers Event:** [OwnerChanged](#ownerchanged)
### ERC725Y

ERC165 identifier: `0x2bd57b73`

#### getData

Returns the data at the specified key.

```js
function getData(bytes32 _key) external view returns (bytes _value);
function getData(bytes32 key) external view returns(bytes value)
```

#### setData
Expand All @@ -59,112 +94,109 @@ Sets the data at a specific key. MUST only be called by the current owner of the
**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;
function setData(bytes32 _key, bytes memory _value) 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 [ERC-1077](./eip-1077.md) 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);
event DataChanged(bytes32 indexed key, bytes value)
```


### Ownership

This contract is controlled by the owner. The owner can be a smart contract or an address, or itself.
This contract is controlled by an owner. The owner can be a smart contract or an external account.
This standard requires [ERC173](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-173.md) and should implement the functions:

- `owner() view`
- `transferOwnership(address newOwner)`
- and the Event `event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)`

### Data keys

Data keys, should be the keccak256 hash of a type name.
e.g. `myNewKeyType` is `0xa94996022594f93c34a730df0ae89d1ecd69dff98c17d0387e69ce58346323a4`
e.g. `keccak256('ERCXXXMyNewKeyType')` is `0x6935a24ea384927f250ee0b954ed498cd9203fc5d2bf95c735e52e6ca675e047`

#### Multiple keys of the same type
The [ERC725JSONSchema standard](https://github.com/lukso-network/LIPs/blob/master/LSPs/LSP-2-ERC725YJSONSchema.md) defines how keys should be named and generated.
This JSON schema can be used to auto decode ERC725Y values from smart contracts for application and smart contract interactions.

Multiple keys for the same key type must add a `keyTypeName-1` at the end of the key type.
#### Default key values

This would looks as follows for `myNewKeyType`:
version 0 `myNewKeyType`: `0xa94996022594f93c34a730df0ae89d1ecd69dff98c17d0387e69ce58346323a4`
version 1 `myNewKeyType-1`: `0xb6dace1ed14874742c4d1b8cd9b270305176f769e0ae22118a02c2db4e620f29`
version 2 `myNewKeyType-2`: `0x6cc96a01de588f4550e8c3a821aed065ae7897f8dfb61836c78c0389e499d9ed`
...
ERC725 key standards need to be defined within new standards, we suggest the following defaults:

| Name | Description | Key | value |
| --- | --- | --- | --- |
| SupportedStandards:XYZ | Allows to determine standards supported by this contract | `0xeafec4d89fa9619884b6b89135626455000000000000000000000000xxxxxxxx`, where `xxxxxxxx` is the 4 bytes identifier of the standard supported | Value can be defined by the standard, by default it should be the 4 bytes identifier e.g. `0x7a30e6fc` |
| SupportedStandards:ERC725Account | Allows to determine standards supported by this contract | `0xeafec4d89fa9619884b6b89135626455000000000000000000000000afdeb5d6`, where `afdeb5d6` is the 4 bytes part of the hash of `keccak256('ERC725Account')` | Value is the 4 bytes identifier `0xafdeb5d6` |

Anyone that would like to standardize a new data key should make a pull request to update the table below.

Other key examples COULD be:

| 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 [ERC-735](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 [ERC-735](https://github.com/ethereum/EIPs/issues/735)) | 0xdaf52dba5981246bcf8fd7c6b00dce587fdcf5e2a95b281eea95dcd1376afdcd | left padded address of the claim registry contract, e.g. `0x000000000000000000000000de0B295669a9FD93d5F28D9Ec85E40f4cb697BAe` |
| ERC735 | A personal claim holder contract (per [ERC735](https://github.com/ethereum/EIPs/issues/735)) | `0x33f5765e0b3f726091f5ab06cd801c2bcd9bf89228534161c70fd7e257b8bfa3` | 20 bytes value `0xcafecafe69a9FD93d5F28D9Ec85E40f4cb69cafe` |
| ERC780 | A registry claim holder contract (per [ERC780](https://github.com/ethereum/EIPs/issues/780)) | `0x62db7b9279d03518c54464b4946aade7cafabff066a90c55b054d5c5ee04c371` | 20 bytes value `0xcafecafe69a9FD93d5F28D9Ec85E40f4cb69cafe` |

## Rationale
##### ERC725Account

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.
An `SupportedStandards` > `ERC725Account` (See key > value above) is an ERC725 smart contract based account/profile for storing of assets and execution of other smart contracts.

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.
- `ERC173` to be controllable by an owner, that could be am external account, or smart contract
- `ERC725X` to interact with other smart contracts
- `ERC725Y` to attach data to the account for future extensibility
- COULD have [ERC1271](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) to be able to verify signatures by the owner (or owner contracts keys).
- Should fire the `event ValueReceived(address indexed sender, uint256 indexed value)` if ETH is received.

It further allows any information to be attached to that proxy accounts which can be in the forms of claims via [ERC-735](https://github.com/ethereum/EIPs/issues/735) or [ERC-780](https://github.com/ethereum/EIPs/issues/780), or any arbitrary new systems and protocols.
A full implementation of an `ERC725Account` can be found [found here](https://github.com/ERC725Alliance/ERC725/tree/master/implementations/contracts).

This specification was chosen to allow the most flexibility and experimentation around verifiable manageable accounts.
## Rationale

The purpose of an smart contract account is to allow an entity to exist as a first-class citizen with the ability to execute arbitrary contract calls.

## Implementation

- [Implementation by ERC725Alliance](https://github.com/ERC725Alliance/erc725/tree/master/contracts/contracts)
- [Latest implementation](https://github.com/ERC725Alliance/ERC725/tree/master/implementations/contracts)


### Solidity Interface
```js
pragma solidity ^0.5.4;
### Solidity Interfaces
```solidity
// SPDX-License-Identifier: CC0-1.0
pragma solidity >=0.5.0 <0.7.0;

interface ERC725 {
event DataChanged(bytes32 indexed key, bytes32 indexed value);
event OwnerChanged(address indexed ownerAddress);
//ERC165 identifier: `0x44c028fe`
interface IERC725X /* is ERC165, ERC173 */ {
event ContractCreated(address indexed contractAddress);
event Executed(uint256 indexed operation, address indexed to, uint256 indexed value, bytes data);

// address public owner;
function execute(uint256 operationType, address to, uint256 value, bytes memory data) external;
}

//ERC165 identifier: `0x2bd57b73`
interface IERC725Y /* is ERC165, ERC173 */ {
event DataChanged(bytes32 indexed key, bytes value);

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;
function getData(bytes32 key) external view returns (bytes memory value);
function setData(bytes32 key, bytes memory value) external;
}

interface IERC725 /* is IERC725X, IERC725Y */ {

}

interface IERC725Account /* is IERC725, IERC725Y, IERC1271 */ {
event ValueReceived(address indexed sender, uint256 indexed value);
}
```
## Flow chart
![ERC725v2-flow](https://user-images.githubusercontent.com/232662/57334038-996a8b00-70ec-11e9-9179-4dda3f30e09d.PNG)
## Additional References
- [Slides of the ERC Identity presentation](https://www.slideshare.net/FabianVogelsteller/erc-725-identity)
Expand Down

0 comments on commit aab0982

Please sign in to comment.