Skip to content

Add Bitcoin Witness Commitment (0xb2)#176

Merged
rvagg merged 1 commit intomasterfrom
rvagg/bitcoin-witness-commitment
May 26, 2020
Merged

Add Bitcoin Witness Commitment (0xb2)#176
rvagg merged 1 commit intomasterfrom
rvagg/bitcoin-witness-commitment

Conversation

@rvagg
Copy link
Copy Markdown
Member

@rvagg rvagg commented May 25, 2020

This completes the set needed to interact with the full Bitcoin graph with IPLD. The Witness Commitment is the link to the second binary merkle that contains the transactions with full witness data, whereas the initial binary merkle pointed to from the block header (known as merkleroot) points to the transactions without witness data. Since SegWit, this second binary merkle tree gets linked to from the coinbase scriptPubKey property and the coinbase is excluded from the binary merkle (replaced with 0x000...000) as a result. The reason we need this new element is that the coinbase points to an intermediate structure which concatenates a nonce and the new merkleroot together and the nonce, in the standard representation, becomes the "witness" property of the coinbase itself. So to reconstruct the original full block graph structure you have to navigate to the transactions in the witness merkle and on the way pick up this nonce to re-attach it to the coinbase. This Witness Commitment is 64-bytes long and otherwise looks like a node in the normal binary merkle, but the leftmost side is the nonce (which happens to be 0x000...000 on most blocks because Bitcoin Core does that, but other miners are allowed to insert random strings here and there are so far ~4000 of these in the blockchain).

Decoding a bitcoin-witness-commitment yields a:

type WitnessCommitment struct {
  merkleRoot &MaybeTransaction
  nonce Bytes # 32-bytes long
}

Where a MaybeTransaction is a union that could be an actual transaction or a node in a binary merkle tree, which are also 64-bytes long but look like this:

type TransactionMerkleNode [&MaybeTransaction] # strictly 2 elements long

Another notable problem that makes a dedicated codec for this helpful is that there are pre-SegWit blocks with a coinbase scriptPubKey that look like they point to a witness commitment and there's no firm way to determine whether it is one or not unless you try to load it (from wherever these blocks are coming from). A failure to load an 0xb2 can be a signal that the presumed witness commitment is actually not a witness commitment. A failure to load anything else can be firmly interpreted as a failure to locate something that should exist.

This is implemented and in use in the code @ ipld/js-ipld-bitcoin#63 (will likely be made into a separate repo for @ipld/bitcoin with the js-ipld-bitcoin repo being the k

@rvagg rvagg merged commit 31aa3ed into master May 26, 2020
@rvagg rvagg deleted the rvagg/bitcoin-witness-commitment branch May 26, 2020 04:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants