ethereum / EIPs

The Ethereum Improvement Proposal repository
https://eips.ethereum.org/
Creative Commons Zero v1.0 Universal
12.79k stars 5.2k 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/).
JosefJ commented 6 years ago

@frozeman Ad getKeyPurpose) I think that's kind of what the function hasRight did in my case, (I agree that searching in an array of key.purposes will be better then in an array of keys with a purpose As there is this redundancy with getKey, I think it would be better to rename this particular functionality as: keyHasPurpose(function keyHasPurpose(bytes32 _key, uint256 _purpose) public view returns (bool)

Ad getKey) I would just keep with one parameter getKey(bytes32 _key) as this would become the one and only function to get all the 'key' data from.

Ad contract testing) The input expects to be web3.sha3('<address>', { encoding: 'hex' }) as I rather store key hashes in order to not having to care about the key type while storing it (I would be nice to have a discussion about a preferred format thou). I also removed the requirements which were throwing on constant functions if the object doesn't exist. Will be in the repo after next push.

sichen1234 commented 6 years ago

Hello, Do you think something similar to this should be done for products or assets? For example, multiple parties could provide information about a product, such as what it is (Model X Car), what its specs are (Electric Vehicle 4 passenger sedan), to what its status is over a period of time (New 2015-10-01, Transferred at 20,000 km 2017-06-01, Major Repair 2018-02-10)?

JosefJ commented 6 years ago

@opentaps I think the #735 - Claim holder functionality would be the case for items. I'm currently working on a project that requires experts (identities) to issue claims about objects and it kind of makes sense to utilize a similar claim scheme on those objects themselves. Combination of ERC20 & ERC735, sort of.

frozeman commented 6 years ago

@JosefJ I think its important that if the key is < 32 bytes, that it is not hashed, otherwise its hard to read a key of an identity, and if its a contract, to interact with this contract,as you cant go back to the original address anymore.

but converting bytes32 to bytes20 should be possible.

frozeman commented 6 years ago

@JosefJ concerning the new getKey would you also return the purposes as part of then key structure e.g. function getKey(bytes32 _key) constant returns(uint256[] purposes, uint256 keyType, bytes32 key);?

JosefJ commented 6 years ago

@frozeman ad key hashing) As we were discussing, there are probably reasons why to store the plain keys (transparency) but also why to hash them (privacy). Not sure what's the right approach but specifying that per key might be good. I think the case of Ethereum addresses as keys are a special case. Something like adding the hashed/notHashed distinction to the key struct could help

struct key {
    uint256[] purposes; //e.g., MANAGEMENT_KEY = 1, ACTION_KEY = 2, etc.
    uint256 keyType; // e.g. 1 = ECDSA, 2 = RSA, etc.
    bool hashed;
}

OR this could be simply agreed on as additional keyType (... 3 = SHA3(ECDSA), 4 = SHA3(RSA),...)

ad returning purposes) Good point, if it is there, contracts can't get the array returned. Also if we just remove it, the function simply degrade to getKeyType (as returning the key itself again doesn't make sense)

Storage redundancy) If we assume the key structs will be stored in a mapping I suggest to remove them from the struct and basically keep them in as mapping keys (This shouldn't affect the interface as such)

Ways forward: i) remove the key from the key struct and just keep it as key from the mapping ii) change getKey to getKeyType(bytes32 key) returns (uint256 keyType) iii) implement getKey just as true/false getKey(bytes32 key) returns (bool isThere); [could probably be renamed toisKey` and it can be up to the implementation to check if it's plain or hashed or both.

FBrinkkemper commented 6 years ago

As commented at EthCC, it would be nice to split up identity into pluggable layers. Erc725 would then be the Identity keys management standard specification, while erc725/780 remain responsible of claims

Would it be possible to rename the erc?

peacekeeper commented 6 years ago

FYI since DIDs have been mentioned a few times on this thread, we've been working on an "erc725" DID method specification, which means that erc725 addresses can be fully compatible with the DID syntax and DID document format. This is experimental and there are some open issues, e.g. most DID documents contain raw public keys, but in the case of erc725 it makes more sense to use hashed public keys. Here's the current thinking how erc725 DIDs would work:

https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-spring2018/blob/master/topics-and-advance-readings/DID-Method-erc725.md

https://github.com/w3c-ccg/did-spec/issues/56

cbruguera commented 6 years ago

@peacekeeper That's a very interesting idea and it gives a lot of room for discussion since DID is a very extensive subject and ERC725 is an obvious link between it and Ethereum... The link you post here is only a document, though. Is there a place where users can discuss on that specific proposal?

peacekeeper commented 6 years ago

@cbruguera Hmm no there's not really a dedicated place for this. I suggest using Github issues on that rebooting-the-web-of-trust-spring2018 repo for now.

cbruguera commented 6 years ago

@frozeman wrote:

Actually now reading @cbruguera comment again. The idea of getKeyPurpose() was to check if a key exists for a specific purpose.

My impression is that that's what getKeyByPurpose does.

The proposal description for getKeyPurpose states it "Returns the purpose of the key, if hold by the identity. If key is not hold it returns 0". And as for the current proposed interface, it returns an array of purposes, not a single one, that's why I suggest renaming it to getKeyPurposes for semantic clarity.

nick commented 6 years ago

I have pushed my implementation based on the one by @JosefJ to https://github.com/nick/identity

It includes tests written with mocha and demonstrates how to verify a claim on an identity once one has been added.

One idea I had was to assume keys with a lower 'purpose id' have all the powers of keys with a higher 'purpose id'. For example a MANAGEMENT_KEY should be able to perform all the actions of an ACTION_KEY, but not vice versa. This means you can check a key's purpose <= the desired purpose, instead of checking the purpose exists in an array associated with the key.

JosefJ commented 6 years ago

@nick Hi, ad the "purpose id" cascade: I thought of that as well, but there are some problems this could cause: 1) You might want to split the functionalities in order not to let anyone require you to do something with a higher permission key. The other party could require you to approve claim with a management key which you have safely stored in a vault, just because it's technically possible (otherwise they will revoke). 2) In future the enum of purposes might be extended with further hierarchy (groups/rwd) and having the implementation with strict order would cause having not intended permissions. Imagine the identity isn't just one person but rather a DAO that split the permissions to its members so non of them have power over the others and they all have to cooperate to manage the identity - in a hierarchical approach this wouldn't be achievable.

ebadiere commented 6 years ago

@oed I like the uPort identity design with its proxy and key recovery at the core. Is there any reason it cannot be upgraded to comply with this spec? Keys are keys, correct, address or bytes32? Are gas costs your concern?

nick commented 6 years ago

@JosefJ perhaps each bit of the Purpose ID can represent a different purpose, for a total of 256 possible purposes. That way we can use bitwise operations to check for purposes without the complexities and gas costs of array management

cbruguera commented 6 years ago

@frozeman Could you describe how could current ERC725 features be used to implement m-of-n signature for approving changes to the contract? I'm thinking of identity recoverability. Perhaps all can be done on the ERC725 itself without the need of an "identity controller" the way uPort is implemented? I'm interested in knowing your views on this regard. Appreciated.

alexvandesande commented 6 years ago

Has this ERC been rewritten to the new EIP format with PRs that can be later merged? I can help with that if that has not been done yet. It's nice because then new additions can be added as a PR while it is still on draft. For instance I would like to suggest adding this to the interface:

New key purpose: 6 - RECOVERY

All providers of identity, be it email providers, social media or governments always have some sort of recovery of last resort mechanism. These are often centralized and dependedent on trust, but given that it's more common for users to lose their password than for these central servers to be irrevocably compromised, these services are useful and users expect these options to exist. This is an attempt of standardizing them in a safer more decentralized way.

Recovery keys are used for a very common pattern on all identities: recovery of identity in the case of total key loss or management key compromised. It's hierarchically a more important key than management but it's also very limited on what it can do.

Recovery keys should be preferably be contracts and are only be able to do 3 actions:

1) Put identity in recovery mode

Any recovery key can put the identity in a recovery mode. Once it's on that mode the contract cannot execute any external action or move funds.

2) Remove identity from recovery mode

Any recovery key can cancel recovery mode. This should be done if another recovery contract was compromised or hacked.

3) Reset all keys

This can only be done if the contract has been continuously in recovery mode for more than PERIOD (which depends on the identity and cannot be changed later) without being cancelled by any other key. Once it does that, it will remove all management keys and replace them by new ones (or the non-compromised old ones again). PERIOD should be dependent on the use case, but should be time enough for the user to take counter-measures if needed.

Adding and removing Recovery Keys

Adding and removing recovery keys is done like adding any other management key: it can only be done by multiple management keys BUT it also requires a minimal waiting period before that key can be activated, which should be equal to or higher than PERIOD.

Threat models

Allowing the recovery keys to be a secure standard allows you to add some "less secure" recovery contracts. How the recovery key works depends on that implementation:

cbruguera commented 6 years ago

@alexvandesande That is a very good idea, in my opinion. However, judging by the complexity of the mechanisms required to perform the recovery, perhaps it makes sense to implement these ideas on a separate interface (e.g. "RecoverableContract" standard, so to speak)? Thus ERC725 would generally be implemented along with these other standards (ERC735 for claims, for example, and the interface for recoverability)... What are your thoughts on this matter?

alexvandesande commented 6 years ago

@cbruguera to be honest I think the whole listing of keys and their purpose should not be in this standard and left to particular implementation. In my opinion, the standard should set that keys should have purposes, and suggest a few examples, but not set any particular one.

If key purposes are part of the standard then I support adding recovery keys. If they are not part, then I would gladly separate this out in an independent EIP.

collincusce commented 6 years ago

Is this and #735 in draft and should it be listed here: http://eips.ethereum.org/erc ?

cbruguera commented 6 years ago

@alexvandesande Completely agree on keeping the "core" purpose-agnostic with regard to keys, and make it flexible enough for different implementations to incorporate different key purposes and schemes. Recovery keys is an evidently useful case, once again, and in time more complex and novel key purposes might (and most probably will) arise, thus it'd be good to take into consideration the extensibility of identities on this regard.

mirceapasoi commented 6 years ago

As an exercise in learning more about Solidity and decentralized identity, I've tried to implement the ERC 725 + 735 standards, following the standards as close as possible: https://github.com/mirceapasoi/erc725-735

Here are some issues / questions I encountered during implementation:

  1. Can't use getClaim and getClaimIdsByType in smart contracts until Solidity 0.4.22 is out because they use variable length types bytes and string (details here https://github.com/ethereum/solidity/issues/3270). As a temporary measure, I've added a getClaimByTypeAndIndex(_claimId, _index) that bypasses the issues and coerces variable length types into bytes32.
  2. Can't pass an initial set of claims on contract deploy, seems like ABIEncodeV2 is needed to have bytes[] signatures, bytes[] data, string[] uris in the constructor.
  3. uri is not included in the signature and could theoretically be changed without changing a claim signature. Is this intentional or not?
  4. Claim IDs are generated using keccak256(address issuer + uint256 _claimType), which doesn't work great for self-claims i.e. issuer is address(this) and we might want multiple self-claims with the same claimType
  5. Added an ExecutionFailed event in ERC725 which isn't part of the standard
  6. For execution requests, I'm using the multi-sig threshold at the time of request, not the one at the time of execution - is that a good idea? (e.g. you request an execution, threshold is X, wait for approvals, threshold is increased to Y, initial execution is approval with X approvals)
  7. Using ERC 165 pseudo-introspection to check if an address implements ERC 725 or 735. Is this the best pattern for that?

Would love any feedback / thoughts on the implementation, I'm not well versed in Solidity :)

nick commented 6 years ago

Excited to see an implementation! I have also been working on one at OriginProtocol/identity-playground with UI at https://erc725.originprotocol.com

  1. Solidity 0.4.22 should be out in the next week or so hopefully
  2. I used a hack to enable passing claims when deploying contract by passing one long string or uris, with a separate parameter with offsets
  3. My interpretation was that the data attribute be a hash of the contents of the URI
  4. Instead of allowing multiple claims of the same type, why not just have all the data under the same claim? For example a claim type of EMAIL could contain all your email addresses
mirceapasoi commented 6 years ago

Thanks for sharing @nick, great to see a UI for these standards—I'll take a closer look in the following days!

To your points:

  1. Good to know!
  2. Great idea/hack, I'll try implementing it as well :)
  3. Interesting, I didn't realize that, but it would make more sense that way
  4. You're right, that works! What character do you use as a separator in that case?
nick commented 6 years ago

Now that Solidity 0.4.22 is out, I updated our implementation to work with arbitrary length data. We also released a blog post and demo video showing how the UI works. Hope they inspire more people to understand and use ERC 725!

fulldecent commented 6 years ago

I do not support this ERC. I believe any practical use case herein is already well handled by the existing ERC-721 which is already enjoying significant marketplace support.

m-schmoock commented 6 years ago

@fulldecent can you extend your concerns?

collincusce commented 6 years ago

@fulldecent you're not technically wrong in so far as someone can definitely build their own identity system using 721, but that's kinda missing the point of standards, no? A common interface for identity is super useful for everyone, and 721 doesn't fill that specific niche.

fulldecent commented 6 years ago

People ARE building identity systems on 721, it's already happening.

After people start building and deploying systems that are NOT 721 then I would recommend that is the time to start discussing a standardization of those alternation approaches.

Right now is premature to standardize a thing where implementations do not exist.

collincusce commented 6 years ago

http://developer.uport.me/overview.html#%3Cstrong%3Euport-identity-protocol%3C/strong%3E

mirceapasoi commented 6 years ago

@fulldecent what are some examples of people building identity systems on 721?

FranciZ commented 6 years ago

http://0xcert.org for example. It's not just identity, but it also addresses that issue.

fulldecent commented 6 years ago

FYI I will be speaking at the 0xcert event this week. Don't be shy, come to Slovenia this Thursday!

https://www.eventbrite.com/e/beyond-cryptokitties-erc721-tokens-tickets-45174230339

agdolla commented 6 years ago

@fulldecent will it be streamed or recorded?

collincusce commented 6 years ago

Just read over that 17-page 0xcert white paper. It isn't an identity system. Hell if you ctrl-f that whitepaper "identity" is used exactly once (I did that to make sure I wasn't missing something). I wish the team their best, but this is nothing like what #725 + #735 offers.

FranciZ commented 6 years ago

@collincusce You're correct that it's not an identity system but it does address the issue of identities and credentials and solves most if not all of the issues discussed here. I think it's fair to say it's related and if we're talking about solutions built on top of #721 possibly being a better alternative to this ERC. It's worth mentioning.

To be clear, I'm not suggesting a standard discussed here is not needed. Just wanted to add some context.

frozeman commented 6 years ago

I also don't understand what #721 would be for identity? The idea of this standard is that anybody can have a self soverign identity, that has the same flexibility like ERC20 where additional features and function can be build in. The idea of key management and attached claims, is something which maybe NFT and a claim registry could do, but doesnt offer the same experimentation and flexibility than proposed here. Im happy to be proven wrong, but i do think there is a place for experimentation around identity being registries where one puts itself in.

fulldecent commented 6 years ago

@agdolla et al. yes. I am setting up a live stream for you

LIVE NOW: 0xcert event: ERC-721 Beyond CryptoKitties

EVENT: https://www.eventbrite.com/e/beyond-cryptokitties-erc721-tokens-tickets-45174230339

LINK: https://www.youtube.com/watch?v=VSVIFdTJLiU

frozeman commented 6 years ago

IMPORTANT!

I move this ERC from discussion to draft status and merge it as draft to the EIP repo: https://github.com/ethereum/EIPs/pull/1036

Once merged specific changes can then be then discussed as separate PRs to the draft and discussion can happen in the respective PRs. General discussions should be kept here.

When creating the draft PR, I added the suggestions from @JosefJ and removed the getKeyPurposes in favour of keyHasPurpose, which returns a bool and will work as a check for checking keys at an identity.

I also changed the key structure to keep an array of purpose IDs in the struct of the key, but we should discuss the idea of @nick to use a bit mask instead for storing purposes.


Concerning storing all keys as hashes, I probably disagree, as it would then be impossible to call a contract that is added as key, as there is no way to get from the hash to the address. But i also favour the idea of having additional keyTypes that reference hashed keys only.

We should move towards a discussion of key Types and claimTypes/Topics IDs to be standardised, so that current implementations of verification contracts have some dough to play with. There is also the idea to make claimType/Topic 0 always refer to the version used for claimType/Topic numbers. This way a contract can check which table to lookup, or such.

@mirceapasoi concerning the URI not being present in the signature. The rationale behind this is that you must always be able to verify the claim data retrieved, so a faulty URI wouldn't make sense to add for anybody. For you point 4. we should think about a better way to do self claims and multiple claim types. One discussion use the scheme to determine if a claim type has multiple values stored in the bytes data, separated by an offset. For ExecutionFailed, when would this be triggered, on an OOG? Concerning 7. and #881 I'm not sure, #820 might be a better idea.

jllaw commented 6 years ago

One of the things I've been struggling with is that fundamentally an ethereum address can be generated anonymously by anyone and then artificially associated with anything. This standard allows for some sort of self-attestation and third-party attestation that this address has been used by or is somehow connected to a particular identity.

How many such attestations/claims do we think are necessary before we can confidently say that this address must belong to this one identity and nobody else? And what if that address happens to be used for someone else?

My concern is more from an legal liability in relying on this standard. If I'm supposed to verify that a particular person is not a bad actor or on some banned list, how confident can I ever be in never actually checking that person, but instead just checking an ethereum address that has been linked to that person before.

frozeman commented 6 years ago

The 725 draft is now merged: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-725.md. Change proposals should be done as PR against that document and referenced here.

@jllaw thanks for you comment, but i think you misunderstood a bit how identity works. You wont take a person for granted because he self-claims anything. Anybody could claim anything about himself.

You take a claim issuer of your choice and see if that identity has a claim from him. If so you verify its signature and check on the claim issuer identity, if he still holds the claim. And only then you can trust that this claim issuer states something about this identity. If you want to check what the claim says, you need to look at the scheme and probably go to the issuer itself to retrieve/check the actual data.

Only this way you trust identities, by trusting the claim issuers (which can be institutions, systems, zero knowledge proofs, smart contracts, etc)

conejoninja commented 6 years ago

After reading this and #735, as well as the implementations listed here, it's still not fully clear to me. If I understood this correctly, the claims I could make are of yes/no type, like "I do have an address", "I do NOT have an address", but the claim verifier has no idea of my actual address, is that correct?

I want to check if an specific address (supplied by the users) does belong to them or not, how could (if possible) achieve that with the current standard?

Also, as per my understanding, it's not possible to issue multiples claims of the same type (for the same identity), for example like I own email address A,B & C, how could I claim I own several different email addresses?

frozeman commented 6 years ago

@conejoninja The idea is that the scheme of the claim determine of how you retrieve of verify that claim. If you want to check an address correctness, you would need to use whatever method the claim issuer provides to return you the validity of the address. The on chain claim, would only be a reference to the data set and the claim issuer itself. In most cases you probably dont need to verify its address again, as long as you trust the claim issuer did it well.

In the future we probably don't even ask for the address anymore, as we can send things to an identity, and the postal serve knows where to send it to.

The on chain/contract claims work solely as a reference point and not to store the actual information.

conejoninja commented 6 years ago

@frozeman thanks , I did realize it after reading #issuecomment-388061120

I have doubts about having multiple claims of the same type, claimId = keccak256(issuer address + claimTypeNumber), If I have two different emails, the claim should be "I have A & B emails" or use two different issuers, or I'm missing something?

jllaw commented 6 years ago

@frozeman, thanks, I really appreciate the response. I get that there are third party validators which I referenced as third-party attestations. The issue is that from a purely logical perspective, it's impossible for anyone to say with 100% confidence that an Ethereum address is always 100% associated with a particular identity. Take for example, if the most trusted and honest third-party in the world physically reviews my identification and confirms that I am indeed who I am, and then physically watches me create a new Ethereum address in front of their eyes, then they can attest that one one point, I had access to the address. That doesn't necessarily mean that the next time that address is used, that it is necessarily going to be mine. Now, I suppose that if many, many people validate the same identity to the same address, the confidence rating shoots up significantly, but it can never be 100% (not that it needs to...but one has to analyze what purpose the validation is used for and the appropriate standards to apply for their use case).

conejoninja commented 6 years ago

@jllaw Someone else using your address it's the same as someone else using your credit card to buy online. The seller verifies the credit card's security code, but doesn't really check the person using it.

frozeman commented 6 years ago

Youre right and its a problem which i liked to discover more.

If i have an identity and i out work in to verify it (maybe payed to verify it), i would make sure i only put in keys that i control. Though youre right, i could create extra keys, that i then give to other people and this way "sell" my identity.

For that case i would suggest that the people who give access, or add new claims will make sure youre you. They could do that by scanning your biometric data, and then sending it to the bio metric data claim issuer to confirm, and only then would actually give you access.

Today we solve that problem with the photos in documents, here we would solve it by scanning/checking biometrics.

In the future those biometrics could be stored in a zero knowledge proof function, and you simply send the data points in, and it tells you if there is a match or not.

But youre right, simply from keys alone you cant have certainty.

collincusce commented 6 years ago

@jllaw I don't see anything in this standard which forces identity to be tied to an Ethereum address. It can be a contract or any sort of key from what I see. Am I right about that, @frozeman ? Furtheris a proxy contract, to be used in the creation of decentralized applications. Finally, claims can be made freely so it is up to you, the one using the claims, to acknowledge the value of the statements made by the claim issuer. Claims are only as valuable as the claimant and the authority they hold. Even if untrue, a claim is a claim. From a legal perspective, maybe look at it as evidence in a libel suit... Same as a bad Yelp review.

jllaw commented 6 years ago

@collincusce, there isn't. There's just a lot of value in being able to force that, but I'm not sure that it's possible off the Ethereum protocol. It might require a new protocol whereby the creation of the address requires identity to be linked, and then if a claim is made challenging that identity, then the address is blacklisted. Anyone want to work on that with me?

This is more important to me b/c I'm thinking about all of this from an aml/kyc/accredited investor verification perspective, and I'm not sure that a regulator or plaintiff's attorney would agree with me that it was reasonable to assume a particular Ethereum address belonged to a certain person when I didn't have total confidence.

Outside of that use case, I honestly don't care that much if someone is who they say they are; I mainly care because the law makes me care.

jllaw commented 6 years ago

@conejoninja, yes, that's right. For most transactions, that's fine because they don't really care about aml/kyc/other verification; they only care about chargebacks. For some transactions, like securities ICOs, however, they need to know that the investor is really who they say they are so they end up having the check the person, not just the address. It's somewhat annoying.