mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-17 04:04:21 +01:00
* move OOR transaction creation client-side * robust redeem tx checks * optimize GetVtxos db call * rename CompleteAsyncPayment --> SubmitRedeemTx * fix permissions.go
81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package bitcointree
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/ark-network/ark/common"
|
|
"github.com/btcsuite/btcd/btcutil/psbt"
|
|
"github.com/btcsuite/btcd/txscript"
|
|
"github.com/btcsuite/btcd/wire"
|
|
)
|
|
|
|
func BuildRedeemTx(
|
|
vtxos []common.VtxoInput,
|
|
outputs []*wire.TxOut,
|
|
feeAmount int64,
|
|
) (string, error) {
|
|
if len(vtxos) <= 0 {
|
|
return "", fmt.Errorf("missing vtxos")
|
|
}
|
|
|
|
ins := make([]*wire.OutPoint, 0, len(vtxos))
|
|
witnessUtxos := make(map[int]*wire.TxOut)
|
|
tapscripts := make(map[int]*psbt.TaprootTapLeafScript)
|
|
|
|
for index, vtxo := range vtxos {
|
|
rootHash := vtxo.Tapscript.ControlBlock.RootHash(vtxo.Tapscript.RevealedScript)
|
|
taprootKey := txscript.ComputeTaprootOutputKey(UnspendableKey(), rootHash)
|
|
|
|
vtxoOutputScript, err := common.P2TRScript(taprootKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
witnessUtxos[index] = &wire.TxOut{
|
|
Value: vtxo.Amount,
|
|
PkScript: vtxoOutputScript,
|
|
}
|
|
|
|
ctrlBlockBytes, err := vtxo.Tapscript.ControlBlock.ToBytes()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
tapscripts[index] = &psbt.TaprootTapLeafScript{
|
|
ControlBlock: ctrlBlockBytes,
|
|
Script: vtxo.Tapscript.RevealedScript,
|
|
LeafVersion: txscript.BaseLeafVersion,
|
|
}
|
|
|
|
ins = append(ins, vtxo.Outpoint)
|
|
}
|
|
|
|
if feeAmount >= outputs[len(outputs)-1].Value {
|
|
return "", fmt.Errorf("redeem tx fee is higher than the amount of the change receiver")
|
|
}
|
|
|
|
sequences := make([]uint32, len(ins))
|
|
for i := range sequences {
|
|
sequences[i] = wire.MaxTxInSequenceNum
|
|
}
|
|
|
|
redeemPtx, err := psbt.New(
|
|
ins, outputs, 2, 0, sequences,
|
|
)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for i := range redeemPtx.Inputs {
|
|
redeemPtx.Inputs[i].WitnessUtxo = witnessUtxos[i]
|
|
redeemPtx.Inputs[i].TaprootLeafScript = []*psbt.TaprootTapLeafScript{tapscripts[i]}
|
|
}
|
|
|
|
redeemTx, err := redeemPtx.B64Encode()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return redeemTx, nil
|
|
}
|