Last active
March 8, 2019 07:01
-
-
Save davecgh/a5d6093c095ec8297e76 to your computer and use it in GitHub Desktop.
Example of stepping through a script using the txscript API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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("") | |
} | |
} | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment