Payment Evidence Statements for BREAD and BEEF
Two different wallets checking the same unconfirmed payment describe what they verified in totally different ways, so there is no way to compare "three hops back to a confirmed block" against "a valid BEEF" or to let an app set one acceptance rule that works regardless of which wallet it is talking to. This leaves users and apps guessing what was actually checked before goods change hands, with no shared way to say it.
Reference for an AI
Everything an assistant needs to answer questions about BRC-237 accurately, including what it depends on.
Summary
- Why
- Receivers need a single, shared way to state exactly what they checked about an unmined payment, since BEEF-based and hop-counting (BREAD) verification describe the same evidence in incompatible terms.
- What
- BRC-237 is a specification for a canonical JSON statement that records what a receiver verified about an unmined Bitcoin SV payment, built from either BREAD-style ancestry distance or a BEEF.
- How
- A maker that holds either a BEEF or raw records walks back through the payment's unconfirmed ancestors, records which checks passed and how far each input is from a trusted header, serializes the result as canonical JSON, and optionally signs it with BRC-77 or exposes it through a BRC-100 wallet method called…
What this lets you do
- Produce a canonical JSON statement describing exactly what was checked about an unmined payment
- Build the statement from either a BEEF or from a wallet's own ancestry records
- Report longest and shortest unconfirmed distance to a trusted block header
- Convert Electrum-style Merkle branches into BRC-74 Merkle path format
- Sign a statement with BRC-77 and expose it via an optional wallet method
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
The specification
Abstract
This BRC defines a payment evidence statement, a small canonical JSON object in which a receiver records what it verified about an unmined payment and what it did not: the ancestors anchored by a Merkle path to a header it trusts, whether every input reaches one, the longest and shortest unconfirmed distance to an anchor, which unconfirmed transactions passed script, amount and lock-time checks, and the payment's observed status. A receiver that reports ancestry distance, as BREAD does, and a receiver that holds a [object Object] can each make one from the evidence it already has. No statement says that a payment will be mined. The BRC also converts Electrum-form Merkle branches to BRC-74 paths and defines an optional signature and wallet method.
Motivation
Two kinds of evidence are in use for a payment that is not yet mined.
The first is ancestry distance. The receiver walks back from the payment through its unconfirmed ancestors until it reaches a transaction with a Merkle path to a block header, and reports the number of steps. The number records distance; which checks were run is a separate fact. ElectrumSVP's release notes for version 0.2.0-beta.1 describe evidence of this kind under the name BREAD: "Improved BREAD verification, including local proof-data handling, unconfirmed transaction verification, confirmed-ancestor anchoring, hop reporting, and BREAD JSON export". Its 0.2.0 release notes expand the name as Blockchain Referenced Evidence and Data.
The second is BEEF (BRC-62, with the Atomic form of BRC-95 and the V2 form of BRC-96), which carries unconfirmed ancestors back to transactions with BRC-74 Merkle paths. With it, a receiver can run every script, check every signature, and check that each transaction's inputs cover its outputs, the checks that BRC-67 lists for simplified payment verification. When it does, the result answers whether every spend from those coins to the payment is valid. The BEEF alone does not say whether a receiver ran those checks, or against which headers.
Neither kind of evidence answers whether the payment will be mined, or whether a conflicting spend of one of its inputs exists. Those depend on what miners do next. A receiver can look for a conflicting spend at a given moment, through a node it runs or a service it asks, and that observation is the most it can hold.
Each kind of evidence is described in its own terms today. "Three hops" and "a valid BEEF" may describe the same payment, and neither phrase alone lists the checks behind it. A statement in common terms lets:
- a user see what their wallet checked before they hand over goods;
- an application apply one acceptance policy, whichever wallet serves it;
- a wallet of either kind report what it knows, without adopting the other kind's format or architecture.
Scope and conformance
Layer. Interface: what one program tells another about a payment, whether wallet to application, wallet to user or wallet to wallet. Whether to accept a payment is policy, and this document does not set it.
Three roles are used, and a MUST binds only an implementation that claims the role its sentence names:
- a maker produces statements (sections 2 to 4, 6 and 7);
- a reader reads them (section 5);
- a wallet that offers the method of section 8, which that section binds.
Adoption is voluntary. A wallet that makes no statements does not follow this document, and its other behaviour is unaffected.
What this document does not require. How a maker obtains its material or its block headers; how it stores anything; which transport carries a statement; whether a maker validates at all (a statement whose validation is "none" conforms); whether and how it checks for a conflicting spend; the values of its bounds and of a reader's; and the BRC-100 interface, which section 8 uses optionally. A statement is self-contained: reading it needs no service and no key, and checking its anchors needs only block headers.
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as described in RFC 2119 and RFC 8174 when, and only when, they appear in capitals.
Specification
1. Terms
- Payment: the transaction a statement is about.
- Txid: the double SHA-256 of a transaction's bytes. Inside a transaction, a BEEF, an Atomic BEEF's prefix and a BRC-74 path, a txid is in internal byte order, the order the hash gives; in a statement, and in this document's tables, it is 64 lowercase hexadecimal digits in display order, the reverse. A maker MUST compute every txid from the bytes it holds. An input names the transaction it spends by txid in internal byte order, and the maker matches it against the txids it computed in that same order. A txid written beside the bytes is a claim.
- Material: what the maker holds of the payment's ancestry, of one of two kinds: a BEEF as received (BRC-62 V1,
0100beef, or BRC-96 V2,0200beef, alone or inside a BRC-95 Atomic BEEF), or raw transactions and Merkle paths from the maker's own records. A statement is made over one material. - Header source: the block headers the maker trusts, by height, and its tip, the highest of them; the source holds the tip's header. How the maker obtains them is outside this document. Every anchor is only as good as this source (see Security Considerations).
- Median time past: the median of the timestamps (bytes 68 to 71 of the 80-byte header, little-endian) of the 11 blocks ending at the header source's tip, that is the tip and the 10 blocks below it. A maker whose header source lacks one of those headers has no median time past.
- Merkle path: BRC-74 bytes. In a BEEF, a path counts for a transaction only when that transaction's entry names its index: BRC-62's has-BUMP byte
01and index, or BRC-96's format01and index. In records, a path is held for a txid, as BRC-74 bytes or as an Electrum-form branch (section 6). - Own path: for a txid at offset
xof level 0 of a path of tree heighth(the lowest such offset, if the txid is at more than one), thehsteps that fold it. At stepi, from 0 toh - 1, the working hash and its sibling, the node at offset(x >> i) XOR 1of leveli, are hashed together, the left node first, as the double SHA-256 of their 64 bytes. The sibling is the hash the path gives at that offset, the working hash again where the path marks that offset a duplicate (flag01), or the node computed from the two nodes below it. The working hash starts as the txid and its last value is the root. A step with no sibling ends the fold with no root, and a txid that is not at level 0 has no own path. A one-transaction block is the exception: a path of tree height 1 that holds one node, the txid at offset 0, has no step, and its root is the txid. - Anchor: a transaction the maker holds, with a Merkle path that (a) gives a root by the fold of the transaction's own path, which takes exactly the path's tree height of steps, or none for a one-transaction block; (b) names a height at or below the header source's tip at which the header source holds a header; (c) gives a root equal to the Merkle root of that header (bytes 36 to 67 of the 80-byte header, in internal byte order); (d) is for a transaction that is not exactly 64 bytes long; and (e) at no step of the own path hashes 64 bytes, the two nodes in the order hashed, that decode as a transaction. Any field carried with the material that asserts confirmation, a height or a header included, is a claim, and is not evidence of an anchor.
- Decodes as a transaction, for 64 bytes: read in the standard transaction serialization, they give, ending exactly at byte 64, a 4-byte version; an input count of at least 1; each input as a 32-byte txid, a 4-byte index, a script length and that many bytes, and a 4-byte sequence number; an output count of at least 1; each output as an 8-byte value, a script length and that many bytes, with every value, and the running sum of the values, at most 2,100,000,000,000,000; and a 4-byte lock time. Counts and lengths are VarInts, in any of their forms.
- Unconfirmed set U: the transactions the walk of section 2.1 reaches that are not anchors. The payment is in U unless it is itself an anchor.
- Unresolved input: an input of a transaction in U whose source transaction the maker does not hold.
2. Making a statement
2.1 The walk
The maker starts at the payment and visits each transaction once, in whatever order the material holds them. It reads the Merkle path of each visited transaction that has one, as BRC-74 permits (below). A path that meets condition (b) of an anchor is checked as one (section 1), and its transaction is not followed further. A path that does not meet condition (b), because it names a height above the tip or one for which the header source holds no header, is not checked: the maker treats its transaction as if it carried no path. Every other visited transaction joins U, and each of its inputs is followed to the transaction it spends, or recorded as unresolved if the maker does not hold that transaction. The inputs come from the held bytes, never from anything carried beside them. The maker decodes only the transactions the walk visits. It reads the rest of the material only as far as its framing needs and, in an Atomic BEEF, as far as each entry's txid and the outpoints its inputs name, to tell an ancestor from an unrelated entry. Framing a BEEF reads every path in it, and a node's flag sets the node's length, so a path that holds a flag other than 00, 01 or 02 cannot be framed: it is MALFORMED whether or not a visited transaction names it.
A BEEF V2 entry that carries only a txid holds no transaction, so an input that spends it is unresolved. BRC-96 treats such an entry as valid by agreement between the parties exchanging the BEEF, and that agreement is not evidence a statement records. A maker that holds the transaction MAY make its statement from its records instead.
An Atomic BEEF that lacks an ancestor is material here. BRC-95 fails the validation of such an Atomic BEEF; a maker reads it, and the statement names the inputs that are unresolved. A statement about it does not say that it passes BRC-95 validation. BRC-95's other rules apply as written: the subject, the 32 bytes after the prefix read in internal byte order, is the payment, and the material holds the subject and its ancestors and nothing else. An ancestor is any entry the material holds whose txid an input of the subject, or of another ancestor, names, an anchor's inputs included. A transaction beyond an anchor is therefore an ancestor: BRC-95 permits it, the byte bound counts it, and the walk does not visit it. An entry that carries only a txid has no inputs, so it names no further ancestor, and one whose txid no such input names is unrelated, as an unrelated transaction is.
A maker MUST refuse, with the code given, and return no statement:
| Code | When |
|---|---|
MALFORMED | Material that does not decode completely: bytes missing or left over (a decoder is told its input is complete). A BEEF whose version is not 0100beef or 0200beef, so the legacy efbe0001 too. An Atomic BEEF whose subject is not the payment, or that holds an entry other than the subject and its ancestors, an entry that carries only a txid included. A BEEF that holds one txid twice. A path in a BEEF that holds a flag other than 00, 01 or 02, whether or not a visited transaction names it. A payment not in the material. Bytes whose txid differs from the txid they are held under. A transaction in U with no inputs or no outputs. An input naming an output that its held source does not have. A path of a visited transaction that BRC-74 does not permit (below). |
ANCHOR_MISMATCH | A Merkle path that meets condition (b) of an anchor fails condition (a), (c), (d) or (e). The transaction is not treated as unconfirmed instead. |
CONFLICT | Two inputs of transactions in U spend the same output, within one transaction or across two; or a transaction in U spends an output that an anchor the walk reached also spends. |
OVER_BOUND | The maker reads more bytes than its bound: for a BEEF, its whole length, with any Atomic prefix, since the maker frames all of it; for records, the bytes of each transaction the walk visits and of the path held for each of those, as BRC-74 bytes (an Electrum-form branch as converted), and nothing else the records hold. Or the walk reads more transactions, anchors and U together, than its bound; or the longest path through U holds more transactions than its bound on distance. Or the statement, in its canonical form (section 4), is longer than the maker's bound on statement length. |
A path that BRC-74 does not permit is one with a tree height of 0 or more than 64; a flag other than 00, 01 or 02; two nodes at one offset of a level; a node outside the tree, at an offset of 2^(h - i) or more at level i of a tree of height h; or a node, given as a hash or as the duplicate of its sibling, that differs from the node computed from the two nodes below it. These are checked on the path of every visited transaction, whether or not it meets condition (b), and the flags on every path of a BEEF, since framing reads them. Nodes off a transaction's own path take part in these checks and in nothing else.
A maker MUST have all four bounds and MUST refuse beyond them, never describe part of a graph. It MUST NOT emit a statement longer than its bound on statement length, and refuses OVER_BOUND instead. Their values are policy. A maker SHOULD use 1,000,000 bytes as its bound on statement length, the value section 5 recommends for a reader's bound, so that a reader with that bound reads every statement a maker with it emits.
After a reorganisation that replaces the block a path names, the header source holds another header at that height, and material that holds the path is refused ANCHOR_MISMATCH (condition c) until its path is replaced.
2.2 Anchoring and distance
fullyAnchoredis true when no input is unresolved.distanceMax, when the payment is fully anchored, is the number of transactions of U on the longest path from the payment back to an anchor. It is 1 when every input of the payment spends an anchor's output, and 0 when the payment is itself an anchor. It is null when the payment is not fully anchored.distanceMinis the number of transactions of U on the shortest path from the payment back to an anchor, whether or not the payment is fully anchored. It is 0 when the payment is itself an anchor, and null when no path reaches an anchor.
A path's number of transactions of U equals its number of edges from the payment to the anchor: for a chain D, C, B, A in which D spends C, C spends B, B spends A and only A is anchored, both distances are 3.
2.3 Validation
A transaction X of U is validated when the maker has run each check below on X and on every transaction of U that X descends from, and every check passed. Only a transaction whose ancestry is fully anchored can be validated, because the checks read the outputs it spends.
- Scripts. For each input, the unlocking script followed by the locking script of the output it spends evaluates to true under the consensus rules in force for the block after the header source's tip. Some of those rules depend on the height at which the spent output was created: for an output that an anchor created, the height of the anchor's block, and for an output that a transaction of U created, the block after the tip, as SV Node judges an output created in its mempool (
validation.cppL2667-L2674 and L2692-L2696). On mainnet the Genesis upgrade activated at height 620,538 and the Chronicle upgrade at 943,816 (SV Nodechainparams.cppL18-L23); for example,OP_2MULis enabled for an output created at or above 943,816 and disabled for one created below it (interpreter.cppL360-L372). A maker whose next block is below an upgrade's activation height applies the rules from before it. This check includes every signature check (BRC-67 step 1). - Amounts. Each output's value, and the sum of X's outputs, is from 0 to 2,100,000,000,000,000 [object Object], and the outputs X spends add up to at least the sum of its outputs. BRC-67 step 2 asks for more than the outputs, as a stand-in for a fee rate. This check asks only that no value is created, and section 2.4 reports the fee.
- Lock time. X can be mined in the block after the header source's tip as it stands: its
nLockTimeis 0; or every input's sequence number is0xFFFFFFFF; or itsnLockTimeis below 500,000,000 and below that block's height; or itsnLockTimeis 500,000,000 or more and below the median time past (section 1). An input that spends an output of an anchored coinbase transaction does so only if that block's height is at least the coinbase's height plus 100, the network's coinbase maturity (SV Nodeconsensus.hL75). An input that spends an output of an anchored transaction whose first output's locking script begins006a0463667478(OP_FALSE OP_RETURNand a push ofcftx), a confiscation transaction (frozentxo_db.cppL614-L636), does so only if that block's height is at least the anchor's height plus 1,000 (consensus.hL79,validation.cppL2627-L2636). Before Genesis, the relative lock times of BIP 68, set by each input's sequence number, also bound a transaction of version 2 or above (validation.cppL272-L273 and L3463-L3468,policy.hL247-L255); a maker whose next block is below the Genesis activation height applies them too. BRC-67 step 4 asks thatnLockTimeand eachnSequencebe set to the values the receiver expects. This check asks only whether X can be mined in the next block; which values a receiver expects is its policy.
Only a check that ran under the consensus rules and failed is a refusal, and the maker then returns no statement:
| Code | When |
|---|---|
SCRIPT_FAILED | Check 1 ran, and an evaluation ended false or broke a consensus rule. |
VALUE_CREATED | Check 2 fails. |
PREMATURE | Check 3 fails: X cannot be mined in the next block as it stands. This does not find X invalid. A transaction whose lock time is still to come may be meant to be replaced before then, as in the payment channels of BRC-9 step 9, and a statement can be made once a later tip lets check 3 pass. |
A maker MUST NOT refuse because of a limit it sets for itself, such as a bound on a script's memory, operations or number length, or because of a stricter rule it applies for its own use. When the maker cannot complete a check on a transaction, it MUST leave that transaction, and every transaction of U that descends from it, out of the validated set, and MUST NOT refuse because of it. It cannot complete a check when its interpreter does not implement an opcode the script uses under the rules in force, or treats it otherwise than those rules do (as disabled, as invalid or as doing nothing); when an evaluation reaches one of its own limits; when a lock time needs a median time past it does not have; or when check 3 needs a relative lock time and the maker does not implement those. Nor can it complete the checks on a transaction of U whose own first output's locking script begins 006a0463667478: that is a confiscation transaction, which SV Node accepts only when it is whitelisted (validation.cpp L2562-L2587), and a maker cannot know the whitelist. A maker MAY also leave out a transaction that passes these checks but not a stricter check of its own, and it need not check a transaction that descends from one it left out. A statement records only checks that passed: a maker MUST NOT count as validated a transaction whose checks were not all completed.
A maker that ran a check and found that it failed MUST refuse. It MUST NOT then report that transaction as not checked, or make a distance-only statement about the same payment from material that holds it, while the failure stands; for PREMATURE, that is until a later tip lets check 3 pass.
validated lists the validated transactions. validation is "all" when the payment is fully anchored and every transaction of U is validated, "none" when U is not empty and no transaction is validated, and "partial" otherwise. A maker that runs no checks reports "none", and conforms. A payment that is itself an anchor has an empty U, so its validation is "all" whether or not the maker validates: the checks of this section apply to U, so both kinds of maker have run the same checks on such a payment, and both make the same statement.
When more than one refusal applies, a maker MAY report any of them.
2.4 Fee
lowestFeeRate covers validated transactions only. It is the fee and size of the validated transaction whose fee per byte is lowest, as {"bytes": size, "satoshis": fee}, where the fee is what its inputs spend less what its outputs pay, and the size is the length of its bytes. Among equal rates it is the one with the smallest txid. It is null when no transaction is validated. Two integers carry the rate without rounding. Whether the rate is enough for a miner is policy.
2.5 Status and observations
status is {"depth": d, "event": e}, where e is the event furthest down this table among those the maker observed for the payment, whatever order it observed them in:
event | Meaning | depth |
|---|---|---|
received | The maker holds the payment, from another party. | null |
signed-locally | The maker signed the payment itself. | null |
handed-to-broadcaster | The maker gave the payment to a broadcaster. | null |
seen-by-network | A node or service reported holding the payment among its unmined transactions. | null |
mined | The payment is itself an anchor. | tip.height less the anchor's height, plus 1 |
A maker MUST say mined when the payment is itself an anchor, and MUST NOT say it otherwise, whatever it was told.
conflicts is {"checked": false}, or a check the maker made for a conflicting spend:
{"at": t, "checked": true, "found": f, "kind": k, "scope": s}
at: when the observation was made, in Unix seconds, no later thanmadeAt.found: true if a transaction other than those in U was observed spending an output in scope.kind:own-node, a node the maker operates, orthird-party, a node or service operated by another party.scope:payment, the outputs the payment's own inputs spend, orunconfirmed, the outputs spent by every transaction of U.
How the observation is made is operation, and outside this document. found: false says only that none was seen at time at.
madeAt is when the statement was made, in Unix seconds.
tip is {"blockHash": b, "height": n}: the header source's tip when the statement was made, and the double SHA-256 of its header in display order. Every depth and lock-time verdict in the statement is for that tip: check 3 was made for the block at n + 1.
3. The statement
A statement is a JSON object with exactly these fields:
| Field | Type | Value |
|---|---|---|
anchors | array | One {"blockHash", "height", "txid"} per anchor the walk reached, sorted by txid. blockHash is the double SHA-256 of the header the path reached, in display order. |
conflicts | object | Section 2.5. |
distanceMax | integer or null | Section 2.2. |
distanceMin | integer or null | Section 2.2. |
fullyAnchored | boolean | Section 2.2. |
lowestFeeRate | object or null | Section 2.4. |
madeAt | integer | Section 2.5. |
status | object | Section 2.5. |
tip | object | Section 2.5. |
txid | string | The payment. |
unconfirmed | array | The txids of U, sorted. |
unresolved | array | One {"txid", "vout"} per unresolved input, the output it spends, sorted by txid and then by vout. |
validated | array | The txids of the validated transactions, sorted. |
validation | string | none, partial or all (section 2.3). |
version | string | bsv-payment-evidence/v1 |
Every txid and block hash is 64 lowercase hexadecimal digits, in display order. Every array is in strictly ascending order of the strings and integers named, so no txid (or txid and vout) is in it twice.
4. Canonical form
A statement is exchanged as the bytes of its canonical form:
- keys sorted by their bytes at every level, with no whitespace and the separators
,and:; - integers in decimal, from 0 to 2^53 - 1, with no sign, leading zero, fraction or exponent; there are no other numbers;
- strings only from the values of section 3, so no character is ever escaped;
null,trueandfalseas JSON writes them; - the whole encoded as ASCII.
This is the canonical form of BRC-179 section 7.2, extended with integers and null as above. A maker MUST emit it.
5. Reading a statement
A reader has a bound on the length of the bytes it reads. Its value is policy, and a reader SHOULD use 1,000,000 bytes, the value section 2.1 recommends for a maker's bound on statement length. A reader MUST, in this order:
- refuse
OVER_BOUNDif the bytes are longer than its bound, before it parses them; - refuse
MALFORMED_STATEMENTunless the bytes are ASCII, nest arrays and objects at most 32 deep (the outermost object is depth 1), and parse as a JSON object, with no key twice in one object, whoseversionis a string; - refuse
UNKNOWN_VERSIONifversionis notbsv-payment-evidence/v1, and read no further; - refuse
MALFORMED_STATEMENTif the bytes are not the canonical form of the object they parse to; if a field is missing, unexpected or of the wrong type (a boolean istrueorfalse, never a number); if a txid or block hash is not 64 lowercase hexadecimal digits; if avoutis above 2^32 - 1, the largest output index a transaction can name; if an array is not in the strictly ascending order section 3 gives; ifvalidation,status.event,conflicts.kindorconflicts.scopehas a value that sections 2.3 and 2.5 do not list; or if the fields disagree with one another:fullyAnchoredis true exactly whenunresolvedis empty;- no txid is in both
anchorsandunconfirmed; - the payment is either in
anchors, withunconfirmedempty, or inunconfirmed; distanceMaxis null exactly whenfullyAnchoredis false, anddistanceMinis null exactly whenanchorsis empty;- for a payment in
anchors,anchorsholds that entry only and both distances are 0; otherwise a fully anchored payment has an anchor, a distance that is not null is at least 1 and at most the length ofunconfirmed, anddistanceMinis at mostdistanceMax; validatedis withinunconfirmed, andvalidationis the value section 2.3 gives for these lists;- the payment is in
validatedonly ifvalidatedequalsunconfirmedandfullyAnchoredis true; - the txid of an
unresolvedentry is not inanchors,unconfirmedorvalidated; lowestFeeRateis null exactly whenvalidatedis empty, and itsbytesis at least 1;status.eventisminedexactly when the payment is inanchors, andstatus.depthis a positive integer then and null otherwise;conflicts.at, when present, is at mostmadeAt;- every anchor's
heightis at mosttip.height, and for a payment inanchors,status.depthistip.heightless the payment's anchor height, plus 1.
A reader MUST NOT take a statement to say more than its fields do. A fully anchored payment is not a mined payment. Validation all does not mean the payment will be mined. found: false does not mean that no conflicting spend exists.
6. Merkle branches in the Electrum form
The Electrum protocol's blockchain.transaction.get_merkle returns a Merkle branch as {"block_height": h, "merkle": [...], "pos": p}: the sibling hashes from the bottom of the tree up, each as hex in display byte order, and the transaction's index in the block. Electrum-protocol servers return branches in this form. A maker MAY hold paths in this form, and raw transactions held with such branches are material (section 1). A maker that converts a branch to a BRC-74 path MUST:
- compute the txid from the raw transaction it holds;
- refuse
MALFORMED, and make no path, if the raw transaction does not decode completely; if the branch is not an object of exactlyblock_height,merkleandpos, with non-negative integershandp(hbelow 2^64, since BRC-74 writes it as a VarInt) and each sibling 64 lowercase hexadecimal digits; if it has more than 64 siblings (BRC-74's limit on a tree's height); or ifpis2^nor more, wherenis the number of siblings (with no sibling,pis 0). The conversion refuses nothing else; - write the path with block height
hand tree heightn, or, with no sibling, tree height 1 and the transaction alone at offset 0, a one-transaction block. Level 0 holds the transaction at offsetpwith flag02and its txid in internal byte order, and, whenn > 0, the first sibling at offsetp XOR 1. Each levelifrom 1 ton - 1holds siblingiat offset(p >> i) XOR 1. Nodes in a level are in ascending offset. A sibling equal to the working hash at a level where the working node's offset is even is written with flag01and no hash; every other sibling is written with flag00and its hash in internal byte order.
The conversion hashes the branch only to find those duplicates. The converted path is a Merkle path like any other: it anchors only through the checks of section 1, against the maker's own header source, so a step that hashes 64 bytes that decode as a transaction is refused ANCHOR_MISMATCH there, when the path is checked. Only the siblings, h and p are used. A maker that holds a branch and does not convert it MUST check it as if converted, with the same refusals and the same anchor. Folding the branch as the Electrum protocol does and folding the converted path give the same root.
7. Signing (optional)
A maker MAY sign the canonical bytes of a statement as a BRC-77 message. The BRC-77 serialization travels beside the statement, never inside it. A verifier checks it over the exact bytes it received; any other serialization of the same object does not verify. A signature says who made a statement and adds nothing to what the statement claims.
8. Offering statements to applications (optional)
A wallet that implements BRC-100 MAY offer one additional method, getPaymentEvidence:
- Arguments. Either
txid, a payment the wallet holds, oratomicBEEF, an Atomic BEEF (BRC-95) for the wallet to evaluate without storing it; andsign, a boolean, false when omitted. ForatomicBEEFthe material is that Atomic BEEF alone: the wallet's records resolve none of its inputs, so any party with the same bytes and the same headers can make the same statement. ForatomicBEEF, too,status.eventisreceivedunless the payment is an anchor, whatever the wallet's records say of the payment, andconflictsis{"checked":false}or an observation made for this call. - Result.
statement, the statement as a string, and, whensignis true,signature, the BRC-77 serialization as hex. A string keeps the bytes exact across transports that re-serialize objects. - Errors. A refusal is a BRC-100 error, with
status"error", acodeofERR_EVIDENCE_followed by the refusal code of section 2 (for exampleERR_EVIDENCE_ANCHOR_MISMATCH), and adescription; no statement is returned. Fortxid, a payment the wallet does not hold and a call the user has not permitted for that payment both give the codeERR_EVIDENCE_UNKNOWN_TXIDwith the samedescription. A call with neithertxidnoratomicBEEFgivesERR_MISSING_PARAMETER, one with both givesERR_CONFLICTING_PARAMETERS, and asignthat is not a boolean givesERR_INVALID_PARAMETER_VALUE, the codes BRC-100 suggests for those cases; none returns a statement.
A wallet that offers the method MUST return the statement's canonical bytes (section 4) unchanged, and its errors as above.
The method is not one of BRC-100's methods. It changes no BRC-100 argument, result, call code or default behaviour, and an application that does not call it sees no change. This document assigns it no wire call code. As BRC-100's compatibility contract requires of an unsupported extension, a wallet that does not offer the method fails the call explicitly, and that failure says nothing about the payment.
An application learns whether a wallet offers the method by calling it, never from the getVersion string (BRC-205 section 6), and a wallet that publishes a BRC-179 capability manifest declares it there as <product>.<surface>.getPaymentEvidence, at the tier of its most sensitive step.
Rationale
Two distances. The longest path is the worst case. A payment is good only if every input is good, and a short path through one input says nothing about a long path through another, so a limit on unconfirmed depth compares with distanceMax. distanceMin, the distance to the nearest anchor, exists even when some input is unresolved. On a chain the two are equal; on S5 they are 3 and 1. Carrying both lets an application see the gap.
A failed check is a refusal. A statement that recorded a failed check would rely on every application reading it correctly in order not to accept an invalid payment. A refusal cannot be misread, and it keeps none meaning "not checked".
Not checked is not failed. A validation refusal (section 2.3) says the payment cannot be mined as it stands, so it is kept for checks that ran under the consensus rules and failed. A maker's own limits, and rules its interpreter does not implement, only leave transactions out of the validated set: the statement then says less, and nothing false.
A path that does not match is a refusal. A Merkle path that leads to a root other than that of the header the maker trusts at its height is contradicted evidence: it is fabricated, or from a block the maker's chain does not hold. Treating its transaction as unconfirmed would hide that. A path above the tip, or at a height for which the header source holds no header, is neither confirmed nor contradicted, so its transaction is walked as an unconfirmed one, and a later statement may anchor it. A path that BRC-74 does not permit is wrong whatever the headers say, so it is refused before any header is read.
The own path. Two inner nodes read as a transaction are 64 bytes long, so condition (d), which never anchors a 64-byte transaction, keeps inner nodes from standing for a transaction. Condition (e) keeps a transaction from standing for inner nodes, and, like condition (a), it concerns only the steps that fold the transaction's own txid, since only those decide what the path proves about that transaction. Nodes elsewhere in a compound path are checked against one another and nothing more: a pair among them that decodes as a transaction proves nothing about this transaction either way (vector S14).
Partial material is reported. A statement exists to say what is missing, so an Atomic BEEF that lacks an ancestor is read and the gap is named. Refusing it would leave a receiver that holds partial evidence no way to say so. Bytes that are wrong in themselves, such as an unrelated entry in an Atomic BEEF, a txid twice or a path BRC-74 does not permit, are refused.
Bounds refuse. A walk cut short would report unresolved inputs for a reason a reader cannot see. A statement longer than a reader's bound is refused unread, so a maker refuses to emit one longer than its own, and one recommended value for both keeps a maker and a reader that use it in agreement.
Status apart from evidence. Broadcast, relay and mining are events the maker observes, and the evidence fields are checks it ran. Keeping them apart stops a report of the first kind standing in for the second. mined is the one status the evidence itself supports, so it is the one status derived from it. The tip is named so that a reader can check the depth, and the lock-time verdict, against its own headers.
Test Vectors
The vectors were generated from code by the reference implementation, never typed.
Common inputs: the header source is the table below and its tip is 950,010, unless a vector says otherwise; madeAt is 1793318400 (2026-10-30T00:00:00Z); the Genesis and Chronicle activation heights are mainnet's, 620,538 and 943,816, and every block here is at height 949,999 or above, so every output is created, and every input judged, under the rules in force after both; the maker's bounds are 1000 transactions, a distance of 100, 32,000,000 bytes of material and 1,000,000 bytes of statement unless a vector says otherwise; the maker validates unless a vector says "distance only"; status is received and conflicts is not checked unless a vector says otherwise; a reader's bound is 1,000,000 bytes unless a vector says otherwise. The headers are synthetic: the header source is an input of each vector, so no proof of work is needed. Every key is the secp256k1 secret SHA-256(payment evidence test vector: + label), and every signature uses RFC 6979 nonces. The keys are test keys and protect nothing.
Keys
| Label | Public key |
|---|---|
payer | 036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3 |
not the payer | 0295214b460ee5aeacb289344c9a2c25070c622181bc1ac9b55436e5c3b72d0bd8 |
receiver | 03fb1aaf51797cd0551feeeacb42dfd98be2bbcd072e6d9445d3a2620b103c3adc |
Every output pays P2PKH to the payer key, and every input is signed by it with SIGHASH_ALL | SIGHASH_FORKID, except as follows. BADSIG's signature is by the not the payer key. The second output of A6 is locked with 8d5487 (OP_2MUL OP_4 OP_EQUAL), and X6 spends it with 52 (OP_2). T64 is exactly 64 bytes: its input's unlocking script is 51515151 in place of OP_TRUE, and its only output has an empty locking script, which P64 spends with 51 (OP_TRUE). TL and TLATE carry lock times given as a time, 1793002399 and 1793002400, with sequence 0xfffffffe. A transaction that carries a Merkle path spends output 0 of a transaction whose txid, in internal byte order, is SHA-256(payment evidence test vector: + its name), with the unlocking script OP_TRUE; only the conflict check of section 2.1 reads that input (vector M20). T01's output value is the first from 100,000 up that puts 01 at byte 4 of its txid in internal byte order. DS spends A1 output 0 and, with OP_TRUE, the outpoint A1 itself spends. Z4, txid 3721db44eccd6e28b0b7cb36cbab33dbdb1f8643603f4d437ace61442800466b, is spent by P4 and held by no maker. CF and CFU each have a first output of 0 satoshis locked with 006a046366747815019d57f040e087001d86955e34665a10eef59c654f, which begins 006a0463667478, so each is a confiscation transaction: CF is mined, and CFS spends its second output; CFU spends A1 output 0.
Header source
| Height | Block hash | Header |
|---|---|---|
| 950001 | d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e | 000000206b0d72cc817bdfe98bc0ccb64c9c8c0a70774fe82939b6a50cff8db0fce17353faac2f5d9533c2686ccf4c05aeb9bd51ed9e5ea108156765378a6e1209a309424002df6affff7f2000000000 |
| 950002 | 64a53adabc6a36de2c5176485d47e64c06f56d1b588e638ba8c7d349bdc459fc | 000000209e5e4ce3338d9d9b195d37052de72eaeaa5ed949e21b634374555030d62031d790d075c6504da015e31e8b4dd7f9b3f13203f6ec553227fa499469aed264cb1a9804df6affff7f2000000000 |
| 950003 | 4ef4e7bfd2500d3ef2c4b89cce091e27feb0f1a82a4ceaca0395f35b9827eda7 | 00000020fc59c4bd49d3c7a88b638e581b6df5064ce6475d4876512cde366abcda3aa564eadfa677c67f2ba97e98f9e7df20bb5ffcffe6e0b5b1158f35af500f74943648f006df6affff7f2000000000 |
| 950004 | ee55e78df915a761c888acb74bf87c5290c24af8a170e8510e7e43f6104e2916 | 00000020a7ed27985bf39503caea4c2aa8f1b0fe271e09ce9cb8c4f23e0d50d2bfe7f44e3fe4119fc9cc69434be8030f23c73af7ce85b9edfa54f46b2acf04894afac78f4809df6affff7f2000000000 |
| 950005 | 23cd77f659989d40993179d03215f98288825156a8d56b5eeec397ae4e4d275e | 0000002016294e10f6437e0e51e870a1f84ac290527cf84bb7ac88c861a715f98de755eef589bf0ce95f64670549013576e136278958bd9b225891d9384b510518f0a9fda00bdf6affff7f2000000000 |
| 950006 | ab14e92c0acb7212d9a1219e6c468b0f2c4ee53a7c351486bf99e916dfa1f90f | 000000205e274d4eae97c3ee5e6bd5a85651828882f91532d0793199409d9859f677cd235fbc9265a1d243f9085e07d40e3c2d788cbcf9f82a3d6af6809a6612b05c6f29f80ddf6affff7f2000000000 |
| 950007 | a036c06c92ea0d49b3b6862932aa4533730bcc711249099595efd41573bd33db | 000000200ff9a1df16e999bf8614357c3ae54e2c0f8b466c9e21a1d91272cb0a2ce914abaf6aad4a6fc106d25c5f08419945672a02c50051e362701fe1cf22d6993ebe115010df6affff7f2000000000 |
| 950008 | cd2ccdbacf490cb9b574720989e69c3a427159e3059b85fcadc6d1b04d5ed86f | 00000020db33bd7315d4ef959509491271cc0b733345aa322986b6b3490dea926cc036a02bbbf06acfeea203c81dc858f5b9f865eda979478e7b1b2a70660212ad8e411ba812df6affff7f2000000000 |
| 950009 | f954b173e1932e44aafc432a0171c2b4c755f11cd479cf3bae8da4d82bcb87fc | 000000206fd85e4db0d1c6adfc859b05e35971423a9ce689097274b5b90c49cfbacd2ccd3bb86fd84bd65820432eb446ddb8e90be9caba4f10e4eb79a414b31066cb618f0015df6affff7f2000000000 |
| 950010 | e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a | 00000020fc87cb2bd8a48dae3bcf79d41cf155c7b4c271012a43fcaa442e93e173b154f9153f4a5e0b2934460eda12e4a427a7125d11e165c771a529056b72135d2697cc5817df6affff7f2000000000 |
Vectors S11 and M12 use a header source that holds the 11 blocks ending at the tip: the table above plus a header at height 950000, block hash a7259cbb2bde89b111fb6b7a61f1ce9ebeb2088db84f2f1e00933598fa4e9f23:
00000020d50cbe4fa99f43bdcd39efc070f7635f17b65aa6cb99fd70be0f3b6375213c42a59eb7b873142035ddceaee8caa686bb7ece1e9ee4ab72e2ba46314439191194e8ffde6affff7f2000000000
Their median time past is 1793002400. The table alone holds no header at height 950000, so it gives no median time past.
Vector M22 uses a header source that is the table above plus the block of CF, at height 949,999, block hash 18fb1eb3ef350fad0145f44278a930e575156e6c8ebc168738328453508c6afb:
000000200b21c7e7ebd8f56f14cf86e3184298b27152624f94d981c89691a359265aba67d5a41d520d3d2ba29119cbde4eb4adc93e164d822ea42243404d87501a16466990fdde6affff7f2000000000
Transactions
| Name | Txid | Bytes |
|---|---|---|
| A1 | 2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344 | 01000000010ddbe8f7bd041d50ea45fa1d9abc6c62fc35e5e91cb1ef61d2c3ba08c72a75ea000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P1 | e2127516adc12a98fdc758e7d6ab36c38505cb6731f6c9b68c3cdc02b3a33896 | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006b483045022100afd0af566d92711cc3fa91d6d1409ab41e1d4008a552760983f84dddd398c0f902205aa4926a19253ac987fce476bb8ab7aee1a14c882e0a6074fde19ab0eff4da174121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| A2 | ecd202a719806cfd5e5a5d768878512bc440a3239e49708a7ab4ea98bc618ee6 | 01000000012dd251ad7d3437397d359f7c7df83f01af6c7963934222956785a790dc39d99a000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| B2 | 8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c | 0100000001e68e61bc98eab47a8a70499e23a340c42b517888765d5a5efd6c8019a702d2ec000000006a47304402207c91686d795c90eabf584a221b1e0cba9145e9e1b0c018b11e4a8b54f658f6eb02204c28638b09f98366a64030670ceae2a0137f2091fc97dd2e4cf962b9a43fc9f84121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| C2 | 04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a | 01000000015c6994e55ef5d3098cb0dffcf4037ca0e419edeeaa1cd720b0d4d90c9f69168e000000006a4730440220416b977da3d863f1dfac7509c20c589bc04c143bbe1afbad725f17fe5284edc602201da34b01f7c79181a61aa61007d948922803e90b3820ee1c3bf56850b04e7c174121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff013c860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| D2 | 83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7 | 01000000019a2368a6fba9d56a3354d5401d646f5ad975131f635937d3f1d002c4b7aff204000000006a4730440220732a8993c5983880684b0b66096023448fd931f0baf7b365eac4165817b6887f02202b318fc1e6dbff167395bf1df60cf1b8eaac4bd581e1829e5622c29a957bb8c54121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff010a860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| A3 | 05e134ab77ba252ee5b17bc519fcfc24d23d70bf0c3f40eea65ca43ea53f61fe | 0100000001c06f2aa49efe4e17440086bf32ce7ac8deb7fa67e0e6780cc11bd99e0a2c00f2000000000151ffffffff0250c30000000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac50c30000000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| B3 | 6a5434d9c86b7a77bfec289f42d0344ff80d904d8542f1001779cad3fabf1b00 | 0100000001fe613fa53ea45ca6ee403f0cbf703dd224fcfc19c57bb1e52e25ba77ab34e105000000006b483045022100ce2bc41e423c1591aa4d91dfb6c23533915be8a161cd567ac2028180231f485b0220260aafb86d9b14f5a531bc3581e5c6179afa2931373c95d62c214983d0cfdc6e4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff011ec30000000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| C3 | 96c8a32fb64394dfc9357306687db01d67c8cadd4ae7483f3123f27f8e6e48f1 | 0100000001001bbffad3ca791700f142854d900df84f34d0429f28ecbf777a6bc8d934546a000000006a47304402205b3a7ab7817a61107393a0db81201417e4ad5db9957d52bf8bcfeeb997affe5a022021afc250c0f0715d92b416f6d04a8343b4b9942d02f7f0427f9eb0ea0bd84ef34121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff01ecc20000000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P3 | 215984478daf11bbe5da2cd5946792e2a1247f11f644eb7ed95e49e27ce56da6 | 0100000002f1486e8e7ff223313f48e74addcac8671db07d68067335c9df9443b62fa3c896000000006b483045022100943569633e37774ece3788de136b1dbc44e81f39f9e6859ec5674dc4c7576fe902202be98d80bed53af0ae6e4d7696acc412c00ec52cd92ba6b3e7766d9dcbd4918d4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3fffffffffe613fa53ea45ca6ee403f0cbf703dd224fcfc19c57bb1e52e25ba77ab34e105010000006a473044022045235ccc847fa7db2d9763ba03fde894bdd9fda3d1fa3dd341880a6450e25fef02205722e2f22b7db4c31e80016137c7015f0d8ce9a275fe93fec0a96441aeffd2154121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff010a860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| A4 | 2749e001f0e6a84653059d4a2404641852717ebd373d935d0ec80b240afd8bae | 01000000017833ba4d7927e865248d4a7f845ca3b2a589f54251ada803645bdd1a22367b07000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| B4 | 6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595 | 0100000001ae8bfd0a240bc80e5d933d37bd7e7152186404244a9d055346a8e6f001e04927000000006b4830450221009bc8d449beb818a25683dd702c185d33c884a1e62ec357f134a6ad5ca3d30fbd02204cdf06d8d1e5aa5d29ce56e79bf89749799632e47e435c58e6083c1aad8b77aa4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P4 | df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c | 010000000295a59779b32c26b267bfd4e063f1ca376b311245e6beaa67b1df955757df0862000000006b483045022100a95750632f4bcdad72f1aa47887c1bb8de0cd8facd972b4760a0b0d81a4f97f602204d4a95dd315d3d0e4ed926b5d46a7683418f7d32be0c06eded7e094d9136e2f54121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff6b4600284461ce7a434d3f6043861fdbdb33abcb36cbb7b0286ecdec44db2137000000006a47304402206b60963ab400117c56cc2237e86e661ea826f2420cdc86d3a9aaed3095042ff8022015c12482686d813cee12bb3d75c76bdd6a8339b7419c1d6c0750e92a93329d124121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016cfb0100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| E5 | ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3 | 0100000001635947ef12b20d2b411090d5ca4db8377624988820ec1d22fad13dcca46a6384000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| BADSIG | 664569513982851cb5aefe29541ddf7de327a14206111191b9d5c07bfa59a60d | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006b48304502210082ac64baa07fab3df18f289ca1a8e5ebd809f641b40950640c2c0ae91875ab09022066bd7ba5ab08c7a6498db0e2ebdbce76fdc84e443416e640adf4434d56609a5c4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| RICH | 8b2fa28e38610df8d9038d48e1035213d8345cfbe38262c5e78159eac52297ce | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006a47304402205d8889878571c949d3d9367a93b628a83cdfedabc212d6a8da8424fb47fd89e90220254d3a6f57dd7093edccfb18d6ecb86cf7e6b0e34dcba89717eb2792a0b9d4b74121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff01a1860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| LATE | d35962714bdb0a3c002e03fffaae05a4700152e23bc5f795f146dedc908d92da | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006b483045022100931d7375eda07bac7fe325d23f826af1feb84310a51a9a72c9727c4e7f4a6c45022004fb05b964cdbb48b733eda5046246af8c994976cfa0e67065f396e373bc440b4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3feffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac047f0e00 |
| X | e2127516adc12a98fdc758e7d6ab36c38505cb6731f6c9b68c3cdc02b3a33896 | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006b483045022100afd0af566d92711cc3fa91d6d1409ab41e1d4008a552760983f84dddd398c0f902205aa4926a19253ac987fce476bb8ab7aee1a14c882e0a6074fde19ab0eff4da174121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| Y | 2db39e9d04331e1e9065267846828abea8c20c94f082f57c9a816a3bc88a2c40 | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006b4830450221009c3b9c7117e117dd12f2028b5fc303b1977dd40768e12577cc994697b6f562cd0220388fed744f6f9b90cce9eb3ca9e5772721f1124b51489f704b880f3f5ade64204121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff013c860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| BOTH | 21a2a6decd9c12fd240a0f39b9e829471221ea15797ff3625a5b0f9fce8df64b | 01000000029638a3b302dc3c8cb6c9f63167cb0585c336abd6e758c7fd982ac1ad167512e2000000006b483045022100dec41f2fd6230f48b0af685b35f9c45ec453a2fc36133049cf62901a50c331c1022000dbe2736de85c7c4c48a296bbf56de37cce5d4e0b7fc3f78e2588511d1030cf4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff402c8ac83b6a819a7cf582f0940cc2a8be8a8246782665901e1e33049d9eb32d000000006b483045022100fd6f9d78ae4a5d01027544a974a40fcc8d063385853a71a693946bdb11756b4702200d3db1df1c32853849dd96cf99ea07e59dfae28bf76f513baa694a0f51b545f04121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff01780c0300000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| A6 | a7274c4562611d5914aee0f2e991a81176f446ecde0d70eeefe6cfc6404b379b | 01000000010224dd1e481f0fd12f9932799188d9482329f46571dff21bf16b6c2cad5d3845000000000151ffffffff02a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac50c3000000000000038d548700000000 |
| B6 | 6158929cc6db06e57aad638ac4b426e53ab9dc1593e33a5b08eabcae6c26f3eb | 01000000019b374b40c6cfe6efee700ddeec46f47611a891e9f2e0ae14591d6162454c27a7000000006a4730440220599490f1b3be6210bf02d60ea351275ac37363d4328673331797fd486f5cd80602205cc2658a0037268cd4aad8969a23fd411199ac4db474c3752031f51ffe87f6a64121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| X6 | c60f7125b095b56b4c703a279599203ccee550bf33811e53617f3c8c44312690 | 01000000019b374b40c6cfe6efee700ddeec46f47611a891e9f2e0ae14591d6162454c27a7010000000152ffffffff011ec30000000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P6 | 420adb2e2fd48ee95bae1e7e972b329a516106e6bfb1b6a321d399561822670f | 0100000002ebf3266caebcea085b3ae39315dcb93ae526b4c48a63ad7ae506dbc69c925861000000006b483045022100eb412527b03ad09d308102a5c12f9415c72af224c4572a66c5b44f14e20841d302207e9bcdede07338ce8a2c54ea5d22148799644ae867ad417526b9e391bd573c0b4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff902631448c3c7f61531e8133bf50e5ce3c209995273a704c6bb595b025710fc6000000006b483045022100c14d1b76d29288f7e3bf192b76dd420d7326dcc340985f179d38ed65880c6d3e022011a22815086b75d8aa366c128ec7dbfaec634d74cb19dc3f5a7cd60a8d56905c4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff0128490200000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| T64 | 6444bf849ea4136a9608b60996cc7d552d65d94c7183ae4f71a678add2de1e02 | 010000000103254c9167ae1de0add271e079a00da53b5e54e6da92dffabb1ada240222f576000000000451515151ffffffff01a0860100000000000000000000 |
| P64 | 23a67c1ad73128861b4741229a462f66d851e60c32e571b9fc8482d279c0f3b3 | 0100000001021eded2ad78a6714fae83714cd9652d557dcc9609b608966a13a49e84bf4464000000000151ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| TL | 525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006a4730440220102209fb202e103f9259e1aa1f26d7ad374dee1adcc4c82c80fcd96a59cad36f02200959f5112871a54e0cb095175a5c8412dd3fe254f6d68a0a6bec25f887d37ec54121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3feffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac9f0bdf6a |
| TLATE | c575cfff2bcd77600fb9f21d5708b69665aabdb98a3229ea38801664a45249b4 | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006a47304402205dab601da164e7598ea5c65a02cfccebcd2904c8624aea6e4aa91855d5835c1b022031e3abbc37976f79b83d84e77c281b66015ae1b67e2991e5b18c75fc1c4927c14121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3feffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988aca00bdf6a |
| A8 | 6ee90c20d3bbd231987e0573f79320f22f9f150a9fa56ec5b5802a99421cd17c | 0100000001b40ed0e317387d6c4472f6f43bc4b8335e58066b8bd6953efea5f7548e8ec810000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P8 | db874543d0c2b32bfe1e38c17a15609285746d278a7abe919e334ae83ee5f98e | 01000000017cd11c42992a80b5c56ea59f0a159f2ff22093f773057e9831d2bbd3200ce96e000000006a4730440220627c9d22a7b2b75d9fc4b442a7ea26e714b721c33eca95ffdde38c9ee9ffac34022058d275c5181ba8c8b3eaad8e321b447eca8ad9d59559b21d33aafd1112cd4bcb4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| T01 | e214b7aee5ba78b228a3ec5c14c396cf0b0cca6d668dfc79034fde0120648943 | 0100000001e8e99c0d85a14ac57d4253af99fc4ab39097e853fc695b4c3fba2d6d8d203906000000000151ffffffff015f870100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| P01 | 3641df02bc7f167afff33c58aec95af11b55df782a1a38783d19ffbb11549a94 | 01000000014389642001de4f0379fc8d666dca0c0bcf96c3145ceca328b278bae5aeb714e2000000006a47304402202bb6d3c07877f489109768b44b4122af671927bbce88412e9c8bd5271b923670022016e57d21e4d5f5aa20024e617524fb444d45ed78be9d559558e76b2734da39574121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff012d870100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| DS | bdd08561a7c9ab11ad839dbe9760a564c31a34bbf352371b26be942a3bba9eef | 010000000244e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006a47304402204b03fadd92054f9538b9ecf5d70f5b8fcf22a9774d4c603a8763e1783065fa31022069bc82ae9e4eefc1f4ca1f646cf3813e5c450e016c48cbf5207d4698f8351d294121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff0ddbe8f7bd041d50ea45fa1d9abc6c62fc35e5e91cb1ef61d2c3ba08c72a75ea000000000151ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| CF | fe8ef6f7bc70c02f4d05e03030aea556a7342298c52c3c2841ac13aa72c1104d | 010000000196c93e406e31b8c5dbfeb0e196372f821bcb4f658283102d1fd84f7cc71bab2c000000000151ffffffff0200000000000000001d006a046366747815019d57f040e087001d86955e34665a10eef59c654fa0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| CFS | 407a99aade12b75765162a6b5ff33750d4d66a076ab9b8895084a4fee5021f29 | 01000000014d10c172aa13ac41283c2cc5982234a756a5ae3030e0054d2fc070bcf7f68efe010000006b483045022100a1a9c4609310d2382d6d598b359db2ebac99354c30510a7616cd7a267d7519f502204fb20d0214e3b505e255b4d611114c7d9cc3af4c623a0452148a1ff66134ff804121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff016e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
| CFU | b93c53d9615c0a2bf6f72791a41abc329d70944630f4fd5dc894fd6c5cf5418c | 010000000144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c000000006a4730440220506fadc65c59834c4c9d82712d3f202cdb80b9ad08061c5f5bb2232491c8253f02207f676fd420928b4443b790b5b634e441a542f3d1484197aa5fb9bdbc6c30013c4121036f1c70084d945c9cf4e48a15c90089b078c0a82d78ce6bfb0f3243e38021a6b3ffffffff0200000000000000001d006a046366747815019d57f040e087001d86955e34665a10eef59c654f6e860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac00000000 |
Merkle paths
Each anchored transaction is in a block of its own, as the leaf at pos; the other leaves are SHA-256(payment evidence test vector: filler + height + + index), except as follows. In the block of A8, the leaves at 2 and 3 are the first and the last 32 bytes of T64. In the block of T01, the leaf at 3 is R, 0000000000000000000451515151ffffffff0100000000000000000000000000 (internal byte order), so that T01's txid in internal byte order followed by R decodes as a transaction. The Electrum form gives pos and the siblings bottom-up; the BRC-74 path is its conversion (section 6).
| Name | Height | pos | Siblings (Electrum form) | BRC-74 path |
|---|---|---|---|---|
| A1 | 950001 | 1 | 7a7f67ff94372f106ab9f59422b9280fd2b0c981e67cf8dc66e3f6cdd9bbbc49<br>e4152cebe7bc09be26d234fb6c435cd211e742f1447b4a47bb55c6a70581d44c | fef17e0e000202000049bcbbd9cdf6e366dcf87ce681c9b0d20f28b92294f5b96a102f3794ff677f7a010244e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c0101004cd48105a7c655bb474a7b44f142e711d25c436cfb34d226be09bce7eb2c15e4 |
| A2 | 950002 | 1 | 0aac0a69b2a97e02a6f103a2309ca105cb715d44ddfc99cf51c74e8b28b61786<br>ab3baadd2384b398f79c90082741f7a55fa2570d11c7b2b10d08eef975626d31 | fef27e0e00020200008617b6288b4ec751cf99fcdd445d71cb05a19c30a203f1a6027ea9b2690aac0a0102e68e61bc98eab47a8a70499e23a340c42b517888765d5a5efd6c8019a702d2ec010100316d6275f9ee080db1b2c7110d57a25fa5f7412708909cf798b38423ddaa3bab |
| A3 | 950003 | 1 | f262106acbcd5b200ba686b689a00e1b2b874c1d79f0d9847533439edd020e0a<br>bf044d4fc3d0afa6a7ea035a99d55498080fadfee0f711705da8c9f8a0afe9b7 | fef37e0e00020200000a0e02dd9e43337584d9f0791d4c872b1b0ea089b686a60b205bcdcb6a1062f20102fe613fa53ea45ca6ee403f0cbf703dd224fcfc19c57bb1e52e25ba77ab34e105010100b7e9afa0f8c9a85d7011f7e0fead0f089854d5995a03eaa7a6afd0c34f4d04bf |
| A4 | 950004 | 1 | 48bdce1503e9475ae3af4f2468e5d1a567aee41f50d5a6c4e2b54532abd91ed0<br>0b5172355c1a44629cdb6f26e4503be43a6b55498d98108defec26e1cfaf844f | fef47e0e0002020000d01ed9ab3245b5e2c4a6d5501fe4ae67a5d1e568244fafe35a47e90315cebd480102ae8bfd0a240bc80e5d933d37bd7e7152186404244a9d055346a8e6f001e049270101004f84afcfe126ecef8d10988d49556b3ae43b50e4266fdb9c62441a5c3572510b |
| E5 | 950006 | 4 | ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3<br>6b157ae9550c8fac7e5aab7c7121162e30ae5cb397a4bd97a661df741d2fcd44<br>9655485f14b20de881eefc0d22692ea5c3d9b724db6afe9206fbeb30eb5885b8 | fef67e0e0003020402a367ee8f4c2ee28a0e473067f46d9d71b29978060ef39efdb4df18bd14831ced0501010301010000b88558eb30ebfb0692fe6adb24b7d9c3a52e69220dfcee81e80db2145f485596 |
| A6 | 950007 | 1 | 37da0e44e17db4fc7079ecdf38296b0800a963e7b5dbbc23564c5c139654e33b<br>96fc5df8ed76f78f4e603fccb74d461d416b8131d0a11efbe4336b51d9ad2c44 | fef77e0e00020200003be35496135c4c5623bcdbb5e763a900086b2938dfec7970fcb47de1440eda3701029b374b40c6cfe6efee700ddeec46f47611a891e9f2e0ae14591d6162454c27a7010100442cadd9516b33e4fb1ea1d031816b411d464db7cc3f604e8ff776edf85dfc96 |
| T64 | 950008 | 1 | ce32ab879aec2243f097a557d39e11844730e0e7145c536d8c9e803619b13f6d<br>cd865c7615cc3a4059dea1d8a8c6f582579e3da49e6e7f96599eb8fe07af4696 | fef87e0e00020200006d3fb11936809e8c6d535c14e7e0304784119ed357a597f04322ec9a87ab32ce0102021eded2ad78a6714fae83714cd9652d557dcc9609b608966a13a49e84bf44640101009646af07feb89e59967f6e9ea43d9e5782f5c6a8d8a1de59403acc15765c86cd |
| A8 | 950009 | 1 | 61fe9043151ceafaeb5d8c4f8ff45ba68fe1c74c4398d99ece9268c496f6222d<br>6444bf849ea4136a9608b60996cc7d552d65d94c7183ae4f71a678add2de1e02 | fef97e0e00020200002d22f696c46892ce9ed998434cc7e18fa65bf48f4f8c5debfaea1c154390fe6101027cd11c42992a80b5c56ea59f0a159f2ff22093f773057e9831d2bbd3200ce96e010100021eded2ad78a6714fae83714cd9652d557dcc9609b608966a13a49e84bf4464 |
| T01 | 950010 | 2 | 0000000000000000000000000001ffffffff5151515104000000000000000000<br>899ba7a5d3c9e32cf1f2068b1c59a6dd0b83b24ab979b26787cb91df12b7e68b | fefa7e0e00020202024389642001de4f0379fc8d666dca0c0bcf96c3145ceca328b278bae5aeb714e203000000000000000000000451515151ffffffff01000000000000000000000000000100008be6b712df91cb8767b279b94ab2830bdda6591c8b06f2f12ce3c9d3a5a79b89 |
| CF | 949999 | 1 | 03ea315f3d30238103cd439d76d566d1ed1b9a7b45b2aa8ad018f1cfc8f369d2<br>3fad8334668a72fe171a229270c0899d55a9ec45983ea45e2621e332908c9706 | feef7e0e0002020000d269f3c8cff118d08aaab2457b9a1bedd166d5769d43cd038123303d5f31ea0301024d10c172aa13ac41283c2cc5982234a756a5ae3030e0054d2fc070bcf7f68efe01010006978c9032e321265ea43e9845eca9559d89c07092221a17fe728a663483ad3f |
Four vectors use a path other than the conversion:
| Path | What it is | BRC-74 path |
|---|---|---|
| A1-junk | A1's path with two more level-0 nodes, at offsets 2 and 3, that are not the block's: the node they give at offset 1 of level 1 differs from the one the path declares there | fef17e0e000204000049bcbbd9cdf6e366dcf87ce681c9b0d20f28b92294f5b96a102f3794ff677f7a010244e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c020026dcbc75da62047ad4739ef3256d17ddc8d615e6b3d0d8d7e40428637b76de440300b5a08be98684587105e56417da2f038e6401968d43ff1dfa5b9b77b34e1ba2dc0101004cd48105a7c655bb474a7b44f142e711d25c436cfb34d226be09bce7eb2c15e4 |
| A1-conflict | A1's block with the third transaction and its duplicate also at level 0, and at offset 1 of level 1 a hash that is not the one they give | fef17e0e000204000049bcbbd9cdf6e366dcf87ce681c9b0d20f28b92294f5b96a102f3794ff677f7a010244e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c0202967ea168a99425d700013485381d5ba0d488e4af6e5c92d92190659a52ae94d30301010100463834cdc4f8debcc79ec98967b74db7b04209cd7f12af1104daf5508cb860c2 |
| A8-compound | A8's block whole at level 0, nothing at level 1: offsets 2 and 3 hold the two halves of T64's bytes, a pair that decodes as a transaction and is not on A8's own path | fef97e0e00020400002d22f696c46892ce9ed998434cc7e18fa65bf48f4f8c5debfaea1c154390fe6101027cd11c42992a80b5c56ea59f0a159f2ff22093f773057e9831d2bbd3200ce96e0202010000000103254c9167ae1de0add271e079a00da53b5e54e6da92dffabb1ada0300240222f576000000000451515151ffffffff01a086010000000000000000000000 |
| A2-flag | A2's path with the flag of the node at offset 0 of level 0 changed from 00 to 04, which BRC-74 does not define; the hash after it is unchanged | fef27e0e00020200048617b6288b4ec751cf99fcdd445d71cb05a19c30a203f1a6027ea9b2690aac0a0102e68e61bc98eab47a8a70499e23a340c42b517888765d5a5efd6c8019a702d2ec010100316d6275f9ee080db1b2c7110d57a25fa5f7412708909cf798b38423ddaa3bab |
Material
An Atomic BEEF here is 01010101, the subject's txid in internal byte order, and a BRC-62 V1 BEEF (0100beef) carrying the paths listed, in order, and then the transactions listed, in order, each anchored one with the index of its path. Where a vector says V2, the BEEF is a BRC-96 V2 BEEF (0200beef) in the same order, each anchored transaction in format 01 with its path's index, each one listed as txid only in format 02, and each other in format 00. Its length and SHA-256 confirm the bytes. Records are raw transactions and Electrum-form paths, by name, from the tables above.
Statements
Equality: identical bytes of the canonical form.
S1: distance 1, every check run
- Material: Atomic BEEF of P1: paths A1; transactions A1 (path 0), P1; 433 bytes, SHA-256
63b6ac11d00e79ad817f1942305428d0114c0ce79f0e9224cae3df1be26079f0. - Inputs: status
handed-to-broadcaster; a conflict check at 1793318340, kindown-node, scopeunconfirmed, found false.
{"anchors":[{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001,"txid":"2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344"}],"conflicts":{"at":1793318340,"checked":true,"found":false,"kind":"own-node","scope":"unconfirmed"},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":{"bytes":192,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"handed-to-broadcaster"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"e2127516adc12a98fdc758e7d6ab36c38505cb6731f6c9b68c3cdc02b3a33896","unconfirmed":["e2127516adc12a98fdc758e7d6ab36c38505cb6731f6c9b68c3cdc02b3a33896"],"unresolved":[],"validated":["e2127516adc12a98fdc758e7d6ab36c38505cb6731f6c9b68c3cdc02b3a33896"],"validation":"all","version":"bsv-payment-evidence/v1"}
S2: a chain of three, every check run
- Material: Atomic BEEF of D2: paths A2; transactions A2 (path 0), B2, C2, D2; 816 bytes, SHA-256
4dfaa602f47e4720d77226c76f49576775c06442aca3a7df4a02ba9c9fa4b6ac.
{"anchors":[{"blockHash":"64a53adabc6a36de2c5176485d47e64c06f56d1b588e638ba8c7d349bdc459fc","height":950002,"txid":"ecd202a719806cfd5e5a5d768878512bc440a3239e49708a7ab4ea98bc618ee6"}],"conflicts":{"checked":false},"distanceMax":3,"distanceMin":3,"fullyAnchored":true,"lowestFeeRate":{"bytes":191,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","unconfirmed":["04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a","83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c"],"unresolved":[],"validated":["04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a","83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c"],"validation":"all","version":"bsv-payment-evidence/v1"}
S3: the same chain, distance only
- Material: Atomic BEEF of D2: paths A2; transactions A2 (path 0), B2, C2, D2; 816 bytes, SHA-256
4dfaa602f47e4720d77226c76f49576775c06442aca3a7df4a02ba9c9fa4b6ac. - Inputs: distance only.
{"anchors":[{"blockHash":"64a53adabc6a36de2c5176485d47e64c06f56d1b588e638ba8c7d349bdc459fc","height":950002,"txid":"ecd202a719806cfd5e5a5d768878512bc440a3239e49708a7ab4ea98bc618ee6"}],"conflicts":{"checked":false},"distanceMax":3,"distanceMin":3,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","unconfirmed":["04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a","83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c"],"unresolved":[],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S4: the same chain from the receiver's records, the path in Electrum form, distance only
- Material: records: transactions A2, B2, C2, D2; the Electrum-form path of A2; payment D2.
- Inputs: distance only.
{"anchors":[{"blockHash":"64a53adabc6a36de2c5176485d47e64c06f56d1b588e638ba8c7d349bdc459fc","height":950002,"txid":"ecd202a719806cfd5e5a5d768878512bc440a3239e49708a7ab4ea98bc618ee6"}],"conflicts":{"checked":false},"distanceMax":3,"distanceMin":3,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","unconfirmed":["04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a","83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c"],"unresolved":[],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S5: an uneven diamond: longest path 3, shortest 1
- Material: Atomic BEEF of P3: paths A3; transactions A3 (path 0), B3, C3, P3; 999 bytes, SHA-256
8b8bd197f55ef26145ea1fee3a87a32fd38dc98a05498f21a35fc839496d2828.
{"anchors":[{"blockHash":"4ef4e7bfd2500d3ef2c4b89cce091e27feb0f1a82a4ceaca0395f35b9827eda7","height":950003,"txid":"05e134ab77ba252ee5b17bc519fcfc24d23d70bf0c3f40eea65ca43ea53f61fe"}],"conflicts":{"checked":false},"distanceMax":3,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":{"bytes":339,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"215984478daf11bbe5da2cd5946792e2a1247f11f644eb7ed95e49e27ce56da6","unconfirmed":["215984478daf11bbe5da2cd5946792e2a1247f11f644eb7ed95e49e27ce56da6","6a5434d9c86b7a77bfec289f42d0344ff80d904d8542f1001779cad3fabf1b00","96c8a32fb64394dfc9357306687db01d67c8cadd4ae7483f3123f27f8e6e48f1"],"unresolved":[],"validated":["215984478daf11bbe5da2cd5946792e2a1247f11f644eb7ed95e49e27ce56da6","6a5434d9c86b7a77bfec289f42d0344ff80d904d8542f1001779cad3fabf1b00","96c8a32fb64394dfc9357306687db01d67c8cadd4ae7483f3123f27f8e6e48f1"],"validation":"all","version":"bsv-payment-evidence/v1"}
S6: one input whose source is not held, every check run
- Material: Atomic BEEF of P4: paths A4; transactions A4 (path 0), B4, P4; 773 bytes, SHA-256
54b7baac8d64b816291290e1b75c26294433be4ef89ee44328cacb45088dfa35.
{"anchors":[{"blockHash":"ee55e78df915a761c888acb74bf87c5290c24af8a170e8510e7e43f6104e2916","height":950004,"txid":"2749e001f0e6a84653059d4a2404641852717ebd373d935d0ec80b240afd8bae"}],"conflicts":{"checked":false},"distanceMax":null,"distanceMin":2,"fullyAnchored":false,"lowestFeeRate":{"bytes":192,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c","unconfirmed":["6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595","df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c"],"unresolved":[{"txid":"3721db44eccd6e28b0b7cb36cbab33dbdb1f8643603f4d437ace61442800466b","vout":0}],"validated":["6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595"],"validation":"partial","version":"bsv-payment-evidence/v1"}
S7: the same from the receiver's records, distance only
- Material: records: transactions A4, B4, P4; the Electrum-form path of A4; payment P4.
- Inputs: distance only.
{"anchors":[{"blockHash":"ee55e78df915a761c888acb74bf87c5290c24af8a170e8510e7e43f6104e2916","height":950004,"txid":"2749e001f0e6a84653059d4a2404641852717ebd373d935d0ec80b240afd8bae"}],"conflicts":{"checked":false},"distanceMax":null,"distanceMin":2,"fullyAnchored":false,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c","unconfirmed":["6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595","df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c"],"unresolved":[{"txid":"3721db44eccd6e28b0b7cb36cbab33dbdb1f8643603f4d437ace61442800466b","vout":0}],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S8: the payment is itself an anchor, its path in Electrum form
- Material: records: transactions E5; the Electrum-form path of E5; payment E5.
{"anchors":[{"blockHash":"ab14e92c0acb7212d9a1219e6c468b0f2c4ee53a7c351486bf99e916dfa1f90f","height":950006,"txid":"ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3"}],"conflicts":{"checked":false},"distanceMax":0,"distanceMin":0,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":5,"event":"mined"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3","unconfirmed":[],"unresolved":[],"validated":[],"validation":"all","version":"bsv-payment-evidence/v1"}
S9: a signature by the wrong key, distance only
- Material: Atomic BEEF of BADSIG: paths A1; transactions A1 (path 0), BADSIG; 433 bytes, SHA-256
078b4cf6087ea739dd9987c131aa1f75b78383c482ccf7cc5eb9885ffe09a694. - Inputs: distance only.
- Note: For a maker that has not run check 1 on this material. A maker that has run it refuses (M6) and makes no distance-only statement about it (section 2.3).
{"anchors":[{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001,"txid":"2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344"}],"conflicts":{"checked":false},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"664569513982851cb5aefe29541ddf7de327a14206111191b9d5c07bfa59a60d","unconfirmed":["664569513982851cb5aefe29541ddf7de327a14206111191b9d5c07bfa59a60d"],"unresolved":[],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S10: a Merkle path above the header source's tip: not checked, the walk goes on
- Material: Atomic BEEF of D2: paths A2; transactions A2 (path 0), B2, C2, D2; 816 bytes, SHA-256
4dfaa602f47e4720d77226c76f49576775c06442aca3a7df4a02ba9c9fa4b6ac. - Inputs: the header source is the table cut at its tip, height 950001.
{"anchors":[],"conflicts":{"checked":false},"distanceMax":null,"distanceMin":null,"fullyAnchored":false,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001},"txid":"83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","unconfirmed":["04f2afb7c402d0f1d33759631f1375d95a6f641d40d554336ad5a9fba668239a","83a6965907f29d1b0561a9da97c7fccaf160aa38dbb2a8a5cfad4d5745362db7","8e16699f0cd9d4b020d71caaeeed19e4a07c03f4fcdfb08c09d3f55ee594695c","ecd202a719806cfd5e5a5d768878512bc440a3239e49708a7ab4ea98bc618ee6"],"unresolved":[{"txid":"9ad939dc90a785679522429363796caf013ff87d7c9f357d3937347dad51d22d","vout":0}],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S11: a lock time given as a time, below the median time past
- Material: Atomic BEEF of TL: paths A1; transactions A1 (path 0), TL; 432 bytes, SHA-256
e3bd46b61095b816c1987425c42261de15430961a55a9a9a3e4468264b223291. - Inputs: the header source is the table plus the header at height 950000 given below it.
{"anchors":[{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001,"txid":"2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344"}],"conflicts":{"checked":false},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":{"bytes":191,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf","unconfirmed":["525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf"],"unresolved":[],"validated":["525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf"],"validation":"all","version":"bsv-payment-evidence/v1"}
S12: the same, without a header the median time past needs: left out
- Material: Atomic BEEF of TL: paths A1; transactions A1 (path 0), TL; 432 bytes, SHA-256
e3bd46b61095b816c1987425c42261de15430961a55a9a9a3e4468264b223291. - Note: The header source is the table, which holds no header at height 950000, so the median time past of the 11 blocks ending at the tip cannot be computed.
{"anchors":[{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001,"txid":"2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344"}],"conflicts":{"checked":false},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf","unconfirmed":["525c61889807b4ba61f16c1f71f91d6ec30e794c8ff6f8727cf9b986bbc35acf"],"unresolved":[],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
S13: a script the maker cannot evaluate: left out, validation partial
- Material: Atomic BEEF of P6: paths A6; transactions A6 (path 0), B6, X6, P6; 872 bytes, SHA-256
b9b3fe3ca0e6d200c60600dff944f8a4be80c74c282608bbdd7e4d21b82aeea5. - Note: A6 is mined at 950007, above the Chronicle activation height, so OP_2MUL (0x8d) is enabled for its output and X6's input evaluates to true under the rules in force. This vector is for a maker whose interpreter does not implement OP_2MUL, or treats it as disabled: it cannot complete the check, so it leaves X6, and P6, which spends it, out of the validated set. A maker that implements OP_2MUL validates both, and its statement differs (validation all); no vector is given for it.
{"anchors":[{"blockHash":"a036c06c92ea0d49b3b6862932aa4533730bcc711249099595efd41573bd33db","height":950007,"txid":"a7274c4562611d5914aee0f2e991a81176f446ecde0d70eeefe6cfc6404b379b"}],"conflicts":{"checked":false},"distanceMax":2,"distanceMin":2,"fullyAnchored":true,"lowestFeeRate":{"bytes":191,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"420adb2e2fd48ee95bae1e7e972b329a516106e6bfb1b6a321d399561822670f","unconfirmed":["420adb2e2fd48ee95bae1e7e972b329a516106e6bfb1b6a321d399561822670f","6158929cc6db06e57aad638ac4b426e53ab9dc1593e33a5b08eabcae6c26f3eb","c60f7125b095b56b4c703a279599203ccee550bf33811e53617f3c8c44312690"],"unresolved":[],"validated":["6158929cc6db06e57aad638ac4b426e53ab9dc1593e33a5b08eabcae6c26f3eb"],"validation":"partial","version":"bsv-payment-evidence/v1"}
S14: a pair off the anchor's own path that decodes as a transaction: the anchor holds
- Material: Atomic BEEF of P8: paths A8-compound; transactions A8 (path 0), P8; 466 bytes, SHA-256
1467a7df31c392303975b6ddf4268b6fb02f5b0844187d1d7d38f0c05f8b5007. - Note: Offsets 2 and 3 of A8's path are the two halves of T64's bytes. The fold of A8's own path hashes A8 with offset 0, then their parent with the node computed from offsets 2 and 3, and never that pair, so condition (e) holds.
{"anchors":[{"blockHash":"f954b173e1932e44aafc432a0171c2b4c755f11cd479cf3bae8da4d82bcb87fc","height":950009,"txid":"6ee90c20d3bbd231987e0573f79320f22f9f150a9fa56ec5b5802a99421cd17c"}],"conflicts":{"checked":false},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":{"bytes":191,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"db874543d0c2b32bfe1e38c17a15609285746d278a7abe919e334ae83ee5f98e","unconfirmed":["db874543d0c2b32bfe1e38c17a15609285746d278a7abe919e334ae83ee5f98e"],"unresolved":[],"validated":["db874543d0c2b32bfe1e38c17a15609285746d278a7abe919e334ae83ee5f98e"],"validation":"all","version":"bsv-payment-evidence/v1"}
S15: S6 as a BEEF V2 that carries Z4 by txid only
- Material: Atomic BEEF (V2) of P4: paths A4; transactions A4 (path 0), Z4 (txid only), B4, P4; 806 bytes, SHA-256
018e960e6caeee1fa521da01bf18d91524e13f95ead1704b5557482efa19231f. - Note: The same statement as S6: a txid-only entry holds no transaction, so the input that spends Z4 is unresolved (section 2.1).
{"anchors":[{"blockHash":"ee55e78df915a761c888acb74bf87c5290c24af8a170e8510e7e43f6104e2916","height":950004,"txid":"2749e001f0e6a84653059d4a2404641852717ebd373d935d0ec80b240afd8bae"}],"conflicts":{"checked":false},"distanceMax":null,"distanceMin":2,"fullyAnchored":false,"lowestFeeRate":{"bytes":192,"satoshis":50},"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c","unconfirmed":["6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595","df3f2029548cb31866c12a73d1ff6da9e3515acf66ce6c145ef34ce2e2ef9d6c"],"unresolved":[{"txid":"3721db44eccd6e28b0b7cb36cbab33dbdb1f8643603f4d437ace61442800466b","vout":0}],"validated":["6208df575795dfb167aabee64512316b37caf163e0d4bf67b2262cb37997a595"],"validation":"partial","version":"bsv-payment-evidence/v1"}
S16: a payment that is a confiscation transaction: left out, validation none
- Material: Atomic BEEF of CFU: paths A1; transactions A1 (path 0), CFU; 470 bytes, SHA-256
9235e27de1c705025668181fd6113f2ad27e82952b3d8c761b4cc3d0abac0aeb. - Note: CFU's first output begins
006a0463667478, so CFU is a confiscation transaction, which SV Node accepts only when it is whitelisted. A maker cannot know the whitelist, so it cannot complete the checks on CFU: CFU is left out, and not refused (section 2.3).
{"anchors":[{"blockHash":"d73120d63050557443631be249d95eaaae2ee72d05375d199b9d8d33e34c5e9e","height":950001,"txid":"2c0746d0edc5d2afb97495acbcc4584087bdc07027360aa03b28cbf40e6ee344"}],"conflicts":{"checked":false},"distanceMax":1,"distanceMin":1,"fullyAnchored":true,"lowestFeeRate":null,"madeAt":1793318400,"status":{"depth":null,"event":"received"},"tip":{"blockHash":"e125c62d3654c2f138f1c39bb74c56181e6d325c38844fd30cc1939d701c493a","height":950010},"txid":"b93c53d9615c0a2bf6f72791a41abc329d70944630f4fd5dc894fd6c5cf5418c","unconfirmed":["b93c53d9615c0a2bf6f72791a41abc329d70944630f4fd5dc894fd6c5cf5418c"],"unresolved":[],"validated":[],"validation":"none","version":"bsv-payment-evidence/v1"}
Refusals by a maker
Equality: a refusal with the code shown, and no statement.
| Vector | Input | Code | Basis |
|---|---|---|---|
| M1: truncated | the material of S1 without its last byte | MALFORMED | the last transaction ends early (BRC-62 framing); the decoder is told its input is complete |
| M2: trailing byte | the material of S1 followed by one byte 00 | MALFORMED | a byte after the end of the BEEF |
| M3: an impossible declared length | below | MALFORMED | 4,294,967,295 transactions declared, one present |
| M4: a path whose root is not the header's | the material of S1 | ANCHOR_MISMATCH | the header at 950001 differs from the one in the header source table in the first byte of its Merkle root |
| M5: outputs above inputs | Atomic BEEF of RICH: paths A1; transactions A1 (path 0), RICH; 432 bytes, SHA-256 3c4ae8c809029759b683a3dd737d4d54f8271415e466d561142858e6b334f5a4 | VALUE_CREATED | 100,001 out of 100,000 in |
| M6: a signature by the wrong key | Atomic BEEF of BADSIG: paths A1; transactions A1 (path 0), BADSIG; 433 bytes, SHA-256 078b4cf6087ea739dd9987c131aa1f75b78383c482ccf7cc5eb9885ffe09a694 | SCRIPT_FAILED | the input's script does not end true |
| M7: a lock time not yet reached | Atomic BEEF of LATE: paths A1; transactions A1 (path 0), LATE; 433 bytes, SHA-256 5de525cb23c0b6bc15f69126da6c11eaa31fe95d899e0df717f6c8d7b5f41759 | PREMATURE | nLockTime 950020 with sequence 0xfffffffe, judged for the block at 950011 |
| M8: two spends of one output | Atomic BEEF of BOTH: paths A1; transactions A1 (path 0), X, Y, BOTH; 967 bytes, SHA-256 92c57a32e872b06868ddbd160b269796abc19ed9c76f194f24dcb6d82006391f | CONFLICT | X and Y both spend A1:0 |
| M9: more transactions than the bound | the material of S2; bound of 3 transactions | OVER_BOUND | S2 reads four transactions; the bound is three |
| M10: a longer path than the bound | the material of S2; bound of distance 2 | OVER_BOUND | S2's longest path holds three unconfirmed transactions; the bound is two |
| M11: a 64-byte transaction as an anchor | Atomic BEEF of P64: paths T64; transactions T64 (path 0), P64; 305 bytes, SHA-256 81883aefaac00f3eedaf51ac8aaf0c8bdc12948fddd7d881dd37e54f84a20fc4 | ANCHOR_MISMATCH | T64 is exactly 64 bytes, so its path is no evidence (section 1, condition d) |
| M12: a lock time equal to the median time past | Atomic BEEF of TLATE: paths A1; transactions A1 (path 0), TLATE; 432 bytes, SHA-256 9ece889c41273845d410b1caa7bfb4f16c752e7a9536c28c3e260a72426c553c; the header source is the table plus the header at height 950000 given below it | PREMATURE | nLockTime 1793002400 with sequence 0xfffffffe; the median time past of the 11 blocks ending at 950010 is 1793002400 |
| M13: an Atomic BEEF over the byte bound | the material of S1; bound of 432 bytes of material | OVER_BOUND | S1's material, the whole Atomic BEEF with its 36 bytes of prefix and subject, is 433 bytes; the bound is one byte less |
| M14: an Atomic BEEF with an unrelated transaction | Atomic BEEF of P1: paths A1; transactions A1 (path 0), A2, P1; 520 bytes, SHA-256 ed83aeb8d4c55ed6d5bc67c5e4d6d81cb68c8ee77ab2b5d88e24d75345690765 | MALFORMED | A2 is neither P1 nor one of its ancestors (BRC-95) |
| M15: a txid twice | Atomic BEEF of P1: paths A1, A1; transactions A1 (path 0), A1 (path 1), P1; 631 bytes, SHA-256 b5d7f6ac76b275499306bc10dd0a148d131ea37a1d371bbb1f789fc22d5e240d | MALFORMED | A1 is held twice |
| M16: the legacy version word | the material of S1 with its BEEF version bytes 0100beef changed to efbe0001 | MALFORMED | efbe0001 is not a BRC-62 version |
| M17: a junk pair under a declared node | Atomic BEEF of P1: paths A1-junk; transactions A1 (path 0), P1; 501 bytes, SHA-256 8584216fa12376a7b8937f5fbdcca91021cdf54f760a203113818231ffccf2c9 | MALFORMED | the path is A1-junk: the node computed at offset 1 of level 1 differs from the declared one, which BRC-74 does not permit |
| M18: a declared sibling that conflicts with the nodes below it | Atomic BEEF of P1: paths A1-conflict; transactions A1 (path 0), P1; 469 bytes, SHA-256 cfc5192f0ad74f99d3640b28514bad911b766479ff721502df02fd4bcfe695ba | MALFORMED | the path is A1-conflict: the node at offset 1 of level 1, A1's own sibling there, differs from the one computed from offsets 2 and 3 |
| M19: a level of the anchor's own path that decodes as a transaction | Atomic BEEF of P01: paths T01; transactions T01 (path 0), P01; 432 bytes, SHA-256 4dc07f5aedfc3b5c57cdf7f6f9534669708da26922b20f941aa8e8553bab613c | ANCHOR_MISMATCH | T01's txid, in internal byte order, followed by its sibling R decodes as a 64-byte transaction (section 1, condition e) |
| M20: a spend of an output an anchor also spends | Atomic BEEF of DS: paths A1; transactions A1 (path 0), DS; 474 bytes, SHA-256 3cfd4950db1cafd98eb99b0064935f00f353d17826ca8247b925d9d147f8f1aa | CONFLICT | DS spends A1:0 and the outpoint A1 itself spends, so it conflicts with a mined spend |
| M21: records over the byte bound | records: transactions A2, B2, C2, D2; the Electrum-form path of A2; payment D2; distance only; bound of 768 bytes of material | OVER_BOUND | the walk reads S4's four transactions, 659 bytes, and A2's path, 110 bytes as BRC-74 bytes, 769 in all; the bound is one byte less |
| M22: a spend of a confiscation output before 1,000 blocks | Atomic BEEF of CFS: paths CF; transactions CF (path 0), CFS; 471 bytes, SHA-256 86c50c3bb0554dd4f760df91bfdde797c28a87991e265f7858dedd25b8955589; the header source is the table plus the header at height 949999 given below it | PREMATURE | CF's first output begins 006a0463667478, so CF is a confiscation transaction; it is mined at 949,999, and the block after the tip, 950,011, is below 949,999 plus 1,000 |
| M23: an undefined flag in a path no transaction names | Atomic BEEF of P1: paths A1, A2-flag; transactions A1 (path 0), P1; 543 bytes, SHA-256 83ae2550985e91da512b4ad005787dbfdd9ea547383d1c2db1ac993e2f55973d | MALFORMED | the second path is A2-flag, which no transaction names: its flag 04 leaves the node's length unknown, so the BEEF cannot be framed (section 2.1) |
| M24: an Atomic BEEF with an unrelated txid-only entry | Atomic BEEF (V2) of P1: paths A1; transactions A1 (path 0), A2 (txid only), P1; 466 bytes, SHA-256 636958b5367f71efb47f52d3350d6f44ae6392be70bd32bf5634dc7adace92ab | MALFORMED | A2's entry carries only its txid, and no input of P1 names it, so it is not an ancestor (BRC-95) |
| M25: a statement over the maker's bound | the material of S1; status handed-to-broadcaster; a conflict check at 1793318340, kind own-node, scope unconfirmed, found false; bound of 867 bytes of statement | OVER_BOUND | S1's statement is 868 bytes; the maker's bound on statement length is one byte less |
M3's input, in full:
0101010144e36e0ef4cb283ba00a362770c0bd874058c4bcac9574b9afd2c5edd046072c0100beef00feffffffff01000000010ddbe8f7bd041d50ea45fa1d9abc6c62fc35e5e91cb1ef61d2c3ba08c72a75ea000000000151ffffffff01a0860100000000001976a9149b0cc517962e22315ce8b46fd4fdd02db0bab31988ac0000000000
M4's header source is the table above with the header at height 950001 replaced by:
000000206b0d72cc817bdfe98bc0ccb64c9c8c0a70774fe82939b6a50cff8db0fce17353fbac2f5d9533c2686ccf4c05aeb9bd51ed9e5ea108156765378a6e1209a309424002df6affff7f2000000000
Conversion of an Electrum-form branch
The anchor of S8, transaction E5 (txid ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3), is at index 4 of a block of five, so its branch repeats the working hash at two levels:
{"block_height":950006,"merkle":["ed1c8314bd18dfb4fd9ef30e067899b2719d6df46730470e8ae22e4c8fee67a3","6b157ae9550c8fac7e5aab7c7121162e30ae5cb397a4bd97a661df741d2fcd44","9655485f14b20de881eefc0d22692ea5c3d9b724db6afe9206fbeb30eb5885b8"],"pos":4}
Its BRC-74 path, byte for byte:
fef67e0e0003020402a367ee8f4c2ee28a0e473067f46d9d71b29978060ef39efdb4df18bd14831ced0501010301010000b88558eb30ebfb0692fe6adb24b7d9c3a52e69220dfcee81e80db2145f485596
Level 0 holds E5 at offset 4 (flag 02) and offset 5 with flag 01; level 1 holds offset 3 with flag 01; level 2 holds offset 0 with flag 00 and its hash. The same branch with pos 12 leaves a bit over after its three siblings: refused MALFORMED. A branch of 65 siblings, its three repeated, with pos 0, is longer than any BRC-74 tree: refused MALFORMED.
Refusals by a reader
Equality: a refusal with the code shown. Each input is a change to the bytes of a statement above, S1 unless the change names another.
| Vector | Change | Code |
|---|---|---|
| R1: another version | the final 1 of version changed to 2, in canonical form | UNKNOWN_VERSION |
| R2: an unexpected field | a field "note":"" added, in canonical form | MALFORMED_STATEMENT |
| R3: not the canonical form (one space) | one space after {"anchors": | MALFORMED_STATEMENT |
| R4: fields that disagree (fullyAnchored false, nothing unresolved) | fullyAnchored set to false, in canonical form | MALFORMED_STATEMENT |
| R5: conflicts.checked a number, not a boolean | conflicts set to {"checked":0}, in canonical form | MALFORMED_STATEMENT |
| R6: nested 33 deep | a field x holding 32 nested empty arrays added, in canonical form | MALFORMED_STATEMENT |
| R7: a validated transaction named as the source of an unresolved input | S6 with unresolved naming B4, output 0, in canonical form | MALFORMED_STATEMENT |
| R8: an anchor named as the source of an unresolved input | S6 with unresolved naming A4, output 0, in canonical form | MALFORMED_STATEMENT |
| R9: the payment validated, not fully anchored | S6 with validated set to all of its unconfirmed, in canonical form | MALFORMED_STATEMENT |
| R10: a key twice, the second naming another version | ,"version":"bsv-payment-evidence/v2" added before the final } | MALFORMED_STATEMENT |
| R11: the payment validated, one of its ancestors not | S2 with validated holding B2 and D2 only and validation set to partial, in canonical form | MALFORMED_STATEMENT |
| R12: a list out of order | S3 with unconfirmed in descending order, in canonical form | MALFORMED_STATEMENT |
| R13: an entry twice | S6 with its unresolved entry given twice, in canonical form | MALFORMED_STATEMENT |
| R14: a txid in capitals | the anchor's txid in capital letters, in canonical form | MALFORMED_STATEMENT |
| R15: a value section 2.5 does not list | conflicts.kind set to own, in canonical form | MALFORMED_STATEMENT |
| R16: a depth the tip does not give | S8 with tip.height one more, its status.depth unchanged, in canonical form | MALFORMED_STATEMENT |
| R17: an anchor above the tip | tip.height set to one less than the anchor's height, in canonical form | MALFORMED_STATEMENT |
| R18: over the reader's bound | none; the reader's bound is 867 bytes, one less than S1's length | OVER_BOUND |
| R19: an anchored payment with a second anchor | S8 with S1's anchor added to anchors, in canonical form | MALFORMED_STATEMENT |
| R20: one txid as two anchors | a second entry for the anchor's txid, at a height one less, after the first, in canonical form | MALFORMED_STATEMENT |
| R21: a conflict check after the statement | conflicts.at set to one more than madeAt, in canonical form | MALFORMED_STATEMENT |
| R22: an output index no transaction can name | S6 with its unresolved entry's vout set to 4,294,967,296 (2^32), in canonical form | MALFORMED_STATEMENT |
Signature
The receiver key signs the canonical bytes of S1 as a BRC-77 message verifiable by anyone, with the key ID pinned to 571fc1f4ed6fafc9cfaa07f77e12149cd95a29f5981bb4633f6f39e47397df19 (the maker draws it at random). Equality: identical bytes.
4242330103fb1aaf51797cd0551feeeacb42dfd98be2bbcd072e6d9445d3a2620b103c3adc00571fc1f4ed6fafc9cfaa07f77e12149cd95a29f5981bb4633f6f39e47397df193045022100d6baa4f0054d9235a8f9fcdd059c83b7360f4a058e0bc397796c466323c2434a02207733ce0babc4ec3cd64200ff2843428939f0a62eb18d6b27b0b1c84b2f147ba9
It verifies over the bytes of S1, and does not verify over the bytes of R3, the same object with one space added.
Implementations
A reference implementation exists: a module of a wallet that makes a statement from an Atomic BEEF or from the wallet's records, in either mode, converts Electrum-form branches, and reads statements. Its script checks run on the interpreter of the wallet's existing BEEF verifier, the one its incoming payments pass, and it counts an input as passed only when that verifier accepts it. That interpreter predates Chronicle, so the implementation leaves out, and never refuses, a transaction whose script uses an opcode Chronicle restored or a signature with the sighash bit 0x20, or a transaction of version 2 or above whose script fails there. It does not implement the relative lock times of section 2.3, check 3, either, and leaves out a transaction that needs one.
Security Considerations
A statement is not a guarantee. A fully anchored payment with validation all has valid spends from proven coins to the payment. It can still go unmined: a conflicting spend may reach miners first, or its fee may be too low for them. A statement records evidence; the receiver's own policy decides whether to accept the payment.
Who made it. A statement says what its maker checked. An unsigned statement from the payer, or from any party with an interest in the payment being accepted, is no evidence: relying on it is relying on that party's word. A receiver makes its own statement from the material, or reads one from a maker it trusts, signed (section 7) when it has travelled.
The header source. An anchor is only as good as the header that confirms it. A source that serves headers whose proof of work nobody checked lets whoever controls it turn any Merkle path into an anchor. A maker SHOULD use headers whose proof of work it has checked. A reader of another party's statement can check the tip and each anchor's height and block hash against its own headers.
A 64-byte transaction. A block header does not say how tall the block's Merkle tree is, and the txid of a 64-byte transaction is computed as an inner node of the tree is, the double SHA-256 of 64 bytes. That allows two attacks, and the anchor definition closes each. In the first, two sibling inner nodes, read together as a transaction, have a Merkle path to the real root: whoever orders a block's transactions can search for an order in which such a pair also parses as a transaction with an output anyone can spend. Condition (d) closes it, since a 64-byte transaction is never an anchor. In the second, a real 64-byte transaction is mined, and its two halves are offered as the bottom step of a path one level taller, so that a transaction whose txid is the first half appears proven; vector M19 builds that shape, a txid with 01 at byte 4 beside a sibling that completes a transaction. Condition (e) closes it, since no step of the own path may hash 64 bytes that decode as a transaction. Neither condition alone is enough. No ordinary payment needs a 64-byte transaction, which has 4 bytes for all of its scripts together. A miner who orders a block can place beside an honest transaction a sibling it searched for, so that the transaction's path fails (e); that payment is then refused, never wrongly accepted.
Bounds. A payment can have very many ancestors, and every script costs time to evaluate. A maker bounds the material's size in bytes and the walk before it does that work (section 2.1), and a maker that evaluates scripts for others SHOULD also limit the work each script may do. Reaching such a limit leaves a transaction unvalidated; it is never a refusal (section 2.3). A statement grows with the payment, since each unconfirmed transaction and each unresolved input adds an entry: one transaction of hundreds of thousands of inputs whose sources are not held gives a statement of tens of megabytes. A maker bounds the statement it emits, and a reader the bytes it parses, at 1,000,000 bytes by default for both (sections 2.1 and 5).
Frozen outputs. SV Node refuses a transaction that spends an output on its freeze lists (validation.cpp L2596-L2607). No header carries those lists, so the checks of section 2.3 do not cover them: a validated transaction can spend a frozen output and never be mined.
Observations age. found: false held at time at, a status held at madeAt, and the depth at tip. A later conflicting spend or a later block changes none of those fields.
The method as an oracle. An application that may call the method of section 8 with any txid could learn which transactions the wallet holds, if the wallet answered calls it has not permitted otherwise than calls about a transaction it does not hold. Section 8 gives both the same error. With atomicBEEF, the status is received unless the payment is an anchor, and a conflict check is one made for that call, so the answer depends on the bytes, the wallet's headers and that check, and on nothing the wallet's records hold.
Privacy. A statement lists txids of the payment's ancestry, and a signed one links the maker's key to the payment. A maker SHOULD give a statement only to whom the user chose, such as the application that asked about that payment.
Not tested
- No mainnet or testnet run: the vectors use synthetic headers without proof of work.
- A second implementation, written from this document over @bsv/sdk 1.10.4, shares no code with the reference, but it reads the same vectors file and has the same author. On this revision it agrees with every vector, S1 to S16, M1 to M25 and R1 to R22, with the conversion and the signature, and with the document's own tables and material descriptions, 71 checks in all; a randomised pass over altered materials, paths, branches and statements found no fault. None has been run over the Go or Python SDKs.
- No vector covers the maturity of a coinbase output, an output created before Genesis or before Chronicle, a relative lock time before Genesis, a transaction of version 2 or above, or a signature with the sighash bit
0x20. - Confiscation and freezing: M22 spends a confiscation output before it matures, and S16 leaves out a confiscation transaction. No vector spends a confiscation output once mature, and none covers a frozen output, since no maker here holds a freeze list.
- Vector S13 is for a maker whose interpreter lacks OP_2MUL. No maker that implements it has been run on that material, and the statement such a maker would make is not given.
- No vector holds an ancestor beyond an anchor in an Atomic BEEF.
- No reorganisation was run. Vector M4, a header whose Merkle root differs from the path's, has the shape of one.
- No wallet offers the method of section 8, so no application has called it, and no capability manifest has declared it. The reference implementation makes the statement for its
atomicBEEFargument, without the method's errors. - The conversion of section 6 has not been run on branches fetched from a live Electrum-protocol server.
- No conflicting-spend observation was made: the vectors record the fields only.
- The bounds on statement length are exercised at one value each: the reader's in R18 and the maker's in M25.
- No wallet that reports ancestry distance today, BREAD in ElectrumSVP included, has produced a statement.
References
- BRC-9: Simplified Payment Verification (step 9, on payment channels).
- BRC-62: Background Evaluation Extended Format (BEEF) Transactions.
- BRC-67: Simplified Payment Verification.
- BRC-74: BSV Unified Merkle Path (BUMP) Format.
- BRC-77: Message Signature Creation and Verification.
- BRC-95: Atomic BEEF Transactions.
- BRC-96: BEEF V2, Txid Only Extension.
- BRC-100: Wallet-to-Application Interface (its Backwards Compatibility Contract, error structure and parameter errors).
- BRC-179: Signed Capability Manifest for Wallet and Tool-Server Method Exposure (sections 5 and 7.2).
- BRC-205: Extensible Wallet Version Strings and Account Labels (section 6).
- SV Node at commit
6504a3aff65ba97c0f6c80962b033e35ecbfed4b, for the activation heights, the era ofOP_2MUL, the height of an output created in the mempool, coinbase and confiscation maturity, confiscation transactions, frozen outputs, and relative lock times before Genesis:src/chainparams.cppL18-L23,src/script/interpreter.cppL360-L372,src/consensus/consensus.hL75-L79,src/validation.cppL272-L273, L2562-L2636, L2667-L2696 and L3463-L3468,src/frozentxo_db.cppL614-L636 andsrc/policy/policy.hL247-L255; and its v1.2.0 release notes, on Chronicle: https://github.com/bitcoin-sv/bitcoin-sv/releases/tag/v1.2.0 - ElectrumSVP 0.2.0-beta.1 release notes, on BREAD: https://github.com/TruthMachine/ElectrumSVP/releases/tag/v0.2.0-beta.1
- ElectrumSVP 0.2.0 release notes, for the name BREAD: https://github.com/TruthMachine/ElectrumSVP/releases/tag/v0.2.0
- The Electrum protocol,
blockchain.transaction.get_merkle: https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get-merkle - BIP 68, relative lock times: https://github.com/bitcoin/bips/blob/6ac8c268704a479bdf65fad642c46d43cf19677e/bip-0068.mediawiki
- RFC 2119 and RFC 8174: key words. RFC 6979: deterministic ECDSA nonces.