ethereum / EIPs

The Ethereum Improvement Proposal repository
https://eips.ethereum.org/
Creative Commons Zero v1.0 Universal
12.72k stars 5.16k forks source link

ERC: Proxy Account #725

Closed frozeman closed 2 years ago

frozeman commented 6 years ago

This proposal has moved to ERC-725 (source).

This issue exists as an archive only.

Original Text ``` eip: title: ERC-725 Smart Contract Based Account author: Fabian Vogelsteller , Tyler Yasaka (@tyleryasaka) discussions-to: https://github.com/ethereum/EIPs/issues/725 status: Draft type: Standards Track category: ERC requires: ERC165, ERC173, ERC1271 (optional) created: 2017-10-02 updated: 2020-07-02 ``` **This is the new 725 v2 standard, that is radically different from [ERC 725 v1](https://github.com/ethereum/EIPs/blob/ede8c26a77eb1ac8fa2d01d8743a8cf259d8d45b/EIPS/eip-725.md). ERC 725 v1 is be moved to #734 as a new key manager standard.** -------- ## Simple Summary A standard interface for a smart contract based account with attachable key value store. ## Abstract 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 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 ERC165 identifier: `0x44c028fe` #### execute 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 function execute(uint256 operationType, address to, uint256 value, bytes data) ``` 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 MUST be triggered when `execute` creates a new contract using the `_operationType` `1`. ```js event ContractCreated(address indexed contractAddress) ``` ### ERC725Y ERC165 identifier: `0x2bd57b73` #### 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 memory _value) external ``` ### Events #### DataChanged MUST be triggered when `setData` was successfully called. ```js event DataChanged(bytes32 indexed key, bytes value) ``` ### Ownership 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. `keccak256('ERCXXXMyNewKeyType')` is `0x6935a24ea384927f250ee0b954ed498cd9203fc5d2bf95c735e52e6ca675e047` #### Multiple keys of the same type If you require multiple keys of the same key type they MUST be defined as follows: - The keytype name MUST have a `[]` add and then hashed - The key hash MUST contain the number of all elements, and is required to be updated when a new key element is added. For all other elements: - The first 16 bytes are the first 16 bytes of the key hash - The second 16 bytes is a `uint128` of the number of the element - Elements start at number `0` ##### Example This would looks as follows for `ERCXXXMyNewKeyType[]` (keccak256: `0x4f876465dbe22c8495f4e4f823d846957ddb8ce6006afe66ddc5bac4f0626767`): - element number: key: `0x4f876465dbe22c8495f4e4f823d846957ddb8ce6006afe66ddc5bac4f0626767`, value: `0x0000000000000000000000000000000000000000000000000000000000000002` (2 elements) - element 1: key: `0x4f876465dbe22c8495f4e4f823d8469500000000000000000000000000000000`, value: `0x123...` (element 0) - element 2: key: `0x4f876465dbe22c8495f4e4f823d8469500000000000000000000000000000001`, value: `0x321...` (element 1) ... #### Default key values ERC725 key standards need to be defined within new standards, we suggest the following defaults: | Name | Description | Key | value | | --- | --- | --- | --- | | SupportedStandards | 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` | ##### ERC725Account An ERC725Account is an ERC725 smart contract based account for storing of assets and execution of other smart contracts. - `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` to be able to verify signatures from owners. - Should fire the `event ValueReceived(address indexed sender, uint256 indexed value)` if ETH is received. A full implementation of an `ERC725Account` can be found [found here](https://github.com/ERC725Alliance/ERC725/tree/master/implementations/contracts). ## 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 - [Latest implementation](https://github.com/ERC725Alliance/ERC725/tree/master/implementations/contracts) ### Solidity Interfaces ```solidity // SPDX-License-Identifier: CC0-1.0 pragma solidity >=0.5.0 <0.7.0; //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); 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 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) - [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/).
alexvandesande commented 6 years ago

This is a very useful ERC. I would remove all the Must and Should comments regarding types of keys as it should really be left up to the implementation of the contract.

Some contract types might want to have the admin functions, like claim or addKey be made by some types of admin keys, some might want to make those available to different types of keys, some might want to make the process to addKeys to go through the same process as any execute call will go to. This actually doesn't add much complexity: if you want a contract like that, just make so that only the contract itself can call some functions, and then make functions like addKey be actually just a proxy that creates a proper request to execute them, via whatever mechanism execute needs to go.


function approve(uint256 _id) returns (bool success)

you should either add a second boolean parameter to say either you approve or not, or add a second function called reject

frozeman commented 6 years ago

I added the bool to the approve, just forgot that.

Concerning the flexibility of key addition/removals, i added: "MUST only be done by keys of type 1, or the identity itself. If its the identity itself, the approval process will determine its approval."

Which includes either using key type 1, or the identity itself, e.g. then only the identity contract itself can call those function, and they always go through the approval process.

alexvandesande commented 6 years ago

It's just that I don't believe defining key types should be in the scope of this ERC. For some cases, like a democracy, the strings can represent different types of agents: voters, election officials, ID validators, those who can propose new stuff, etc. For a more hierarchical organization, type can be a number representing their rank: for some smaller is more important, for others, bigger is more important.

frozeman commented 6 years ago

The reason to add key types, is to prevent people from running around with keys, which can overtake their identity, but rather only use they action keys on a daily basis. Those wont have the ability to remove or change keys, which reduces the risk to loose your identity all together.

The other advantage is that it allows to define purposes to keys, which other entities or contracts can then use to derive the purpose of a user action on their system. E.g. if key type 23 means award collector, then a game interface knows which one to assign awards to.

MicahZoltu commented 6 years ago

I would like to see some details/arguments as to why this benefits from being a standard. In what ways do we gain interoperability benefits from having this standardized? What types of general purpose tooling are we expecting people to build that will need to work with unknown future implementations of this?

Looking over the methods, it seems like a large number of them would qualify as "implementation details" and are not relevant to creating an generic identity management standard. For example, how a particular identity provider does key management is not something that needs to work with many tools, it just needs to work with the identity provider's tool suite. Even some contract that supports 10 identity providers and wants to interface with them all presumably needs to trust those providers in advance, meaning they don't need to build their contract to support arbitrary future providers.

Given the current motivation section, I would recommend that this not be a standard and instead just be a contract/dApp that anyone can write and deploy. 😄

alexvandesande commented 6 years ago

@MicahZoltu I disagree there. If I'd like to be able to use an identity in Mist, it means that I want to create an account, allow that account do things on behalf of others. What I mostly need to be standardized is the addKey, execute and approve. We can use our own private contract, but I think it's nice to try to work together with others.

frozeman commented 6 years ago

This needs to be standardized so that other contracts can interact with real world identities, automatically check and verify them. It’s not mainly necessary for interfaces alone. Also this contract represents ONE identity. The addition of claims need to be standardized, so that other identities can issue claims about each other.

Verifying an identity would happen in the following ways:

But I assume over time known and trusted issuers will appear so only one check needs to be done.

I might write an extra document to explain all the ways of how one can interact with this contract. But I would like to keep that apart from the ERC itself to keep it easy to read.

MicahZoltu commented 6 years ago

In order for there to be value in a standard there needs to be interoperability concerns that are being addressed. We don't need a standard for prediction markets, or a standard for exchanges or a standard for gambling games unless there is a compelling argument as to how one of these things would be better if they were interoperable. There isn't significant value in making it so all gambling games have the same interface, since users will interact with each gambling game via a dApp custom built for that gambling game.

A good example of useful standardization is token contracts. There is value in standardizing tokens so that an application (e.g., Wallet, exchange, etc.) can interact with any token the user provides without needing to know about it in advance or write custom integrations for each token. However, there is little to no value in standardizing how tokens come into existence because there isn't a strong need for a general purpose UI for token management. Each token author can build a token management UI just for their token, end users won't be using this so it doesn't even need to have a familiar interface.

@alexvandesande You have indicated that you want addKey, execute and approve standardized. How would standardizing those add value to the ecosystem? What can you do with those things standardized across many implementations that you wouldn't be able to do if they were not standardized?

@frozeman It sounds like you have a grand vision in your head that isn't expressed clearly in this EIP or discussion. I would love to hear more about it.

As a dApp developer who wants to verify the identity of someone interacting with my contract, I need to go to an identity provider that I trust and and say, "account X claims to be UUID Y, please verify" (or similar) and they would then return true or false. This is certainly useful, but I do not see where in this process a standard adds value. Since I need a pre-existing trust relationship with the identity provider, my dApp won't be accepting any random identity provider that a user gives me. I must integrate my dApp with specific identity providers, and in almost all situations I can think of I will pick one (and only one).

To be really clear, I'm not arguing that Identity Providers are bad. I'm arguing that creating a "standard" (and going through the RFC process) for every useful contract someone can think of is bad. There may be value in this being standardized, but it is not immediately apparent to me and I want you to convince me that standardization adds value.

Edit: In case it isn't clear exactly what I'm looking for, I would like to see a problem statement that shows some problem that can't be solved without a standard. Right now this EIP is missing a problem statement.

Arachnid commented 6 years ago

Some upfront definitions would be good. What are keys? Are they cryptographic identities? Why not addresses? What is a claim for, and how does it work?

Interface definitions probably shouldn't contain Solidity-specific types (eg, mapping(foo=>bar) baz), but instead the interfaces they generate (eg, function baz(foo) returns(bar);). How it's implemented is an implementation detail for the contract.

I agree with @alexvandesande that principal types should be left up to the implementation. Role accounts are a good thing and should be encouraged, but there's no need for the spec to mandate what roles exist and what privileges they have.

@MicahZoltu I believe the purpose of standardising this is to allow multiple clients (eg, wallets) to interact with multiple implementations of identity providers (Eg, multisigs, etc). Without a standard, you have the current situation, where Mist has native UI for multisigs, but only for its own API, Parity has another, and so forth.

frozeman commented 6 years ago

@MicahZoltu i see this needs a lot more explanation. I kept the standard description concise to make it readable, but many of the concepts i introduce here are not apparent right from the start. I will address each of these points here in the discussion, but also keep in mind, as i wrote above; the ERC draft is not finished yet. I will be giving a talk at the london meet up on the october 11th, where i will lay out my vision for that standard in more detail. This will be recorded and i will post the video here.

First of this is a standard for a self sovereign identity; This means the owner controls its identity and he allows claims about himself to be attached to his identity. There are no identity providers, but claim issuer (or certifiers). Those simply say: "I saw him in person, stored his biometric data, and attached a link on his identity". People who want to verify that they are dealing with a person, either in their contracts, or dapps, websites, etc. can then check on their identity - given they got a signed message from one of its keys - and look for a claim they trust.

But to answer you questions:

Do i think all of the current proposed functions need to be standardised? No; i just wanted to give a more or less complete set of functions, which make clear how they interact together.

The whole example above, won't work automated and with unknown parties, if these processes and functions aren't standardised.

Another extension of this could be that you have to hop through multiple claim issuers, to reach one you trust, which in return makes you trust all the others, including the one you verify the identity of.

Also every claim issuer, needs to implement this identity interface himself, to make sure he is verifiable himself (and keys can be checked).

@Arachnid concerning key types: If we standardise them we allow many upcoming use cases for keys, as described in my previous comment. Currently i only propose two types: 1 management keys, and 2 action keys. The former is for manage your identity and they should stay safe. There can be n of m required for any change. The latter is for actions in the world, keys which can act in the name of your identity. Those are replaceable, and for everybody who wants to interact with you, should always check of you still hold those keys in your identity.

Claim types in return need to be predefined, to allow somebody who wants to verify you to look for what he want a proof about you.

I choose the word keys, over addresses as this is better understandable in the "off-chain" world. Keys are something we use on a daily basis to get into houses and objects, and the term is used in cryptography as well. Addresses is very blockchain specific. Though your identity contract address - i would call "address".

The current draft allows for all kind of different key management implementations, it doesn't force any, expect that there have to be at least one second step of approval to execute, as stated in the draft, some functions..:

"MUST only be done by keys of type 1, or the identity itself. If its the identity itself, the approval process will determine its approval."

(There is certainly a lot of improvement potential here, and when we think of compatible UIs, we will need to revise that)

Many of the above concepts may not be clear yet, but they are in the description of the ERC as a very concise sentence:

"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, as well as a proxy function to act directly on the blockchain."

Arachnid commented 6 years ago

I choose the word keys, over addresses, as this is better understandable in the "off-chain" world. Keys are something we use on a daily basis to get into houses and objects, and the term used in cryptography as well. Addresses is very blockchain specific. Though you identity contract address, i would call "address".

The problem is, 'keys' has a specific use in cryptography, and you're using them to refer to something that isn't a cryptographic key, or necessarily controlled by one. I'd really suggest choosing a different term.

In either case, the EIP definitely needs a definitions section.

frozeman commented 6 years ago

I agree we should add a definition section.

Short answer to the above. keys are public keys: Those keys are you hands in the real world, you sign things, you make transactions etc. Through these keys and a pointer to your identity, others can go check that its really you. If they want to know things about you: e.g. are you a human, or have an address, then they look on the claims about you by others.

‘Keys’ here can be public keys or other contract, like multisigs and reputation systems. If anybody has a better word for them, I’m happy to change that.

overdrev commented 6 years ago

claims :
a.I would suggest a logic that permits explicit approval of claim by issuer - perhaps requiring an asynchronous process.
b. Do we cover a single usage access method such that a third party can prove my info, but only once. Maybe time limited.

alexvandesande commented 6 years ago

@MicahZoltu

There is value in standardizing tokens so that an application (e.g., Wallet, exchange, etc.) can interact with any token the user provides without needing to know about it in advance or write custom integrations for each token.

Exactly. I'd like to be able to login with my uPort identity into Mist, use my Mist identity in Status, or log in with my Status identity on a ether play game or post a blog post in Steemit from my Aragon Company identity. Each one can be implemented differently, just keep some common interfaces.

oed commented 6 years ago

This is very interesting and it overlaps a bunch with stuff we are doing with uport. Although we have a quite different design I think discussion and standardization around this will be very usefull. I'll give a breif description of our design before I go on.

As the base of our identity we use a very simple proxy contract, see also ERC: Proxy standard. This makes our system very flexible in terms of how you can control an identity. To control a proxy contract we use a contract we call IdentityManager. The basic idea is that we want a single contract that multiple users can use to control their proxies, mostly to reduce gas cost. Here we have the ability to add multiple users etc, but this is something we want to iterate on in the future. To issue and lookup claims we have a separate contract uport-registry. The basic idea here is that we want to separate the storing of the claims from the identity itself to a different contract.

I think this ERC touches two very interesting things, transaction execution and claim structures.

Transaction execution

The execute/approve looks promising and definitely something that should be used for high value transactions. e.g. transaction of > 100 eth needs to be aproved by my hardware wallet. But in the case of low value transactions it seems like a bit of overhead, e.g. I need to send two transactions in order to send a tweet on leeroy. Would be interesting to have a system where some execute are automatically approved.

Claims

We've opted for not storing claims in the identity contract itself, this makes it cheeper to depoy identities while claims can still be associated with the identity with the same level of security. Another thing we have though a lot about is the privacy of claims. Right now there is basically no privacy for claims that are on-chain, which is basically a no-go for a lot of our use cases. Instead we are mostly using off-chain claims which also can be securely linked to the identity (proxy contract in our case). Of course we see the benefits of having on-chain claims as well, and standardization around the format of these is very useful, but they should be decoupled from the identity contract itself. Maybe the claim section could be put into a separate ERC?

bneiluj commented 6 years ago

I agree with @Arachnid - 'keys' should refer to cryptographic key.

@frozeman Great initiative! This is so needed. It's a great step forward a standard for a self sovereign identity but it will not prevent people from creating more than one identity which is a no-go regarding KYC institution requirement process. Except if the identity public address is linked to multiple trustworthy services.

frozeman commented 6 years ago

@overdrev I’m not sure if a Claim permission process is needed, except when an entity wants to know the details of the claim, e.g. see the biometric data stored by the issuer. Then of course we need a async process. I have made some thoughts about that, but this is not really part of this ERC and can be a separate standard.

I see it as follows: claim data (referenced by ‘bytes claim’) is double encrypted by the issuer and me, if somebody wants to see the actual data they request it at the issuers ‘bytes _location’ and request the issuers part to be decrypted, then they come to me and ask for decrypting the second part, which i can always decline.

For b. I’m not sure how a single claim proof should look like, but interesting idea.

@oed thanks for participating, you guys should have actually started that standardization process ;) Concerning your approaches:

Transaction execution: the excite function is mainly to act as your identity on the Blockchain in the least cases this contract should and will be used for storing and sending ether. If you want to move money and what that to be publicly visible and attached to your identity, use a multisig, or a wallet which is controlled by your keys from your identity .

Claim storage: I do understand you wanted to create a system which is cheap in gas, as uport will overtake most transaction costs in the beginning, but I don’t think this applies for a self owned standard, and would be the wrong approach to that. At the same time when a standard is found and a library is deployed, deploying a contract which uses that library is quite cheap.

Claims themself will be added by others, the owner of the identity will only pay for the confirmation. As I think A real used identity won’t attach every new app, or social network as new claim, those claim additions will be rather less. Things like this will be stored in other Reputation systems or uport like systems and can be attached as a self made claim to my identity, this way the identity can be kept rather raw. The “cool” stuff can happen on other experimental systems.

I’d say there are two main reasons why claims should be with the identity contract:

  1. It allows for on chain verifications and in the best case the contract, which wants to verify, only needs to call you identity once. He doesn’t have to go look on another address, or even outside of the BC. This allows for complex automated authentication systems purely running on the Blockchain.
  2. People want the feeling of having their things on one place, as funny as this sounds but it makes people feel more in control. It’s hard for people to acces their identity through registry contracts, if they don’t fully trust the registry. On top of that this standard allow for many different implementations of identities, which will all be able to create claims about each other.

There is probably more reasons, which don’t come to my mind now.

Concerning privacy: as the claim data is only meta data, the only viable information one can retrieve from your identity is: which claim issuer has claims about me (e.g. the German state, or Vitalik claims something about me), and when that data has changed.

This can be an issue, if I don’t want anybody to know I live or are German, but we share a lot more information on social networks daily. Also privacy focused claim provider can pop up, which claim things, like address etc globally, but are trusted by many. Then the only thing it leaks, is that you are privacy focused :)

@bneiluj people will have more than one identity for sure, as we just start to experiment with this, but once your have gone through the effort to get claims about biometric data and address, etc. you will treat this identity as more valueable. As long as you can add new claims of importance to more than one identity, that’s fine too. The person verifying your identity doesn’t need to care, as long as he can trust the claim issuer.

frozeman commented 6 years ago

@Arachnid I added a definitions section. I’m still open for better names for keys.

Arachnid commented 6 years ago

@frozeman Anything other than keys, really. I'd suggest 'principals', for instance.

It's still not clear to me what goes in this field. The definition says "public keys", but contracts don't have public keys. What would the 'key' for a contract be?

alexvandesande commented 6 years ago

@oed

I need to send two transactions in order to send a tweet on leeroy.

Actually I don't think that's how I would recommend. You can sign your tweet with any account, publish and say: "I am tweeting in behalf of foo.eth". Then the tweet app can check either that account is listed in one of these keys. No on-chain transaction required.

jpitts commented 6 years ago
  1. Will the claimTypes enumeration be maintained as part of the standard?

  2. Claim location might be better represented as claim uri, even if it involves a hash. But is a URI scheme involving a hash defined for all cases? I saw a lot of discussions in IPLD / IPFS about URI schemes, and in that community it seems inconclusive.

Example discussion: https://github.com/ipfs/ipfs/issues/227

https://en.wikipedia.org/wiki/Uniform_Resource_Identifier

Wesley-Arrington commented 6 years ago

Is the plan to allow claimTypes to not only be used to verify an identity but also to verify information about an identity?

claimTypes could be used to confirm accreditations from institutions, attendance at events and place of work. So for example if a decentralized Uber was created and this dApp only wanted drivers who had gone to driving school, then claimTypes could be used to confirm this. If the drivers received the proper claimType from a credible driving school they could be drivers for this decentralized application. So claimTypes if used this way could automate the process of checking the credentials of identities.

MicahZoltu commented 6 years ago

I understand that you want to keep the contents of the ERC "just the spec" but reading over all of the comments here I think the lack of a really clear problem statement and really clear and targeted solution is causing confusion. It sounds like there are several different interpretations of what this ERC is about in this discussion and everyone has a different image in their head as to what this will be used for.

@frozeman Can you provide a problem statement or user story as a starting point? Describe the problem that you are trying to solve (without describing the solution as part of the problem). I just tried to think of an example problem statement that requires this system but was unable to come up with one, which is why I'm struggling to understand the value of this being a standard. An example problem statement for a token standard (pre-ERC20) is:

I want to be able to build a smart wallet that can control any token the user desires, including future tokens that don't yet exist. The user needs to be able to transfer tokens into the wallet and out of the wallet without risk of the tokens being trapped in the wallet contract. Currently, each token has a slightly different API so it is not possible to build a wallet without designing it to support each token, and such a wallet would not support future tokens (with as of yet unknown APIs).

Note: Be prepared for me to offer alternative solutions to your problem statement that don't involve a standard. 😉

frozeman commented 6 years ago

@jpitts thanks for sharing. I would suggest coming up with a set of claimTypes and new standard additions can come up with new ones, that’s why it’s a uint256. We could also leave the type description out of here and make that a totally different standard.

URI makes sense, I will change that and also change it for a string for now.

@CDsigma your use case it exactly right, you can have people and institutions claiming things about you, and you can allow those claims attached to your identity. And yes; you can never verify an identity if you don’t verify claims about it.

@MicahZoltu I agree that it doesn’t seem to catch on right away what the use of this ERC is, though I brought already a few exmpakes which cover your points. But I can try to reformulate:

There are plenty more, and all come down to yourself wanting to prove something in front of others. And the claim model solves that: you can also take a look at https://sovrin.org/wp-content/uploads/2017/06/The-Inevitable-Rise-of-Self-Sovereign-Identity.pdf as they describe a similar system.

So in short the solution the ERC brings:

  1. I want to prove something
  2. Everybody can verify claims, as they know how and where to look - automatically.
  3. This can go as deep as it needs to reach a trusted claim issuer (jumping from issuer to issuer)
  4. Your identity can be taken to any interface which needs an identity, without creating a new one for every app.
  5. Smart contracts can verify claims automatically
  6. You can act outside of the Blockchain and third parties can check your identity on chain.

I am not aware of any system, which doesn’t require a central authority that allows to create a self sovereign identity. And I am unclear how this can be solved without a standard.

The token standard is quite the same. Everybody could have made their own tokens, but only by creating a standard we are able to use them anywhere, and with erc223 we will be able to have those tokens interact. And as you brought up ERC20 a lot, I assume you are aware that I proposed that standard.

Also for this standard, the target is not mainly the UIs, but other identities and smart contracts. Though UIs are as important, to be able to take your identity around.

oed commented 6 years ago

@frozeman Sorry I think I missunderstood what you are trying to do. Let me see if I understand correctly now. Transaction execution: So this is more something along the lines of an identitfier for an identity that you can attach accounts to? It would mostly be used to attach claims to and send claims from. Uport are trying to come up with something similar, but without relying as much on on-chain logic to do so. Check out the work of the Decentralized Identity Foundation, in particular the DID spec which uport will be compatible with.

Claim storage: So this will be kind of like a personal registry of claims associated with your identity? If it's only meta data that is being stored on-chain, where would the claim itself be stored?

Right now claims are stored off-chain by the users themself in uport. One of the main reason for putting a claim on-chain would be if it needs to be verified by a smart contract. The smart contract is likely to want to know something about a particular account that it is interacting with, rather than the identity itself. Having the claims in a separate registry makes it possible to make claims on any kind of account. Not just this very specific identity contract. This opens upp for the possiblitity of proving something about an account with a zkp without revelaing which identity owns that account.

