txscript

package
v0.0.0-...-46f88e6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2023 License: ISC Imports: 23 Imported by: 9

README

txscript

ISC License

Package txscript implements the bitcoin transaction script language. There is a comprehensive test suite.

This package has intentionally been designed so it can be used as a standalone package for any projects needing to use or validate bitcoin transaction scripts.

Bitcoin Scripts

Bitcoin provides a stack-based, FORTH-like language for the scripts in the bitcoin transactions. This language is not turing complete although it is still fairly powerful. A description of the language can be found at https://en.bitcoin.it/wiki/Script

License

Package txscript is licensed under the Copyfree ISC License.

Documentation

Overview

Package txscript implements the bitcoin transaction script language.

A complete description of the script language used by bitcoin can be found at https://en.bitcoin.it/wiki/Script. The following only serves as a quick overview to provide information on how to use the package.

This package provides data structures and functions to parse and execute bitcoin transaction scripts.

Script Overview

Bitcoin transaction scripts are written in a stack-base, FORTH-like language.

The bitcoin script language consists of a number of opcodes which fall into several categories such pushing and popping data to and from the stack, performing basic and bitwise arithmetic, conditional branching, comparing hashes, and checking cryptographic signatures. Scripts are processed from left to right and intentionally do not provide loops.

The vast majority of Bitcoin scripts at the time of this writing are of several standard forms which consist of a spender providing a public key and a signature which proves the spender owns the associated private key. This information is used to prove the the spender is authorized to perform the transaction.

One benefit of using a scripting language is added flexibility in specifying what conditions must be met in order to spend bitcoins.

Errors

Errors returned by this package are of type txscript.Error. This allows the caller to programmatically determine the specific error by examining the ErrorCode field of the type asserted txscript.Error while still providing rich error messages with contextual information. A convenience function named IsErrorCode is also provided to allow callers to easily check for a specific error code. See ErrorCode in the package documentation for a full list.

Index

Examples

Constants

View Source
const (
	OpCondFalse = 0
	OpCondTrue  = 1
	OpCondSkip  = 2
)

Conditional execution constants.

View Source
const (
	// MaxDataCarrierSize is the maximum number of bytes allowed in pushed
	// data to be considered a nulldata transaction
	MaxDataCarrierSize = 80

	// StandardVerifyFlags are the script flags which are used when
	// executing transaction scripts to enforce additional checks which
	// are required for the script to be considered standard.  These checks
	// help reduce issues related to transaction malleability as well as
	// allow pay-to-script hash transactions.  Note these flags are
	// different than what is required for the consensus rules in that they
	// are more strict.
	//
	// TODO: This definition does not belong here.  It belongs in a policy
	// package.
	StandardVerifyFlags = ScriptBip16 |
		ScriptVerifyDERSignatures |
		ScriptVerifyStrictEncoding |
		ScriptVerifyMinimalData |
		ScriptStrictMultiSig |
		ScriptDiscourageUpgradableNops |
		ScriptVerifyCleanStack |
		ScriptVerifyNullFail |
		ScriptVerifyCheckLockTimeVerify |
		ScriptVerifyCheckSequenceVerify |
		ScriptVerifyLowS |
		ScriptStrictMultiSig |
		ScriptVerifyWitness |
		ScriptVerifyDiscourageUpgradeableWitnessProgram |
		ScriptVerifyMinimalIf |
		ScriptVerifyWitnessPubKeyType
)

Variables

View Source
var (
	// ErrUnsupportedScriptType is an error returned when we attempt to
	// parse/re-compute an output script into a PkScript struct.
	ErrUnsupportedScriptType = er.GenericErrorType.CodeWithDetail("ErrUnsupportedScriptType",
		"unsupported script type")
)
View Source
var OpcodeByName = make(map[string]byte)

OpcodeByName is a map that can be used to lookup an opcode by its human-readable name (OP_CHECKMULTISIG, OP_CHECKSIG, etc).

Functions

func CalcMultiSigStats

