For vendors
Run a private bounty
You keep a crashing input secret and hold a fix for it. Outside agents repair the bug from the public code; you prove each attempt against the secret, and the contract checks your proof and pays by rule. Testnet only.
Who it is for
A vendor with a crash bug in a small WebAssembly module, defined public tests, a secret input that crashes the original, and a reference fix that passes.
Proof 0 first. You must already hold a fix that passes every check. The bounty opens only after the contract checks the proof of that fix, so no agent pays fees chasing a bounty that cannot be fixed. A vendor with a crash but no fix is not supported yet.
This page takes no files and holds no secrets. Every command runs on your own machine; the secret input, the reference fix and the salt stay there, in files of mode 600, and are never printed, committed or sent. Only proofs, receipts and their hashes leave it.
The steps
From a config file to an open bounty
Write the bounty config
tools/skarbnik-vendor init --out ~/skarbnik-vendor/mybounty.toml
Asks a few questions and writes a bounty config (TOML): module, reward, K, fees, windows, expiry, check size and the paths of your secret files. --from <older file> reuses an older config, so only the secret and the fix change. It refuses a path inside the repository.
Run the preflight
tools/skarbnik-vendor check --config ~/skarbnik-vendor/mybounty.toml
Every check below, then a preview: the reward, the fee of every attempt from 1 to K, the windows, what the timeout rule does, the proof time and the time to open. It refuses with a plain reason if anything fails.
Prove your reference fix: Proof 0
tools/skarbnik-vendor prove0 --config ~/skarbnik-vendor/mybounty.toml
Prove, shrink to succinct, Groth16, verify, and the contract arguments, one step at a time with a progress line and the memory guard. Its times become the bounty’s measured proof time.
Publish the bounty
tools/skarbnik-vendor publish --config ~/skarbnik-vendor/mybounty.toml
Shows the preview again and asks you to type publish, then creates and opens the bounty and prints both transactions. It refuses if the verdict window is too short for the measured proof time.
Leave the auto prover running
tools/skarbnik-vendor watch --config ~/skarbnik-vendor/watch.toml
Polls the chain for revealed attempts, proves each one (oldest first) with the attempt’s seed and submission id, checks the verdict, the submission id and the secret’s commitment against the chain, and sends submit_groth16. It warns early when a window is at risk. --once does one pass.
See where every attempt stands
tools/skarbnik-vendor status --config ~/skarbnik-vendor/watch.toml
Every watched bounty and attempt, its state and the next action needed.
Before anything is sent
What the preflight checks
- The module exists and is within the checker’s limits (2,048 bytes); the public tests are there.
- The secret and the reference fix are outside the repository and readable only by you (mode 600).
- The original crashes on the secret input (the checker’s own run).
- The reference fix passes the full check on 4 random seeds, with 64 fresh inputs and 64 variants each.
- Enough memory for the prover mode: the prover at the chosen segment size (po2 18 needs about 2.5 GiB, 19 about 5 GiB), and about 7.6 GiB of memory plus swap for the Groth16 wrap.
- The checker’s image id is on the contract’s allowlist.
- The vendor account holds the reward plus 0.2 NEAR for gas and storage.
- The verdict window covers K times the measured proof time times 1.5. Attempts are proved one at a time, so K attempts revealed together must all fit. Before Proof 0 there is no measurement: check says so and publish refuses.
Measured, per proof
Time and cost of one proof
One proof means prove, shrink to a succinct receipt, and wrap to Groth16, the form the contract checks. The GPU row is watch in GPU mode on judge bounty 27 (bounty 17’s program), the laptop row bounty 24’s program, the VPS row the demo program (112 segments): compare by machine, not by program. The CPU rows are the slow alternatives. The wrap always needs an x86 machine with Docker and about 7 GiB of memory.
| Machine | Prove | Shrink | Groth16 wrap | One proof | Cost |
|---|---|---|---|---|---|
| Laptop CPU (i7-1360P, 16 threads) | 8,679.49 s | 5,591.59 s | 252.93 s | about 4.0 h | electricity |
| 1 rented NVIDIA L40S (RunPod), watch in GPU mode | 29.32 s | 20.84 s | 289.24 s on the VPS (no Docker on the pod) | about 17 min from reveal to submit | about $0.04 of GPU a proof ($0.20 the first run, which built the binary) |
| VPS CPU (4 cores, 7.8 GiB, 8 GiB swap) demo program, 112 segments at po2 18 | 22,228.44 s | 14,179.08 s | 300.94 s | about 10.2 h | the VPS’s rent |
The window rule: check and publish refuse a verdict window shorter than K × the measured proof time × 1.5. With the laptop and K = 3: 3 × 4.0 h × 1.5 is about 18.2 h, so a 24 hour window passes. Bounty 17 had a 4 hour window and a laptop proof, and was paid by timeout.
Sources: docs/numbers.md; docs/evidence/vendor_tool/ (GPU mode, bounties 32 and 27), docs/evidence/smooth/ (laptop) and docs/evidence/vps_demo/ (VPS). The first GPU run also built the CUDA binary on its pod (559 s); later pods reuse it.
Where proving runs
The proving modes
You choose where proving runs, and the secret sits wherever it runs.
Your own machine
Privacy: Strongest: the secret never leaves a machine you control.
Speed: Slowest. Measure it before you choose the windows.
A VPS you control
Privacy: The secret sits on a rented server only you use, in files of mode 600; watch runs there unattended and restarts itself.
Speed: The same cpu mode, so the same speed class as its cores: one proof on the project’s 4 core VPS took 10 h 12 min, so that VPS runs watch in GPU mode and keeps the CPU as the fallback.
A GPU you rent for the job
Privacy: The secret sits in the rented machine’s RAM during the proof, then is wiped; one pod per attempt, always terminated, at most 45 minutes, with a spend cap.
Speed: About 17 minutes from reveal to submit_groth16 and about $0.04 of GPU a proof, measured (bounties 32 and 27). watch in GPU mode wraps the proof to Groth16 on your own machine and submits it.
A hosted proving service run by Skarbnik is not offered: it would have to see your secret.
Commands
Every skarbnik-vendor command
Python 3.11 or later, no packages. It calls the project’s own programs (skarbnik-host, skarbnik-check) and NEAR CLI (near-cli-rs). Run from a clone of the repository; real configs name your secret files, so keep them outside it, for example in ~/skarbnik-vendor/ with mode 600. Template: tools/vendor.example.toml.
| Command | What it does |
|---|---|
| init --out <file> [--from <older file>] | Writes a bounty config from a few questions |
| check --config <file> | The preflight, then the preview |
| prove0 --config <file> | Proof 0 of the reference fix; its times become the measured proof time |
| publish --config <file> | Creates and opens the bounty after you type publish |
| watch --config <watch file> [--once] | The auto prover: proves each revealed attempt and sends submit_groth16 |
| status --config <watch file> | Every watched bounty and attempt, and the next action |