-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ERC: Claim Holder #735
Comments
This is implemented by #725 |
I added |
I'm still not sure why you're using signatures here, and thus restricting things to only externally owned accounts using ECDSA sigs. Wouldn't it be more general to rely on caller address? |
In order to auto-verify an claim - which could have been added by anybody - each claim needs to contain a in smart contract verifiable signature from one key of an issuers identity. The signature must sign, claim type, claim holder address and claim reference hash. This way any contract can auto-verify claims. There is no way to enforce this standard, and if a supposed claim holder added a claim with I added the And yes you need an external owned account, or key to sign, to allow fully on chain verification. Or do you have any other method in mind, how we could solve that problem? I will repost a pure on chain claim verification process:
|
@frozeman Would be something like this? pragma solidity ^0.4.15;
import "https://gist.githubusercontent.com/AugustoL/9ddf7996e23a01c6599323761c0deeef/raw/17ae59c3dc2c82df791b2e48e5d05a5c012fec42/ECRecover.sol"; //todo: change to repo
contract IdentityRegistry {
//(... other logic)
enum SignatureType {
DirectCall,
SignedMessage
}
function addClaim(uint256 _claimType, address issuer, uint256 signatureType, bytes _signature, bytes _claim, string _uri) returns (uint256 claimId){
if (signatureType == SignatureType.DirectCall) {
require(issuer == msg.sender);
} else if (signatureType == SignatureType.SignedMessage) {
bytes32 signedMsg = keccak256(address(this), _claimType, _claim);
require(issuer == ECRecover.ecrecovery(_signature, signedMsg));
} else { revert(); }
//(... store claim and do stuff)
}
//(... more other logic)
} With this user could call directly without using signed message, and other account could register the user using the signed message? |
Why not just have a registry of claims, whose smart contract code ensures that only valid claims can be stored there? |
@frozeman - interesting stuff! On-chain attestations is an important use case and this is a good outline. I think the general idea of having claim types or categories are good, and the specifications you outlined are also useful. We’ve had some similar ideas in uPort although we have mainly focused on off-chain attestations. I tend to agree with @Arachnid that the claim architecture would be more general if we were to allow any transaction to define a claim by using the |
I have a use case for this where a registry is using Oraclize, for example with Oraclize+GitHubGists=user register, and also there will be the organizations in that registry (also by oraclize), so oraclize would be the "claimer", and by default it's a direct message call (not sure if is possible other way). Also they provide a 'bytes proof', which should be stored together with claim? Or this case might be out of ERC735 scope? |
@3esmit the check shouldn’t be at the addClaim happen, but rather when the claim is verified by third party. There the signature of the claim needs to be checked. The signature type went to support different signatures in the future, e.g. it could hold non ecdsa siagntures as well. @christianlundkvist good that your are here ;) Claims are not only meant to be only from other smart contracts (but they can come from any), but any off chain entity, as long as they attach a valid signature they could even go through a proxy to add claims to contracts. Concerning adding claims for external accounts, yes that not possible. But I think it’s not really wanted either, your identity should have more than just a public key, which can be lost or stolen. The reason why I kept the claim so flexible (e.g. sigtype, bytes for claim etc) is to allow all kind of claim type and verification to be added in the future. Only on chain verifications need the signature check. But claims can slow be checked off chain. Issuers could even attest claims about external accounts, but those doesn’t need to be stored in the Blockchain, this can be a transfer of those claims between two parties only. E.g. if I want to have a claim about me form an issuer, but I don’t want that the person which will verify the claim later can connect it to my on chain identity. In this case only the claim issuer need to be able to make that connection. I will present tomorrow this ERC at the London ethereum Meetup, and there will be a video of that later on attached to this ERC. I am also available for a call to discuss the details of how I think this works in a skype call. @christianlundkvist and @Arachnid you should have my skype already. |
Wouldn't be equivalent, or more flexible to have Also, |
@frozeman
Maybe you can provide some pseudo code of how this would look like.. |
@3esmit Thanks for the catches, i fixed it and change the function to I changed the @m-schmoock for self assigned claims one wouldn't need the approval process and not even a signature, if the for 3. you could get claims but type using |
I added a |
A |
@realcodywburns according to this standard you approve any claim addition, and you can remove claims at any point. So there is no dispute necessary. |
@frozeman @realcodywburns Another use case for a |
Yes, the inability to remove some claims would be the goal. For example: an issuer assets a claim that identity If the situation arises by mistake, Allowing only positive assertions my establish identity but may not capture the full picture of an individual. At the same time, one should have the right to self defense |
I'm not sure if I've misunderstood it here @frozeman but I think a common structure for claimType like this would be awesome (if I'm understanding correctly on first glance). I get that this may be out of scope for this EIP in particular, and the list will always grow over time, but something that outlines things like this?
Then specifying the following:
//
//
Looking up an individual for their sovereign doc, in USA, that is a passport. Feel like I may have misunderstood something, or this is a bit outside of scope, but either way, really excited for this, and thanks for doing it! |
Great initiative @frozeman, I think using a unique URI field can lead to mistake when different Unique Resource Ids from different protocols are uploaded. Additionally to the collusion risk, as we are aggregating many different protocols, a resolver would not be able to know where to take the resource (should I request from IPFS?). A solution could be an additional generic |
@realcodywburns @andrewrd the dispute claim is IMO not necessary. This standard is a shell for your own identity. First of you don't want to have every buy transaction references with your real world identity INSIDE you identity smart contract, that would be a huge privacy issue. And second there can be many reputation systems referencing this identity, this doesn't mean, every step needs to be a claim added to your identity. Technically everybody can issuer a claim and post it anywhere (e.g. a reputation system, or facebook, twitter, etc) You can't defend yourself from that anyway (and shouldn't, as it might be legit). Allowing a claim on YOUR identity means, YOU approve it. Again don't get me wrong, reputation systems should exists, which allow sellers to verify the credibility of a buyer, but this is outside of this standard, and might just happen in a peer2peer way by sending over reputation claims you collected over time, or referencing your identity AND a reputation system you are using (These two don't have to be publicly connected, as long as you can proof owner ship of both) @MikeD123 I think you get it a bit wrong. The idea of claimTypes is more of the nature of properties of you, e.g. If you want to verify a claim, you most likely will not look for the type, but for a specific issuer you trust, so you can generate the ID of the claim in advance e.g.:
will generate you the hash of the claim you can get using As over time, there will be trusted claim issuer, like the US gov, or some decentralised service, people can always know the index of the claims they want to retrieve and even hardcode that in their smart contracts. On the end in most cases we don't care about the data itself, but that somebody verified it. Concerning the subTypes. I wouldn't go so detailed, as then people can know why sub type of claim was changed when, which could be a privacy leak. For some data it might make sense to give them a separate type, but for example for biometric data, just that might be enough. To auto verify a person in front of you, the claim issuer for biometric data needs to have some bio matching services, or zero knowledge proof smart contracts, which can take some takes biometric data, and match it against their data set, and return @buendiadas concerning the URI, it should contain the protocol like |
As next steps, it would be good to create a collection of PROs and CONs for having claim issues in a registry vs. having them on your identity contract directly. Some short ideas i gathered when talking to @Arachnid, I put into this wiki page, which everybody can extend and add to it, so we don't have to do this over a series of issues: https://github.com/ethereum/wiki/wiki/ERC-735:-Claim-Holder-Registry-vs.-in-contract This will allow us gather a good overview over both sides. |
@frozeman Great idea the wiki page ! https://github.com/ethereum/wiki/wiki/ERC-735:-Claim-Holder-Registry-vs.-in-contract. Let's create a vote counting with some eth ! 😅 |
Keep in mind both can work hand in hand, so a claim registry could be useful for some cases, and for others the attached claims in the contract itself are more useful. So can one claim referencing the claim registry, maybe with |
@frozeman - so one question I had is about the possibility of expiring claims. I can imagine something like a physical address being semi-permanent, and needing re-verification every couple of years. As far as I understand it - with current layout of a Claim one would use the data field in the struct to store a value in the future? OR one would have to look up the date of ClaimAdded in the event log - which we can't do from within another contract right ;) |
@jacqueswww Currently there would be two ways to handle that situation:
|
I like this proposal, but how could be map it exactly ? Proposal 1 Mapping Schema.org > People => topic in the order. First property on the page is additionalName so = topic 1 and so on. But what if properties get added to Schema.org > People? And additionalName = topic 1 makes no sense. Proposal 2 We define here a "manual" list for Schema properties that makes sense, like familyName = topic 1, givenName = topic 2, ... Maybe we can find another referential that already has mapped properties to integers, or that is easier to map. Proposal 3 I like the Schema.org > People reference and I would prefer the mapping to be deterministic. Maybe we could just convert the schema.org property from ASCII to integer. Example: http://schema.org/Person, givenName property Storing it from UI to BC
This approach would allow (2^256 - 1) / 3 = about 10^25 triplets = up to 25 characters for properties. Some properties topic IDs with this conversion:
For properties that have their first character ASCII code beginning with 0, we'll just remove the first zero:
This approach could add many other properties of other schemas, the only limits being:
The other problem with this approach is that it would consume a lot of topics ID distributed more or less randomly according to ASCII to integer conversion and that we have no more ranges for other custom topics not on Schema.org. One solution could be to treat all those custom topics like if they were in Schema.org with a first ASCII character encoded in integer on 3 decimals but that is not on the alphabet, like for instance | (124). Example implementation: https://github.com/guix77/erc735example Example uses a helper module to convert property names from ASCII to BigNumber, and from BigNumber to ASCII: https://github.com/guix77/erc735js |
In light of ERC 725 v2, this standard needs a bit of re-work, as now it can sit separate from the ERC725 proxy account, in its own contract. We would now need to manage the approver different, as well as probably add a subject to the claims. |
Seems to have a missing |
Hi All, I like what this EIP is trying to achieve but think it could be better implemented. I discussed the idea of using a salted merkle tree here and I think it is more sensible because it preserves privacy and enables link-ability to the source e.g. drivers license -> DOB -> above 21. |
Why does Does the plus symbol in |
Does that mean that the identity contract's owner should be the address used for signature verification? If not: How is the address / the public key specified? |
I think that if the identity contract does not "hold the key with which the above message was signed" (whatever this means) anymore, rendering the claim invalid, anyone should be able to remove it. Not just the subject or the issuer. Maybe the standard should even specify a preferred mechanism for removing such claim automatically. |
a claim should only be removed by the subject (the identity holder) because only they can decide what should be forgotten about them. |
I would prefer to have an |
I believe it is necessary to separate the revocation of claims from their update. While a revocation is a special kind of update, it MUST be available to both the subject and the issuer WITHOUT a permission. It MUST NOT be possible for the subject to prevent the revocation of a claim. Arguably it is the only permissible update to a claim. If a claim is not current anymore, it should be removed and a new one should be added. The claimId MUST be unique. Indeed, if applications can trust that a claim can not changed (except for early revocation) they will not need to verify the claim each time it is read. |
A claim's issuer should have the authority to retract his assessment. Besides: Your premise is flawed. The blockchain does not forget.
Didn't you just say that only the subject should be able to remove a claim?
Couldn't you just store a hash for that purpose? |
retracting the assessment is what revocation is for. A deletion makes the claim disappear from the current state.
revoking and removing are two very different things. A removed claim will not be returned by
Of course you can create workarounds. What is your argument for updating a claim instead of creating a new one?
there are a few arguments for making the interface fatter:
|
Is there any reason why the claim id does not contain the identityHolder_address. By including the identityHolder_address the claim id would be globally unique, which comes in handy when tracking claims from multiple 735 instances. |
hi all, do we have a beta version of this code just like erc725.. thanks much in advance! cheers |
There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. |
This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. |
NOTE: Due to the changes in ERC725, this spec is not fully compatible with the current ERC725v2. If you're interested in adopting this spec to work with 725v2, please comment below, or send a gist with changes.
Abstract
The following describes standard functions for adding, removing and holding of claims.
These claims can attested from third parties (issuers) or self attested.
Motivation
This standardised claim holder interface will allow Dapps and smart contracts to check the claims about a claim holder. Trust is here transfered to the issuers of claims.
Definitions
claim issuer
: is another smart contract or external account, which issues claims about this identity. The claim issuer can be an identity contract itself.claim
: A claim is an information an issuer has about the identity holder. This contains the following:topic
: Auint256
number which represents the topic of the claim. (e.g. 1 biometric, 2 residence (ToBeDefined: number schemes, sub topics based on number ranges??))scheme
: The scheme with which this claim SHOULD be verified or how it should be processed. Its auint256
for different schemes. E.g. could3
mean contract verification, where thedata
will be call data, and theissuer
a contract address to call (ToBeDefined). Those can also mean different key types e.g. 1 = ECDSA, 2 = RSA, etc. (ToBeDefined)issuer
: The issuers identity contract address, or the address used to sign the above signature. If an identity contract, it should hold the key with which the above message was signed, if the key is not present anymore, the claim SHOULD be treated as invalid. The issuer can also be a contract address itself, at which the claim can be verified using the calldata
.signature
: Signature which is the proof that the claim issuer issued a claim oftopic
for this identity. it MUST be a signed message of the following structure:keccak256(address identityHolder_address, uint256 _ topic, bytes data)
// orkeccak256(abi.encode(identityHolder_address, topic, data))
?data
: The hash of the claim data, sitting in another location, a bit-mask, call data, or actual data based on the claim scheme.uri
: The location of the claim, this can be HTTP links, swarm hashes, IPFS hashes, and such.Specification
Claim Holder
claim structure
The claims issued to the identity. Returns the claim properties.
getClaim
Returns a claim by ID.
getClaimIdsByTopic
Returns an array of claim IDs by topic.
addClaim
Requests the ADDITION or the CHANGE of a claim from an
issuer
.Claims can requested to be added by anybody, including the claim holder itself (self issued).
_signature
is a signed message of the following structure:keccak256(address identityHolder_address, uint256 topic, bytes data)
.Claim IDs are generated using
keccak256(address issuer_address + uint256 topic)
.This COULD implement an approval process for pending claims, or add them right away.
Possible claim topics:
1
: Biometric data2
: Permanent address(TODO: add more in the initial standard?
3
: Claim registry?)Returns
claimRequestId
: COULD be send to theapprove
function, to approve or reject this claim.Triggers if the claim is new Event and approval process exists: ClaimRequested
Triggers if the claim is new Event and is added: ClaimAdded
Triggers if the claim index existed Event: ClaimChanged
removeClaim
Removes a claim.
Can only be removed by the claim issuer, or the claim holder itself.
Triggers Event: ClaimRemoved
Events
ClaimRequested
COULD be triggered when
addClaim
was successfully called.ClaimAdded
MUST be triggered when a claim was successfully added.
ClaimRemoved
MUST be triggered when
removeClaim
was successfully called.ClaimChanged
MUST be triggered when
changeClaim
was successfully called.Solidity Interface
Constraints
Additional References
The text was updated successfully, but these errors were encountered: