Skip to content

Instantly share code, notes, and snippets.

Last active Mar 15, 2022
What would you like to do?

Proof of Humanity integration docs

General information

Registry Policy

This link leads to the current Proof of Humanity Registry policy. In it, you will find the requirements that a submission must follow to be successfully included in the list. Note that Proof of Humanity governance process can change it.


This is the submission flowchart, numbered to ease referencing.


1. Submit profile (#L421)

In this step, users will upload to IPFS the data requested in the Registry Policy and declare their intention to join it.

As you can see in this example the transaction parameters are the name (not used in the code) and a link to a registration evidence /ipfs/QmQ3zm9y76sPT5Qyaxfpbtmdp8LNNGPrg2CrNYqbzGFokk/registration.json.

  "fileURI": "/ipfs/QmV1moPbEqfy1KK6vHaiJvNCGbcMhwvpbnjJLKV2Ptg7FK/file.json",
  "name": "Registration"

You can read more about the evidence standard here.

The field fileURI leads to a JSON with all user-provided data:

  "name": "Vitalik Buterin",
  "firstName": "Vitalik",
  "lastName": "Buterin",
  "bio": "Vitalik is the founder of the Ethereum project.",

Here you can find the validation rules that we are using before uploading the data.

Note that you can call addSubmission without paying the deposit. If this is the case, to contribute to the funding anyone can call fundSubmission (#L486). This function takes the submission address as parameter and accepts any amount of ETH. The contract will use that ETH (up to the deposit being fully paid, if there are any remainings, those are returned in this same transaction) to fund the target submission.

After this transaction, the submission will be in Vouching Phase and it will need to be fully funded and to receive a vouch from an already registered profile to advance to Pending Registration.

The amount needed is equal to submissionBaseDeposit plus the arbitrator arbitrationCost(arbitratorExtraData).

During the Vouching Phase a submitter can withdraw their submission by calling withdrawSubmission. (#L520)

If the registration request is rejected, the profile is removed, or the profile expires, the user will need to call addSubmission to try to register again.

2. Vouch

To advance to Pending Registration, submitters need users already registered to vouch for them. Those who are already registered can only vouch for one submission at a time, but they can "queue" their vouches. There are two methods to vouch, on-chain such that the voucher pays gas when vouching (#L505), or off-chain where the voucher signs a message that will be sent as parameter in changeStateToPending (#L541).

A submission will need a certain number of vouches to pass to Pending state, this amount is stored in the variable requiredNumberOfVouches and can be change via governance process.

The on-chain approach is quite simple, the voucher just needs to call the addVouch (#L505) function. Then, when the profile has received enough vouches, changeStateToPending can be called. (Right now we have a system that executes the changeStateToPending transaction for them, you can read more here , and it will be explained in more detail in the gasless vouch section).

For the off-chain vouches, there are two ways that you could use, on the one hand, we have a running database to store the off-chain vouches (URL, repository) that you could also use. On the other hand, you could host your own database and manage it yourself.

Here is the specification of the database endpoint. You can access this swagger UI by following the instructions in the repository. There is also an endpoint to delete old vouches before reapplying, you can check its use here.

Here you can find the details of our off-chain vouch implementation, including how to send a vouch to our database. As mentioned above, to avoid running a bot that sends a changeStateToPending call every time a submission gets enough vouches, we put a system in place such that when a user finalizes their registration the frontend checks if there are submissions with enough vouches, both on-chain and off-chain, if there are, the frontend takes the oldest one and adds that changeStateToPending transaction to the batch. Here you can see the implementation of this solution.

3. Challenge (#L610)

In order to curate the registry anyone can challenge a submission in Pending State if they think that registration is not compliant with the acceptance criteria established in the Registry Policy. To challenge a submission, the challenger must provide a reason. If the profile is incorrect, but not for the reason specified, the challenger can lose the dispute. These are the challenge reasons allowed:

  • Duplicate: The submitter is already registered in the list. The challenge has to point to a registered submission made by the same human. If someone tries to register multiple times simultaneously, all submissions are to be rejected.

  • Does not exist: The submitter is not real. For example, this can be used for videos showing computer generated persons.

  • Incorrect submission: The elements submitted in the submission's evidence are incorrect or don't follow the Registry Policy.

  • Deceased: The submitter has existed but does not exist anymore.

You can read more about the evidence standard here.

4. Submit evidence (#L881)

Anyone can submit evidence calling the function submitEvidence providing a submissionID. This evidence will be linked to the current request of that submission, whether it's a registration or a removal request. You can read more about the evidence standard here.

5. Appeal (#L686)

Once a dispute is ruled, its result can be appealed during the Appeal period. Any actor can help fund a side's appeal by calling this function and paying the desired amount. The contract will take as much as possible up to fully paying the appeal, and will reimburse the exceeding amount in this same transaction. If only one of the two sides fully funds the appeal, that side is automatically declared the winner. If both sides fully fund the appeal, a new round of arbitration is performed.

Once the dispute is finally resolved, if both sides fully funded the appeals in the round that you contributed and if your side finally won, you get a reward proportional to your contribution.

The reward withdrawal is done in this function.

You can check how we are handling appeals here.

6. Finalize registration (#L740)

When the challenge period is over, and if there were no successful challenges, anyone can execute the request finalizing the submission process. This function will mark the submission as registered. To start receiving UBIs, once the request has been executed, this function in the UBI contract must be called to start accruing.

In our frontend we send the transactions here note that we also advance to Pending state another submission with enough vouches as discussed in the vouching section.

7. Removal Request (#L453)

Anyone can request the removal of a registered submission from the registry if it's not in the renewal period. This function requires the deposit to be fully paid. This deposit is the same as the registration request, submissionBaseDeposit plus arbitrator's arbitrationCost(arbitratorExtraData).

The evidence should prove that either the submission does not follow the registry acceptance criteria as described in the Registry Policy, or that they are the submitter and want to voluntarily remove their submission.

If the submitter doesn't want their profile removed, they will need to challenge this request submitting some evidence answering the concerns raised. In this case the challenge reason used must be Reason.None.

8. Reapplication

Once a submission is registered it will expire after a certain time, the duration is stored in seconds in submissionDuration. To save the submission from expiring, the users need to call reapplySubmission (#L438) during the renewal period. This period starts a certain amount of seconds before the submission expires, that number of seconds is stored in renewalPeriodDuration. This is the expression to check if a submission is in renewal period. For now, the evidence must comply with the same requirements as the initial submission, while a more clear policy is being worked on. This policy will be reflected in the Registry Policy document and will need to go through the DAO governance process.

Data querying

To use a subgraph you can either:

  • Create an API key and query the decentralized service subgraph (Link)
  • Query our hosted service deployment (Link)
  • Use our code to deploy your own subgraph (Link)
  • Create your own code and deploy it yourself.

You can also query the contract directly deployed at 0xC5E9dDebb09Cd64DfaCab4011A0D5cEDaf7c9BDb. In this case, to check if an address is currently accepted in the registry, you can use isRegistered (#L1029).

Common problems

1. User wants to use a new address.

In case someone loses access to their wallet or wants to change the address that is linked to their humanity, that user must first remove their current registered profile with a removal request as stated in section 7. This is because one human can be linked to only one registered address.

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