On anyone-can-spend Pay-to-Taproot outputs before activation

Spending P2TR for fun and non-profit
Friday, July 23, 2021

While working on taproot support for transactionfee.info, it became apparent that there already exist a few Pay-to-Taproot (P2TR) outputs on mainnet. Anyone can spend these outputs, but they are non-standard and thus not relayed between nodes in the Bitcoin peer-to-peer network. However, a mining pool can include non-standard transactions in their block. We cover the six P2TR outputs already present on mainnet and explain why the outputs can be spent by anyone before taproot activates. With the help of the f2pool.com mining pool, four P2TR outputs are donated to brink.dev, a non-profit company focused on supporting open-source Bitcoin development.


Taproot is a softfork upgrade to the Bitcoin protocol and tightens the consensus rules. A softfork forbids something that was previously allowed once it activates. Taproot restricts how native SegWit outputs, with a witness version of 1 and a 32-byte witness program, can be spent. The spending rules for other witness versions, nested SegWit, and native SegWit outputs with a witness version of 1, but longer or shorter witness programs are unaffected.

Existing P2TR outputs on Bitcoin mainnet

While it is possible to create P2TR outputs before taproot activates, it is not recommended to do so. Likewise, wallets shouldn’t generate P2TR addresses before activation. Nonetheless, at the time of writing, there are already six P2TR outputs on Bitcoin mainnet.

The first P2TR output was created on December 17, 2019, in a withdrawal transaction from purse.io. Matthew Zipkin initiated a withdrawal of 5431 sat to a witness version 1 bech32 address to test sending support for witness version 1. He added his test results to the Bitcoin Optech Compatibility Matrix and provided a screenshot showing the withdrawal on the purse.io frontend. The public key encoded in the address is 010​10101​01010101​010​101010101010​10​10​101010101​0101010101​0​101010​101, which is likely not generated from a private key. It is to be assumed that the private key to this public key is unknown, and the funds won’t be spendable once taproot activates.

The second P2TR output was created on January 28th, 2020. With a value of 700 sat, it is close to the default SegWit dust threshold of 294 sat. The creator of this output is unknown.

The third, fourth, and fifth P2TR outputs are test outputs created while checking send support to a witness v1 bech32 addresses that Pieter Wuille posted to the bitcoin-dev mailing list on October 19th, 2020. The third P2TR output has a value of 3656 sat and was created by Riccardo Casatta using the Blockstream Aqua wallet. The fourth P2TR output with a value of 50.000 sat was likely created by Mike Schmidt using the BRD wallet. It’s unknown who created the fifth P2TR output with a value of 100.000 sat.

The sixth P2TR output, with a value of 1324 sat, was created on July 7th, 2021. It is the only P2TR output created after taproot locked in on June 13th, 2021. The other P2TR outputs were created while it was still unclear when or if taproot would activate.

Why can P2TR outputs currently be spent by anyone?

Note (added on 2021-07-24): This post mentions anyone-can-spend outputs. While this term is commonly used to describe outputs with not yet enforced spending rules, it has been the source for a lot of misinformation about SegWit in the past 1. A better name might be “outputs with not yet consensus enforced spending rules” or “unenforced outputs before activation”.

Before taproot activates, these six P2TR outputs can be spent by anyone. However, none of these P2TR outputs have been spent yet, as the spending transaction is currently considered non-standard. Non-standard transactions aren’t relayed on the Bitcoin network 2. Bitcoin Core checks each input for standardness in the AreInputsStandard function before accepting a transaction to the mempool. If the spend UTXO is a P2TR output, the function currently returns false, indicating that the transaction has non-standard inputs. Nodes don’t accept the transaction to their mempool and it is not relayed to peers.

However, a non-standard transaction can still be valid when directly included in a block. Next to other checks, the transaction has to pass the script verification. Standardness is not checked. In Bitcoin Core, the VerifyScript function is responsible for script verification. The script verification for native SegWit spends consists of two parts: the script evaluation and the verification of the witness program.

During script evaluation, the scriptSig is evaluated first. The resulting stack is used as the initial stack state when evaluating the scriptPubKey from the UTXO referenced in the input. The script evaluation succeeds if it finishes without failing, the stack is not empty, and the top stack element casts to true (is not zero). When spending native SegWit outputs like, for example, P2TR outputs, the scriptSig is empty. The scriptPubKey contains the witness version and the witness program. As the scriptSig is empty, an empty stack is used for the scriptPubKey evaluation. There, the witness version and witness program are pushed onto the stack. The script evaluation finishes. As the stack isn’t empty and the top stack element is the witness program (which usually isn’t zero), the script evaluation will succeed. This behavior makes SegWit a softfork. SegWit transactions are valid for nodes without SegWit support as the top stack element is not empty.

UTXO and input in an P2TR keypath spend

A keypath P2TR spend that will be valid and standard once taproot activates. A anyone-can-spend P2TR spend will likely have an empty witness, but otherwise look the same.

As a next step, the witness program is verified if the witness version is known. If the witness version is unknown, the witness program is treated as valid 3. One of the first checks during verification of version 1 witness programs (i.e. when spending P2TR outputs) is if the SCRIPT_VERIFY_TAPROOT script verification flag is set. If unset, the verification succeeds before checking the witness program. This flag is only set when taproot is active. This causes taproot outputs to be anyone-can-spend before activation. The witness program isn’t verified, and the witness can be left empty.

Spending P2TR outputs before activation

We demonstrate the spending of P2TR outputs before the taproot softfork activates by constructing a non-standard transaction that is consensus valid. The mining pool f2pool.com helps by including the non-standard transaction in a block.

For our transaction, we pick the first, third, fourth, and fifth P2TR output out of the six available outputs discussed earlier. The first output with a value of 5.431 sat will be unspendable upon taproot activation and would otherwise remain in the UTXO-set forever. The third (3.656 sat), fourth (50.000 sat), and fifth (100.000 sat) P2TR output were sent in test transactions with the knowledge that the funds will most likely be lost or donated to charity. This allows us to spend a total of 159.087 sat. We leave the other two P2TR outputs (700 sat and 1.324 sat) for someone else to spend either before or after activation.

Our transaction contains two outputs. The first output donates the full input amount of 159.087 sat (about 50 USD at the time of writing) to brink.dev to support open-source Bitcoin development. The transaction purposefully doesn’t pay a miner fee to maximize the donation amount. The second output is an OP_RETURN output with a link to this blog post. This makes it possible for someone finding the anyone-can-spend transaction to learn more about why the P2TR outputs were spendable before Taproot activation.

We constructed the transaction with a quick and dirty Rust script. For Bitcoin Core to accept the non-standard transaction, this patch had to be applied to v0.21.1.

The transaction b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41 was included in block 0000000000000000000f14c35b2d841e986ab5441de8c585d5ffe55ea1e395ad (height 692261) mined by f2pool.com.

Show decoded transaction
{
  "txid": "b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41",
  "hash": "b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41",
  "version": 1,
  "size": 234,
  "vsize": 234,
  "weight": 936,
  "locktime": 45324,
  "vin": [
    {
      "txid": "b53e3bc5edbb41b34a963ecf67eb045266cf841cab73a780940ce6845377f141",
      "vout": 0,
      "scriptSig": { "asm": "", "hex": "" },
      "sequence": 6817749
    },
    {
      "txid": "b48a59fa9e036e997ba733904f631b1a64f5274be646698e49fd542141ca9404",
      "vout": 0,
      "scriptSig": { "asm": "", "hex": "" },
      "sequence": 45324
    },
    {
      "txid": "7641c08f4bd299abfef26dcc6b477938f4a6c2eed2f224d1f5c1c86b4e09739d",
      "vout": 1,
      "scriptSig": { "asm": "", "hex": "" },
      "sequence": 45324
    },
    {
      "txid": "fd43650477e0ba6825ae0482a8b0b2b509d5443fa2a8cdd101872752a9171dd6",
      "vout": 1,
      "scriptSig": { "asm": "", "hex": "" },
      "sequence": 45324
    }
  ],
  "vout": [
    {
      "value": 0.00159087,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 fb94f9a556bae3f98f44186e1ccaa4f5ff6a3187 OP_EQUAL",
        "hex": "a914fb94f9a556bae3f98f44186e1ccaa4f5ff6a318787",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "3QdFzfpU3u92GeRN4U5pLLezbBaHbj2ppr"
        ]
      }
    },
    {
      "value": 0.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_RETURN 68747470733a2f2f623130632e6d652f37",
        "hex": "6a1168747470733a2f2f623130632e6d652f37",
        "type": "nulldata"
      }
    }
  ]
}
Show raw transaction
010000000441f1775384e60c9480a773ab1c84cf665204eb67cf3e964ab341bbedc53b3eb50000000000d50768000494ca412154fd498e6946e64b27f5641a1b634f9033a77b996e039efa598ab400000000000cb100009d73094e6bc8c1f5d124f2d2eec2a6f43879476bcc6df2feab99d24b8fc0417601000000000cb10000d61d17a952278701d1cda8a23f44d509b5b2b0a88204ae2568bae077046543fd01000000000cb10000026f6d02000000000017a914fb94f9a556bae3f98f44186e1ccaa4f5ff6a3187870000000000000000136a1168747470733a2f2f623130632e6d652f370cb10000

Note (added on 2021-07-24): There is a downside to including a transaction spending P2TR outputs in a block before the taproot softfork activates. A few months or years after the softfork has activated, the activation height becomes fact and can be hardcoded into Bitcoin Core 4. If there would have been no spends from P2TR outputs on-chain before activation, the taproot activation height would have been irrelevant. The taproot rules could have been enforced starting with the Genesis block (or maybe starting at the SegWit activation). However, with the P2TR outputs spending transaction included in a block, the activation height needs to be kept as part of the consensus logic. This slightly increases the software complexity of Bitcoin nodes.

Changes on taproot activation

When taproot activates on block 709632, Bitcoin Core v0.21.1 and newer will start enforcing the taproot rules. Spending P2TR will only be possible by supplying a valid signature for the keypath spend or a by satisfying the script requirements for a scriptpath spend. However, older nodes that don’t know about the taproot softfork will continue to treat the P2TR spends as anyone-can-spend. This can become a problem if, for example, a mining pool forgets to upgrade and includes a transaction spending from a P2TR output without satisfying the taproot rules enforced by the network. The chain would split between upgraded nodes enforcing taproot and not upgraded nodes. It is recommended to upgrade production and payment handling nodes before taproot activates.

I like to thank f2pool.com for their cooperation. Without them including the non-standard transaction in a block, donating the P2TR outputs to brink.dev, wouldn’t have been possible. You can support me and my work here.


  1. Some SegWit opponents claimed that the SegWit softfork could be reversed after activation and the outputs would then be anyone-can-spend. To learn more about this I recommend reading The Blocksize War – Chapter 5 – SegWit. ↩︎

  2. A good summary on non-standard transactions and forward compatibility can be found in this comment by nullc on Hacker News. ↩︎

  3. This allows introducing of new rules to currently unused witness versions via a future softforks. The witness program verification succeeds at nodes unaware of the softfork. ↩︎

  4. See, for example, the notes from the Bitcoin Core PR Review Club on #19438: Introduce deploymentstatus for more information. ↩︎

All text and images in this work are licensed under a Creative Commons Attribution-ShareAlike 4.0 International License Creative Commons License

Next

Image for Userspace, Statically Defined Tracing support for Bitcoin Core

August 30, 2021

Userspace, Statically Defined Tracing support for Bitcoin Core

This report updates on what 0xB10C, Coinbase Crypto Community Fund grant recipient, has been working on over the first half of his year-long Bitcoin development grant. This specifically covers his work on Userspace, Statically Defined Tracing support for Bitcoin Core. This report was published on the Coinbase blog too.

Previous

Image for Evolution of the signature size in Bitcoin

November 10, 2020

Evolution of the signature size in Bitcoin

Digital signatures are an essential building block of the Bitcoin protocol and account for a large part of the data stored on the blockchain. We detail how the size of the encoded ECDSA signatures reduced multiple times over the last years and how the proposed Schnorr signature compares to the length of the currently used ECDSA signatures.