- site/build.html and site/grants.html rendered by site/build.mjs from docs/build/build.md and docs/build/grants.md (the gate's site-only copy keeps the committed pages, as for /bench); site-relative links in the markdown renderer - the nav's fourth group, Build (/build, /faucet, /grants), in the partial, the sheet, the footer, the sitemap and tools/ci/site-nav-check.mjs; the faucet leaves the Mine panel - site/faucet.html is the Devnet 3 faucet: 10 IGN per address per day, 500 a day, chain id 4463, no value, resets without notice; the page posts to https://faucet.igneum.network/api/faucet and shows the balance - infra/build-server/faucet: faucet.mjs (zero dependencies, signs with site/lib/eth.mjs, limiter self-test known-failed first, 100 IGN cap on the amount), the unit, faucet.sh install/status; live on build-1 behind Caddy since 10:16Z, funded 2,000 IGN by the fleet's funder at 10:01Z; first drip 0x8620e9d8 at 10:17Z - docs/build: README, first-contract.md with its test script and the PASS line (24 s end to end through the public RPC and faucet, Foundry 1.8.5, Counter deployed at block 27055), rpc.md read from the node (75 methods probed, served and not served), faucet.md, verify-a-block.md, grants.md - .forgejo/issue_template/grant.md: the grant application template on git.igneum.network Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
34 lines
2.3 KiB
Markdown
34 lines
2.3 KiB
Markdown
# Verify a block in your browser
|
|
|
|
Igneum's finality is a certificate: miners sign a checkpoint every 30 seconds, and when two thirds of the 30-day mining weight have signed, it is locked. A browser can check that certificate by itself. The site ships the verifier: `site/verify/core.js` does the work, `site/verify/verify.js` fetches the data and calls it.
|
|
|
|
## Twelve lines
|
|
|
|
```
|
|
<script type="module">
|
|
import { fetchCheckpoint, verify } from 'https://igneum.network/verify/verify.js';
|
|
const data = await fetchCheckpoint('https://igneum.network/api/checkpoint');
|
|
const r = verify(data);
|
|
console.log(r.verified ? 'verified' : 'not verified', r.reason || '');
|
|
console.log(`checkpoint ${r.index} on ${r.network}, block ${r.hash.slice(0, 12)}`);
|
|
console.log(`${r.signers} of ${r.voters} voters signed`);
|
|
console.log(`${(r.weight_fraction_total * 100).toFixed(1)}% of total weight`);
|
|
console.log(`${r.headers_checked} headers checked in ${r.ms} ms`);
|
|
</script>
|
|
```
|
|
|
|
## What is checked, in the tab
|
|
|
|
1. The header chain from the previous locked checkpoint to this one: each header's hash is recomputed and each links to its parent.
|
|
2. The voter table: each voter's key hash, and the weights the bitmap selects.
|
|
3. The BLS aggregate signature over the checkpoint message, against the aggregated public keys of the signers, and that the signed weight reaches two thirds of the total.
|
|
|
|
Nothing is trusted from the server but the data itself. Change one bit of the signature, drop one signer from the bitmap, alter a header's nonce, and `verify` says `false` with the reason. The live run of exactly those cases is [igneum.network/verify/test.html](https://igneum.network/verify/test.html).
|
|
|
|
## The data
|
|
|
|
`GET /api/checkpoint` returns the latest certified checkpoint: the certificate as carried in a block, the voter list with public keys and weights, and the selected-chain headers from the previous lock. `?source=test` returns the finality test network's instead. Libraries, pinned: BLAKE2b from `@noble/hashes` 2.4.0 and BLS12-381 from `@noble/curves` 2.4.0, pure JavaScript.
|
|
|
|
## From a node
|
|
|
|
The same certificate is in the block that carries it, and `igneum_getProofRecords` returns a block's records. A light client that reads blocks from a node instead of the site's API verifies the same way; `core.js` has no dependency on the site.
|