Closed frozeman closed 2 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.
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)?
@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.
@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.
@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);
?
@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 to
isKey` and it can be up to the implementation to check if it's plain or hashed or both.
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?
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:
@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?
@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.
@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.
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.
@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.
@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?
@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
@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.
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:
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:
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.
Any recovery key can cancel recovery mode. This should be done if another recovery contract was compromised or hacked.
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 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.
One or more than your management keys is compromised: In this scenario the user can still use the recovery key to freeze the identity and prevent any further loss of funds. After the waiting period is over they can reset the keys. If the attacker compromised enough keys to add a new recovery key, then the owner can use the lock and recover process faster than the new key can be activated.
Catastrophic loss of keys or life of owner: in this scenario the original owner passes away, or loses all his key in a house fire. In this case their family can use a recovery key (which might be included on the will) to have access to funds. If the recovery key is leaked while the owner is alive, they will be able to cancel it with another recovery key during the lock period.
Compromised recovery key: Recovery keys should only be contracts or cold wallets to secure them. But in the case that one contract is hacked or the key is leaked (maybe the lawyer that wrote the will tries to use it) then the user can use other recovery keys to override them. These can be used to cancel the recovery mode and in the mean time, normal management keys should be used to remove the compromise recovery contract/keys.
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:
@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?
@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.
Is this and #735 in draft and should it be listed here: http://eips.ethereum.org/erc ?
@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.
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:
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
.ABIEncodeV2
is needed to have bytes[] signatures, bytes[] data, string[] uris
in the constructor.uri
is not included in the signature and could theoretically be changed without changing a claim signature. Is this intentional or not?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
ExecutionFailed
event in ERC725
which isn't part of the standardX
, wait for approvals, threshold is increased to Y
, initial execution is approval with X
approvals)Would love any feedback / thoughts on the implementation, I'm not well versed in Solidity :)
Excited to see an implementation! I have also been working on one at OriginProtocol/identity-playground with UI at https://erc725.originprotocol.com
data
attribute be a hash of the contents of the URIThanks for sharing @nick, great to see a UI for these standards—I'll take a closer look in the following days!
To your points:
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!
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.
@fulldecent can you extend your concerns?
@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.
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.
@fulldecent what are some examples of people building identity systems on 721?
http://0xcert.org for example. It's not just identity, but it also addresses that issue.
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
@fulldecent will it be streamed or recorded?
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.
@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.
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.
@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
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.
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.
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)
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?
@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.
@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?
@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).
@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.
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.
@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.
@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.
@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.
This proposal has moved to ERC-725 (source).
This issue exists as an archive only.
Original Text
``` eip: