# Census Service
The Census Service provides a service for both organizations and users. Its purpose is to store and manage census, which are a list of public keys stored as a Merkle Tree.
The organizer can:
- Create a new census
- Add new claims to a census (hash of the public key)
- Export the list of claims
- Recover the Merkle Root
- Publish the census to IPFS or similar
- Import a census from IPFS
A user can:
- Request the Merkle Root
- Given a claim, request the Merkle Proof (the siblings allowing to prove that the claim matches the current root hash)
- Check if a Merkle Proof is valid
# JSON API
The Census API interactions follow the JSON API.
# Add Census
Private Method
When using censushttp
only the root key administration can create new census if rootKey
specified.
When using the gateway
, only the public keys specified in --allowedAddrs
can create new census and the address is added automatically as prefix for the censusId
(to avoid colision and for security reasons).
{
"id": "req-12345678",
"request": {
"method": "addCensus",
"censusId": "<entropy-hash>", // Unique hex payload like the hash of the original census name
"pubKeys": ["040012345...", "040123456...", "..."], // hex pubKeys allowed to request private methods
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"ok": true,
"censusId": "0x12345678.../<entropy-hash>", // The full census ID that any client should use from now on
"request": "req-12345678", // request ID here as well, to check its integrity
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Add Claim
Private Method
Adds a payload to the census Merkle Tree and returns the updated Root Hash
- If
digested
isfalse
, the receiver will handlecensusKey
as a raw public key encoded in base64- The receiver should compute its Poseidon Hash and store it
- If
digested
istrue
, the receiver will handlecensusKey
as an already hashed public key, encoded in base64- The receiver should store
censusKey
as it is
- The receiver should store
- On weighted census,
weight
contains the amount of power that the givencensusKey
has
{
"id": "req-12345678",
"request": {
"method": "addClaim",
"censusId": "0x12345678/0x23456789", // where to add the claim (must already exist)
"digested": false, // is the key digested? the Gateway should do it if not
"censusKey": "base64-string", // usually the public key in base64 or its hash, also in base64
"weight": "bigInt-string", // usually the numeric weight (big num). If empty, weight=1 is assumed
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"ok": true,
"root": "0x1234...",
"request": "req-12345678", // request ID here as well, to check its integrity
"timestamp": 1556110672
},
"signature": "0x1234..."
}
Used in:
# Add Claim Bulk
Private Method
Adds a set of payloads to the census Merkle Tree and returns the updated Root Hash
- If
digested
isfalse
, the receiver will handlecensusKey
as raw public keys encoded in base64- The receiver should compute their Poseidon Hashes and store them
- If
digested
istrue
, the receiver will handlecensusKey
as already hashed public keys, encoded in base64- The receiver should store
censusKeys
as they are
- The receiver should store
- If any of the claims could not be added,
invalidClaims
contains an array with the indexes that failed
{
"id": "req-2345679",
"request": {
"method": "addClaimBulk",
"censusId": "0x12345678/0x23456789", // where to add the claims (must already exist)
"digested": false, // are the keys digested? the Gateway should do it if not
"censusKeys": [ // the public keys in base64 or their hashes, also in base64
"base64-string-1",
"base64-string-2",
"base64-string-3"
],
"weights": [ // if empty, weight=1 is assumed
"bigInt-string",
"bigInt-string",
"bigInt-string"
],
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-2345679",
"response": {
"ok": true,
"root": "0x1234...",
"invalidClaims": [1, 2], // string-1 and string-2 were not added
"request": "req-2345679",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Get Root
Public Method
{
"id": "req-12345678",
"request": {
"method": "getRoot",
"censusId": "0x12345678/0x23456789",
},
"signature": "" // Leave empty
}
{
"id": "req-12345678",
"response": {
"root": "0x1234...", // the current census root hash
"request": "req-2345679",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Get Size
Public Method
{
"id": "req-12345678",
"request": {
"method": "getSize",
"censusId": "0x12345678/0x23456789",
"rootHash": "optional-hexString", // from a specific version
},
"signature": "" // Leave empty
}
{
"id": "req-12345678",
"response": {
"size": int64, // the current size of the census
"request": "req-2345679",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Generate Proof
Public Method
{
"id": "req-12345678",
"request": {
"method": "genProof",
"censusId": "0x123456789", // Merkle Root of the census for which the claim siblings are requested
"censusKey": "base64-string", // the leaf for which the proof is requested (base64 encoded)
"digested": false, // is the key digested? the backend should do it if not
"rootHash": "optional-hexString" // from a specific version
},
"signature": "" // Leave empty
}
{
"id": "req-12345678",
"response": {
"siblings": "hexString",
"censusValue": "base64-string", // the bytes representation of the numeric big num weight
"weight": "bigInt-string", // the string representation of the weight
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Check Proof
Public Method
{
"id": "req-12345678",
"request": {
"method": "checkProof",
"censusId": "0x123456789", // Merkle Root of the census for which the Merkle Tree's claim will be checked
"censusKey": "base64-string", // the leaf for which data is requested
"censusValue": "base64-string", // the bytes representation of the weight big num
"proofData": "hexString", // the siblings, same format obtained in genProof
"digested": false, // is the claim digested? the backend should do it if not
"rootHash": "optional-hexString" // from a specific version
},
"signature": "" // Leave empty
}
{
"id": "req-12345678",
"response": {
"validProof": bool, // it's a valid proof or not
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Census Dump
Dumps the entire content of the census as an array of hexStrings ready to be imported to another census service.
Private Method
{
"id": "req-12345678",
"request": {
"method": "dump",
"censusId": "0x12345678/0x23456789",
"rootHash": "optional-hexString", // from a specific version
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"censusDump": "base64-string", // the serialized, base64 encoded, census data (for using with import)
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Census Dump Plain
Dumps the content of the census in base64 format. The dump cannot be used afterwars with importDump
.
Private Method
{
"id": "req-12345678",
"request": {
"method": "dumpPlain",
"censusId": "0x12345678/0x23456789",
"rootHash": "optional-hexString", // from a specific version
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"censusKeys": [
"base64-string",
"base64-string",
"base64-string"
],
"censusValues": [ // can be empty if not weighted census
"hexString-1",
"hexString-2",
"hexString-3",
]
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Census Import Local Dump
Only works with specific merkle tree format used by dump
method. To add a list of plain claims use addClaimBulk
instead.
Private Method
{
"id": "req-12345678",
"request": {
"method": "importDump",
"censusId": "0x12345678/0x23456789", // the censusId where to import the data
"censusDump": "base64-string", // serialized base64 encoded raw census data (generated with dump)
"timestamp": 1556110671
},
"signature": "0x1234..."
}
{
"id": "req-12345678",
"response": {
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Census Publish
Exports and publish the entire census on the storage of the backend (usually IPFS). Returns the URI.
Private Method
{
"id": "req-12345678",
"request": {
"method": "publish",
"censusId": "0x12345678/0x23456789",
"rootHash": "optional-hexString", // the census snapshot to publish, if not specified, use the last one
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"request": "req-12345678",
"uri": "uri-string", // where to find the census, i.e ipfs://Qmasdf94341...
"timestamp": 1556110672
},
"signature": "0x1234..."
}
# Census Import Remote
Import a previously published remote census. Only valid URIs accepted (depends on the backend).
Private Method
{
"id": "req-12345678",
"request": {
"method": "importRemote",
"censusId": "0x12345678/0x23456789",
"uri": "uri-string", // where to find the remote census, i.e ipfs://Qmasdf94341...
"timestamp": 1556110671
},
"signature": "hexString"
}
{
"id": "req-12345678",
"response": {
"request": "req-12345678",
"timestamp": 1556110672
},
"signature": "0x1234..."
}