mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
reservation: add reservation script
This commit adds the reservation script file. This file contains the neccessary function to create the reservation script and addresses from the pubkeys and expiry.
This commit is contained in:
parent
23b818e436
commit
3142e98726
1 changed files with 122 additions and 0 deletions
122
instantout/reservation/script/script.go
Normal file
122
instantout/reservation/script/script.go
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
package script
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// TaprootMultiSigWitnessSize evaluates to 66 bytes:
|
||||
// - num_witness_elements: 1 byte
|
||||
// - sig_varint_len: 1 byte
|
||||
// - <sig>: 64 bytes
|
||||
TaprootMultiSigWitnessSize = 1 + 1 + 64
|
||||
|
||||
// TaprootExpiryScriptSize evaluates to 39 bytes:
|
||||
// - OP_DATA: 1 byte (trader_key length)
|
||||
// - <trader_key>: 32 bytes
|
||||
// - OP_CHECKSIGVERIFY: 1 byte
|
||||
// - <reservation_expiry>: 4 bytes
|
||||
// - OP_CHECKLOCKTIMEVERIFY: 1 byte
|
||||
TaprootExpiryScriptSize = 1 + 32 + 1 + 4 + 1
|
||||
|
||||
// TaprootExpiryWitnessSize evaluates to 140 bytes:
|
||||
// - num_witness_elements: 1 byte
|
||||
// - trader_sig_varint_len: 1 byte (trader_sig length)
|
||||
// - <trader_sig>: 64 bytes
|
||||
// - witness_script_varint_len: 1 byte (script length)
|
||||
// - <witness_script>: 39 bytes
|
||||
// - control_block_varint_len: 1 byte (control block length)
|
||||
// - <control_block>: 33 bytes
|
||||
TaprootExpiryWitnessSize = 1 + 1 + 64 + 1 + TaprootExpiryScriptSize + 1 + 33
|
||||
)
|
||||
|
||||
// ReservationScript returns the tapscript pkscript for the given reservation
|
||||
// parameters.
|
||||
func ReservationScript(expiry uint32, serverKey,
|
||||
clientKey *btcec.PublicKey) ([]byte, error) {
|
||||
|
||||
aggregatedKey, err := TaprootKey(expiry, serverKey, clientKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return PayToWitnessTaprootScript(aggregatedKey.FinalKey)
|
||||
}
|
||||
|
||||
// TaprootKey returns the aggregated MuSig2 combined key.
|
||||
func TaprootKey(expiry uint32, serverKey,
|
||||
clientKey *btcec.PublicKey) (*musig2.AggregateKey, error) {
|
||||
|
||||
expiryLeaf, err := TaprootExpiryScript(expiry, serverKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rootHash := expiryLeaf.TapHash()
|
||||
|
||||
aggregateKey, err := input.MuSig2CombineKeys(
|
||||
input.MuSig2Version100RC2,
|
||||
[]*btcec.PublicKey{
|
||||
clientKey, serverKey,
|
||||
}, true,
|
||||
&input.MuSig2Tweaks{
|
||||
TaprootTweak: rootHash[:],
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error combining keys: %v", err)
|
||||
}
|
||||
|
||||
return aggregateKey, nil
|
||||
}
|
||||
|
||||
// PayToWitnessTaprootScript creates a new script to pay to a version 1
|
||||
// (taproot) witness program.
|
||||
func PayToWitnessTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error) {
|
||||
builder := txscript.NewScriptBuilder()
|
||||
|
||||
builder.AddOp(txscript.OP_1)
|
||||
builder.AddData(schnorr.SerializePubKey(taprootKey))
|
||||
|
||||
return builder.Script()
|
||||
}
|
||||
|
||||
// TaprootExpiryScript returns the leaf script of the expiry script path.
|
||||
//
|
||||
// <server_key> OP_CHECKSIGVERIFY <reservation_expiry> OP_CHECKLOCKTIMEVERIFY.
|
||||
func TaprootExpiryScript(expiry uint32,
|
||||
serverKey *btcec.PublicKey) (*txscript.TapLeaf, error) {
|
||||
|
||||
builder := txscript.NewScriptBuilder()
|
||||
|
||||
builder.AddData(schnorr.SerializePubKey(serverKey))
|
||||
builder.AddOp(txscript.OP_CHECKSIGVERIFY)
|
||||
|
||||
builder.AddInt64(int64(expiry))
|
||||
builder.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
|
||||
|
||||
script, err := builder.Script()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
leaf := txscript.NewBaseTapLeaf(script)
|
||||
return &leaf, nil
|
||||
}
|
||||
|
||||
// ExpirySpendWeight returns the weight of the expiry path spend.
|
||||
func ExpirySpendWeight() int64 {
|
||||
var weightEstimator input.TxWeightEstimator
|
||||
weightEstimator.AddWitnessInput(TaprootExpiryWitnessSize)
|
||||
|
||||
weightEstimator.AddP2TROutput()
|
||||
|
||||
return int64(weightEstimator.Weight())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue