Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
oxf71 committed Jan 14, 2024
1 parent 7c2261d commit 35948ea
Show file tree
Hide file tree
Showing 6 changed files with 466 additions and 39 deletions.
63 changes: 37 additions & 26 deletions example/taprootmusig/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ import (
"log"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/oxf71/musig2-demo/lib/go-ord-tx/pkg/btcapi/mempool"
"github.com/oxf71/musig2-demo/lib/go-ord-tx/pkg/ord"
musig2demo "github.com/oxf71/musig2-demo/musig2"
"github.com/oxf71/musig2-demo/psbt"
)

func decodeHex(hexStr string) []byte {
Expand All @@ -26,36 +24,46 @@ func decodeHex(hexStr string) []byte {
return b
}
func main() {
netParams := &chaincfg.SigNetParams
netParams := &chaincfg.TestNet3Params
btcApiClient := mempool.NewClient(netParams)
privKey1, _ := btcec.PrivKeyFromBytes(decodeHex("440bb3ec56d213e90d006d344d74f6478db4f7fa4cdd388095d8f4edef0c5156"))
privKey2, _ := btcec.PrivKeyFromBytes(decodeHex("e0087817fd1d1154a781c11b394a0dcec82f076bbf026df9d61667ead16fa778"))

musigPrivKey := musig2demo.TwoBtcTaprootAddress(privKey1, privKey2)
privKey1, publicKey1 := btcec.PrivKeyFromBytes(decodeHex("440bb3ec56d213e90d006d344d74f6478db4f7fa4cdd388095d8f4edef0c5156"))
privKey2, publicKey2 := btcec.PrivKeyFromBytes(decodeHex("e0087817fd1d1154a781c11b394a0dcec82f076bbf026df9d61667ead16fa778"))
_, publicKey3 := btcec.PrivKeyFromBytes(decodeHex("e0087817fd1d1154a781c11b394a0dcec82f076bbf026df9d61667ead16fa771"))
publicKey1Hex := hex.EncodeToString(publicKey1.SerializeCompressed())
publicKey2Hex := hex.EncodeToString(publicKey2.SerializeCompressed())
publicKey3Hex := hex.EncodeToString(publicKey3.SerializeCompressed())
allSignerPubKeys := []string{publicKey1Hex, publicKey2Hex, publicKey3Hex}
// gen 2-3 multi address

multiTaprootAddress, multiScript, err := psbt.GenerateMultiTaprootAddress(allSignerPubKeys, 2, netParams)
if err != nil {
log.Fatal(err)
}
// musigPrivKey := musig2demo.TwoBtcTaprootAddress(privKey1, privKey2)

musigPriv := make([]*btcec.PrivateKey, 0)
musigPriv = append(musigPriv, privKey1, privKey2)

musigAddress, _ := btcutil.DecodeAddress(musigPrivKey, netParams)
musigAddress, _ := btcutil.DecodeAddress(multiTaprootAddress, netParams)

utxoPrivateKeyHex := "440bb3ec56d213e90d006d344d74f6478db4f7fa4cdd388095d8f4edef0c5156"
utxoPrivateKeyBytes, err := hex.DecodeString(utxoPrivateKeyHex)
if err != nil {
log.Fatal(err)
}
utxoPrivateKey, _ := btcec.PrivKeyFromBytes(utxoPrivateKeyBytes)
// // // // utxoPrivateKeyHex := "440bb3ec56d213e90d006d344d74f6478db4f7fa4cdd388095d8f4edef0c5156"
// // // utxoPrivateKeyBytes, err := hex.DecodeString(utxoPrivateKeyHex)
// // if err != nil {
// // log.Fatal(err)
// }
// utxoPrivateKey, _ := btcec.PrivKeyFromBytes(utxoPrivateKeyBytes)

utxoPublicKey := utxoPrivateKey.PubKey()
// utxoPublicKey := utxoPrivateKey.PubKey()

utxoTaprootAddress, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(txscript.ComputeTaprootKeyNoScript(utxoPublicKey)), netParams)
if err != nil {
log.Fatal(err)
}
// utxoTaprootAddress, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(txscript.ComputeTaprootKeyNoScript(utxoPublicKey)), netParams)
// if err != nil {
// log.Fatal(err)
// }

fmt.Println("utxoTaprootAddress:", utxoTaprootAddress.EncodeAddress())
// fmt.Println("utxoTaprootAddress:", utxoTaprootAddress.EncodeAddress())
fmt.Println("musigAddress no script:", musigAddress.EncodeAddress())

unspentList, err := btcApiClient.ListUnspent(utxoTaprootAddress)
unspentList, err := btcApiClient.ListUnspent(musigAddress)

if err != nil {
log.Fatalf("list unspent err %v", err)
Expand All @@ -68,12 +76,13 @@ func main() {
commitTxOutPointList := make([]*wire.OutPoint, 0)
commitTxPrivateKeyList := make([]*btcec.PrivateKey, 0)
for i := range unspentList {
// if i > 0 {
// break
// }
if i > 0 {
break
}
commitTxOutPointList = append(commitTxOutPointList, unspentList[i].Outpoint)
commitTxPrivateKeyList = append(commitTxPrivateKeyList, utxoPrivateKey)
commitTxPrivateKeyList = append(commitTxPrivateKeyList, privKey1)
fmt.Println("unspentList:", unspentList[i].Outpoint)
fmt.Println("unspentList out:", unspentList[i].Output)
}

// panic("err")
Expand All @@ -93,6 +102,8 @@ func main() {
FeeRate: 19,
DataList: dataList,
SingleRevealTxOnly: false,
MultiScript: multiScript,
MultiPriv: musigPriv,
}

tool, err := ord.NewInscriptionToolWithBtcApiClient(netParams, btcApiClient, &request, musigPriv)
Expand Down
10 changes: 8 additions & 2 deletions lib/go-ord-tx/pkg/btcapi/mempool/addresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package mempool
import (
"encoding/json"
"fmt"
"net/http"

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/oxf71/musig2-demo/lib/go-ord-tx/pkg/btcapi"
"net/http"
)

type UTXO struct {
Expand Down Expand Up @@ -43,9 +45,13 @@ func (c *MempoolClient) ListUnspent(address btcutil.Address) ([]*btcapi.UnspentO
if err != nil {
return nil, err
}
pkScript, err := txscript.PayToAddrScript(address)
if err != nil {
return nil, err
}
unspentOutputs = append(unspentOutputs, &btcapi.UnspentOutput{
Outpoint: wire.NewOutPoint(txHash, uint32(utxo.Vout)),
Output: wire.NewTxOut(utxo.Value, address.ScriptAddress()),
Output: wire.NewTxOut(utxo.Value, pkScript),
})
}
return unspentOutputs, nil
Expand Down
136 changes: 126 additions & 10 deletions lib/go-ord-tx/pkg/ord/ord.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type InscriptionRequest struct {
SingleRevealTxOnly bool // Currently, the official Ordinal parser can only parse a single NFT per transaction.
// When the official Ordinal parser supports parsing multiple NFTs in the future, we can consider using a single reveal transaction.
RevealOutValue int64
MultiScript []byte
MultiPriv []*btcec.PrivateKey
}

type inscriptionTxCtxData struct {
Expand All @@ -69,6 +71,8 @@ type InscriptionTool struct {
revealTxPrevOutputFetcher *txscript.MultiPrevOutFetcher
revealTx []*wire.MsgTx
commitTx *wire.MsgTx
MultiScript []byte
MultiPriv []*btcec.PrivateKey
}

const (
Expand Down Expand Up @@ -107,6 +111,8 @@ func NewInscriptionToolWithBtcApiClient(net *chaincfg.Params,
commitTxPrevOutputFetcher: txscript.NewMultiPrevOutFetcher(nil),
commitTxPrivateKeyList: request.CommitTxPrivateKeyList,
revealTxPrevOutputFetcher: txscript.NewMultiPrevOutFetcher(nil),
MultiScript: request.MultiScript,
MultiPriv: request.MultiPriv,
}
return tool, tool._initTool(net, request, musigPriv)
}
Expand Down Expand Up @@ -523,28 +529,138 @@ func (tool *InscriptionTool) signCommitTx() error {
tool.commitTx = commitSignTransaction
} else {
fmt.Println("taproot sign")
witnessList := make([]wire.TxWitness, len(tool.commitTx.TxIn))
// witnessList := make([]wire.TxWitness, len(tool.commitTx.TxIn))
for i := range tool.commitTx.TxIn {
txOut := tool.commitTxPrevOutputFetcher.FetchPrevOutput(tool.commitTx.TxIn[i].PreviousOutPoint)
witness, err := TaprootWitnessSignature(
fmt.Println(txOut.PkScript)
// esig, err := txscript.RawTxInSignature(
// tool.commitTx,
// i,
// txOut.PkScript,
// txscript.SigHashAll,
// tool.MultiPriv[0],
// )
sig, err := TaprootWitnessSignatureTest(
tool.commitTx,
txscript.NewTxSigHashes(tool.commitTx, tool.commitTxPrevOutputFetcher),
i,
txOut.Value,
txOut.PkScript,
txscript.SigHashDefault,
tool.commitTxPrivateKeyList[i],
nil,
// tool.txCtxDataList[0].controlBlockWitness,
txscript.SigHashAll,
tool.MultiPriv[0],
)
if err != nil {
return err
}
witnessList[i] = witness
}
for i := range witnessList {
tool.commitTx.TxIn[i].Witness = witnessList[i]
rBytes := sig.Serialize()[:32]
sBytes := sig.Serialize()[32:64]

fmt.Println("sig len", len(sig.Serialize()))
fmt.Println("sig rbytes:", hex.EncodeToString(rBytes))
fmt.Println("sig sbytes:", hex.EncodeToString(sBytes))

newsig := []byte{}
newsig2 := []byte{}

derprefix, _ := hex.DecodeString("30440220")

newsig = append(newsig, derprefix...)
newsig = append(newsig, rBytes...)
sLen, _ := hex.DecodeString("0220")
derversion, _ := hex.DecodeString("01")
newsig = append(newsig, sLen...)
newsig = append(newsig, sBytes...)
newsig = append(newsig, derversion...)

// 创建一个包含公钥和签名的结构
// schnorrSignature := struct {
// PubKey *btcec.PublicKey
// Signature []byte
// }{
// PubKey: tool.MultiPriv[0].PubKey(),
// Signature: sig.Serialize(),
// }
// ecdsa.ParseDERSignature()
// 对签名进行DER编码
// derSignature, err := asn1.Marshal(sig)
// if err != nil {
// fmt.Println("Failed to encode signature:", err)
// return err
// }
// esig2, err := txscript.RawTxInSignature(
// tool.commitTx,
// i,
// txOut.PkScript,
// txscript.SigHashAll,
// tool.MultiPriv[1],
// )

sig2, err := TaprootWitnessSignatureTest(
tool.commitTx,
txscript.NewTxSigHashes(tool.commitTx, tool.commitTxPrevOutputFetcher),
i,
txOut.Value,
txOut.PkScript,
txscript.SigHashAll,
tool.MultiPriv[1],
)
if err != nil {
return err
}

witnessSig1, err := WitnessSignature(
tool.commitTx,
txscript.NewTxSigHashes(tool.commitTx, tool.commitTxPrevOutputFetcher),
i,
txOut.Value,
tool.MultiScript,
txscript.SigHashAll,
tool.MultiPriv[0],
true,
)

witnessSig2, err := WitnessSignature(
tool.commitTx,
txscript.NewTxSigHashes(tool.commitTx, tool.commitTxPrevOutputFetcher),
i,
txOut.Value,
tool.MultiScript,
txscript.SigHashAll,
tool.MultiPriv[1],
true,
)

if err != nil {
return err
}

rBytes2 := sig2.Serialize()[:32]
sBytes2 := sig2.Serialize()[32:64]

newsig2 = append(newsig2, derprefix...)
newsig2 = append(newsig2, rBytes2...)
newsig2 = append(newsig2, sLen...)
newsig2 = append(newsig2, sBytes2...)
newsig2 = append(newsig2, derversion...)

fmt.Println("sig:", hex.EncodeToString(newsig))
fmt.Println("sig2:", hex.EncodeToString(newsig2))
fmt.Println("multi script:", hex.EncodeToString(tool.MultiScript))
// txscript.WitnessStack
// for k, v := range witnessSig1 {
// fmt.Println("witness:", k, hex.EncodeToString(v))
// }
fmt.Println("witnesssig:", witnessSig1)
fmt.Println("witnesssig2:", witnessSig2)
// witnessList[i] = wire.TxWitness{nil, esig, esig2, tool.MultiScript}
tool.commitTx.TxIn[i].Witness = wire.TxWitness{nil, witnessSig1, witnessSig2, tool.MultiScript}

// tool.commitTx.TxIn[i].SignatureScript = esig
}
// for i := range witnessList {

// tool.commitTx.TxIn[i].Witness = witnessList[i]
// }
}
return nil
}
Expand Down
Loading

0 comments on commit 35948ea

Please sign in to comment.