package main import ( "encoding/hex" "fmt" "os" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" ) // createSpendTx generates a basic spending transaction given the passed // signature and public key scripts. func createSpendingTx(sigScript, pkScript []byte) (*wire.MsgTx, error) { coinbaseTx := wire.NewMsgTx(wire.TxVersion) outPoint := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0)) txIn := wire.NewTxIn(outPoint, []byte{txscript.OP_0, txscript.OP_0}) txOut := wire.NewTxOut(0, pkScript) coinbaseTx.AddTxIn(txIn) coinbaseTx.AddTxOut(txOut) spendingTx := wire.NewMsgTx(wire.TxVersion) coinbaseTxSha := coinbaseTx.TxHash() outPoint = wire.NewOutPoint(&coinbaseTxSha, 0) txIn = wire.NewTxIn(outPoint, sigScript) txOut = wire.NewTxOut(0, nil) spendingTx.AddTxIn(txIn) spendingTx.AddTxOut(txOut) return spendingTx, nil } func main() { txscript.SetLogWriter(os.Stdout, "trace") sigScript, err := hex.DecodeString("47304402202f7505132be14872581f35d74b759212d9da40482653f1ffa3116c3294a4a51702206adbf347a2240ca41c66522b1a22a41693610b76a8e7770645dc721d1635854f0143410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ac") if err != nil { fmt.Println(err) return } pkScript, err := hex.DecodeString("a91431edc23bdafda4639e669f89ad6b2318dd79d03287") if err != nil { fmt.Println(err) return } tx, err := createSpendingTx(sigScript, pkScript) if err != nil { fmt.Println(err) return } vm, err := txscript.NewEngine(pkScript, tx, 0, txscript.StandardVerifyFlags, nil) if err != nil { fmt.Println(err) return } if err := vm.Execute(); err != nil { fmt.Println(err) return } // Alternatively, you can comment out the execute above, step through // it manually, and examine the stack. /* done := false for !done { // Display the instruction and associated data at the program // counter. dis, err := vm.DisasmPC() if err != nil { fmt.Printf("stepping (%v)\n", err) } fmt.Printf("stepping %v\n", dis) // Execute the next instruction. done, err = vm.Step() if err != nil { fmt.Println(err) return } // Display the stacks. dataStack := vm.GetStack() if len(dataStack) != 0 { fmt.Println("Data stack:") spew.Dump(dataStack) fmt.Println("") } altStack := vm.GetAltStack() if len(altStack) != 0 { fmt.Println("Alternate stack:") spew.Dump(altStack) fmt.Println("") } } */ }