See the documentation
Block Qualified allows users to gain credentials by solving tests directly on-chain: we use zero-knowledge proofs to ensure these solutions remain a secret, so cheating becomes mathematically unfeasible. Additionally, we integrate with the Semaphore protocol, which allows users to prove their membership of a group and send signals without revealing their original identity.
The end result is a protocol that allows users to:
- gain credentials by solving tests without revealing their solutions, and
- make claims that they own these credentials without revealing their identities.
Block Qualified allows anyone to design their own open education platform, where users can:
- Earn credentials attesting to their knowledge.
- Anonymously prove ownership of their credentials.
- Anonymously prove that they obtained a grade above a certain threshold.
- Anonymously rate credential issuers.
All of this being done directly on-chain, with verifiable data, and preserving the privacy of users via zk-proofs.
The protocol is built on a comprehensive tech stack:
- The circom circuits, which define the base logic of the protocol.
- The core smart contracts, developed in Solidity, and acting as verifiers to enforce this logic.
- A subraph used to index events from these smart contracts, and that can be interacted with via the separate data package.
- A series of TypeScript/JavaScript libraries are also provided, enabling developers to easily interact with the protocol and generate and verify all the proofs that power Block Qualified.
These have each been released as their separate npm packages, allowing developers to build on top of the protocol. More information on these can be found on each of the links above.
Additionally, a simple frontend has been build on React, implementing a demo usecase of the protocol, and can be accessed at:
At the core of Block Qualified is the Credential Registry, built to support any kind of credential types, each with their own behavior. A credential type defines how a credential operates: the rules that must be followed to obtain them. Users can define the behavior of their own credential types, link them to the registry, and create and obtain different credentials that follow these set behaviors.
The Credential Registry keeps track of all credential states, which are represented by Merkle trees:
- The grade group, composed of the grade commitments of all the users that attempted to gain the credential, regardless of whether they obtained it.
- The credentials group, composed of the Semaphore identity commitments of all the users that obtained the credential.
- THe no-credentials group, composed of the Semaphore identity commitments of all the users that did not obtain the credential.
Block Qualified has native support for the Test Credential. Each test credential contains two distinct components, each forming a Merkle tree formed with the SNARK-friendly Poseidon hash function:
- A multiple choice component, where the answer to each question is part of a given finite set. The grade for this component is only awarded if the user gets all the answers right.
- An open answer component, where the answer to each question can be any value. The leaves being the keccak256 hashes of the answers, made compatible with the SNARK scalar modulus. The grade for this component is awarded incrementally per answer that the user gets right.
When the user's grade is over the defined minimumGrade
,they have gained the test credential, and their identity commitment gets added to the credentials group. Otherwise, their identity commitment gets added to the no-credentials group. This is all done inside of the zk-proof via the Test circuit -- the Test Credential smart contract then enforces the correctness of the proof.
After users have attempted a credential, they can:
- Use the Semaphore circuit to signal anonymously with a zero-knowledge proof that they are a part of the credentials/no-credentials group.
- Use the Grade Claim circuit to signal anonymously with a zero-knowledge proof that they obtained a grade that is greater than or equal to a certain threshold.
Users earn these credentials by sending transactions to the Credential Registry. In order to increase privacy, and since these transactions do not require a direct interaction from the user (like when managing funds), a transaction relayer is used. This way, all transactions originate from the same address, so tracing them back to a user becomes a harder task. The Defender Relay service by OpenZeppelin is used to this end.
You can read more about the technical implementation on the documentation.
Check out the documentation
You can check this 3-minute demo walkthrough highlighting the main functionalities.
This demo has been deployed on the Polygon Mumbai testnet network. If you wish to interact directly with the protocol, you can get yourself some testnet funds at this faucet or this faucet.
Contract | Mumbai |
---|---|
SemaphoreVerifier.sol | 0x5f4e...5a49 |
PoseidonT3.sol | 0x181B...1648 |