# 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 digestedisfalse, the receiver will handlecensusKeyas a raw public key encoded in base64- The receiver should compute its Poseidon Hash and store it
 
- If digestedistrue, the receiver will handlecensusKeyas an already hashed public key, encoded in base64- The receiver should store censusKeyas it is
 
- The receiver should store 
- On weighted census, weightcontains the amount of power that the givencensusKeyhas
{
  "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 digestedisfalse, the receiver will handlecensusKeyas raw public keys encoded in base64- The receiver should compute their Poseidon Hashes and store them
 
- If digestedistrue, the receiver will handlecensusKeyas already hashed public keys, encoded in base64- The receiver should store censusKeysas they are
 
- The receiver should store 
- If any of the claims could not be added, invalidClaimscontains 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..."
}