[brc-20] Single-step transfer proposal

Motivation:

When inscribing a transfer inscription to address A in the BRC20 protocol, a certain available balance of A is locked in this transfer inscription, which is called a transferable balance. When this inscription is transferred to B for the first time, this transferable balance will become B’s available balance.

Because inscribing a transfer inscription for address A does not require A’s consent, locking his available balance in the inscription without A’s consent constitutes an attack. For ordinary users, this is generally not a serious problem because this attack does not cause a decrease in the user’s overall balance, and the user can recover the available balance at a lower cost than the attacker. However, for entities that need to frequently and heavily send BRC20, this attack method may bring great trouble and loss of on-chain transaction fees.

We hope to improve the transfer mechanism of BRC20 in three aspects:

  1. Prevent unauthorized creation of transfer inscription
  2. Implement single-step transfer to reduce transfer costs
  3. Improves user experience by streamlining interactions

Single-step transfer mechanism:

In the transaction script for inscribing any inscription, a public key is almost always attached and requires a signature, mainly to prevent others from replacing the inscribing transaction. As follows:

OP_PUSHBYTES_32 9e2849b90a2353691fccedd467215c88eec89a5d0dcf468e6cf37abed344d746
OP_CHECKSIG
OP_FALSE
OP_IF
OP_PUSHBYTES_3 6f7264
...
OP_ENDIF

The public key signature check in this taproot script branch uses a standard Schnorr signature. This signature type is already used in many features like inscriptions, relative timelocks, and Lightning Network HTLCs. It’s expected to remain the core signature verification method for new taproot contracts going forward. Support for it from infrastructure tools is only going to grow, and it doesn’t depend on the user’s original address format.

We can simply reuse this mechanism. The address corresponding to the public key as the source of available balance locked when inscribing brc20 transfer, can effectively avoid unauthorized transfer inscribing.

In legacy transfer, the locked transferable balance belongs to the holding address of the inscription, which is also the source address of the available balance. However, in the case where the public key can already specify the balance source address without the need for the inscription holding address, the inscription holding address can be used as the new receiving address, which creates a new way of transferring the balance in a single step during inscribing.

Single-step transfers and legacy transfers differ only in how the available balance source address is chosen during inscribing. After that, once the transfer inscription is inscribed, they behave the same.

All addresses can use legacy transfer or single-step transfer by default, but after a public key first inscribed the valid single-step transfer inscription, the address corresponding to this public key will permanently disable legacy transfer.

The new mechanism solves two problems at once. Next, we need to discuss some details.

Public key signature and corresponding address

The Ordinals protocol doesn’t mandate that inscriptions include a public key and signature. Because the common OP_PUSHBYTES_32 + OP_CHECKSIG pattern can fail, allowing for the circumvention and forgery of any public key, we need to use the stricter OP_CHECKSIGVERIFY to properly validate signatures. Furthermore, we need to explicitly specify the address type corresponding to the public key. Similar to how Bitcoin’s three main address types are distinguished in ScriptPK using a single-byte prefix, we will also use a single byte to describe the six address types derivable from a public key.

We define that a single-step transfer inscription script must begin with OP_PUSHBYTES_32 + OP_CHECKSIGVERIFY + OP_N, where N represents the address type:

  1. P2TR: empty script path
  2. P2WPKH: with compressed even public key
  3. P2WPKH: with compressed odd public key
  4. P2PKH: with compressed even public key
  5. P2PKH: with compressed odd public key
  6. P2SH-P2WPKH: with compressed even public key
  7. P2SH-P2WPKH: with compressed odd public key
  8. P2TR: key path

The simplest case, a taproot address with an empty script path, uses this script format:

OP_PUSHBYTES_32 9e2849b90a2353691fccedd467215c88eec89a5d0dcf468e6cf37abed344d746
OP_CHECKSIGVERIFY
OP_1
OP_FALSE
OP_IF
...
OP_ENDIF

Inscriptions that do not belong to these 6 standard formats are not single-step transfer inscriptions.

After inscribing a single-step transfer, the specified type address will deduct the available balance, and disable legacy transfer.

Vendicated Inscription Support

BRC20 inscriptions can not be Cursed or Vendicated , that is, they do not accept inscribing multiple inscriptions in the same transaction using the POINTER tag. We can partially modify this rule, that is, single-step transfer allows Vendicated inscriptions.

It is important to allow multiple single-step transfer inscriptions to be inscribed in a single transaction.

This way, we can inscribe multiple single-step transfer inscriptions in a single transaction and send BRC20 balances to multiple recipients in bulk. In particular, we can inscribe multiple single-step transfers to recipients while sending a confirmed transfer inscription. This kind of one-to-many or even many-to-many sending is as secure as sending transfers one-to-one now. Just like the current BRC20 market sell order mechanism, this security is guaranteed by the transaction structure and will not be affected by whether the transaction is confirmed or not.

This not only significantly reduces the cost of high-frequency transfers, but more importantly, it enhances the UTXO properties of BRC20. Building a complete lightning network for brc20 becomes possible.

Activation plan

We can first enable single-step transfer on 5 characters, then enable it in 4-character brc20. This is much safer. And when we need to enable 4 characters, the workload is very small.

Proposal Implementation

We have submitted PR in all 3 major brc20 indexers (OKX, OPI, UniSat), with less than 200 lines of core code changes.

Other

Compared to single-step transfer, legacy transfer costs 184% when sent to a single recipient. When sent to up to 1560 recipients, the cost is 574%.

As it can significantly reduce the amount of ordinals original data, we also recommend that in the future, deploy/transfer and mint can also allow the use of Vendicated inscriptions.

Mint inscriptions can also be designed to use standard taproot signatures, meaning ownership is tied to the signer’s public key, not the current holder. This allows users to effectively “burn” the inscription (or lock it in an OP_RETURN), avoiding the need to manage it in their UTXO set.

Acknowledgements

We would like to express our gratitude to @domo for their insightful feedback and suggestions regarding the single-step transfer scheme. We are also grateful to @seesharp from BestInSlot for highlighting the need to address inscription UTXO bloat.

Refer