As for your two main reasons for keeping it in the identity contract:

  1. I don't really see a problem of having to look at another contract, as long as it's standardized, maybe accessable from a ENS record? Complex automated auth will still be very much possible.
  2. The end user will not know or care about how many contracts are involved. The end user will likely not even know what a smart contract is. The registry would of course be designed so it can be interacted with in a trust-less way.

This being said I can see some benefits of putting claims in an identity contract, but for the reasons I stated above I don't think that's the way to go.

Btw, you should also check out the work being done on verifiable claims

frozeman commented 6 years ago

@oed thanks for the links, that looks very interesting and is very similar to what i am trying to do here as well, but with a purely on chain logic. What i can see every body in this space has come up with, is attributes, or claims and keys as actors. Same as me.

Let me try to break down the contract:

-> keys: public keys, or other owned smart contract address, which can interact in your name

- keys are there to prove identity ownership
- keys can hold money and act on the blockchain, and can be traced back to this identity
- smart contracts owned by this identity can be extension systems to the identity, e.g. reputation systems

-> execute: A function to allow this identity to act directly on other smart contracts, to be an actor "on-chain", including holding and transfer of ether.

-> claims: can be added by others, and verified by others. The claim content is stored off-chain, or onchain, but this is not defined here. Important is that the claim has to a have a proofable piece (which here is the signature) and a link to the claim, as well as the issuer.

- claims can requested to be added by anyone.
- claims can only be approved to be added by the owner of this identity
- claims can be removed at any time by the owner of this identity
- claims can be altered by the issuer, punishment would be removal (OR we add approval from the owner as well)

To compare that to the DID, its similar, just that its all in a smart contract and verifiable on chain.

To compare that with the W3C verifiable claims, its basically the same, though we can try to align them even more.

Also to be clear this is not standardising how claims can look like, how the content is stored, or where. Claims can easily be DDOs for example stored on IPFS. Also how identity verifications are handled off chain, e.g how the message will look like when signing off chain and including your identity address on chain. So there is a lot of defining necessary. This ERC mainly should give a very slick framework to put all those claims and claimtypes and keys inside.

Concerning the registry and the identity object (DID vs. DDOs), there can sure be a registry on top which holds the addresses of many identity contracts, e.g. governments could this way group citizens etc. but i don't see a need for that in the basic identity spec.

I am open for a call, to discuss that in person, as i see some misconceptions, or i myself have some.

lukehedger commented 6 years ago

We've been researching and prototyping a solution for identity in the META Network for the last few months and make use of a lot of the same primitives in this proposal and other projects. Our current implementation uses the ENS to register a subdomain to an identity owner's public address, which resolves to a content-addressed object (eg. stored in Swarm, IPFS) where the identity's metadata (or claims) can be retrieved and verified against signatures on that data. This way we utilise an existing standard and minimise what is stored on-chain.

Given how much of an essential component identity is to a system or network, it would be great to see a flexible standard that developers could build on - we know first-hand how complex this can be! If it can incorporate/accommodate other efforts (like W3C standards) then all the better.

frozeman commented 6 years ago

@lukehedger looking forward to contributions.

I just had a fruitful in person discussion with @oed and we came upon with a few small alterations:

It would be really good if work on the holder spec is done first, so that its a good basis, for #725. I will create an issue to discuss this spec part in the coming days.

m-schmoock commented 6 years ago

@frozeman I like the proposal, also, as already pointed out in this discussion, I would see the need to define a standard set of claimTypes. This can be done by defining a low-range of well known types: i.e. 0 - arbitrary_number also to be defined in this ERC). As the number 256 Bit number is big enough, we could also think about using a bit-mask to organize topics and sub-types or even claim multiple types as once... just a thought.

I also think some details are missing regarding the claim (bytes) storage and access.

... Also a question for a better undestanding: Regarding the approve function, can you hint out what do you mean by "Triggers on successfull claim addition Event"

Does it mean that if the approve was called by the identity itself or a type 1/2 key, the approve function is automatically called by the Contract, as a self verified claims do not need to be approved? If so, please point that out.

oed commented 6 years ago

To add to @frozeman's comment it might be good to have an example of how this might be used. Let's assume accouont A, that implements the "Claim Holder" part (Identity verification in the spec), wants to call a smart contract C. C requires everyone that interacts with it to have some biometric data verified by verifier V. The interaction would go like this:

A calls a method on C. C calls A.getClaimsByType(1), finds the claim issued by V, then uses ecrecover to get the public address k of the signer of the claim. It can then call V.getType(k) to verify that the identity V owns the public address k.

Worth noting here is that i getClaimsByType returns more than one claim this might become a quite costly call. One way around this would be to check which claim the contract needs and include the claimIndex in the method call.

As noted this allows for smart contracts to receive and use claims if they implement the "Claim holder" interface. But the smart contract wouldn't need the Identity part of this ERC since it can never sign claims anyway.

m-schmoock commented 6 years ago

@oed For this claimIndex on execution to work, the Caller also needs to know V, which may not be known in advance, or may even be a set of valid Claim issuers [V,W, ...] , meaning that C must make publicly known their trust set, correct?

oed commented 6 years ago

@m-schmoock since C is a smart contract V will be publicly known.

m-schmoock commented 6 years ago

@oed It sounds overcomplicated, but for this to work in a generic way, there needs to be an additional interface for C (maybe called IdentityConsumer) that declare the set of issuers [V, W, ...] a Contract C is trusting.

frozeman commented 6 years ago

@oed thanks for this example, though i would make a small correction: C doesn't need to call getClaimsByType, but instead getClaim, as it knows which claim issuers it trusts, it can generate the index using keccak256(address issuer_address + uint256 _claimType) beforehand and pass it to getClaim. After that it ecrecover's, and checks that the public key k is in fact still hold by issuer V. If the identity doesn't have a claim from that issuer, its anyway not able to pass..

@m-schmoock Every claim addition request should have a approve required. Obviously for the standalone claim holder standard it wont be like this, but for an identity it should. Technically speaking, its up to the implementation if they adhere that, thats why i changed it from "MUST" to "SHOULD create a pending claim...". On the end this contract doesn't have validity because people are forced to use that standard, but because claims are properly signed <- Thats what other contracts can trust. Defining the approve function here, is mainly to make sure it is interoperable in all interfaces, if some implementations won't require approve for execute, thats up to them. E.g. deportations might solely rely on one multisig being the soley owner.

frozeman commented 6 years ago

@m-schmoock C Surely needs to have predefined issuers it trusts, otherwise it can’t autoverify any claim. But for unknown claim issuers it could start an async manual process which involves people or other off chain systems. But I don’t think the claim issuer needs to be standardized, the process needs to be described for sure, but ultimatively it’s up to any contract what verification process they really trust. The simplest version would look like the following:

  1. getClaim by index, which is the type for a trusted issuer (keccak256(address issuer_address + uint256 _claimType))
  2. Ecrecover signature, retrieve address k
  3. Check if k is still a key hold by the claim issuers identity contract (issuer address)

That’s all it needs to verify an identities claim.

m-schmoock commented 6 years ago

@frozeman I get the point. This will work for a known set of V's, and there will be ways to get there. Helpful i.e. for checking identity/user access to dapps and such, which will probably be the first but not the last usecase.

I think in reality what we will face is the need to share trust in a broader sense. Just like when multiple companies would trust each others KYC Claims on identities. This will have a real-world benefit today, and complexity related gas costs would easily be covered by not having mutliple KYC video-ident sessions. What I mean that there will be the need to have a large set of V's in reality, just like we have today in our OS/Webbrowser root CA stores.

A concrete usecase for this would be: Allow access to anyone that has a KYC video-ident (or better) from a publicly known company that is: a bank, a telco, a ...

We should be clear about the expected use cases, meaning to support many trustful Issuers, even more identities, but each identity will have few/handful claims (at least so I think). Having C calling keccak256(address issuer_address + uint256 _claimType) for all known issuers maybe too costly if done within a execution/proxy call.

Maybe, what also would be helpful to get this of the ground, is to give the issuers incentives when providing claims on identities. This can be optional and paid by the ones checking the claims, maybe offchain when the uri data is fetched. This will grow the identity ecosystem faster with a larger set of economically useful claims.

Feel free to correct me if I'm getting to far off from the basic idea, but that's why its important to identify the usecases and relations precisely in the problem statement of the proposal.

frozeman commented 6 years ago

@m-schmoock your thoughts are valid.

Concerning: pre-known issuer. I think there is no way around it for on chain auto verification to know the issuers a contract trust, and may have to check multiple ones of those. Even checking a few of them should be relatively payable. Also think that the person who wants a service is paying for the gas, not the contract which is called.

I could also imagine that some contracts will go n dimensions deeper, and hop from claim to claim issuer to claim and again claim issuer, until they find a trustworthy one. All this is thinkable.

I would not want this ERC to try to create monetary incentives, as this is not the purpose of this ERC. Incentive systems can be created on top of this standard, once we have a valid one.

bneiluj commented 6 years ago

@frozeman I totally agree. Incentive systems can be created on top of this standard !

@m-schmoock It could be used for creating unique identities leveraged by trustworthy claim issuers or based on transactions history like Trustlines Network / State Channels. I'm behind this NGO identity project IDbox so it's a fantastic EIP for projects like that.

m-schmoock commented 6 years ago

I didn't say this to be part of this standard, but rather think about how this can/will be done in the wild. Don't underestimate this, as it can be a huge advantage as a side-effect to this proposal. I don't like propretary paid stuff probably even less than you think ;)

frozeman commented 6 years ago

I moved the Claims part into its own ERC: 735. Lets discuss details there, the current standard requires only slight changes to #735 to add the approval process.

I added I added uint256 signatureType to #735

jonnycrunch commented 6 years ago

@frozeman we missed you at the Rebooting Web of Trust meeting last week. I was asking who was going to summit the DID method spec for ETH. Will you write it up using this template?:

https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-fall2017/blob/master/draft-documents/DID%20Method%20Spec%20Template%20Definition.md

I started a DID method spec on top of IPFS called IPID. The draft is here:

https://github.com/jonnycrunch/ipid

other examples are: Sovrin, Veres one, btcr

cc. @christianlundkvist, @talltree

tjayrush commented 6 years ago

I would ask that as the community build out this powerful capability that we remember that sometimes it is important to be able to fake your identification, hide your past affiliations, and be "un-remembered". For example, in the face of an oppressive government regime, as one flees persecution, one would not want to be tagged with an immutable, unfakeable identifier. I wrote about this issue here: https://medium.com/@tjayrush/be-careful-little-brain-what-you-code-6ad4d5fb9d9b. I think this part of the equation is important and should be openly discussed.

frozeman commented 6 years ago

@jonnycrunch can you connect me in skype and we have a chat? (mine: frozeman.de)

@tjayrush i fully agree. But you could always start a new life with a new identity, or ask one of your former claim issuers to sign the new identity or just a key instead.

Do you have any other ideas? (ps. didn't read your blog post yet)

frozeman commented 6 years ago

I added a Additional References section.

tjayrush commented 6 years ago

@frozeman I don't have any ideas about "un-remembering", but I'll share if I do. It's very interesting.

M41 commented 6 years ago

if still looking for a replacement term for 'key': idkey, idnkey, inkey, stub, epigraph, signkey, keychain

alexvandesande commented 6 years ago

@M41 seems keys in this context are basically Ethereum accounts, why not use "accounts"?

frozeman commented 6 years ago

@alexvandesande actuallythats what I want to prevent. This standard can and should hold keys of non ethereum types as well ideally, or it’s 20bytes hash at least. And currently that can be also contract addresses. But the more flexible we are the more open this standard will be.

@tjayrush I’ve read your article and I do see what you mean. Let me come up with a possible implementation solution for this standard:

As this standard in most cases stores references and not the data directly, I ALWAYS have to authenticate myself in front of a third party and men know WHICH identity I have.

This is the step where the third party gives me a challenge (random string) and I sign it incl my identity address. This way I point them to my identity in the first place. Only form there he goes on to check claims and may retrieve the actual claim data, e.g. biometric data to compare with my physical person.

I could technically always sign with a different key which belongs to a fake identity, and as long as the claim issuer for biometric data is not giving everybody access, so they can go from biometric data to my real identity, then I would be safe to use any new created identity.

The reason why this wouldn’t happen in a normal functioning society, is because I want to keep my identity for as long as possible, to build up reputation.

So the flaw here lies within the claim issuers we trust, they could technically always reveal who we really are. So we should move to decentralized claim issuer models, which perfectly fit in this standard as well.

andrewrd commented 6 years ago

@frozeman The idea of a standard behind identity of the blockchain makes complete sense. Public keys being verified via a 'claims' system to validate a public key's authenticity would make sense for physical objects as opposed to simply human and machine identity. An example use case of this would be by using ERC-725 in conjunction with ERC-735 this standard could be used to prove the unique identities items that are manufactured and passed along a supply chain.

The addKey & removeKey functions could correspond unique identifiers to physical object in terms of authenticity and the actors across a marking process on the supply chain dependent on the key types. The transaction cost of this contract may be high but dependent on the item itself it justifies a steep transaction cost to execute functions on the contract. The execute & approve functions are interesting as it opens up the idea of allowing tokens to execute the claims process.

One use case which is the project I have been developing(https://devery.io) looks at physical products identified individually via public keys on the blockchain. I could see this standard being built upon for that specific use case among others. I was initially writing out a very similar spec until I came across this standard which would make a lot of sense to build upon for my implementation. I'm very interested in aiding in the development of this standard.

@MicahZoltu Apart from my project, there are a number of other projects aiming to uniquely identify products using a identity based blockchain implementation. A standardised approach to this would make a lot of sense as it would allow unification between competing physical product identity systems much like ERC-20 has done for tokens.

@alexvandesande In my mind, the term 'key' is more generic to allow the account name to apply to a number of varying identities whether it be an object, machine or person. It distinguishes the keys from typical Ethereum addresses, despite that "accountId" is another suggestion.

tjayrush commented 6 years ago

@frozeman Does this accurately summarize?

Functional society:

Dysfunctional society:

Current design anticipates (but does not require) fully decentralized third-party claim issuers.