@@ -57,8 +57,8 @@ func CreatePubKeyTimeLockScript(pubKey []byte, lockTime int64) ([]byte, error) {
5757
5858// CreateTaprootAddress creates the taproot address with the given internal key and scripts
5959func CreateTaprootAddress (internalKey * secp256k1.PublicKey , scripts [][]byte , params * chaincfg.Params ) (string , error ) {
60- tapScriptTree := GetTapScriptTree (scripts )
61- scriptRoot := tapScriptTree .RootNode .TapHash ()
60+ tapscriptTree := GetTapscriptTree (scripts )
61+ scriptRoot := tapscriptTree .RootNode .TapHash ()
6262
6363 taprootOutKey := txscript .ComputeTaprootOutputKey (internalKey , scriptRoot [:])
6464
@@ -145,7 +145,7 @@ func GetInternalKey(borrowerPubKey []byte, dcmPubKey []byte) *btcec.PublicKey {
145145 return btcec .NewPublicKey (& P .X , & P .Y )
146146}
147147
148- func GetTapScriptTree (scripts [][]byte ) * txscript.IndexedTapScriptTree {
148+ func GetTapscriptTree (scripts [][]byte ) * txscript.IndexedTapScriptTree {
149149 leaves := []txscript.TapLeaf {}
150150
151151 for _ , script := range scripts {
@@ -157,6 +157,29 @@ func GetTapScriptTree(scripts [][]byte) *txscript.IndexedTapScriptTree {
157157 return tree
158158}
159159
160+ // GetThreeLeafTapscriptTreeProofs gets the tapscript proofs from the given 3-leaf tapscript tree
161+ // This is a workaround because btcsuite.AssembleTaprootScriptTree generates incorrect proofs if there exist same scripts
162+ // NOTE: Assume that this is a tapscript tree with three leaves
163+ // LeafA,LeafB,LeafC:
164+ // LeafA proof: H(LeafB),H(LeafC)
165+ // LeafB proof: H(LeafA),H(LeafC)
166+ // LeafC proof: H(H(LeafA),H(LeafB)) if H(LeafA) <= H(LeafB)
167+ func GetThreeLeafTapscriptTreeProofs (tapscriptTree * txscript.IndexedTapScriptTree ) []txscript.TapscriptProof {
168+ leaves := []txscript.TapLeaf {}
169+
170+ for _ , p := range tapscriptTree .LeafMerkleProofs {
171+ leaves = append (leaves , p .TapLeaf )
172+ }
173+
174+ rootNode := tapscriptTree .RootNode
175+
176+ return []txscript.TapscriptProof {
177+ newTapscriptProof (leaves [0 ], rootNode , append (getTapLeafHash (leaves [1 ]), getTapLeafHash (leaves [2 ])... )),
178+ newTapscriptProof (leaves [1 ], rootNode , append (getTapLeafHash (leaves [0 ]), getTapLeafHash (leaves [2 ])... )),
179+ newTapscriptProof (leaves [2 ], rootNode , getBranchNodeHash (leaves [0 ], leaves [1 ])),
180+ }
181+ }
182+
160183func GetControlBlock (pubKey * secp256k1.PublicKey , proof txscript.TapscriptProof ) ([]byte , error ) {
161184 controlBlock := proof .ToControlBlock (pubKey )
162185
@@ -225,3 +248,26 @@ func GetNUMSPoint() *btcec.PublicKey {
225248
226249 return point
227250}
251+
252+ // getTapLeafHash gets hash of the given tap leaf
253+ func getTapLeafHash (leaf txscript.TapLeaf ) []byte {
254+ hash := leaf .TapHash ()
255+ return hash [:]
256+ }
257+
258+ // getBranchNodeHash gets the branch node hash from the given left and right nodes
259+ func getBranchNodeHash (left txscript.TapNode , right txscript.TapNode ) []byte {
260+ tapBranch := txscript .NewTapBranch (left , right )
261+ tapBranchHash := tapBranch .TapHash ()
262+
263+ return tapBranchHash [:]
264+ }
265+
266+ // newTapscriptProof creates a tapscript proof from the given params
267+ func newTapscriptProof (leaf txscript.TapLeaf , rootNode txscript.TapNode , proof []byte ) txscript.TapscriptProof {
268+ return txscript.TapscriptProof {
269+ TapLeaf : leaf ,
270+ RootNode : rootNode ,
271+ InclusionProof : proof ,
272+ }
273+ }
0 commit comments