github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/script/taproot_test.go (about) 1 package script 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/hex" 7 "encoding/json" 8 "fmt" 9 "github.com/piotrnar/gocoin/lib/btc" 10 "io/ioutil" 11 "testing" 12 ) 13 14 type one_scr_tst struct { 15 Tx string `json:"tx"` 16 Prevouts []string `json:"prevouts"` 17 Index int `json:"index"` 18 Success struct { 19 ScriptSig string `json:"scriptSig"` 20 Witness []string `json:"witness"` 21 } `json:"success"` 22 Failure struct { 23 ScriptSig string `json:"scriptSig"` 24 Witness []string `json:"witness"` 25 } `json:"failure"` 26 Flags string `json:"flags"` 27 Final bool `json:"final"` 28 Comment string `json:"comment"` 29 } 30 31 func dump_test(tst *one_scr_tst) { 32 b, er := json.MarshalIndent(tst, "", " ") 33 if er == nil { 34 fmt.Println(string(b)) 35 } 36 } 37 38 func TestTaprootScritps(t *testing.T) { 39 var tests []one_scr_tst 40 var res bool 41 42 DBG_ERR = false 43 dat, er := ioutil.ReadFile("../test/bip341_script_tests.json") 44 if er != nil { 45 t.Error(er.Error()) 46 return 47 } 48 er = json.Unmarshal(dat, &tests) 49 if er != nil { 50 t.Error(er.Error()) 51 return 52 } 53 for i := 0; i < len(tests); i++ { 54 //println("+++++++++++++", i, "+++++++++++++++") 55 tv := tests[i] 56 57 d, e := hex.DecodeString(tv.Tx) 58 if e != nil { 59 t.Fatal(i, e.Error()) 60 } 61 tx, off := btc.NewTx(d) 62 if tx == nil { 63 t.Fatal(i, "Tx decode error", off, tv.Tx) 64 } 65 if off != len(d) { 66 t.Fatal(i, "Tx not fully decoded", off, len(d), tv.Tx) 67 } 68 69 tx.Spent_outputs = make([]*btc.TxOut, len(tv.Prevouts)) 70 71 /* 72 _b := new(bytes.Buffer) 73 btc.WriteVlen(_b, uint64(len(tv.Prevouts))) 74 outs := _b.Bytes() 75 */ 76 77 for i, pks := range tv.Prevouts { 78 d, e = hex.DecodeString(pks) 79 if e != nil { 80 t.Fatal(i, e.Error()) 81 } 82 tx.Spent_outputs[i] = new(btc.TxOut) 83 rd := bytes.NewReader(d) 84 e = binary.Read(rd, binary.LittleEndian, &tx.Spent_outputs[i].Value) 85 if e != nil { 86 t.Fatal(i, e.Error()) 87 } 88 le, e := btc.ReadVLen(rd) 89 if e != nil { 90 t.Fatal(i, e.Error()) 91 } 92 tx.Spent_outputs[i].Pk_script = make([]byte, int(le)) 93 _, e = rd.Read(tx.Spent_outputs[i].Pk_script) 94 if e != nil { 95 t.Fatal(i, e.Error()) 96 } 97 //outs = append(outs, txout_serialize(tx.Spent_outputs[i])...) 98 } 99 100 idx := tv.Index 101 if tv.Success.ScriptSig != "" { 102 if d, er = hex.DecodeString(tv.Success.ScriptSig); er != nil { 103 t.Fatal(i, e.Error()) 104 } 105 tx.TxIn[idx].ScriptSig = d 106 } 107 if len(tv.Success.Witness) > 0 { 108 tx.SegWit = make([][][]byte, len(tx.TxIn)) 109 tx.SegWit[idx] = make([][]byte, len(tv.Success.Witness)) 110 for i := range tv.Success.Witness { 111 tx.SegWit[idx][i], e = hex.DecodeString(tv.Success.Witness[i]) 112 //println("wit", idx, i, hex.EncodeToString(tx.SegWit[idx][i])) 113 if er != nil { 114 t.Fatal(i, e.Error()) 115 } 116 } 117 } 118 flags, er := decode_flags(tv.Flags) 119 if er != nil { 120 t.Fatal(i, er.Error()) 121 } 122 123 //DBG_ERR = true 124 res = VerifyTxScript(tx.Spent_outputs[idx].Pk_script, &SigChecker{Tx: tx, Idx: idx, Amount: tx.Spent_outputs[idx].Value}, flags) 125 126 if false { 127 hasz := tx.TaprootSigHash(&btc.ScriptExecutionData{ 128 M_tapleaf_hash: btc.NewUint256FromString("b45b31b6d43e11c6e3c38b09942a7e6d8178eaa97965f387b0872b5857c6768d").Hash[:], 129 M_codeseparator_pos: 0xffffffff}, idx, 2, false) 130 131 println("hasz:", btc.NewUint256(hasz).String()) 132 break 133 } 134 135 if !res { 136 //dump_test(&tv) 137 t.Fatal(i, "Verify Failed for", tv.Comment) 138 } 139 140 if tv.Failure.ScriptSig != "" || len(tv.Failure.Witness) > 0 { 141 if tv.Failure.ScriptSig != "" { 142 if d, er = hex.DecodeString(tv.Failure.ScriptSig); er != nil { 143 t.Fatal(i, e.Error()) 144 } 145 tx.TxIn[idx].ScriptSig = d 146 } 147 if len(tv.Failure.Witness) > 0 { 148 tx.SegWit = make([][][]byte, len(tx.TxIn)) 149 tx.SegWit[idx] = make([][]byte, len(tv.Failure.Witness)) 150 for i := range tv.Failure.Witness { 151 tx.SegWit[idx][i], e = hex.DecodeString(tv.Failure.Witness[i]) 152 if er != nil { 153 t.Fatal(i, e.Error()) 154 } 155 } 156 } 157 158 res = VerifyTxScript(tx.Spent_outputs[idx].Pk_script, &SigChecker{Tx: tx, Idx: idx, Amount: tx.Spent_outputs[idx].Value}, flags) 159 160 if res { 161 dump_test(&tv) 162 t.Fatal(i, "Verify not Failed but should") 163 } 164 } 165 166 //break 167 } 168 //println("counters:", btc.EcdsaVerifyCnt(), btc.SchnorrVerifyCnt(), btc.CheckPay2ContractCnt()) 169 }