func CalcMultiSigStats(script []byte) (int, int, er.R)

CalcMultiSigStats returns the number of public keys and signatures from a multi-signature transaction script. The passed script MUST already be known to be a multi-signature script.

func CalcSignatureHash

func CalcSignatureHash(script []byte, hashType params.SigHashType, tx *wire.MsgTx, idx int) ([]byte, er.R)

CalcSignatureHash will, given a script and hash type for the current script engine instance, calculate the signature hash to be used for signing and verification.

func CalcWitnessSigHash

func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType params.SigHashType,
	tx *wire.MsgTx, idx int, amt int64) ([]byte, er.R)

CalcWitnessSigHash computes the sighash digest for the specified input of the target transaction observing the desired sig hash type.

func DisasmString

func DisasmString(buf []byte) (string, er.R)

DisasmString formats a disassembled script for one line printing. When the script fails to parse, the returned string will contain the disassembled script up to the point the failure occurred along with the string '[error]' appended. In addition, the reason the script failed to parse is returned if the caller wants more information about the failure.

func ElectionGetVotesForAgainst

func ElectionGetVotesForAgainst(pkScript []byte) (voteFor []byte, voteAgainst []byte)

ElectionGetVotesForAgainst gets the candidates who are voted for and voted against by the provided pkScript

func ExtractWitnessProgramInfo

func ExtractWitnessProgramInfo(script []byte) (int, []byte, er.R)

ExtractWitnessProgramInfo attempts to extract the witness program version, as well as the witness program itself from the passed script.

func GetPreciseSigOpCount

func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int

GetPreciseSigOpCount returns the number of signature operations in scriptPubKey. If bip16 is true then scriptSig may be searched for the Pay-To-Script-Hash script in order to find the precise number of signature operations in the transaction. If the script fails to parse, then the count up to the point of failure is returned.

func GetSigOpCount

func GetSigOpCount(script []byte) int

GetSigOpCount provides a quick count of the number of signature operations in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20. If the script fails to parse, then the count up to the point of failure is returned.

func GetWitnessSigOpCount

func GetWitnessSigOpCount(sigScript, pkScript []byte, witness wire.TxWitness) int

GetWitnessSigOpCount returns the number of signature operations generated by spending the passed pkScript with the specified witness, or sigScript. Unlike GetPreciseSigOpCount, this function is able to accurately count the number of signature operations generated by spending witness programs, and nested p2sh witness programs. If the script fails to parse, then the count up to the point of failure is returned.

func IsPayToScriptHash

func IsPayToScriptHash(script []byte) bool

IsPayToScriptHash returns true if the script is in the standard pay-to-script-hash (P2SH) format, false otherwise.

func IsPayToWitnessPubKeyHash

func IsPayToWitnessPubKeyHash(script []byte) bool

IsPayToWitnessPubKeyHash returns true if the is in the standard pay-to-witness-pubkey-hash (P2WKH) format, false otherwise.

func IsPayToWitnessScriptHash

func IsPayToWitnessScriptHash(script []byte) bool

IsPayToWitnessScriptHash returns true if the is in the standard pay-to-witness-script-hash (P2WSH) format, false otherwise.

func IsPushOnlyScript

func IsPushOnlyScript(script []byte) bool

IsPushOnlyScript returns whether or not the passed script only pushes data.

False will be returned when the script does not parse.

func IsUnspendable

func IsUnspendable(pkScript []byte) bool

IsUnspendable returns whether the passed public key script is unspendable, or guaranteed to fail at execution. This allows inputs to be pruned instantly when entering the UTXO set.

func IsWitnessProgram

func IsWitnessProgram(script []byte) bool

IsWitnessProgram returns true if the passed script is a valid witness program which is encoded according to the passed witness program version. A witness program must be a small integer (from 0-16), followed by 2-40 bytes of pushed data.

func MultiSigScript

func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er.R)

MultiSigScript returns a valid script for a multisignature redemption where nrequired of the keys in pubkeys are required to have signed the transaction for success. An Error with the error code ErrTooManyRequiredSigs will be returned if nrequired is larger than the number of keys provided.

func NullDataScript

func NullDataScript(data []byte) ([]byte, er.R)

NullDataScript creates a provably-prunable script containing OP_RETURN followed by the passed data. An Error with the error code ErrTooMuchNullData will be returned if the length of the passed data exceeds MaxDataCarrierSize.

func PayToAddrScript

func PayToAddrScript(addr btcutil.Address) ([]byte, er.R)

PayToAddrScript creates a new script to pay a transaction output to the specified address.

Example

This example demonstrates creating a script which pays to a bitcoin address. It also prints the created script hex and uses the DisasmString function to display the disassembled script.

package main

import (
	"fmt"

	"github.com/kaotisk-hund/cjdcoind/btcutil"
	"github.com/kaotisk-hund/cjdcoind/chaincfg"
	"github.com/kaotisk-hund/cjdcoind/txscript"
)

func main() {
	// Parse the address to send the coins to into a btcutil.Address
	// which is useful to ensure the accuracy of the address and determine
	// the address type.  It is also required for the upcoming call to
	// PayToAddrScript.
	addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV"
	address, err := btcutil.DecodeAddress(addressStr, &chaincfg.MainNetParams)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Create a public key script that pays to the address.
	script, err := txscript.PayToAddrScript(address)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("Script Hex: %x\n", script)

	disasm, err := txscript.DisasmString(script)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Script Disassembly:", disasm)

}
Output:

Script Hex: 76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac
Script Disassembly: OP_DUP OP_HASH160 128004ff2fcaf13b2b91eb654b1dc2b674f7ec61 OP_EQUALVERIFY OP_CHECKSIG

func PayToAddrScriptWithVote

func PayToAddrScriptWithVote(addr btcutil.Address, voteFor, voteAgainst []byte) ([]byte, er.R)

PayToAddrScriptWithVote creates a new script to pay a transaction output to a the specified address and adds a vote for the specified network steward, if voteFor and/or voteAgainst are non-null and if the address type is non-segwit.

func PkScriptToAddress

func PkScriptToAddress(pkScript []byte, chainParams *chaincfg.Params) btcutil.Address

PkScriptToAddress returns the address corrisponding to a script. Because most multi-signature scripts are segwit and are thus able to be represented as addresses, most scripts are able to be represented directly as addresses, but if there is a script which is not directly parsable, this function will return "script:" followed by a base-64 representation of the pkScript itself such that it can be decoded later.

func PushedData

func PushedData(script []byte) ([][]byte, er.R)

PushedData returns an array of byte slices containing any pushed data found in the passed script. This includes OP_0, but not OP_1 - OP_16.

func RawTxInSignature

func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
	hashType params.SigHashType, key *btcec.PrivateKey) ([]byte, er.R)

RawTxInSignature returns the serialized ECDSA signature for the input idx of the given transaction, with hashType appended to it.

func RawTxInWitnessSignature

func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
	amt int64, subScript []byte, hashType params.SigHashType,
	key *btcec.PrivateKey) ([]byte, er.R)

RawTxInWitnessSignature returns the serialized ECDA signature for the input idx of the given transaction, with the hashType appended to it. This function is identical to RawTxInSignature, however the signature generated signs a new sighash digest defined in BIP0143.

func SignTxOutput

func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int,
	pkScript []byte, hashType params.SigHashType, kdb KeyDB, sdb ScriptDB,
	previousScript []byte) ([]byte, er.R)

SignTxOutput signs output idx of the given tx to resolve the script given in pkScript with a signature type of hashType. Any keys required will be looked up by calling getKey() with the string of the given address. Any pay-to-script-hash signatures will be similarly looked up by calling getScript. If previousScript is provided then the results in previousScript will be merged in a type-dependent manner with the newly generated. signature script.

Example

This example demonstrates manually creating and signing a redeem transaction.

package main

import (
	"encoding/hex"
	"fmt"

	"github.com/kaotisk-hund/cjdcoind/btcutil/er"
	"github.com/kaotisk-hund/cjdcoind/txscript/opcode"
	"github.com/kaotisk-hund/cjdcoind/txscript/params"
	"github.com/kaotisk-hund/cjdcoind/wire/constants"

	"github.com/kaotisk-hund/cjdcoind/btcec"
	"github.com/kaotisk-hund/cjdcoind/btcutil"
	"github.com/kaotisk-hund/cjdcoind/chaincfg"
	"github.com/kaotisk-hund/cjdcoind/chaincfg/chainhash"
	"github.com/kaotisk-hund/cjdcoind/txscript"
	"github.com/kaotisk-hund/cjdcoind/wire"
)

func main() {
	// Ordinarily the private key would come from whatever storage mechanism
	// is being used, but for this example just hard code it.
	privKeyBytes, errr := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2" +
		"d4f8720ee63e502ee2869afab7de234b80c")
	if errr != nil {
		fmt.Println(errr)
		return
	}
	privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes)
	pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed())
	addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash,
		&chaincfg.MainNetParams)
	if err != nil {
		fmt.Println(err)
		return
	}

	// For this example, create a fake transaction that represents what
	// would ordinarily be the real transaction that is being spent.  It
	// contains a single output that pays to address in the amount of 1 BTC.
	originTx := wire.NewMsgTx(constants.TxVersion)
	prevOut := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
	txIn := wire.NewTxIn(prevOut, []byte{opcode.OP_0, opcode.OP_0}, nil)
	originTx.AddTxIn(txIn)
	pkScript, err := txscript.PayToAddrScript(addr)
	if err != nil {
		fmt.Println(err)
		return
	}
	txOut := wire.NewTxOut(100000000, pkScript)
	originTx.AddTxOut(txOut)
	originTxHash := originTx.TxHash()

	// Create the transaction to redeem the fake transaction.
	redeemTx := wire.NewMsgTx(constants.TxVersion)

	// Add the input(s) the redeeming transaction will spend.  There is no
	// signature script at this point since it hasn't been created or signed
	// yet, hence nil is provided for it.
	prevOut = wire.NewOutPoint(&originTxHash, 0)
	txIn = wire.NewTxIn(prevOut, nil, nil)
	redeemTx.AddTxIn(txIn)

	// Ordinarily this would contain that actual destination of the funds,
	// but for this example don't bother.
	txOut = wire.NewTxOut(0, nil)
	redeemTx.AddTxOut(txOut)

	// Sign the redeeming transaction.
	lookupKey := func(a btcutil.Address) (*btcec.PrivateKey, bool, er.R) {
		// Ordinarily this function would involve looking up the private
		// key for the provided address, but since the only thing being
		// signed in this example uses the address associated with the
		// private key from above, simply return it with the compressed
		// flag set since the address is using the associated compressed
		// public key.
		//
		// NOTE: If you want to prove the code is actually signing the
		// transaction properly, uncomment the following line which
		// intentionally returns an invalid key to sign with, which in
		// turn will result in a failure during the script execution
		// when verifying the signature.
		//
		// privKey.D.SetInt64(12345)
		//
		return privKey, true, nil
	}
	// Notice that the script database parameter is nil here since it isn't
	// used.  It must be specified when pay-to-script-hash transactions are
	// being signed.
	sigScript, err := txscript.SignTxOutput(&chaincfg.MainNetParams,
		redeemTx, 0, originTx.TxOut[0].PkScript, params.SigHashAll,
		txscript.KeyClosure(lookupKey), nil, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	redeemTx.TxIn[0].SignatureScript = sigScript

	// Prove that the transaction has been validly signed by executing the
	// script pair.
	flags := txscript.ScriptBip16 | txscript.ScriptVerifyDERSignatures |
		txscript.ScriptStrictMultiSig |
		txscript.ScriptDiscourageUpgradableNops
	vm, err := txscript.NewEngine(originTx.TxOut[0].PkScript, redeemTx, 0,
		flags, nil, nil, -1)
	if err != nil {
		fmt.Println(err)
		return
	}
	if err := vm.Execute(); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Transaction successfully signed")

}
Output:

Transaction successfully signed

func SignatureScript

func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte, hashType params.SigHashType, privKey *btcec.PrivateKey, compress bool) ([]byte, er.R)

SignatureScript creates an input signature script for tx to spend BTC sent from a previous output to the owner of privKey. tx must include all transaction inputs and outputs, however txin scripts are allowed to be filled or empty. The returned script is calculated to be used as the idx'th txin sigscript for tx. subscript is the PkScript of the previous output being used as the idx'th input. privKey is serialized in either a compressed or uncompressed format based on compress. This format must match the same format used to generate the payment address, or the script validation will fail.

func WitnessSignature

func WitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64,
	subscript []byte, hashType params.SigHashType, privKey *btcec.PrivateKey,
	compress bool) (wire.TxWitness, er.R)

WitnessSignature creates an input witness stack for tx to spend BTC sent from a previous output to the owner of privKey using the p2wkh script template. The passed transaction must contain all the inputs and outputs as dictated by the passed hashType. The signature generated observes the new transaction digest algorithm defined within BIP0143.

Types

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine is the virtual machine that executes scripts.

func NewEngine

func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags,
	sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64) (*Engine, er.R)

NewEngine returns a new script engine for the provided public key script, transaction, and input index. The flags modify the behavior of the script engine according to the description provided by each flag.

func (*Engine) CheckErrorCondition

func (vm *Engine) CheckErrorCondition(finalScript bool) er.R

CheckErrorCondition returns nil if the running script has ended and was successful, leaving a a true boolean on the stack. An error otherwise, including if the script has not finished.

func (*Engine) DisasmPC

func (vm *Engine) DisasmPC() (string, er.R)

DisasmPC returns the string for the disassembly of the opcode that will be next to execute when Step() is called.

func (*Engine) DisasmScript

func (vm *Engine) DisasmScript(idx int) (string, er.R)

DisasmScript returns the disassembly string for the script at the requested offset index. Index 0 is the signature script and 1 is the public key script.

func (*Engine) Execute

func (vm *Engine) Execute() (err er.R)

Execute will execute all scripts in the script engine and return either nil for successful validation or an error if one occurred.

func (*Engine) GetStack

func (vm *Engine) GetStack() [][]byte

GetStack returns the contents of the primary stack as an array. where the last item in the array is the top of the stack.

func (*Engine) SetStack

func (vm *Engine) SetStack(data [][]byte)

SetStack sets the contents of the primary stack to the contents of the provided array where the last item in the array will be the top of the stack.

func (*Engine) Step

func (vm *Engine) Step() (done bool, err er.R)

Step will execute the next instruction and move the program counter to the next opcode in the script, or the next script if the current has ended. Step will return true in the case that the last opcode was successfully executed.

The result of calling Step or any other method is undefined if an error is returned.

type HashCache

type HashCache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

HashCache houses a set of partial sighashes keyed by txid. The set of partial sighashes are those introduced within BIP0143 by the new more efficient sighash digest calculation algorithm. Using this threadsafe shared cache, multiple goroutines can safely re-use the pre-computed partial sighashes speeding up validation time amongst all inputs found within a block.

func NewHashCache

func NewHashCache(maxSize uint) *HashCache

NewHashCache returns a new instance of the HashCache given a maximum number of entries which may exist within it at anytime.

func (*HashCache) AddSigHashes

func (h *HashCache) AddSigHashes(tx *wire.MsgTx)

AddSigHashes computes, then adds the partial sighashes for the passed transaction.

func (*HashCache) ContainsHashes

func (h *HashCache) ContainsHashes(txid *chainhash.Hash) bool

ContainsHashes returns true if the partial sighashes for the passed transaction currently exist within the HashCache, and false otherwise.

func (*HashCache) GetSigHashes

func (h *HashCache) GetSigHashes(txid *chainhash.Hash) (*TxSigHashes, bool)

GetSigHashes possibly returns the previously cached partial sighashes for the passed transaction. This function also returns an additional boolean value indicating if the sighashes for the passed transaction were found to be present within the HashCache.

func (*HashCache) PurgeSigHashes

func (h *HashCache) PurgeSigHashes(txid *chainhash.Hash)

PurgeSigHashes removes all partial sighashes from the HashCache belonging to the passed transaction.

type KeyClosure

type KeyClosure func(btcutil.Address) (*btcec.PrivateKey, bool, er.R)

KeyClosure implements KeyDB with a closure.

func (KeyClosure) GetKey

func (kc KeyClosure) GetKey(address btcutil.Address) (*btcec.PrivateKey,
	bool, er.R)

GetKey implements KeyDB by returning the result of calling the closure.

type KeyDB

type KeyDB interface {
	GetKey(btcutil.Address) (*btcec.PrivateKey, bool, er.R)
}

KeyDB is an interface type provided to SignTxOutput, it encapsulates any user state required to get the private keys for an address.

type PkScript

type PkScript struct {
	// contains filtered or unexported fields
}

PkScript is a wrapper struct around a byte array, allowing it to be used as a map index.

func ComputePkScript

func ComputePkScript(sigScript []byte, witness wire.TxWitness) (PkScript, er.R)

ComputePkScript computes the script of an output by looking at the spending input's signature script or witness.

NOTE: Only P2PKH, P2SH, P2WSH, and P2WPKH redeem scripts are supported.

func ParsePkScript

func ParsePkScript(pkScript []byte) (PkScript, er.R)

ParsePkScript parses an output script into the PkScript struct. ErrUnsupportedScriptType is returned when attempting to parse an unsupported script type.

func (PkScript) Address

func (s PkScript) Address(chainParams *chaincfg.Params) (btcutil.Address, er.R)

Address encodes the script into an address for the given chain.

func (PkScript) Class

func (s PkScript) Class() ScriptClass

Class returns the script type.

func (PkScript) Script

func (s PkScript) Script() []byte

Script returns the script as a byte slice without any padding.

func (PkScript) String

func (s PkScript) String() string

String returns a hex-encoded string representation of the script.

type ScriptClass

type ScriptClass byte

ScriptClass is an enumeration for the list of standard types of script.

const (
	NonStandardTy         ScriptClass = iota // None of the recognized forms.
	PubKeyTy                                 // Pay pubkey.
	PubKeyHashTy                             // Pay pubkey hash.
	WitnessV0PubKeyHashTy                    // Pay witness pubkey hash.
	ScriptHashTy                             // Pay to script hash.
	WitnessV0ScriptHashTy                    // Pay to witness script hash.
	MultiSigTy                               // Multi signature.
	NullDataTy                               // Empty data-only (provably prunable).
)

Classes of script payment known about in the blockchain.

func ExtractPkScriptAddrs

func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, er.R)

ExtractPkScriptAddrs returns the type of script, addresses and required signatures associated with the passed PkScript. Note that it only works for 'standard' transaction script types. Any data such as public keys which are invalid are omitted from the results.

Example

This example demonstrates extracting information from a standard public key script.

package main

import (
	"encoding/hex"
	"fmt"

	"github.com/kaotisk-hund/cjdcoind/chaincfg"
	"github.com/kaotisk-hund/cjdcoind/txscript"
)

func main() {
	// Start with a standard pay-to-pubkey-hash script.
	scriptHex := "76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
	script, errr := hex.DecodeString(scriptHex)
	if errr != nil {
		fmt.Println(errr)
		return
	}

	// Extract and print details from the script.
	scriptClass, addresses, reqSigs, err := txscript.ExtractPkScriptAddrs(
		script, &chaincfg.MainNetParams)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Script Class:", scriptClass)
	fmt.Println("Addresses:", addresses)
	fmt.Println("Required Signatures:", reqSigs)

}
Output:

Script Class: pubkeyhash
Addresses: [12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV]
Required Signatures: 1

func GetScriptClass

func GetScriptClass(script []byte) ScriptClass

GetScriptClass returns the class of the script passed.

NonStandardTy will be returned when the script does not parse.

func (ScriptClass) IsSegwit

func (t ScriptClass) IsSegwit() bool

IsSegwit returns true if the script is a known segwit type.

func (ScriptClass) String

func (t ScriptClass) String() string

String implements the Stringer interface by returning the name of the enum script class. If the enum is invalid then "Invalid" will be returned.

type ScriptClosure

type ScriptClosure func(btcutil.Address) ([]byte, er.R)

ScriptClosure implements ScriptDB with a closure.

func (ScriptClosure) GetScript

func (sc ScriptClosure) GetScript(address btcutil.Address) ([]byte, er.R)

GetScript implements ScriptDB by returning the result of calling the closure.

type ScriptDB

type ScriptDB interface {
	GetScript(btcutil.Address) ([]byte, er.R)
}

ScriptDB is an interface type provided to SignTxOutput, it encapsulates any user state required to get the scripts for an pay-to-script-hash address.

type ScriptFlags

type ScriptFlags uint32

ScriptFlags is a bitmask defining additional operations or tests that will be done when executing a script pair.

const (
	// ScriptBip16 defines whether the bip16 threshold has passed and thus
	// pay-to-script hash transactions will be fully validated.
	ScriptBip16 ScriptFlags = 1 << iota

	// ScriptStrictMultiSig defines whether to verify the stack item
	// used by CHECKMULTISIG is zero length.
	ScriptStrictMultiSig

	// ScriptDiscourageUpgradableNops defines whether to verify that
	// NOP1 through NOP10 are reserved for future soft-fork upgrades.  This
	// flag must not be used for consensus critical code nor applied to
	// blocks as this flag is only for stricter standard transaction
	// checks.  This flag is only applied when the above opcodes are
	// executed.
	ScriptDiscourageUpgradableNops

	// ScriptVerifyCheckLockTimeVerify defines whether to verify that
	// a transaction output is spendable based on the locktime.
	// This is BIP0065.
	ScriptVerifyCheckLockTimeVerify

	// ScriptVerifyCheckSequenceVerify defines whether to allow execution
	// pathways of a script to be restricted based on the age of the output
	// being spent.  This is BIP0112.
	ScriptVerifyCheckSequenceVerify

	// ScriptVerifyCleanStack defines that the stack must contain only
	// one stack element after evaluation and that the element must be
	// true if interpreted as a boolean.  This is rule 6 of BIP0062.
	// This flag should never be used without the ScriptBip16 flag nor the
	// ScriptVerifyWitness flag.
	ScriptVerifyCleanStack

	// ScriptVerifyDERSignatures defines that signatures are required
	// to compily with the DER format.
	ScriptVerifyDERSignatures

	// ScriptVerifyLowS defines that signtures are required to comply with
	// the DER format and whose S value is <= order / 2.  This is rule 5
	// of BIP0062.
	ScriptVerifyLowS

	// ScriptVerifyMinimalData defines that signatures must use the smallest
	// push operator. This is both rules 3 and 4 of BIP0062.
	ScriptVerifyMinimalData

	// ScriptVerifyNullFail defines that signatures must be empty if
	// a CHECKSIG or CHECKMULTISIG operation fails.
	ScriptVerifyNullFail

	// ScriptVerifySigPushOnly defines that signature scripts must contain
	// only pushed data.  This is rule 2 of BIP0062.
	ScriptVerifySigPushOnly

	// ScriptVerifyStrictEncoding defines that signature scripts and
	// public keys must follow the strict encoding requirements.
	ScriptVerifyStrictEncoding

	// ScriptVerifyWitness defines whether or not to verify a transaction
	// output using a witness program template.
	ScriptVerifyWitness

	// ScriptVerifyDiscourageUpgradeableWitnessProgram makes witness
	// program with versions 2-16 non-standard.
	ScriptVerifyDiscourageUpgradeableWitnessProgram

	// ScriptVerifyMinimalIf makes a script with an OP_IF/OP_NOTIF whose
	// operand is anything other than empty vector or [0x01] non-standard.
	ScriptVerifyMinimalIf

	// ScriptVerifyWitnessPubKeyType makes a script within a check-sig
	// operation whose public key isn't serialized in a compressed format
	// non-standard.
	ScriptVerifyWitnessPubKeyType
)

