Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Design]: Deposit into sBTC directly from Bitcoin #1168

Open
3 tasks
djordon opened this issue Dec 19, 2024 · 0 comments
Open
3 tasks

[Design]: Deposit into sBTC directly from Bitcoin #1168

djordon opened this issue Dec 19, 2024 · 0 comments
Labels
deposit The deposit sBTC operation. design making a design decision. sbtc signer binary The sBTC Bootstrap Signer.

Comments

@djordon
Copy link
Contributor

djordon commented Dec 19, 2024

Design - Deposit into sBTC directly from Bitcoin

This ticket holds the design of depositing into sBTC directly from the bitcoin layer, with no need for the user to use Emily or a bridge.

1. Summary

Include the necessary peg-in data in an OP_RETURN output. Signers will then be able to identify and process transactions if the OP_RETURN and deposit outputs are formatted correctly.

2. Context & Purpose

The proposed design is to have deposit transactions that have enough data on chain to make deposit UTXOs discoverable without the need for the transaction to be revealed to an external API like Emily. This will make it easier for others to build their own bridges, or forgo using a bridge entirely if they desire.

Pegging in directly from Bitcoin L1 places the burden on wallets

Relevant Research Discussions

Other bridges support direct from the L1 peg-ins, link to them from #153.

External Resources

3. Design

3.1 Proposed Component Design

The design is to have an OP_RETURN that is discoverable, and contains enough data for the signers to spend the deposit UTXO, committing the full deposit data on chain.

Process Overview:

  1. Deposit Construction: Users create a deposit UTXO and an OP_RETURN output containing data correlating with their deposit UTXO specifics.
  2. Signer Validation: Signers scan all transactions for OP_RETURN outputs matching the HASH160 of a signer’s aggregate key. Valid transactions are considered for sweep operations.
  3. Transaction Processing: Validated deposits are added to Emily.

Note that the signers already scan all outputs in all transactions in every block that they process, so matching on an OP_RETURN output is not much additional effort.

The proposed layout for the OP_RETURN output is this:

0         1                    21     22        23         24                    44          65
|---------|--------------------|------|---------|----------|---------------------|-----------|
  version   signer pubkey hash   vout   max fee   locktime   reclaim pubkey hash   recipient

Meaning:

  1. version (1 byte) is just a version byte for the layout.
  2. signer pubkey hash (20 bytes) is the HASH160 of one of the signers’ x-only aggregate key.
  3. vout (1 byte) is the output index of the deposit UTXO.
  4. max fee (1 byte) determines the max fee by taking the byte, interpreting it as an unsigned integer between 1 and 256, and multiplying it by 1000.
  5. locktime (1 byte) determines the OP_CSV locktime, interpreting the byte as an unsigned integer between 6 and 262.
  6. reclaim pubkey hash (20 bytes) is the HASH160 of the x-only public key locking the reclaim script.
  7. recipient (21 bytes) is the recipient address. It is always a standard address.

The above information maps to proper deposit and reclaim scripts while allowing for future updates. Reclaim scripts are assumed to be of the form

<locktime> OP_CSV OP_DROP OP_DUP OP_HASH160 <reclaim-pubkey-hash> OP_EQUAL OP_CHECKSIG 
  • The above layout is for the version 0 layout. We can support more compact layouts in other versions, where we eliminate some combination of vout, max fee, and locktime by standardizing their values.
  • The max size that a depositor will have to pay for in a sweep transaction is ~267 vbytes. So the maximum fee rate that a user could pay in the above design is 256,000 sats, or ~958 sats per vbyte (256,000 / 267 ~= 958).
  • Deposits made through this path must go to standard addresses. We cannot support contract addresses unless we constrain the supported contract lengths to be less than the actual contract lengths.
  • By default the signers do not consider deposits after 1000 blocks, so having a maximum supported locktime of 262 is likely fine.
  • Informing Emily is a little better for the user than not informing Emily, so that was the path taken here. If we do not inform Emily, we'd have to ignore 404 Not Found error responses.

3.1.1 Deposit scripts

Each sBTC deposit script have the following form

<deposit-data> OP_DROP OP_PUSHBYTES_32 <x-only-public-key> OP_CHECKSIG

The <x-only-public-key> is the signers’ aggregate key. It’s HASH160 maps to the signer pubkey hash from above. The <deposit-data> is expected to have the format <max-fee><recipient-address>, where the recipient address follows the format for a principal from SIP-005. The expected wire format for <deposit-data> is:

0         8             9         10        30
|---------|-------------|---------|---------|
  max fee   type prefix   version   hash160  

The max fee is an unsigned integer written in big endian format. The type prefix will be fixed to 5, since the Stacks address is always the standard variant, while the version and hash160 map to the recipient above.

<locktime> OP_CSV <rest-of-deposit-script>

3.1.2 Wallets

The tough part with supporting direct from L1 to sBTC is wallet support. But we could influence the state of things by adding support for them into the Leather wallet.

I believe the Leather wallet doesn’t necessarily use the same derivation path for Stacks and Bitcoin keypairs. If so, this means that Leather may not associate public keys underlying their bitcoin address with a Stacks address, even though they could control the associated Stacks address with the bitcoin keypair.

3.2 Design Diagram

TODO

3.3 Considerations & Alternatives

TODO

3.4 Areas of Ambiguity

For wallets where the derivation path of bitcoin and stacks addresses are the same, we could simplify the OP_RETURN data to something like

0                    20        21            41                42
|--------------------|---------|-------------|-----------------|
  signer pubkey hash   version   pubkey hash   address version

The assumption is that the stacks address is formed from the same pubkey hash noted in bytes 21-41, so we do not need to note the recipient.

Wallets

TODO

Closing Checklist

  • The design proposed in this issue is clearly documented in the description of this ticket.
  • Everyone necessary has reviewed the resolution and agrees with the proposal.
  • This ticket has or links all the information necessary to familiarize a contributor with the design decision, why it was made, and how it'll be included.
@djordon djordon added design making a design decision. sbtc signer binary The sBTC Bootstrap Signer. deposit The deposit sBTC operation. labels Dec 19, 2024
@djordon djordon added this to the sBTC: Nice to have milestone Dec 19, 2024
@djordon djordon added this to sBTC Dec 19, 2024
@github-project-automation github-project-automation bot moved this to Needs Triage in sBTC Dec 19, 2024
@djordon djordon moved this from Needs Triage to Todo in sBTC Dec 19, 2024
@djordon djordon moved this from Todo to Needs Triage in sBTC Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deposit The deposit sBTC operation. design making a design decision. sbtc signer binary The sBTC Bootstrap Signer.
Projects
Status: Needs Triage
Development

No branches or pull requests

1 participant