DEV Community

k0k0ne
k0k0ne

Posted on

Understand Witness of Bitcoin -- A developer's view

Understanding the witness concept is crucial for developers working with Bitcoin. However, most discussions focus on a general perspective. In this post, let's delve deeper into the details.

Witness

A witness refers to the part of a transaction that contains the unlocking scripts (also known as signatures or witness data) necessary to prove ownership of the funds being spent. This concept was introduced with the SegWit upgrade (BIP141) to help solve transaction malleability and improve scalability by segregating (separating) the signature data from the transaction data.

Key Points

  • A witness is a part of a tx.

  • Old tx HAS "witness": A witness is the object that contains unlocking scripts (signatures or witness data)

{
  "version": 1,
  "marker": 0,
  "flag": 1,
  "inputs": [
    {
      "previous_tx": "abcd1234...",
      "index": 0,
      "scriptSig": "",
      "sequence": 4294967295
    }
  ],
  "outputs": [
    {
      "value": 5000000000,
      "scriptPubKey": "76a914...88ac"
    }
  ],
  "witness": [
    "3045022100...022f01e5..."
  ],
  "locktime": 0
}

Enter fullscreen mode Exit fullscreen mode

Above we have an example of transitional bitcoin tx. scriptSig contains the signature and public key needed to unlock the output being spent, alike witness, while in a narrow definition, witness is a separate component in SegWit transactions.

Here is an example:

  • For a Segwit Tx: Witness is saved separately.
{
  "version": 1,
  "marker": 0,
  "flag": 1,
  "inputs": [
    {
      "previous_tx": "abcd1234...",
      "index": 0,
      "scriptSig": "",
      "sequence": 4294967295
    }
  ],
  "outputs": [
    {
      "value": 5000000000,
      "scriptPubKey": "76a914...88ac"
    }
  ],
  "witness": [
    "3045022100...022f01e5..."
  ],
  "locktime": 0
}

Enter fullscreen mode Exit fullscreen mode

In a SegWit transaction, the witness data is stored separately from the traditional parts of the transaction. The overall structure of a SegWit transaction includes:

  1. Transaction Version
  2. Marker and Flag: Indicate the presence of witness data.
  3. Input and Output Lists: As in traditional transactions.
  4. Witness Data: Contains the actual witness for each input.
  5. Locktime

This separation means that the witness data does not affect the transaction's hash used for identifying the transaction, addressing the malleability issue.

How is the Witness Constructed and Used?

Construction

When creating a SegWit transaction, the witness is constructed by providing the necessary unlocking scripts for each input. Typically, this includes a signature and a public key for P2WPKH (Pay-to-Witness-Public-Key-Hash) transactions.

Usage:

  • Verification: Nodes and miners use the witness data to verify that the spender has the right to spend the UTXO.
  • Storage: Witness data is stored in the witness section of the transaction but can be pruned or segregated to save space.
  • Weight Units: In calculating the transaction's weight, witness data is given a lower weight, incentivizing the use of SegWit.

Viewing the Witness Data

After constructing and signing the transaction, you can inspect the witness data using a tool like Bitcoin Core's decoderawtransaction or online explorers that support SegWit.

For example:

bitcoin-cli decoderawtransaction <serialized_tx>
Enter fullscreen mode Exit fullscreen mode

This command will output the transaction details, including the vout, vin, and crucially the witness field for each input, showing the signature and public key used to unlock the funds.

Top comments (0)