type ScriptInfo

type ScriptInfo struct {
	// PkScriptClass is the class of the public key script and is equivalent
	// to calling GetScriptClass on it.
	PkScriptClass ScriptClass

	// NumInputs is the number of inputs provided by the public key script.
	NumInputs int

	// ExpectedInputs is the number of outputs required by the signature
	// script and any pay-to-script-hash scripts. The number will be -1 if
	// unknown.
	ExpectedInputs int

	// SigOps is the number of signature operations in the script pair.
	SigOps int
}

ScriptInfo houses information about a script pair that is determined by CalcScriptInfo.

func CalcScriptInfo

func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
	bip16, segwit bool) (*ScriptInfo, er.R)

CalcScriptInfo returns a structure providing data about the provided script pair. It will error if the pair is in someway invalid such that they can not be analysed, i.e. if they do not parse or the pkScript is not a push-only script

type SigCache

type SigCache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

SigCache implements an ECDSA signature verification cache with a randomized entry eviction policy. Only valid signatures will be added to the cache. The benefits of SigCache are two fold. Firstly, usage of SigCache mitigates a DoS attack wherein an attack causes a victim's client to hang due to worst-case behavior triggered while processing attacker crafted invalid transactions. A detailed description of the mitigated DoS attack can be found here: https://bitslog.wordpress.com/2013/01/23/fixed-bitcoin-vulnerability-explanation-why-the-signature-cache-is-a-dos-protection/. Secondly, usage of the SigCache introduces a signature verification optimization which speeds up the validation of transactions within a block, if they've already been seen and verified within the mempool.

func NewSigCache

func NewSigCache(maxEntries uint) *SigCache

NewSigCache creates and initializes a new instance of SigCache. Its sole parameter 'maxEntries' represents the maximum number of entries allowed to exist in the SigCache at any particular moment. Random entries are evicted to make room for new entries that would cause the number of entries in the cache to exceed the max.

func (*SigCache) Add

func (s *SigCache) Add(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey)

Add adds an entry for a signature over 'sigHash' under public key 'pubKey' to the signature cache. In the event that the SigCache is 'full', an existing entry is randomly chosen to be evicted in order to make space for the new entry.

NOTE: This function is safe for concurrent access. Writers will block simultaneous readers until function execution has concluded.

func (*SigCache) Exists

func (s *SigCache) Exists(sigHash chainhash.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) bool

Exists returns true if an existing entry of 'sig' over 'sigHash' for public key 'pubKey' is found within the SigCache. Otherwise, false is returned.

NOTE: This function is safe for concurrent access. Readers won't be blocked unless there exists a writer, adding an entry to the SigCache.

type TxSigHashes

type TxSigHashes struct {
	HashPrevOuts chainhash.Hash
	HashSequence chainhash.Hash
	HashOutputs  chainhash.Hash
}

TxSigHashes houses the partial set of sighashes introduced within BIP0143. This partial set of sighashes may be re-used within each input across a transaction when validating all inputs. As a result, validation complexity for SigHashAll can be reduced by a polynomial factor.

func NewTxSigHashes

func NewTxSigHashes(tx *wire.MsgTx) *TxSigHashes

NewTxSigHashes computes, and returns the cached sighashes of the given transaction.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL