Attestations
Depth says the output has not moved. An attestation adds that somebody with the key is here today. It costs nothing and spends nothing.
- The exact string to sign: the tag
PTNA/attest, then the artifact id, then a recent block hash, with nothing between them. - Why the block hash is what stops a signature from having been made earlier.
- How to verify one starting from the carrier in the artifact record, rather than from an address somebody sent you.
- The three things an attestation shows and the three it does not, including whether anybody else holds a copy of the key.
The message
An attestation is a BIP-322 signature over one exact string, produced by the key that controls the carrier.
"PTNA/attest" || artifact_id_hex || block_hash_hex
All three parts are concatenated with no separator, no newline, and no spaces. The two hashes are
lowercase hex. A worked example, with the values computed by
docs/tools/vectors.mjs:
PTNA/attestd3b8d3013c23dd3df76882034df80935ba55aa75772007f0b142b63adce5eff06b86b9521630996bec957312d95d273f4e19e1d87e00ca8928f3c736c6d73308
The cuts always fall at the same two offsets, so a message of the wrong length is the first thing to check when a signature will not verify.
| Part | Length | Value |
|---|---|---|
| Tag | 11 characters | PTNA/attest |
| Artifact id | 64 characters | d3b8d301...ce5eff0 |
| Block hash | 64 characters | 6b86b952...6d73308 |
Why a block hash
The block hash is the timestamp. It cannot be predicted before that block is mined, so a signature over it cannot have been made earlier. That turns "I have the key" into "I had the key at or after this block".
- Pick a recent block. A signature over a block from last year proves you had the key last year, which is much weaker.
- Whoever verifies it decides what counts as recent. A common rule is within 144 blocks.
- Signing again later is normal. Attestations are meant to be repeated, not permanent.
Producing one
-
Get the artifact id
From your own records, or from
GET /patina/artifacts/:id. Use the lowercase hex form exactly as it appears. -
Get a recent block hash
bitcoin-cli getbestblockhashUse the block hash in the standard display order, the same string a block explorer shows.
-
Build the message and sign it
Concatenate the three parts. Sign with BIP-322 using the key that controls the carrier output. Do not sign with a different key from the same wallet, because a verifier checks the signature against the carrier's address.
-
Publish the three items together
The signature alone is useless. Publish artifact id, block hash, and signature, so anyone can rebuild the message and check it.
Verifying one
Five steps, in this order. The node commands for the lookups in steps one to three are on the public page for verifying it yourself.
- Fetch the artifact and read
carrier.txidandcarrier.vout. - Look up the address that carrier output pays.
- Confirm the block hash is a real block on the chain you care about, and note its height.
- Rebuild the message exactly and verify the BIP-322 signature against that address.
- Decide whether the block is recent enough for your purpose.
Always read the carrier from the artifact record at verification time. If you verify against an address someone told you about, you are trusting the teller. The point of the exercise is to avoid that.
What it proves and what it does not
The left column is what a verifier can state after the signature checks out. The right column is what people will assume anyway, and none of it is supported.
| Proves | Does not prove |
|---|---|
| Somebody could sign for the carrier at or after that block | That the signer is the original minter |
| The key is not lost, at least for that signer | That only one person holds the key |
| Combined with depth: unmoved since height H, and signable now | That the same person held it for the whole stretch |
Keys can be copied and keys can be sold. An attestation raises the floor on what is verifiable. It does not close the gap, and no message signature can. See What it does not promise.
Attestations are off chain
- They cost nothing, publish nothing to the blockchain, and cannot reset depth.
- The indexer does not require them and does not store them. Nothing in the state model depends on an attestation.
- You can produce as many as you like, for as many different blocks as you like.
- An artifact with no attestation is not suspicious. It is just an artifact whose holder did not sign anything.