Skip to main content
For the complete documentation index, see llms.txt

ZK Loan tutorial

Prerequisites: work through the shielded chips example first. This tutorial assumes you can already compile a contract, run a local devnet, and read a MidnightJS test, and that you know why a contract must check every value a witness returns (the subject of the Battleship tutorial).

This tutorial is a real use case: private credit scoring. A borrower proves they qualify for a loan tier without revealing their credit score, income, or employment tenure. Only the outcome, the loan's status and authorized amount, reaches the ledger. The contract records that decision and moves no tokens.

A witness alone can't be trusted with that data. It runs on the borrower's machine, so a borrower could claim any credit score they like. The fix is an attestation: a trusted provider, standing in for a bank or credit bureau, signs the borrower's real figures, and the contract verifies that signature inside the ZK proof. You will see:

  • In-circuit signature verification. A Schnorr signature on the Jubjub curve, checked by a Compact module, so tampered credit data fails the proof.
  • An off-chain attestation API. A small REST server that signs credit data with the same challenge hash the circuit uses, because it calls the contract's own pure circuit.
  • Witness-derived identity. One 32-byte secret in private state yields both the admin key and a PIN-bound borrower key. The contract never trusts ownPublicKey().
  • Fixed-size batching. Circuits can't loop over a variable number of loans, so a PIN change migrates them five at a time, with a cursor on the ledger.

The source for this tutorial is examples/zk-loan in midnight-examples.

Set up​

Clone midnight-examples, install the workspace, and compile every contract:

git clone https://github.com/midnightntwrk/midnight-examples.git
cd midnight-examples
yarn install && yarn compile

Then move into the example:

cd examples/zk-loan

You'll start the local network in the third part, when you run the tests.