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: Ethereum Claims Registry #780

Open
oed opened this Issue Nov 29, 2017 · 55 comments

Comments

Projects
None yet
@oed

oed commented Nov 29, 2017

EIP: <to be assigned>
Title: ERC: Ethereum Claims Registry
Author: Joel Torstensson <oed@consensys.net>
Type: Standard
Category: ERC
Status: Discussion
Created: 2017-11-29

Abstract

This text describes a proposal for an Ethereum Claims Registry (ECR) which allows persons, smart contracts, and machines to issue claims about each other, as well as self issued claims. The registry provides a flexible approach for claims that makes no distinction between different types of Ethereum accounts. The goal of the registry is to provide a central point of reference for on-chain claims on Ethereum.

Motivation

On-chain claims is becoming increasingly relevant as lots of different smart contracts might want to verify certain attributes about its users. However that is only one out of a very large space of use cases for on-chain claims. By providing a central repository for claims, developers are equipped with a common ground for experimentation. A standardized registry also makes claim lookup simple and gas efficient. Third party contracts only need to make one external call, no need for adding logic for verifying signatures, lookup identity signing keys, etc.

Specification

The ECR is a contract that is deployed once and can then be commonly used by everyone. Therefore it's important that the code of the registry has been reviewed by lots of people with different use cases in mind. The ECR provides an interface for adding, getting, and removing claims. Claims are issued from an issuer to a subject with a key, which is of type bytes32. The claims data is stored as type bytes32.

Claim types

The key parameter is used to indicate the type of claim that is being made. There are three ways that are encuraged for use in the ECR:

  • Standardised claim types use syntax borrowed from HTTP and do not start with X-. The key is the hash of the claim type (eg, keccak256('Owner-Address'))
  • Private types not intended for interchange use the same syntax, but with X- prefix. The key is the hash of the claim type (eg, keccak256('X-My-Thing'))
  • Ad-hoc types use 32 random bytes for the key, enabling allocation of new globally used keys without the need for standardisation first.

Standard claim types

New claim types can be added by making a PR to modify this table.

Claim type Description
ERC780Example This is an example

Registry specification

The ECR provides the following functions:

setClaim
Used by an issuer to set the claim value with the key about the subject.

function setClaim(address subject, bytes32 key, bytes32 value) public;

setSelfClaim
Convenience function for an issuer to set a claim about themself.

function setSelfClaim(bytes32 key, bytes32 value) public;

getClaim
Used by anyone to get a specific claim.

function getClaim(address issuer, address subject, bytes32 key) public constant returns(bytes32);

removeClaim
Used by an issuer to remove a claim it has made.

function removeClaim(address issuer, address subject, bytes32 key) public;

Type conversions

The value parameter was choosen to have the type bytes32. This in order to make the registry entries as general as possible while maintaining a very simple code base. However it is likely that usecases where other types such as address and uint etc. will emerge. Support for this can be added in various ways. We suggest that a library is implemented that can covert between various solidity types. This means that the registry itself keeps its simplicity. Contracts that need specific types can use such a library to convert the bytes32 into their desired type and back.

Deployment

After some discussion on the design of the registry contract it will be deployed and its address should be written in this document. This should include the addresses for the ropsten, rinkeby, and kovan testnets as well.

Updates and governance

In the future there might be new features needed in the registry. In order for such an event to be as transparent as possible the new features should be proposed and approved in a new EIP that contains the new contract code as well as a way of migrating any old claims if deemed necessary.

Appendix: Registry implementation

contract EthereumClaimsRegistry {

    mapping(address => mapping(address => mapping(bytes32 => bytes32))) public registry;

    event ClaimSet(
        address indexed issuer,
        address indexed subject,
        bytes32 indexed key,
        bytes32 value,
        uint updatedAt);

    event ClaimRemoved(
        address indexed issuer,
        address indexed subject,
        bytes32 indexed key,
        uint removedAt);

    // create or update clams
    function setClaim(address subject, bytes32 key, bytes32 value) public {
        registry[msg.sender][subject][key] = value;
        emit ClaimSet(msg.sender, subject, key, value, now);
    }

    function setSelfClaim(bytes32 key, bytes32 value) public {
        setClaim(msg.sender, key, value);
    }

    function getClaim(address issuer, address subject, bytes32 key) public view returns(bytes32) {
        return registry[issuer][subject][key];
    }

    function removeClaim(address issuer, address subject, bytes32 key) public {
        require(msg.sender == issuer);
        delete registry[issuer][subject][key];
        emit ClaimRemoved(msg.sender, subject, key, now);
    }
}
@alex-miller-0

This comment has been minimized.

Show comment
Hide comment
@alex-miller-0

alex-miller-0 Nov 29, 2017

I think the submitter's identity should be recovered from a v,,r,s signature rather than requiring msg.sender be the submitter. I can imagine a claim issuer who doesn't want to interact with Ethereum, but is happy to sign a message and pass that over http. It would be good if this signed claim could be submitted by any party.

alex-miller-0 commented Nov 29, 2017

I think the submitter's identity should be recovered from a v,,r,s signature rather than requiring msg.sender be the submitter. I can imagine a claim issuer who doesn't want to interact with Ethereum, but is happy to sign a message and pass that over http. It would be good if this signed claim could be submitted by any party.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Nov 29, 2017

@alex-miller-0 The main reason to use msg.sender is to benefit from ethereums signature abstractions. This allows users to implement other signature schemes in contracts and still be able to use the registry. By having the signature verification in the registry contract itself means that it becomes less future proof.

oed commented Nov 29, 2017

@alex-miller-0 The main reason to use msg.sender is to benefit from ethereums signature abstractions. This allows users to implement other signature schemes in contracts and still be able to use the registry. By having the signature verification in the registry contract itself means that it becomes less future proof.

@nmushegian

This comment has been minimized.

Show comment
Hide comment
@nmushegian

nmushegian Nov 29, 2017

Aww man I liked the KeyGraph and src,dst,key,val nomenclature. Good innovation with updatedAt though Edit: nvm looks like tau existed too

nmushegian commented Nov 29, 2017

Aww man I liked the KeyGraph and src,dst,key,val nomenclature. Good innovation with updatedAt though Edit: nvm looks like tau existed too

@nmushegian

This comment has been minimized.

Show comment
Hide comment
@nmushegian

nmushegian Nov 29, 2017

Here's a bunch of context for people just catching up: uport-project/uport-registry#24

nmushegian commented Nov 29, 2017

Here's a bunch of context for people just catching up: uport-project/uport-registry#24

@alex-miller-0

This comment has been minimized.

Show comment
Hide comment
@alex-miller-0

alex-miller-0 Nov 29, 2017

@oed That make sense, but it still gives me pause because this requires every claim issuer pay gas (maybe not in the future, but for now). Seems like you could still add something like setRemoteECDSAClaim(). Not pretty, but I do think there are use cases that will be blocked by the gas requirement.

In any event, great use of Ethereum overall 👍

alex-miller-0 commented Nov 29, 2017

@oed That make sense, but it still gives me pause because this requires every claim issuer pay gas (maybe not in the future, but for now). Seems like you could still add something like setRemoteECDSAClaim(). Not pretty, but I do think there are use cases that will be blocked by the gas requirement.

In any event, great use of Ethereum overall 👍

@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto Nov 30, 2017

@oed can you put some example use cases? For me this just look like a generic key value store contract and no specific functions to handle claim(such as validate Claim) but I may be wrong as I am not so sure what kind of usecase you have in mind.

makoto commented Nov 30, 2017

@oed can you put some example use cases? For me this just look like a generic key value store contract and no specific functions to handle claim(such as validate Claim) but I may be wrong as I am not so sure what kind of usecase you have in mind.

@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto commented Nov 30, 2017

A comment from Pelle on Reddit has more context and use cases https://www.reddit.com/r/ethereum/comments/7gewn7/erc_780_ethereum_claim_registry/

@lukehedger

This comment has been minimized.

Show comment
Hide comment
@lukehedger

lukehedger Nov 30, 2017

@oed - I'm not sure about this statement:

A standardized registry also makes claim lookup simple and gas efficient.

Say I want to look up all claims made by an issuer - I can't see that this is possible with the current contract and, although it could be added, it would be pretty inefficient. Also, if I want to look up all claims made about a subject - how could I do this?

Or is the model designed to be augmented by another form of storage that can be queried more easily, meaning the contract storage is used for arbitration?

lukehedger commented Nov 30, 2017

@oed - I'm not sure about this statement:

A standardized registry also makes claim lookup simple and gas efficient.

Say I want to look up all claims made by an issuer - I can't see that this is possible with the current contract and, although it could be added, it would be pretty inefficient. Also, if I want to look up all claims made about a subject - how could I do this?

Or is the model designed to be augmented by another form of storage that can be queried more easily, meaning the contract storage is used for arbitration?

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Nov 30, 2017

@nmushegian I know you do ;) But I think that issuer, subject makes more sense in the context of claims.

@alex-miller-0 setRemoteECDSAClaim() doesn't really solve the gas problem either right? Someone who is intrested in publishing the claims would still need to pay for the gas for that function call. Then they could just as easily pay for the creation of a thin proxy contract that only allows to send txs to the registry if signed by a specific key. This could also be made into a factory that (in the future) uses copyof for gas efficiency. New factories could then be made for new signature types.

@makoto It is very generic! The goal here is to create something that allows for any type of claim to be issued. As you saw @pelle mention on reddit, the first use case for uport is to store the public signing and encryption key of identities. But other usecases include:

  • User A claims that user B is a cool cat
  • Exchange C claims that user A is a verified member of tier 3
  • Contract D claims that user B has reputation X

The idea of a contract being able to make claims is very interesting. One could construct a contract that for example verifies a zero-knowledge proof and if it is correct issues a claim. So it should be possible to create a contract such that; if a subject has a claim issued by this contract, we can be sure that the subject is a European citizen without revealing which exact country, for example.

@lukehedger You are right, with this design you can't currently look up all the claims made by an issuer or to a subject from another contract. This can of course be done off-chain by querying the logs though. The reason we chose this design was that other contracts most likely will have to know the issuer, subject, and key anyway, since there might be hundreds of claims about a speciffic subect for example.
If there is a speciffic use case for what you are asking about you can of course augment it like you suggested. Good idea btw, had not thought of that :)

oed commented Nov 30, 2017

@nmushegian I know you do ;) But I think that issuer, subject makes more sense in the context of claims.

@alex-miller-0 setRemoteECDSAClaim() doesn't really solve the gas problem either right? Someone who is intrested in publishing the claims would still need to pay for the gas for that function call. Then they could just as easily pay for the creation of a thin proxy contract that only allows to send txs to the registry if signed by a specific key. This could also be made into a factory that (in the future) uses copyof for gas efficiency. New factories could then be made for new signature types.

@makoto It is very generic! The goal here is to create something that allows for any type of claim to be issued. As you saw @pelle mention on reddit, the first use case for uport is to store the public signing and encryption key of identities. But other usecases include:

  • User A claims that user B is a cool cat
  • Exchange C claims that user A is a verified member of tier 3
  • Contract D claims that user B has reputation X

The idea of a contract being able to make claims is very interesting. One could construct a contract that for example verifies a zero-knowledge proof and if it is correct issues a claim. So it should be possible to create a contract such that; if a subject has a claim issued by this contract, we can be sure that the subject is a European citizen without revealing which exact country, for example.

@lukehedger You are right, with this design you can't currently look up all the claims made by an issuer or to a subject from another contract. This can of course be done off-chain by querying the logs though. The reason we chose this design was that other contracts most likely will have to know the issuer, subject, and key anyway, since there might be hundreds of claims about a speciffic subect for example.
If there is a speciffic use case for what you are asking about you can of course augment it like you suggested. Good idea btw, had not thought of that :)

@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto Nov 30, 2017

@oed Thank you for the clarification.

Do you expect entire Ethereum universe to put their claims into one contract (like ENS Registry contract), or each project (eg: uPort, Gnosis, MelonPort) to have their own repository like ERC20 does for their tokens?

makoto commented Nov 30, 2017

@oed Thank you for the clarification.

Do you expect entire Ethereum universe to put their claims into one contract (like ENS Registry contract), or each project (eg: uPort, Gnosis, MelonPort) to have their own repository like ERC20 does for their tokens?

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Nov 30, 2017

@makoto This would be more similar to ENS where there is one central registry contract, rather then ERC20 which is just an interface. The reason for this is that the contract code itself has to be verified. In the case of ERC20 you just need to have the same interface.

oed commented Nov 30, 2017

@makoto This would be more similar to ENS where there is one central registry contract, rather then ERC20 which is just an interface. The reason for this is that the contract code itself has to be verified. In the case of ERC20 you just need to have the same interface.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Nov 30, 2017

Collaborator
  • Can you give example use-cases? What will this be used for?
  • Why use bytes32 for key and value, instead of bytes?
  • It'd be a good idea to follow the lead of other standards, and reserve keys starting with x- as nonstandardised ones, while requiring a standards process for non-prefixed keys, to avoid namespace collisions.
Collaborator

Arachnid commented Nov 30, 2017

  • Can you give example use-cases? What will this be used for?
  • Why use bytes32 for key and value, instead of bytes?
  • It'd be a good idea to follow the lead of other standards, and reserve keys starting with x- as nonstandardised ones, while requiring a standards process for non-prefixed keys, to avoid namespace collisions.
@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto Nov 30, 2017

Should EthereumClaimRegistry be EthereumClaimsRegistry(plural)?

makoto commented Nov 30, 2017

Should EthereumClaimRegistry be EthereumClaimsRegistry(plural)?

@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto Nov 30, 2017

If the function name is setClaim the event name should be ClaimSet rather than ClaimAdded ?

makoto commented Nov 30, 2017

If the function name is setClaim the event name should be ClaimSet rather than ClaimAdded ?

@makoto

This comment has been minimized.

Show comment
Hide comment
@makoto

makoto Nov 30, 2017

In terms of use case, I have something similar which could potentially replace with this Claims registry

https://github.com/makoto/blockparty/blob/master/contracts/InvitationRepository.sol

The above contract manages a set of a unique code which I use to invite a participant to register my event management smart contract (more detail is at http://www.noblockno.party).

I once thought about replacing it with ENS and I gave up because ENS value only allows certain set of record type (eth address, ABI, etc). https://docs.ens.domains/en/latest/implementers.html#writing-a-resolver

The ClaimRegistry is better suited because both key and value can be anything (in fact you don't really need subject because you can namespace as part of a key just like you use Redis DB).

The big question is what is the benefit of mixing my party invitation data with Uport attestation data which are remotely related under the same contract?

in case of ENS, the more dapp/wallet and exchange implement ENS interface, it allows everybody to lookup naming service in consistent manner. In case of ClaimRegistry I am not sure what benefit brings.

The alternative solution could be to propose more generic ENS record type which Uport can make use of.

makoto commented Nov 30, 2017

In terms of use case, I have something similar which could potentially replace with this Claims registry

https://github.com/makoto/blockparty/blob/master/contracts/InvitationRepository.sol

The above contract manages a set of a unique code which I use to invite a participant to register my event management smart contract (more detail is at http://www.noblockno.party).

I once thought about replacing it with ENS and I gave up because ENS value only allows certain set of record type (eth address, ABI, etc). https://docs.ens.domains/en/latest/implementers.html#writing-a-resolver

The ClaimRegistry is better suited because both key and value can be anything (in fact you don't really need subject because you can namespace as part of a key just like you use Redis DB).

The big question is what is the benefit of mixing my party invitation data with Uport attestation data which are remotely related under the same contract?

in case of ENS, the more dapp/wallet and exchange implement ENS interface, it allows everybody to lookup naming service in consistent manner. In case of ClaimRegistry I am not sure what benefit brings.

The alternative solution could be to propose more generic ENS record type which Uport can make use of.

@alex-miller-0

This comment has been minimized.

Show comment
Hide comment
@alex-miller-0

alex-miller-0 Dec 1, 2017

@oed My ECDSACall would solve the gas problem because someone else could submit a signed message. But you're right - this functionality could be abstracted to a second layer contract.

@Arachnid I like the use of bytes32 rather than bytes because it keeps people from storing arbitrary data on-chain; obviously these would be hashes to the actual information you are referencing. There are also advantages to having a consistently sized key/value pair from a parsing perspective.

One immediate use I can think of is providing a hash of customer balances at a given timestamp that can later be verified by an auditor. This could be a hash of some data dump, a database itself, or a blockchain.

Another use could be for identity - someone could submit a claim that I purchased insurance for my car for 6 months. This information is persisted to their system and can be verified based on some lookup schema in this immutable key-value store. Once my insurance expires, they can revoke that claim.

alex-miller-0 commented Dec 1, 2017

@oed My ECDSACall would solve the gas problem because someone else could submit a signed message. But you're right - this functionality could be abstracted to a second layer contract.

@Arachnid I like the use of bytes32 rather than bytes because it keeps people from storing arbitrary data on-chain; obviously these would be hashes to the actual information you are referencing. There are also advantages to having a consistently sized key/value pair from a parsing perspective.

One immediate use I can think of is providing a hash of customer balances at a given timestamp that can later be verified by an auditor. This could be a hash of some data dump, a database itself, or a blockchain.

Another use could be for identity - someone could submit a claim that I purchased insurance for my car for 6 months. This information is persisted to their system and can be verified based on some lookup schema in this immutable key-value store. Once my insurance expires, they can revoke that claim.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Dec 4, 2017

@Arachnid

Can you give example use-cases? What will this be used for?

Right now uport uses a similar contract to store public keys of users as a simple PKI. Other than that we will use it for storing claims that needs to be read and verified by smart contracts. It could also potentially be used to revoke off-chain claims.

Why use bytes32 for key and value, instead of bytes?

This was my initial thought, but it seems like retriving a claim couldn't be done by another contract then. Atleast with the current solidity version. For example, this does not compile. Am I doing something wrong here?

It'd be a good idea to follow the lead of other standards, and reserve keys starting with x- as nonstandardised ones, while requiring a standards process for non-prefixed keys, to avoid namespace collisions.

Sounds resonable.

@makoto

If the function name is setClaim the event name should be ClaimSet rather than ClaimAdded ?

Good point, updating the example code :)

oed commented Dec 4, 2017

@Arachnid

Can you give example use-cases? What will this be used for?

Right now uport uses a similar contract to store public keys of users as a simple PKI. Other than that we will use it for storing claims that needs to be read and verified by smart contracts. It could also potentially be used to revoke off-chain claims.

Why use bytes32 for key and value, instead of bytes?

This was my initial thought, but it seems like retriving a claim couldn't be done by another contract then. Atleast with the current solidity version. For example, this does not compile. Am I doing something wrong here?

It'd be a good idea to follow the lead of other standards, and reserve keys starting with x- as nonstandardised ones, while requiring a standards process for non-prefixed keys, to avoid namespace collisions.

Sounds resonable.

@makoto

If the function name is setClaim the event name should be ClaimSet rather than ClaimAdded ?

Good point, updating the example code :)

@devinrsmith

This comment has been minimized.

Show comment
Hide comment
@devinrsmith

devinrsmith Dec 4, 2017

I might suggest another function,

function removeClaim(address issuer, address subject, bytes32 key, bytes32 value) public constant returns(bytes32);

such that the claim is removed iff the passed in value is also equal.

I might also consider returning the previous value on setClaim and the proposed removeClaim.

devinrsmith commented Dec 4, 2017

I might suggest another function,

function removeClaim(address issuer, address subject, bytes32 key, bytes32 value) public constant returns(bytes32);

such that the claim is removed iff the passed in value is also equal.

I might also consider returning the previous value on setClaim and the proposed removeClaim.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Dec 4, 2017

@devinrsmith What would be the usecase for those additions? (I don't have any strong feelings either way)

oed commented Dec 4, 2017

@devinrsmith What would be the usecase for those additions? (I don't have any strong feelings either way)

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Dec 5, 2017

Added a function called setSelfClaim which allows the caller to not have to specify the subject. Instead msg.sender is used.
This is useful if you want to set a claim with a proxy contract which is also created in the same call, so you don't know the address beforehand.

oed commented Dec 5, 2017

Added a function called setSelfClaim which allows the caller to not have to specify the subject. Instead msg.sender is used.
This is useful if you want to set a claim with a proxy contract which is also created in the same call, so you don't know the address beforehand.

@machinae

This comment has been minimized.

Show comment
Hide comment
@machinae

machinae Dec 5, 2017

What is the reason for only allowing an issuer to set a claim, but either the issuer or the subject to remove a claim? It seems inconsistent and could lead to potential unexpected outcomes.

For example, there was discussion on reddit about registering a claim that a particular address is malicious. You would not want to enable that malicious contract to unilaterally remove claims about itself.

machinae commented Dec 5, 2017

What is the reason for only allowing an issuer to set a claim, but either the issuer or the subject to remove a claim? It seems inconsistent and could lead to potential unexpected outcomes.

For example, there was discussion on reddit about registering a claim that a particular address is malicious. You would not want to enable that malicious contract to unilaterally remove claims about itself.

@ukstv

This comment has been minimized.

Show comment
Hide comment
@ukstv

ukstv Dec 5, 2017

@machinae Flagging an address as malicious contradicts the very notion of Self-Sovereign Identity, and claims logic. For SSI to work a claim has to be made that the address is safe according to the party.

I bet claim removal is for an erroneous claim only.

ukstv commented Dec 5, 2017

@machinae Flagging an address as malicious contradicts the very notion of Self-Sovereign Identity, and claims logic. For SSI to work a claim has to be made that the address is safe according to the party.

I bet claim removal is for an erroneous claim only.

@machinae

This comment has been minimized.

Show comment
Hide comment
@machinae

machinae Dec 5, 2017

@ukstv That makes sense, thanks for explaining. In other words, claims could be made by issuers to whitelist the subject, but not blacklist.

@oed should this proposal include any mechanism for attestation/third party validation of claims, or is that out of scope?

machinae commented Dec 5, 2017

@ukstv That makes sense, thanks for explaining. In other words, claims could be made by issuers to whitelist the subject, but not blacklist.

@oed should this proposal include any mechanism for attestation/third party validation of claims, or is that out of scope?

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Dec 5, 2017

@machinae Can you elaborate? Since msg.sender is used the signatures are verified by ethereum. What kind of validation are you talking about?

oed commented Dec 5, 2017

@machinae Can you elaborate? Since msg.sender is used the signatures are verified by ethereum. What kind of validation are you talking about?

@machinae

This comment has been minimized.

Show comment
Hide comment
@machinae

machinae Dec 5, 2017

@oed I mean more like proof of off-chain validation of the substance of the claim itself.
Sticking with the self-sovereign identity theme, if I submit a claim that my date of birth is 01-01-1970, msg.sender lets you prove that I am the one who issued that claim, but not that the claim itself is true. You would need a trusted third party that can check my DOB off chain to attest to the validity of the claim.

A simple idea for an implementation would be adding a third entity, validator , that would attest to the validity of claims using off-chain data.

So you might have something like

function attestClaim(address issuer, address subject, bytes32 key, address validator) public;

which would record that a particular validator entity has attested that claim is valid.
This could fire off an event ClaimAttested similar to the other events in the proposal.

The idea being that anyone can self-issue claims, and those claims can be confirmed by multiple entities, increasing decentralization and confidence that the claim is proven. Think of it as almost a multisig scenario for claims, where n attestations might be required.

validator in this case could be a government entity, employer, exchange, another smart contract, etc.

machinae commented Dec 5, 2017

@oed I mean more like proof of off-chain validation of the substance of the claim itself.
Sticking with the self-sovereign identity theme, if I submit a claim that my date of birth is 01-01-1970, msg.sender lets you prove that I am the one who issued that claim, but not that the claim itself is true. You would need a trusted third party that can check my DOB off chain to attest to the validity of the claim.

A simple idea for an implementation would be adding a third entity, validator , that would attest to the validity of claims using off-chain data.

So you might have something like

function attestClaim(address issuer, address subject, bytes32 key, address validator) public;

which would record that a particular validator entity has attested that claim is valid.
This could fire off an event ClaimAttested similar to the other events in the proposal.

The idea being that anyone can self-issue claims, and those claims can be confirmed by multiple entities, increasing decentralization and confidence that the claim is proven. Think of it as almost a multisig scenario for claims, where n attestations might be required.

validator in this case could be a government entity, employer, exchange, another smart contract, etc.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Dec 5, 2017

@machinae this could be done now by the "validator" calling setClaim with the same data as you (or anyone else) did.

oed commented Dec 5, 2017

@machinae this could be done now by the "validator" calling setClaim with the same data as you (or anyone else) did.

@christianlundkvist

This comment has been minimized.

Show comment
Hide comment
@christianlundkvist

christianlundkvist Dec 9, 2017

@machinae

proof of validation of substance of claim
One goal of this kind of spec is to add credibility to claims by letting specific parties validate the claims. If my neighbor claims I have a degree from Harvard that might not mean much, but if Harvard themselves have an identity then they can issue the attestation claiming I have a degree from there, and this would be basically a proof of the substance of the claim.

If the claim is date of birth, then a claim from a local government that this is my date of birth is a good validation. The best would be a claim by the physician that actually delivered me as a baby that I was born. My birthday would then by definition be the time stamp of that claim.

christianlundkvist commented Dec 9, 2017

@machinae

proof of validation of substance of claim
One goal of this kind of spec is to add credibility to claims by letting specific parties validate the claims. If my neighbor claims I have a degree from Harvard that might not mean much, but if Harvard themselves have an identity then they can issue the attestation claiming I have a degree from there, and this would be basically a proof of the substance of the claim.

If the claim is date of birth, then a claim from a local government that this is my date of birth is a good validation. The best would be a claim by the physician that actually delivered me as a baby that I was born. My birthday would then by definition be the time stamp of that claim.

@ajunge

This comment has been minimized.

Show comment
Hide comment
@FBrinkkemper

This comment has been minimized.

Show comment
Hide comment
@FBrinkkemper

FBrinkkemper Jan 26, 2018

I have been following and reading the various ERC discussions for identity standards, and thanks to the above linked article decided to join the discussion.

An obvious use-case for this, that is being worked on by many already, is a registry for academic degrees. I am currently in the final stage of my master thesis around this subject, and have used the implementation of this standard for a Proof of Concept.

In this PoC, the claims are used as follows:
issuer = Ethereum address/Identity smart contract of University X
subject = Ethereum address/Identity smart contract of Alumni of university X
key = location of "keys" JSON file of University X (for example UniversityX.com/keys
value = Degree title (MSc/BSc + abbreviation used by University X of the study (e.g. BA for Business Administration)) + a context hash.

This context hash is the merkle root of a set of certificates that follow the Blockcerts standard (blockcerts.org/). Each leaf in the merkle tree is a certificate that represents a single verifiable claim issued by the University (e.g. leaf 1: grade A for course X, leaf 2: Grade A- for course Y. etc). These blockcerts are bundled together and send to the alumni off-chain. The alumni has an app that can be used for selective disclosure of these leafs.

Overall, great work. Personally, I believe that verifiable claims in all sorts of use cases /variations will be the "killer-app" for enterprises implementing blockchain.

FBrinkkemper commented Jan 26, 2018

I have been following and reading the various ERC discussions for identity standards, and thanks to the above linked article decided to join the discussion.

An obvious use-case for this, that is being worked on by many already, is a registry for academic degrees. I am currently in the final stage of my master thesis around this subject, and have used the implementation of this standard for a Proof of Concept.

In this PoC, the claims are used as follows:
issuer = Ethereum address/Identity smart contract of University X
subject = Ethereum address/Identity smart contract of Alumni of university X
key = location of "keys" JSON file of University X (for example UniversityX.com/keys
value = Degree title (MSc/BSc + abbreviation used by University X of the study (e.g. BA for Business Administration)) + a context hash.

This context hash is the merkle root of a set of certificates that follow the Blockcerts standard (blockcerts.org/). Each leaf in the merkle tree is a certificate that represents a single verifiable claim issued by the University (e.g. leaf 1: grade A for course X, leaf 2: Grade A- for course Y. etc). These blockcerts are bundled together and send to the alumni off-chain. The alumni has an app that can be used for selective disclosure of these leafs.

Overall, great work. Personally, I believe that verifiable claims in all sorts of use cases /variations will be the "killer-app" for enterprises implementing blockchain.

@Janther

This comment has been minimized.

Show comment
Hide comment
@Janther

Janther Mar 20, 2018

@jbaylina I like your idea but, when implementing it, you need to remember also that the subject is by definition the sovereign over its own identity and therefore should be able to delete the whole history of a claim.
Another thing.
According to this article binary search starts being noticeably better after the array has a length of 64, I see a transaction history of a token growing way past 64 transactions, but in identity, I don't see a claim changing that much over time.
Maybe I'm wrong.
Any thoughts?

Janther commented Mar 20, 2018

@jbaylina I like your idea but, when implementing it, you need to remember also that the subject is by definition the sovereign over its own identity and therefore should be able to delete the whole history of a claim.
Another thing.
According to this article binary search starts being noticeably better after the array has a length of 64, I see a transaction history of a token growing way past 64 transactions, but in identity, I don't see a claim changing that much over time.
Maybe I'm wrong.
Any thoughts?

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Mar 20, 2018

I would suggest using the same deployment method as #820. This method allows to have a single address in all networks.

@jbaylina will definately be doing this, super cool.

It'd also be good to define a format for claim keys so people don't collide - maybe one prefix for keys registered in an EIP, and another for ad-hoc ones

@Arachnid Yes I think that is a good idea. Sorry for not picking up on your comment regarding this earlier. Do you think it's best to do one prefix for registered and one for ad-hoc, or just have x- as you mentioned before? I'm thinking just going with x- is probably the easiest.

One thing that is worth noting here is that the key can specify what format of the value is. An example that we use is uPortProfileIPFS1220. In this case the key specify that we use ipfs and which hash function (from multihash) we use, since the entire multihash won't fin in bytes32. So it would make sense if I register uPortProfile then I'm allowed to use any key which starts with that.

oed commented Mar 20, 2018

I would suggest using the same deployment method as #820. This method allows to have a single address in all networks.

@jbaylina will definately be doing this, super cool.

It'd also be good to define a format for claim keys so people don't collide - maybe one prefix for keys registered in an EIP, and another for ad-hoc ones

@Arachnid Yes I think that is a good idea. Sorry for not picking up on your comment regarding this earlier. Do you think it's best to do one prefix for registered and one for ad-hoc, or just have x- as you mentioned before? I'm thinking just going with x- is probably the easiest.

One thing that is worth noting here is that the key can specify what format of the value is. An example that we use is uPortProfileIPFS1220. In this case the key specify that we use ipfs and which hash function (from multihash) we use, since the entire multihash won't fin in bytes32. So it would make sense if I register uPortProfile then I'm allowed to use any key which starts with that.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Mar 20, 2018

Collaborator

@oed Yes I think that is a good idea. Sorry for not picking up on your comment regarding this earlier. Do you think it's best to do one prefix for registered and one for ad-hoc, or just have x- as you mentioned before? I'm thinking just going with x- is probably the easiest.

I would suggest the following (or any subset thereof):

  • Standardised claim types use syntax borrowed from HTTP and do not start with X-. The key is the hash of the claim type (eg, keccak256('Owner-Address'))
  • Private types not intended for interchange use the same syntax, but with X- prefix. The key is the hash of the claim type (eg, keccak256('X-My-Thing'))
  • Ad-hoc types use 32 random bytes for the key, enabling allocation of new globally used keys without the need for standardisation first.
Collaborator

Arachnid commented Mar 20, 2018

@oed Yes I think that is a good idea. Sorry for not picking up on your comment regarding this earlier. Do you think it's best to do one prefix for registered and one for ad-hoc, or just have x- as you mentioned before? I'm thinking just going with x- is probably the easiest.

I would suggest the following (or any subset thereof):

  • Standardised claim types use syntax borrowed from HTTP and do not start with X-. The key is the hash of the claim type (eg, keccak256('Owner-Address'))
  • Private types not intended for interchange use the same syntax, but with X- prefix. The key is the hash of the claim type (eg, keccak256('X-My-Thing'))
  • Ad-hoc types use 32 random bytes for the key, enabling allocation of new globally used keys without the need for standardisation first.
@wagner-daniel

This comment has been minimized.

Show comment
Hide comment
@wagner-daniel

wagner-daniel Mar 22, 2018

What do you think about approving claims by others? E.g. Person A issues a claim. Person B can approve the claim is correct. Person C who only trusts Person B can look up that Person B approved the claim from Person A.

With the current implementation this can be achieved by Person B issuing the same claim as Person A.

Can you think of any scenario where Person A and Person B issue a claim with the same key but different values? Then the approval is not possible.

wagner-daniel commented Mar 22, 2018

What do you think about approving claims by others? E.g. Person A issues a claim. Person B can approve the claim is correct. Person C who only trusts Person B can look up that Person B approved the claim from Person A.

With the current implementation this can be achieved by Person B issuing the same claim as Person A.

Can you think of any scenario where Person A and Person B issue a claim with the same key but different values? Then the approval is not possible.

@Janther

This comment has been minimized.

Show comment
Hide comment
@Janther

Janther Mar 27, 2018

by setting every call to external you will save some gas per transaction but that would mean that setSelfClaim would need to be changed to avoid making an internal call to setClaim:

function setSelfClaim(bytes32 key, bytes32 value) external {
    registry[msg.sender][msg.sender][key] = value;
    ClaimSet(msg.sender, msg.sender, key, value, now);
}

Janther commented Mar 27, 2018

by setting every call to external you will save some gas per transaction but that would mean that setSelfClaim would need to be changed to avoid making an internal call to setClaim:

function setSelfClaim(bytes32 key, bytes32 value) external {
    registry[msg.sender][msg.sender][key] = value;
    ClaimSet(msg.sender, msg.sender, key, value, now);
}
@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Apr 3, 2018

@Arachnid
Thanks, I think that sounds good. One question: Why would anyone use an Ad-hoc type over a Private type? Nothing prevents multiple parties to use the same private one together.

@Janther
How much gas would be saved with that? The solidity documentation says External functions are sometimes more efficient when they receive large arrays of data. We don't have any arrays here.

oed commented Apr 3, 2018

@Arachnid
Thanks, I think that sounds good. One question: Why would anyone use an Ad-hoc type over a Private type? Nothing prevents multiple parties to use the same private one together.

@Janther
How much gas would be saved with that? The solidity documentation says External functions are sometimes more efficient when they receive large arrays of data. We don't have any arrays here.

@Janther

This comment has been minimized.

Show comment
Hide comment
@Janther

Janther Apr 5, 2018

@oed Must have done something wrong when I tested last time (I had seen some gas difference).

I did a full test just now on remix and there is no difference in gas usage.

There is a small win (40 gas without optimization and 59 gas with optimization) when implementing the setSelfClaim instead of doing an internal call. The deployment is more expensive though.

Janther commented Apr 5, 2018

@oed Must have done something wrong when I tested last time (I had seen some gas difference).

I did a full test just now on remix and there is no difference in gas usage.

There is a small win (40 gas without optimization and 59 gas with optimization) when implementing the setSelfClaim instead of doing an internal call. The deployment is more expensive though.

@dwking2000

This comment has been minimized.

Show comment
Hide comment
@dwking2000

dwking2000 Apr 6, 2018

Allowing the subject of a claim to call removeClaim seems to invite censorship. If I claim something about a subject I don't want the subject of my claim to remove it. The claim about a subject should stand on its own and carry the weight the issuer's reputation however weak or strong. A claim should be something others can attest to as well, strengthening the claim. An attestation is just a claim about a claim. This allows a claim to be assessed as to its validity by third parties that interpret the validity based on their own metrics (multiple attestations, age of claim, trust graph of attesters, etc.).

Self sovereignty still works without allowing a subject to remove a claim. If a subject wants to make a claim stronger they only need to attest to it. Claims not attested to by the subject would indicate the subject does not approve of or does not care. If a subject does not agree with a claim they can even attest to a counter claim that points to the original claim. This keeps the subject in control without allowing for censorship.

I feel strongly that removeClaim should be allowed by the claim issuer only and the subject should use other means to attest, validate and expose the claims they agree with.

dwking2000 commented Apr 6, 2018

Allowing the subject of a claim to call removeClaim seems to invite censorship. If I claim something about a subject I don't want the subject of my claim to remove it. The claim about a subject should stand on its own and carry the weight the issuer's reputation however weak or strong. A claim should be something others can attest to as well, strengthening the claim. An attestation is just a claim about a claim. This allows a claim to be assessed as to its validity by third parties that interpret the validity based on their own metrics (multiple attestations, age of claim, trust graph of attesters, etc.).

Self sovereignty still works without allowing a subject to remove a claim. If a subject wants to make a claim stronger they only need to attest to it. Claims not attested to by the subject would indicate the subject does not approve of or does not care. If a subject does not agree with a claim they can even attest to a counter claim that points to the original claim. This keeps the subject in control without allowing for censorship.

I feel strongly that removeClaim should be allowed by the claim issuer only and the subject should use other means to attest, validate and expose the claims they agree with.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed Apr 17, 2018

@dwking2000 I don't really have a strong opinion either way anymore. However I think for many use cases though there will be issuers that are trusted so it wouldn't matter if the subject issued a counter claim.
However I think my major concern is the "Right to be forgotten" law in the EU. I know that the claim is still retreivable through the logs, but it seems less troublesome.

oed commented Apr 17, 2018

@dwking2000 I don't really have a strong opinion either way anymore. However I think for many use cases though there will be issuers that are trusted so it wouldn't matter if the subject issued a counter claim.
However I think my major concern is the "Right to be forgotten" law in the EU. I know that the claim is still retreivable through the logs, but it seems less troublesome.

@dwking2000

This comment has been minimized.

Show comment
Hide comment
@dwking2000

dwking2000 Apr 22, 2018

@oed "Right to be forgotten" laws are complex and beyond the scope of the EIP so we should probably leave compliance of data removal to the implementor. Anyone opting into a blockchain claims system should either waive their rights to removal of data or agree to storage of claims in some mutable data store (off chain). Allowing the subject to 'remove' only self-claims might be useful and allows for schemes where the subject receives a request to self-claim the data in the request and then the requesting party would add attestations 'verifying' the self-claim as correct or true. In this case the subject would be able to remove the self-claim at some point making future attestations against it impossible, but "because blockchain", any previous claim and attestation data would still be readable. Other solutions preserve sovereignty might involve zero knowledge proofs or proxy re-encryption (such as proposed by the NuCypher project).

dwking2000 commented Apr 22, 2018

@oed "Right to be forgotten" laws are complex and beyond the scope of the EIP so we should probably leave compliance of data removal to the implementor. Anyone opting into a blockchain claims system should either waive their rights to removal of data or agree to storage of claims in some mutable data store (off chain). Allowing the subject to 'remove' only self-claims might be useful and allows for schemes where the subject receives a request to self-claim the data in the request and then the requesting party would add attestations 'verifying' the self-claim as correct or true. In this case the subject would be able to remove the self-claim at some point making future attestations against it impossible, but "because blockchain", any previous claim and attestation data would still be readable. Other solutions preserve sovereignty might involve zero knowledge proofs or proxy re-encryption (such as proposed by the NuCypher project).

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed May 3, 2018

@dwking2000 Thanks for your input. I'll go ahead and remove the ability for subject if no one else have strong feelings for it being kept there.

oed commented May 3, 2018

@dwking2000 Thanks for your input. I'll go ahead and remove the ability for subject if no one else have strong feelings for it being kept there.

@oed

This comment has been minimized.

Show comment
Hide comment
@oed

oed May 4, 2018

Made some updates to the proposal:

  • Claims can now only be revoked by the issuer, as per suggestion by @dwking2000
  • Claim types are now standardizable, as per suggestion by @Arachnid
  • Claims can be added with raw signatures, as per suggestion by @alex-miller-0

oed commented May 4, 2018

Made some updates to the proposal:

  • Claims can now only be revoked by the issuer, as per suggestion by @dwking2000
  • Claim types are now standardizable, as per suggestion by @Arachnid
  • Claims can be added with raw signatures, as per suggestion by @alex-miller-0
@davux

This comment has been minimized.

Show comment
Hide comment
@davux

davux May 14, 2018

@dwking2000, @oed. I think this kind of policy discussion (e.g. "whom do we allow to remove a negative claim?") cannot have a definite and consensual answer.

This kind of dilemma arises from the fact of having a central contract in the first place, which is why I'm very dubious about this EIP's approach.

One possible way I'm thinking of (but there are probably more clever ones) to resolve this centralisation problem would be to have spawnable registries -- with varying policies -- and a signaling method to point to them from self-sovereign contracts.

davux commented May 14, 2018

@dwking2000, @oed. I think this kind of policy discussion (e.g. "whom do we allow to remove a negative claim?") cannot have a definite and consensual answer.

This kind of dilemma arises from the fact of having a central contract in the first place, which is why I'm very dubious about this EIP's approach.

One possible way I'm thinking of (but there are probably more clever ones) to resolve this centralisation problem would be to have spawnable registries -- with varying policies -- and a signaling method to point to them from self-sovereign contracts.

@kern

This comment has been minimized.

Show comment
Hide comment
@kern

kern May 14, 2018

hey @davux @dwking2000 @oed, also have been thinking about the removal of negative claims and other challenges of a central registry contract. These issues seem like something that justifies multiple registry instances. Also unsure about the UX of squashing all claim data into a bytes32 key/val mapping. A richer claims interface might be possible with a federated registry approach. Would love to know your thoughts—have been putting together a prototype of sorts! :)

kern commented May 14, 2018

hey @davux @dwking2000 @oed, also have been thinking about the removal of negative claims and other challenges of a central registry contract. These issues seem like something that justifies multiple registry instances. Also unsure about the UX of squashing all claim data into a bytes32 key/val mapping. A richer claims interface might be possible with a federated registry approach. Would love to know your thoughts—have been putting together a prototype of sorts! :)

@dwking2000

This comment has been minimized.

Show comment
Hide comment
@dwking2000

dwking2000 May 16, 2018

@davux @kern @oed I should be able to make a claim and not have it censored (removed). This is already enforced by the blockchain, so in some respects removing a claim is a moot point except to save space and computation (gas). There is a need to signal a claim is not longer valid according to some criteria. UIs or other contracts can filter or derive meaning (reputation) from that. Given that, I can conceptualize several types of registries.

  1. a 'centralized' canonical registry that should not be censored or curated, e.g. ENS
  2. a curated registry that is intended to be 'censored', e.g. a TCR
  3. a personal (sovereign) registry that only I can censor, e.g. a self claims registry
  4. linked registries, or registries with linked claims that make claims about other registries or claims

I assume the sovereign registry will be curated by the sovereign entity, and that a canonical registry can in effect be curated by linking claims (attesting to validity or status of existing claims)

The power of linked registries or linked claims is where I see solutions that are interesting. I should be able to make a sovereign claim (which I can revoke at a later date) and expose that for others to attest to. In many cases this self claim would be a request from some other entity that needs to attest to the claim. For example, you send me a claim such as 'IsMember 42 of the l33th4x0r club' requesting I enter it into my sovereign claim registry. You then attest to it as the authority. If I don't pay my dues you remove the IsMember claim in your curated club registry that links to my claim. As the club curator your registry is the authority on the membership status but to be truly believable it would require my acceptance first via the self-claim. I can also imagine linked claims being made that are encrypted but verifiable by specific parties. This allows for 'opt in' claims and gives individuals the ability to expose and self-censor. Further, I can see individuals setting up policies that auto-accept certain types of claim requests or claim requests from whitelisted entities.

I think the problem we are struggling with is the concept of a single central canonical registry when it could be an ecosystem of registries and claims that attest to other claims building out trust graphs.

dwking2000 commented May 16, 2018

@davux @kern @oed I should be able to make a claim and not have it censored (removed). This is already enforced by the blockchain, so in some respects removing a claim is a moot point except to save space and computation (gas). There is a need to signal a claim is not longer valid according to some criteria. UIs or other contracts can filter or derive meaning (reputation) from that. Given that, I can conceptualize several types of registries.

  1. a 'centralized' canonical registry that should not be censored or curated, e.g. ENS
  2. a curated registry that is intended to be 'censored', e.g. a TCR
  3. a personal (sovereign) registry that only I can censor, e.g. a self claims registry
  4. linked registries, or registries with linked claims that make claims about other registries or claims

I assume the sovereign registry will be curated by the sovereign entity, and that a canonical registry can in effect be curated by linking claims (attesting to validity or status of existing claims)

The power of linked registries or linked claims is where I see solutions that are interesting. I should be able to make a sovereign claim (which I can revoke at a later date) and expose that for others to attest to. In many cases this self claim would be a request from some other entity that needs to attest to the claim. For example, you send me a claim such as 'IsMember 42 of the l33th4x0r club' requesting I enter it into my sovereign claim registry. You then attest to it as the authority. If I don't pay my dues you remove the IsMember claim in your curated club registry that links to my claim. As the club curator your registry is the authority on the membership status but to be truly believable it would require my acceptance first via the self-claim. I can also imagine linked claims being made that are encrypted but verifiable by specific parties. This allows for 'opt in' claims and gives individuals the ability to expose and self-censor. Further, I can see individuals setting up policies that auto-accept certain types of claim requests or claim requests from whitelisted entities.

I think the problem we are struggling with is the concept of a single central canonical registry when it could be an ecosystem of registries and claims that attest to other claims building out trust graphs.

@phahulin

This comment has been minimized.

Show comment
Hide comment
@phahulin

phahulin May 21, 2018

@oed description for removeClaim still mentions that subject can remove a claim about self, while in implementation code it's no longer possible.

phahulin commented May 21, 2018

@oed description for removeClaim still mentions that subject can remove a claim about self, while in implementation code it's no longer possible.

@phahulin phahulin referenced this issue May 21, 2018

Closed

(Refactor) Apply updates of ERC780 #133

5 of 5 tasks complete
@colourful-land

This comment has been minimized.

Show comment
Hide comment
@colourful-land

colourful-land Aug 20, 2018

Being an open registry, the data set (key, value), workflow (claim pending, claim issued, expiration, replacement, update, revocation), semantics† wasn't defined yet. This clarity affects the value of the registry, akin to ftp not being as valued as a SQL interface. At the minimum, do you consider adding expiry? I would argue that the use-cases not depending on claim's expiry is not many.

To provide clarity multiple features are needed. e.g. localised (translated) value, set of values (telephoneNumber can be more than one), set of attributes (e.g. my authentication key, my encryption key as a combined set). Hashed value (instead of actual string value in value parameter), the type of hash (if keyed hash to counter preimage attack, how to generate the key etc) etc.

In most case, an event of claim resulted in at least 2 attributes - the pubkey/address the claim is associated with, plus one attribute for each claim statement. These expire together, gets revoked together. That is, in most cases, a claim is not a key-value pair but a dictionary.

† Speaking of semantic, say, the key being "ecdsa pub key" and the value being a public key. What does that mean? There are 2 typical notions: "the subject has, among others, this key"; "the subject is identified by this key". But other cases exist: "I propose the subject has the key (apply for a claim)"; "I know the subject has the key (testify a claim)"; "I recognise the subject has the key (providing context)" etc. If you think I am making the problem look bigger than it really is, compare it to TLS's CSR/DV/OV/EV differences.

Regarding the use of HTTP header style - how do you consider the good old X.509 object identifier? After all thousands of attributes and their meaning is defined on a semantic level. e.g. there is no address but rather country, state, locality, street, buildingNumber etc. Rather well defined with the long-term consistency in mind since signed X.509 data can't be changed. (That is true even before blockchain.)

colourful-land commented Aug 20, 2018

Being an open registry, the data set (key, value), workflow (claim pending, claim issued, expiration, replacement, update, revocation), semantics† wasn't defined yet. This clarity affects the value of the registry, akin to ftp not being as valued as a SQL interface. At the minimum, do you consider adding expiry? I would argue that the use-cases not depending on claim's expiry is not many.

To provide clarity multiple features are needed. e.g. localised (translated) value, set of values (telephoneNumber can be more than one), set of attributes (e.g. my authentication key, my encryption key as a combined set). Hashed value (instead of actual string value in value parameter), the type of hash (if keyed hash to counter preimage attack, how to generate the key etc) etc.

In most case, an event of claim resulted in at least 2 attributes - the pubkey/address the claim is associated with, plus one attribute for each claim statement. These expire together, gets revoked together. That is, in most cases, a claim is not a key-value pair but a dictionary.

† Speaking of semantic, say, the key being "ecdsa pub key" and the value being a public key. What does that mean? There are 2 typical notions: "the subject has, among others, this key"; "the subject is identified by this key". But other cases exist: "I propose the subject has the key (apply for a claim)"; "I know the subject has the key (testify a claim)"; "I recognise the subject has the key (providing context)" etc. If you think I am making the problem look bigger than it really is, compare it to TLS's CSR/DV/OV/EV differences.

Regarding the use of HTTP header style - how do you consider the good old X.509 object identifier? After all thousands of attributes and their meaning is defined on a semantic level. e.g. there is no address but rather country, state, locality, street, buildingNumber etc. Rather well defined with the long-term consistency in mind since signed X.509 data can't be changed. (That is true even before blockchain.)

@colourful-land

This comment has been minimized.

Show comment
Hide comment
@colourful-land

colourful-land Aug 20, 2018

There is a huge privacy concern: the more claims there are about a subject, the less privacy the subject enjoys. This works to the advantage of detecting fraud (user 0xxxxx is a scammer) and disadvantage to heavy users.

For example, a subject who, as claims show, to be of 18 years old in order to buy a beer, to be of a non-US citizen in order to participate some ICOs, to be of a Computer Science graduate to enjoy alumni club membership, is likely identified and matched to the exact person. (3 connection is all you need in a social network to de-anonymous a person). The more the subject refers to this contract when calling other contracts which call this contract's getClaim, the quicker it gets linked to his/her real-world identity. Simply assigning these claims to different addresses of the subject (e.g. by key derivation) without additional treatments invites drawbacks†.

I am a bit surprised my post is the first to mention the word "privacy". Even with the privacy concern, the use-cases that demand entire public verifiable claim sets, e.g. ATL (referring to things like Adobe Approved Trust List), might still be a good fit for this ERC.

https://github.com/alpha-wallet/ethereum-attestation/releases (I'm one of the authors)

colourful-land commented Aug 20, 2018

There is a huge privacy concern: the more claims there are about a subject, the less privacy the subject enjoys. This works to the advantage of detecting fraud (user 0xxxxx is a scammer) and disadvantage to heavy users.

For example, a subject who, as claims show, to be of 18 years old in order to buy a beer, to be of a non-US citizen in order to participate some ICOs, to be of a Computer Science graduate to enjoy alumni club membership, is likely identified and matched to the exact person. (3 connection is all you need in a social network to de-anonymous a person). The more the subject refers to this contract when calling other contracts which call this contract's getClaim, the quicker it gets linked to his/her real-world identity. Simply assigning these claims to different addresses of the subject (e.g. by key derivation) without additional treatments invites drawbacks†.

I am a bit surprised my post is the first to mention the word "privacy". Even with the privacy concern, the use-cases that demand entire public verifiable claim sets, e.g. ATL (referring to things like Adobe Approved Trust List), might still be a good fit for this ERC.

https://github.com/alpha-wallet/ethereum-attestation/releases (I'm one of the authors)

@davux

This comment has been minimized.

Show comment
Hide comment
@davux

davux Aug 20, 2018

@colourful-land The right solution for correlation issues is managing multiple identifiers. A famous system that uses that approach is Bitcoin. Another one is Sovrin, based on Hyperledger Indy.

davux commented Aug 20, 2018

@colourful-land The right solution for correlation issues is managing multiple identifiers. A famous system that uses that approach is Bitcoin. Another one is Sovrin, based on Hyperledger Indy.

@negedzuregal

This comment has been minimized.

Show comment
Hide comment
@negedzuregal

negedzuregal Aug 20, 2018

Hi guys,
Are there any thoughts for off-chain claims that can be selectively broadcasted?

Example: say we want to distribute a reward between many users.
One way to go about it is that the organisers will make many txs to publish claims for winners (the claim is that a particular user is a winner).
Another possibility is that the organisers sign claims and publish them off chain. The winners can send those claims to the contract, each user on his own, to get the reward.

Example 2: a user has an off-chain asset score that a 3rd party can issue as a claim (For example a platform that connects to his various wallets and exchange accounts to fetch balance data).
The claim has a timestamp and the said score.
The company doesn't broadcast the claim since it has many users and it will cost a significant amount.
Instead it publishes the claims off-chain to anyone to see. The user can broadcast those claims on his own.

negedzuregal commented Aug 20, 2018

Hi guys,
Are there any thoughts for off-chain claims that can be selectively broadcasted?

Example: say we want to distribute a reward between many users.
One way to go about it is that the organisers will make many txs to publish claims for winners (the claim is that a particular user is a winner).
Another possibility is that the organisers sign claims and publish them off chain. The winners can send those claims to the contract, each user on his own, to get the reward.

Example 2: a user has an off-chain asset score that a 3rd party can issue as a claim (For example a platform that connects to his various wallets and exchange accounts to fetch balance data).
The claim has a timestamp and the said score.
The company doesn't broadcast the claim since it has many users and it will cost a significant amount.
Instead it publishes the claims off-chain to anyone to see. The user can broadcast those claims on his own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment