What a tender record establishes, how anyone can check it, and — at length — what it does not prove. Version 0.2, September 2026. Draft for comment.
Written for counsel, procurement officers and auditors. The authors are not lawyers and this is not legal advice; corrections are more useful than agreement.
Summary
Waxseal runs sealed-bid tenders and auctions on the Midnight network. Each tender is a smart contract. Bids never appear on the ledger: each bidder publishes a commitment (a 32-byte hash of the bid and a random value) and a zero-knowledge proof that the hidden bid is valid. The winner is later proven from the commitments, not announced by anyone.
A tender record lets any party, without an account and without Waxseal's cooperation, establish five things:
- the rules and the published description were fixed before bidding, and nobody could change them afterwards;
- each sealed bid was recorded before the deadline, and none was changed afterwards;
- the published result follows from the sealed bids and the rules;
- deposits were locked and released as the rules say;
- a bidder can later prove to a person of their choosing exactly what they bid.
Each point is separately checkable. Losing bids are never disclosed by the system.
1. What a record establishes
1.1 The rules were fixed, and could not change
At creation the contract stores the public parameters (valid bid range, deadline, deposit, whether the lowest or highest bid wins, clock or committee settings) and the SHA-256 hash of the tender's description and document list. Anyone holding the description can hash it and compare; a single changed character gives a different hash.
What the contract can do is determined by its circuits. On Midnight, a contract accepts a transaction only with a zero-knowledge proof that verifies against the contract's stored verifier keys. Waxseal publishes the fingerprint of every verifier key of every release (packages/contracts/releases.json); a verifier compares the keys stored on chain with that list.
Midnight contracts can carry a maintenance authority able to replace their verifier keys. Tenders created by Waxseal software from 25 September 2026 renounce it immediately after creation: the authority is replaced by one with no keys, which the ledger will never allow to sign anything. The renunciation is itself a transaction on the record. Test tenders created earlier were renounced on 25 September 2026, and their records show when. The verifier reports any tender that is still changeable, and whether a change ever happened.
1.2 Each bid was sealed before the deadline, and not changed
A bid is recorded as commitment = SHA-256(tag ‖ bid ‖ salt ‖ bidder id) (specified byte for byte in docs/COMMITMENT_FORMAT.md). The contract accepts at most one commitment per bidder id and refuses commitments once the deadline has passed by its own clock. Each commitment appears in a specific transaction in a specific block, with the block's time.
Producing a different bid that matches an existing commitment requires finding a SHA-256 collision, which is not considered feasible. So the commitment fixes the bid at the time of the block, without disclosing it. Shortly after each transaction the tender's state, including every commitment, is also time-stamped by public time-stamping authorities (section 5), so the time does not rest on the network's clocks alone.
1.3 The result follows from the bids and the rules
Clock mode. After the deadline a public price moves one step per round. A bidder can claim only in the first round whose price reaches their sealed bid, proving this in zero knowledge against their own commitment; the first valid claim settles the tender at that round's price. The record shows the round, the time of the claim, and that the winner holds one of the commitments. The published price is the clock price, within one step of the winning bid.
Committee mode. A named committee can decrypt the bids (each is encrypted to the committee's key, with a proof that the ciphertext holds the same values as the commitment). The committee then submits one proof that consumes every commitment on the ledger in order and shows that the named winner's bid is the best. It cannot leave a bid out or substitute one.
In both modes losing bids stay sealed on the ledger.
1.4 Deposits followed the rules
Where a deposit is required, each bid locks a shielded deposit in the contract. Losers recover theirs; the winner's becomes a performance bond; the organiser can collect only what the rules allow. The record shows each lock, refund and collection, and the verifier checks that they add up.
1.5 A bidder can prove what they bid
The bidder's device holds the bid and the random value. The bidder can give a receipt (tender, bidder id, commitment, block — no bid) to anyone, and, if they choose, an opening (the same plus the bid and random value) to a specific person, who recomputes the commitment and compares. Only the bidder can create an opening. Waxseal cannot, because it never holds the values.
2. How a record is checked
Everything below uses public data and open procedures. No account is needed, and nothing depends on Waxseal continuing to exist.
- Public ledger. The contract's state and full history are read from any Midnight indexer; Midnight runs a public one per network. The verifier believes the indexer it reads; for a dispute, read from your own node and indexer, or compare two.
- The verifier (
/verifyon the website, andpackages/sdk/scripts/verify-tender.ts) reads the history straight from the indexer and checks: the verifier keys against the published releases; that the maintenance authority is renounced; that the keys never changed; that no commitment was replaced; that every commitment precedes the deadline; that the count is consistent; that the result follows the rules; that deposits add up; and, if given the description, that it matches the hash. It produces a report with a SHA-256 digest; two parties running it against the same block get the same findings. - Independent time stamps. The verifier also checks every RFC 3161 time stamp supplied with the tender: the authority's signature, its certificate chain to a pinned root, and that the time-stamped statement is exactly the chain's state after the stated transaction. It then reports, for each sealed bid, the earliest independent time that covers it. Each time stamp can also be checked with OpenSSL alone.
- Independent recomputation.
conformance/waxseal_verify.pyis a second implementation of the commitment format using only the Python standard library, written from the specification. It recomputes commitments from an opening and hashes of descriptions. The compiled contracts, the TypeScript SDK and the Python program are checked against the same published test vectors (conformance/vectors.json); a deliberately wrong implementation is included to show that the vectors catch errors.
A useful practice for a dispute: record the report digest and the block height it was produced at, and keep the tender description file and any documents whose hashes it lists.
3. What a record does not prove
Stated at length, because a record that is trusted for more than it shows is worse than no record.
- Who a bidder is. A bidder id is a per-tender pseudonym derived from a secret on the bidder's device. The record does not name anyone. Linking a bidder id to a person or company needs the bidder's cooperation (an opening from their device) or the organiser's own off-chain procedure.
- That a bidder can deliver. The record concerns prices, timing and the rules. It says nothing about capacity, quality, eligibility beyond an optional allow list, or conflicts of interest.
- That the clock found the best bid in every case. The clock result is within one price step of the best committed bid only if the best bidder claims in their round. A better bidder who stays silent loses their deposit, which makes silence costly; with no deposit there is no such incentive, and the result is only as good as the bidders' conduct. The verifier reports the deposit setting.
- That a committee kept bids confidential. In committee mode the committee can read every bid as it arrives and could leak it before the deadline. It cannot change the result or omit a bid. Splitting the committee key between several members reduces the risk of a single insider; the key is reassembled on one machine to decrypt.
- An exact time. Block times are set by the network's block producers. They order events and are close to real time, but a Midnight block time is not a qualified electronic timestamp in the sense of EU law. The independent time stamps of section 5 come from public, non-qualified authorities: they show that a state existed no later than the time signed, typically within a minute or so of the transaction, not the exact moment it happened. A bid sealed in the last minute before the deadline may therefore carry an independent time just after it; its block time and the contract's own deadline check remain the evidence for that bid.
- That the description is true. The hash proves the description was not edited after creation; it does not prove its content accurate. Documents are referenced by their hash; the parties must keep the files themselves.
- Unlinkability of every transaction. Deposits are shielded, but a party who already knows a bidder's shielded address can test the refund transaction against it and confirm that the bidder took part (not what they bid); and fees on Midnight are paid from a resource tied to the payer's registered NIGHT, whose linkability is an open question. Both are stated in
docs/THREAT_MODEL.md, invariant I4. - Audited software. As of this version the contracts have been reviewed by their authors but not by an independent auditor, and run on a test network only. Deployment to the production network is locked in the software until an audit is complete.
- That a tender satisfies procurement law. Whether a smart-contract procedure is an acceptable procurement procedure depends on the jurisdiction and the kind of buyer. Public procurement is generally bound to prescribed systems; Waxseal is intended for private-sector procurement and auctions until a legal partner has reviewed a public-sector use.
4. Authentication: orientation by jurisdiction
Pointers only, to be confirmed by counsel in the jurisdiction concerned.
- European Union. Under the eIDAS Regulation (EU) No 910/2014, an electronic time stamp may not be denied legal effect solely because it is electronic (Art. 41(1)); the presumption of accuracy of date and time attaches only to qualified time stamps (Art. 41(2)). The 2024 amendment (Regulation (EU) 2024/1183) adds electronic ledgers as a trust service with presumptions for qualified ledgers. Midnight is not a qualified trust service, so a Waxseal record is ordinary electronic evidence, assessed on its merits.
- Italy. Art. 8-ter of Decree-Law 135/2018 (converted by Law 12/2019) gives the storage of an electronic document on a distributed ledger the effect of an electronic time stamp under eIDAS Art. 41, subject to technical standards issued by AgID.
- United States. Authentication may rely on evidence describing a process or system that produces an accurate result (Fed. R. Evid. 901(b)(9)), or on a certification by a qualified person for records generated by an electronic process and for data identified by a process of digital identification such as hash values (Fed. R. Evid. 902(13) and (14)). Vermont provides specifically for blockchain records (12 V.S.A. § 1913).
- China. Since 2018 the Supreme People's Court's provisions on internet courts allow electronic data fixed by blockchain, trusted time stamps or hash verification to be confirmed where its authenticity can be shown (Art. 11).
- Vietnam. The Law on Electronic Transactions 2023 (No. 20/2023/QH15) recognises data messages as evidence, weighed on the reliability of how they were created, stored and kept intact. Public procurement is governed by the Law on Bidding 2023 (No. 22/2023/QH15) and conducted on the national e-procurement system; Waxseal is not a substitute for it.
5. Independent time stamps
A record carries more than one anchor. Besides the ledger, each tender's public state is time-stamped under RFC 3161, the Internet standard for trusted time stamps, by two independent public authorities: DigiCert and Sectigo. They are free services, and each time stamp is a small signed file.
- What is stamped. A statement of the tender's state after a transaction: the contract, the network, the block and its hash, the transaction, the deadline, the phase, every sealed commitment and any result (format in
docs/COMMITMENT_FORMAT.md, section 8). Only its SHA-256 digest is sent to the authority. Statements contain public ledger data only. - What it proves. That this state, and that block, existed no later than the signed time. Because anyone can rebuild the statement from the chain, the time stamp ties the ledger's history to a clock outside the network. A later claim that the history was different would contradict a signed statement from a third party.
- Who requests them. The Waxseal service requests them shortly after each transaction and publishes them with the tender. It cannot forge or backdate one; it could only fail to request one, and anyone can request their own for any tender with
packages/sdk/scripts/anchor-tender.ts, with no account. - How to check one. In the browser on the verification page, with the repository's verifier, with the Python program (
anchor), or with OpenSSL alone:openssl ts -verify -data statement.json -in response.tsr -CAfile tsa-roots.pem. - Legal weight. In the EU these are electronic time stamps: they may not be denied legal effect solely for being electronic (eIDAS Art. 41(1)), but they do not carry the presumption of accurate time that only qualified time stamps do (Art. 41(2)). Where that presumption matters, the same statements can be stamped by a qualified trust service provider as well; that is a paid service and has not been set up.
- Limits. The Waxseal verifier checks certificate validity at the signed time but not revocation; OpenSSL can be asked to (
-crl_checkwith the authority's CRL). Both authorities state their accuracy as unspecified in the tokens.
6. Reproducing a verification
# from a checkout of the repository
cd packages/sdk
npx tsx scripts/verify-tender.ts <tender address> --network preprod --api https://waxseal.xyz/api --json report.json
# recompute a commitment from an opening a bidder gave you, with no dependencies
python3 conformance/waxseal_verify.py opening --file waxseal-opening.json
# check the independent implementation against the published vectors
python3 conformance/waxseal_verify.py selftest
# time-stamp a tender yourself, then check those time stamps along with the chain
cd packages/sdk
npx tsx scripts/anchor-tender.ts <tender address> --network preprod --out anchors
npx tsx scripts/verify-tender.ts <tender address> --network preprod --anchors anchors
# check one time stamp without any Waxseal code
openssl ts -verify -data statement.json -in response.tsr -CAfile tsa-roots.pem
python3 conformance/waxseal_verify.py anchor --statement statement.json --tsr response.tsrThe specification, vectors, Python program and release list are also served at https://waxseal.xyz/conformance.
Source: docs/EVIDENCE.md in the Waxseal repository.