txscript

package
v0.0.0-...-6e04e41 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2024 License: ISC Imports: 24 Imported by: 0

README

txscript

Build Status ISC License GoDoc

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

Installation and Updating

$ go get -u github.com/sat20-labs/satsnet_btcd/txscript

Examples

GPG Verification Key

All official release tags are signed by Conformal so users can ensure the code has not been tampered with and is coming from the btcsuite developers. To verify the signature perform the following:

  • Download the public key from the Conformal website at https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt

  • Import the public key into your GPG keyring:

    gpg --import GIT-GPG-KEY-conformal.txt
    
  • Verify the release tag with the following command where TAG_NAME is a placeholder for the specific tag:

    git tag -v TAG_NAME
    

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 as 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 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 (
	// MaxStackSize is the maximum combined height of stack and alt stack
	// during execution.
	MaxStackSize = 1000

	// MaxScriptSize is the maximum allowed length of a raw script.
	MaxScriptSize = 10000
)
View Source
const (
	// BaseSegwitWitnessVersion is the original witness version that defines
	// the initial set of segwit validation logic.
	BaseSegwitWitnessVersion = 0

	// TaprootWitnessVersion is the witness version that defines the new
	// taproot verification logic.
	TaprootWitnessVersion = 1
)
View Source
const (
	OP_0                   = 0x00 // 0
	OP_FALSE               = 0x00 // 0 - AKA OP_0
	OP_DATA_1              = 0x01 // 1
	OP_DATA_2              = 0x02 // 2
	OP_DATA_3              = 0x03 // 3
	OP_DATA_4              = 0x04 // 4
	OP_DATA_5              = 0x05 // 5
	OP_DATA_6              = 0x06 // 6
	OP_DATA_7              = 0x07 // 7
	OP_DATA_8              = 0x08 // 8
	OP_DATA_9              = 0x09 // 9
	OP_DATA_10             = 0x0a // 10
	OP_DATA_11             = 0x0b // 11
	OP_DATA_12             = 0x0c // 12
	OP_DATA_13             = 0x0d // 13
	OP_DATA_14             = 0x0e // 14
	OP_DATA_15             = 0x0f // 15
	OP_DATA_16             = 0x10 // 16
	OP_DATA_17             = 0x11 // 17
	OP_DATA_18             = 0x12 // 18
	OP_DATA_19             = 0x13 // 19
	OP_DATA_20             = 0x14 // 20
	OP_DATA_21             = 0x15 // 21
	OP_DATA_22             = 0x16 // 22
	OP_DATA_23             = 0x17 // 23
	OP_DATA_24             = 0x18 // 24
	OP_DATA_25             = 0x19 // 25
	OP_DATA_26             = 0x1a // 26
	OP_DATA_27             = 0x1b // 27
	OP_DATA_28             = 0x1c // 28
	OP_DATA_29             = 0x1d // 29
	OP_DATA_30             = 0x1e // 30
	OP_DATA_31             = 0x1f // 31
	OP_DATA_32             = 0x20 // 32
	OP_DATA_33             = 0x21 // 33
	OP_DATA_34             = 0x22 // 34
	OP_DATA_35             = 0x23 // 35
	OP_DATA_36             = 0x24 // 36
	OP_DATA_37             = 0x25 // 37
	OP_DATA_38             = 0x26 // 38
	OP_DATA_39             = 0x27 // 39
	OP_DATA_40             = 0x28 // 40
	OP_DATA_41             = 0x29 // 41
	OP_DATA_42             = 0x2a // 42
	OP_DATA_43             = 0x2b // 43
	OP_DATA_44             = 0x2c // 44
	OP_DATA_45             = 0x2d // 45
	OP_DATA_46             = 0x2e // 46
	OP_DATA_47             = 0x2f // 47
	OP_DATA_48             = 0x30 // 48
	OP_DATA_49             = 0x31 // 49
	OP_DATA_50             = 0x32 // 50
	OP_DATA_51             = 0x33 // 51
	OP_DATA_52             = 0x34 // 52
	OP_DATA_53             = 0x35 // 53
	OP_DATA_54             = 0x36 // 54
	OP_DATA_55             = 0x37 // 55
	OP_DATA_56             = 0x38 // 56
	OP_DATA_57             = 0x39 // 57
	OP_DATA_58             = 0x3a // 58
	OP_DATA_59             = 0x3b // 59
	OP_DATA_60             = 0x3c // 60
	OP_DATA_61             = 0x3d // 61
	OP_DATA_62             = 0x3e // 62
	OP_DATA_63             = 0x3f // 63
	OP_DATA_64             = 0x40 // 64
	OP_DATA_65             = 0x41 // 65
	OP_DATA_66             = 0x42 // 66
	OP_DATA_67             = 0x43 // 67
	OP_DATA_68             = 0x44 // 68
	OP_DATA_69             = 0x45 // 69
	OP_DATA_70             = 0x46 // 70
	OP_DATA_71             = 0x47 // 71
	OP_DATA_72             = 0x48 // 72
	OP_DATA_73             = 0x49 // 73
	OP_DATA_74             = 0x4a // 74
	OP_DATA_75             = 0x4b // 75
	OP_PUSHDATA1           = 0x4c // 76
	OP_PUSHDATA2           = 0x4d // 77
	OP_PUSHDATA4           = 0x4e // 78
	OP_1NEGATE             = 0x4f // 79
	OP_RESERVED            = 0x50 // 80
	OP_1                   = 0x51 // 81 - AKA OP_TRUE
	OP_TRUE                = 0x51 // 81
	OP_2                   = 0x52 // 82
	OP_3                   = 0x53 // 83
	OP_4                   = 0x54 // 84
	OP_5                   = 0x55 // 85
	OP_6                   = 0x56 // 86
	OP_7                   = 0x57 // 87
	OP_8                   = 0x58 // 88
	OP_9                   = 0x59 // 89
	OP_10                  = 0x5a // 90
	OP_11                  = 0x5b // 91
	OP_12                  = 0x5c // 92
	OP_13                  = 0x5d // 93
	OP_14                  = 0x5e // 94
	OP_15                  = 0x5f // 95
	OP_16                  = 0x60 // 96
	OP_NOP                 = 0x61 // 97
	OP_VER                 = 0x62 // 98
	OP_IF                  = 0x63 // 99
	OP_NOTIF               = 0x64 // 100
	OP_VERIF               = 0x65 // 101
	OP_VERNOTIF            = 0x66 // 102
	OP_ELSE                = 0x67 // 103
	OP_ENDIF               = 0x68 // 104
	OP_VERIFY              = 0x69 // 105
	OP_RETURN              = 0x6a // 106
	OP_TOALTSTACK          = 0x6b // 107
	OP_FROMALTSTACK        = 0x6c // 108
	OP_2DROP               = 0x6d // 109
	OP_2DUP                = 0x6e // 110
	OP_3DUP                = 0x6f // 111
	OP_2OVER               = 0x70 // 112
	OP_2ROT                = 0x71 // 113
	OP_2SWAP               = 0x72 // 114
	OP_IFDUP               = 0x73 // 115
	OP_DEPTH               = 0x74 // 116
	OP_DROP                = 0x75 // 117
	OP_DUP                 = 0x76 // 118
	OP_NIP                 = 0x77 // 119
	OP_OVER                = 0x78 // 120
	OP_PICK                = 0x79 // 121
	OP_ROLL                = 0x7a // 122
	OP_ROT                 = 0x7b // 123
	OP_SWAP                = 0x7c // 124
	OP_TUCK                = 0x7d // 125
	OP_CAT                 = 0x7e // 126
	OP_SUBSTR              = 0x7f // 127
	OP_LEFT                = 0x80 // 128
	OP_RIGHT               = 0x81 // 129
	OP_SIZE                = 0x82 // 130
	OP_INVERT              = 0x83 // 131
	OP_AND                 = 0x84 // 132
	OP_OR                  = 0x85 // 133
	OP_XOR                 = 0x86 // 134
	OP_EQUAL               = 0x87 // 135
	OP_EQUALVERIFY         = 0x88 // 136
	OP_RESERVED1           = 0x89 // 137
	OP_RESERVED2           = 0x8a // 138
	OP_1ADD                = 0x8b // 139
	OP_1SUB                = 0x8c // 140
	OP_2MUL                = 0x8d // 141
	OP_2DIV                = 0x8e // 142
	OP_NEGATE              = 0x8f // 143
	OP_ABS                 = 0x90 // 144
	OP_NOT                 = 0x91 // 145
	OP_0NOTEQUAL           = 0x92 // 146
	OP_ADD                 = 0x93 // 147
	OP_SUB                 = 0x94 // 148
	OP_MUL                 = 0x95 // 149
	OP_DIV                 = 0x96 // 150
	OP_MOD                 = 0x97 // 151
	OP_LSHIFT              = 0x98 // 152
	OP_RSHIFT              = 0x99 // 153
	OP_BOOLAND             = 0x9a // 154
	OP_BOOLOR              = 0x9b // 155
	OP_NUMEQUAL            = 0x9c // 156
	OP_NUMEQUALVERIFY      = 0x9d // 157
	OP_NUMNOTEQUAL         = 0x9e // 158
	OP_LESSTHAN            = 0x9f // 159
	OP_GREATERTHAN         = 0xa0 // 160
	OP_LESSTHANOREQUAL     = 0xa1 // 161
	OP_GREATERTHANOREQUAL  = 0xa2 // 162
	OP_MIN                 = 0xa3 // 163
	OP_MAX                 = 0xa4 // 164
	OP_WITHIN              = 0xa5 // 165
	OP_RIPEMD160           = 0xa6 // 166
	OP_SHA1                = 0xa7 // 167
	OP_SHA256              = 0xa8 // 168
	OP_HASH160             = 0xa9 // 169
	OP_HASH256             = 0xaa // 170
	OP_CODESEPARATOR       = 0xab // 171
	OP_CHECKSIG            = 0xac // 172
	OP_CHECKSIGVERIFY      = 0xad // 173
	OP_CHECKMULTISIG       = 0xae // 174
	OP_CHECKMULTISIGVERIFY = 0xaf // 175
	OP_NOP1                = 0xb0 // 176
	OP_NOP2                = 0xb1 // 177
	OP_CHECKLOCKTIMEVERIFY = 0xb1 // 177 - AKA OP_NOP2
	OP_NOP3                = 0xb2 // 178
	OP_CHECKSEQUENCEVERIFY = 0xb2 // 178 - AKA OP_NOP3
	OP_NOP4                = 0xb3 // 179
	OP_NOP5                = 0xb4 // 180
	OP_NOP6                = 0xb5 // 181
	OP_NOP7                = 0xb6 // 182
	OP_NOP8                = 0xb7 // 183
	OP_NOP9                = 0xb8 // 184
	OP_NOP10               = 0xb9 // 185
	OP_CHECKSIGADD         = 0xba // 186
	OP_UNKNOWN187          = 0xbb // 187
	OP_UNKNOWN188          = 0xbc // 188
	OP_UNKNOWN189          = 0xbd // 189
	OP_UNKNOWN190          = 0xbe // 190
	OP_UNKNOWN191          = 0xbf // 191
	OP_UNKNOWN192          = 0xc0 // 192
	OP_UNKNOWN193          = 0xc1 // 193
	OP_UNKNOWN194          = 0xc2 // 194
	OP_UNKNOWN195          = 0xc3 // 195
	OP_UNKNOWN196          = 0xc4 // 196
	OP_UNKNOWN197          = 0xc5 // 197
	OP_UNKNOWN198          = 0xc6 // 198
	OP_UNKNOWN199          = 0xc7 // 199
	OP_UNKNOWN200          = 0xc8 // 200
	OP_UNKNOWN201          = 0xc9 // 201
	OP_UNKNOWN202          = 0xca // 202
	OP_UNKNOWN203          = 0xcb // 203
	OP_UNKNOWN204          = 0xcc // 204
	OP_UNKNOWN205          = 0xcd // 205
	OP_UNKNOWN206          = 0xce // 206
	OP_UNKNOWN207          = 0xcf // 207
	OP_UNKNOWN208          = 0xd0 // 208
	OP_UNKNOWN209          = 0xd1 // 209
	OP_UNKNOWN210          = 0xd2 // 210
	OP_UNKNOWN211          = 0xd3 // 211
	OP_UNKNOWN212          = 0xd4 // 212
	OP_UNKNOWN213          = 0xd5 // 213
	OP_UNKNOWN214          = 0xd6 // 214
	OP_UNKNOWN215          = 0xd7 // 215
	OP_UNKNOWN216          = 0xd8 // 216
	OP_UNKNOWN217          = 0xd9 // 217
	OP_UNKNOWN218          = 0xda // 218
	OP_UNKNOWN219          = 0xdb // 219
	OP_UNKNOWN220          = 0xdc // 220
	OP_UNKNOWN221          = 0xdd // 221
	OP_UNKNOWN222          = 0xde // 222
	OP_UNKNOWN223          = 0xdf // 223
	OP_UNKNOWN224          = 0xe0 // 224
	OP_UNKNOWN225          = 0xe1 // 225
	OP_UNKNOWN226          = 0xe2 // 226
	OP_UNKNOWN227          = 0xe3 // 227
	OP_UNKNOWN228          = 0xe4 // 228
	OP_UNKNOWN229          = 0xe5 // 229
	OP_UNKNOWN230          = 0xe6 // 230
	OP_UNKNOWN231          = 0xe7 // 231
	OP_UNKNOWN232          = 0xe8 // 232
	OP_UNKNOWN233          = 0xe9 // 233
	OP_UNKNOWN234          = 0xea // 234
	OP_UNKNOWN235          = 0xeb // 235
	OP_UNKNOWN236          = 0xec // 236
	OP_UNKNOWN237          = 0xed // 237
	OP_UNKNOWN238          = 0xee // 238
	OP_UNKNOWN239          = 0xef // 239
	OP_UNKNOWN240          = 0xf0 // 240
	OP_UNKNOWN241          = 0xf1 // 241
	OP_UNKNOWN242          = 0xf2 // 242
	OP_UNKNOWN243          = 0xf3 // 243
	OP_UNKNOWN244          = 0xf4 // 244
	OP_UNKNOWN245          = 0xf5 // 245
	OP_UNKNOWN246          = 0xf6 // 246
	OP_UNKNOWN247          = 0xf7 // 247
	OP_UNKNOWN248          = 0xf8 // 248
	OP_UNKNOWN249          = 0xf9 // 249
	OP_SMALLINTEGER        = 0xfa // 250 - bitcoin core internal
	OP_PUBKEYS             = 0xfb // 251 - bitcoin core internal
	OP_UNKNOWN252          = 0xfc // 252
	OP_PUBKEYHASH          = 0xfd // 253 - bitcoin core internal
	OP_PUBKEY              = 0xfe // 254 - bitcoin core internal
	OP_INVALIDOPCODE       = 0xff // 255 - bitcoin core internal
)

These constants are the values of the official opcodes used on the btc wiki, in bitcoin core and in most if not all other references and software related to handling BTC scripts.

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

Conditional execution constants.

View Source
const (
	// TaprootAnnexTag is the tag for an annex. This value is used to
	// identify the annex during tapscript spends. If there're at least two
	// elements in the taproot witness stack, and the first byte of the
	// last element matches this tag, then we'll extract this as a distinct
	// item.
	TaprootAnnexTag = 0x50

	// TaprootLeafMask is the mask applied to the control block to extract
	// the leaf version and parity of the y-coordinate of the output key if
	// the taproot script leaf being spent.
	TaprootLeafMask = 0xfe
)
View Source
const (
	MaxOpsPerScript       = 201 // Max number of non-push operations.
	MaxPubKeysPerMultiSig = 20  // Multisig can't have more sigs than this.
	MaxScriptElementSize  = 520 // Max bytes pushable to the stack.
)

These are the constants specified for maximums in individual scripts.

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 |
		ScriptVerifyTaproot |
		ScriptVerifyDiscourageUpgradeableTaprootVersion |
		ScriptVerifyDiscourageOpSuccess |
		ScriptVerifyDiscourageUpgradeablePubkeyType |
		ScriptVerifyConstScriptCode
)
View Source
const (
	// ControlBlockBaseSize is the base size of a control block. This
	// includes the initial byte for the leaf version, and then serialized
	// schnorr public key.
	ControlBlockBaseSize = 33

	// ControlBlockNodeSize is the size of a given merkle branch hash in
	// the control block.
	ControlBlockNodeSize = 32

	// ControlBlockMaxNodeCount is the max number of nodes that can be
	// included in a control block. This value represents a merkle tree of
	// depth 2^128.
	ControlBlockMaxNodeCount = 128

	// ControlBlockMaxSize is the max possible size of a control block.
	// This simulates revealing a leaf from the largest possible tapscript
	// tree.
	ControlBlockMaxSize = ControlBlockBaseSize + (ControlBlockNodeSize *
		ControlBlockMaxNodeCount)
)
View Source
const (
	// LockTimeThreshold is the number below which a lock time is
	// interpreted to be a block number.  Since an average of one block
	// is generated per 10 minutes, this allows blocks for about 9,512
	// years.
	LockTimeThreshold = 5e8 // Tue Nov 5 00:53:20 1985 UTC
)

Variables

View Source
var Bip16Activation = time.Unix(1333238400, 0)

Bip16Activation is the timestamp where BIP0016 is valid to use in the blockchain. To be used to determine if BIP0016 should be called for or not. This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.

View Source
var (
	// ErrUnsupportedScriptType is an error returned when we attempt to
	// parse/re-compute an output script into a PkScript struct.
	ErrUnsupportedScriptType = errors.New("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 AsSmallInt

func AsSmallInt(op byte) int

AsSmallInt returns the passed opcode, which must be true according to IsSmallInt(), as an integer.

func CalcMultiSigStats

func CalcMultiSigStats(script []byte) (int, int, error)

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.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

func CalcSignatureHash

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

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.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

func CalcTaprootSignatureHash

func CalcTaprootSignatureHash(sigHashes *TxSigHashes, hType SigHashType,
	tx *wire.MsgTx, idx int,
	prevOutFetcher PrevOutputFetcher) ([]byte, error)

CalcTaprootSignatureHash computes the sighash digest of a transaction's taproot-spending input using the new sighash digest algorithm described in BIP 341. As the new digest algorithms may require the digest to commit to the entire prev output, a PrevOutputFetcher argument is required to obtain the needed information. The TxSigHashes pre-computed sighash midstate MUST be specified.

func CalcTapscriptSignaturehash

func CalcTapscriptSignaturehash(sigHashes *TxSigHashes, hType SigHashType,
	tx *wire.MsgTx, idx int, prevOutFetcher PrevOutputFetcher,
	tapLeaf TapLeaf,
	sigHashOpts ...TaprootSigHashOption) ([]byte, error)

CalcTaprootSignatureHash is similar to CalcTaprootSignatureHash but for _tapscript_ spends instead. A proper TapLeaf instance (the script leaf being signed) must be passed in. The functional options can be used to specify an annex if the signature was bound to that context.

NOTE: This function is able to compute the sighash of scripts that contain a code separator if the caller passes in an instance of WithBaseTapscriptVersion with the valid position.

func CalcWitnessSigHash

func CalcWitnessSigHash(script []byte, sigHashes *TxSigHashes, hType SigHashType,
	tx *wire.MsgTx, idx int, amt int64, assets wire.TxAssets) ([]byte, error)

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

func ComputeTaprootKeyNoScript

func ComputeTaprootKeyNoScript(internalKey *btcec.PublicKey) *btcec.PublicKey

ComputeTaprootKeyNoScript calculates the top-level taproot output key given an internal key, and a desire that the only way an output can be spent is with the keyspend path. This is useful for normal wallet operations that don't need any other additional spending conditions.

func ComputeTaprootOutputKey

func ComputeTaprootOutputKey(pubKey *btcec.PublicKey,
	scriptRoot []byte) *btcec.PublicKey

ComputeTaprootOutputKey calculates a top-level taproot output key given an internal key, and tapscript merkle root. The final key is derived as: taprootKey = internalKey + (h_tapTweak(internalKey || merkleRoot)*G).

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func DisasmString

func DisasmString(script []byte) (string, error)

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.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

func ExtractWitnessProgramInfo

func ExtractWitnessProgramInfo(script []byte) (int, []byte, error)

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, _ 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.

WARNING: This function always treats the passed script as version 0. Great care must be taken if introducing a new script version because it is used in consensus which, unfortunately as of the time of this writing, does not check script versions before counting their signature operations which means nodes on existing rules will count new version scripts as if they were version 0.

The third parameter is DEPRECATED and is unused.

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.

WARNING: This function always treats the passed script as version 0. Great care must be taken if introducing a new script version because it is used in consensus which, unfortunately as of the time of this writing, does not check script versions before counting their signature operations which means nodes on existing rules will count new version scripts as if they were version 0.

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 IsErrorCode

func IsErrorCode(err error, c ErrorCode) bool

IsErrorCode returns whether or not the provided error is a script error with the provided error code.

func IsMultisigScript

func IsMultisigScript(script []byte) (bool, error)

IsMultisigScript returns whether or not the passed script is a standard multisignature script.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

The error is DEPRECATED and will be removed in the major version bump.

func IsMultisigSigScript

func IsMultisigSigScript(script []byte) bool

IsMultisigSigScript returns whether or not the passed script appears to be a signature script which consists of a pay-to-script-hash multi-signature redeem script. Determining if a signature script is actually a redemption of pay-to-script-hash requires the associated public key script which is often expensive to obtain. Therefore, this makes a fast best effort guess that has a high probability of being correct by checking if the signature script ends with a data push and treating that data push as if it were a p2sh redeem script

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

func IsNullData

func IsNullData(script []byte) bool

IsNullData returns true if the passed script is a null data script, false otherwise.

func IsPayToPubKey

func IsPayToPubKey(script []byte) bool

IsPayToPubKey returns true if the script is in the standard pay-to-pubkey (P2PK) format, false otherwise.

func IsPayToPubKeyHash

func IsPayToPubKeyHash(script []byte) bool

IsPayToPubKeyHash returns true if the script is in the standard pay-to-pubkey-hash (P2PKH) format, false otherwise.

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.

WARNING: This function always treats the passed script as version 0. Great care must be taken if introducing a new script version because it is used in consensus which, unfortunately as of the time of this writing, does not check script versions before determining if the script is a P2SH which means nodes on existing rules will analyze new version scripts as if they were version 0.

func IsPayToTaproot

func IsPayToTaproot(script []byte) bool

IsPayToTaproot returns true if the passed script is a standard pay-to-taproot (PTTR) scripts, and false otherwise.

func IsPayToWitnessPubKeyHash

func IsPayToWitnessPubKeyHash(script []byte) bool

IsPayToWitnessPubKeyHash returns true if the script 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 script 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 according to the consensus definition of pushing data.

WARNING: This function always treats the passed script as version 0. Great care must be taken if introducing a new script version because it is used in consensus which, unfortunately as of the time of this writing, does not check script versions before checking if it is a push only script which means nodes on existing rules will treat new version scripts as if they were version 0.

func IsSmallInt

func IsSmallInt(op byte) bool

IsSmallInt returns whether or not the opcode is considered a small integer, which is an OP_0, or OP_1 through OP_16.

NOTE: This function is only valid for version 0 opcodes. Since the function does not accept a script version, the results are undefined for other script versions.

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 outputs to be pruned instantly when entering the UTXO set.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

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 MakeScriptNum

func MakeScriptNum(v []byte, requireMinimal bool, scriptNumLen int) (scriptNum, error)

MakeScriptNum interprets the passed serialized bytes as an encoded integer and returns the result as a script number.

Since the consensus rules dictate that serialized bytes interpreted as ints are only allowed to be in the range determined by a maximum number of bytes, on a per opcode basis, an error will be returned when the provided bytes would result in a number outside of that range. In particular, the range for the vast majority of opcodes dealing with numeric values are limited to 4 bytes and therefore will pass that value to this function resulting in an allowed range of [-2^31 + 1, 2^31 - 1].

The requireMinimal flag causes an error to be returned if additional checks on the encoding determine it is not represented with the smallest possible number of bytes or is the negative 0 encoding, [0x80]. For example, consider the number 127. It could be encoded as [0x7f], [0x7f 0x00], [0x7f 0x00 0x00 ...], etc. All forms except [0x7f] will return an error with requireMinimal enabled.

The scriptNumLen is the maximum number of bytes the encoded value can be before an ErrStackNumberTooBig is returned. This effectively limits the range of allowed values. WARNING: Great care should be taken if passing a value larger than maxScriptNumLen, which could lead to addition and multiplication overflows.

See the Bytes function documentation for example encodings.

func MultiSigScript

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

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, error)

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, error)

PayToAddrScript creates a new script to pay a transaction output to a 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/sat20-labs/satsnet_btcd/btcutil"
	"github.com/sat20-labs/satsnet_btcd/chaincfg"
	"github.com/sat20-labs/satsnet_btcd/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 PayToTaprootScript

func PayToTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error)

PayToTaprootScript creates a pk script for a pay-to-taproot output key.

func PushedData

func PushedData(script []byte) ([][]byte, error)

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 SigHashType, key *btcec.PrivateKey) ([]byte, error)

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

func RawTxInTaprootSignature

func RawTxInTaprootSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
	amt int64, assets wire.TxAssets, pkScript []byte, tapScriptRootHash []byte, hashType SigHashType,
	key *btcec.PrivateKey) ([]byte, error)

RawTxInTaprootSignature returns a valid schnorr signature required to perform a taproot key-spend of the specified input. If SigHashDefault was specified, then the returned signature is 64-byte in length, as it omits the additional byte to denote the sighash type.

func RawTxInTapscriptSignature

func RawTxInTapscriptSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
	amt int64, assets wire.TxAssets, pkScript []byte, tapLeaf TapLeaf, hashType SigHashType,
	privKey *btcec.PrivateKey) ([]byte, error)

RawTxInTapscriptSignature computes a raw schnorr signature for a signature generated from a tapscript leaf. This differs from the RawTxInTaprootSignature which is used to generate signatures for top-level taproot key spends.

TODO(roasbeef): actually add code-sep to interface? not really used anywhere....

func RawTxInWitnessSignature

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

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 ScriptHasOpSuccess

func ScriptHasOpSuccess(witnessScript []byte) bool

ScriptHasOpSuccess returns true if any op codes in the script contain an OP_SUCCESS op code.

func SignTxOutput

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

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.

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

Example

This example demonstrates manually creating and signing a redeem transaction.

package main

import (
	"encoding/hex"
	"fmt"

	"github.com/sat20-labs/satsnet_btcd/btcec"
	"github.com/sat20-labs/satsnet_btcd/btcutil"
	"github.com/sat20-labs/satsnet_btcd/chaincfg"
	"github.com/sat20-labs/satsnet_btcd/chaincfg/chainhash"
	"github.com/sat20-labs/satsnet_btcd/txscript"
	"github.com/sat20-labs/satsnet_btcd/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, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2" +
		"d4f8720ee63e502ee2869afab7de234b80c")
	if err != nil {
		fmt.Println(err)
		return
	}
	privKey, pubKey := btcec.PrivKeyFromBytes(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(wire.TxVersion)
	prevOut := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
	txIn := wire.NewTxIn(prevOut, []byte{txscript.OP_0, txscript.OP_0}, nil)
	originTx.AddTxIn(txIn)
	pkScript, err := txscript.PayToAddrScript(addr)
	if err != nil {
		fmt.Println(err)
		return
	}

	txOut := wire.NewTxOut(100000000, wire.TxAssets{}, pkScript)
	originTx.AddTxOut(txOut)
	originTxHash := originTx.TxHash()

	// Create the transaction to redeem the fake transaction.
	redeemTx := wire.NewMsgTx(wire.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, wire.TxAssets{}, nil)
	redeemTx.AddTxOut(txOut)

	// Sign the redeeming transaction.
	lookupKey := func(a btcutil.Address) (*btcec.PrivateKey, bool, error) {
		// 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, txscript.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, wire.TxAssets{}, nil)
	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 SigHashType, privKey *btcec.PrivateKey, compress bool) ([]byte, error)

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 TaprootWitnessSignature

func TaprootWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
	amt int64, assets wire.TxAssets, pkScript []byte, hashType SigHashType,
	key *btcec.PrivateKey) (wire.TxWitness, error)

TaprootWitnessSignature returns a valid witness stack that can be used to spend the key-spend path of a taproot input as specified in BIP 342 and BIP 86. This method assumes that the public key included in pkScript was generated using ComputeTaprootKeyNoScript that commits to a fake root tapscript hash. If not, then RawTxInTaprootSignature should be used with the actual committed contents.

TODO(roasbeef): add support for annex even tho it's non-standard?

func TweakTaprootPrivKey

func TweakTaprootPrivKey(privKey btcec.PrivateKey,
	scriptRoot []byte) *btcec.PrivateKey

TweakTaprootPrivKey applies the same operation as ComputeTaprootOutputKey, but on the private key instead. The final key is derived as: privKey + h_tapTweak(internalKey || merkleRoot) % N, where N is the order of the secp256k1 curve, and merkleRoot is the root hash of the tapscript tree.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info.

func VerifyTaprootKeySpend

func VerifyTaprootKeySpend(witnessProgram []byte, rawSig []byte, tx *wire.MsgTx,
	inputIndex int, prevOuts PrevOutputFetcher, hashCache *TxSigHashes,
	sigCache *SigCache) error

VerifyTaprootKeySpend attempts to verify a top-level taproot key spend, returning a non-nil error if the passed signature is invalid. If a sigCache is passed in, then the sig cache will be consulted to skip full verification of a signature that has already been seen. Witness program here should be the 32-byte x-only schnorr output public key.

NOTE: The TxSigHashes MUST be passed in and fully populated.

func VerifyTaprootLeafCommitment

func VerifyTaprootLeafCommitment(controlBlock *ControlBlock,
	taprootWitnessProgram []byte, revealedScript []byte) error

VerifyTaprootLeafCommitment attempts to verify a taproot commitment of the revealed script within the taprootWitnessProgram (a schnorr public key) given the required information included in the control block. An error is returned if the reconstructed taproot commitment (a function of the merkle root and the internal key) doesn't match the passed witness program.

func WitnessSignature

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

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 AtomicSwapDataPushes

type AtomicSwapDataPushes struct {
	RecipientHash160 [20]byte
	RefundHash160    [20]byte
	SecretHash       [32]byte
	SecretSize       int64
	LockTime         int64
}

AtomicSwapDataPushes houses the data pushes found in atomic swap contracts.

func ExtractAtomicSwapDataPushes

func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDataPushes, error)

ExtractAtomicSwapDataPushes returns the data pushes from an atomic swap contract. If the script is not an atomic swap contract, ExtractAtomicSwapDataPushes returns (nil, nil). Non-nil errors are returned for unparsable scripts.

NOTE: Atomic swaps are not considered standard script types by the dcrd mempool policy and should be used with P2SH. The atomic swap format is also expected to change to use a more secure hash function in the future.

This function is only defined in the txscript package due to API limitations which prevent callers using txscript to parse nonstandard scripts.

DEPRECATED. This will be removed in the next major version bump. The error should also likely be removed if the code is reimplemented by any callers since any errors result in a nil result anyway.

type CannedPrevOutputFetcher

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

CannedPrevOutputFetcher is an implementation of PrevOutputFetcher that only is able to return information for a single previous output.

func NewCannedPrevOutputFetcher

func NewCannedPrevOutputFetcher(script []byte, amt int64, assets wire.TxAssets) *CannedPrevOutputFetcher

NewCannedPrevOutputFetcher returns an instance of a CannedPrevOutputFetcher that can only return the TxOut defined by the passed script and amount.

func (*CannedPrevOutputFetcher) FetchPrevOutput

func (c *CannedPrevOutputFetcher) FetchPrevOutput(wire.OutPoint) *wire.TxOut

FetchPrevOutput attempts to fetch the previous output referenced by the passed outpoint.

NOTE: This is a part of the PrevOutputFetcher interface.

type ControlBlock

type ControlBlock struct {
	// InternalKey is the internal public key in the taproot commitment.
	InternalKey *btcec.PublicKey

	// OutputKeyYIsOdd denotes if the y coordinate of the output key (the
	// key placed in the actual taproot output is odd.
	OutputKeyYIsOdd bool

	// LeafVersion is the specified leaf version of the tapscript leaf that
	// the InclusionProof below is based off of.
	LeafVersion TapscriptLeafVersion

	// InclusionProof is a series of merkle branches that when hashed
	// pairwise, starting with the revealed script, will yield the taproot
	// commitment root.
	InclusionProof []byte
}

ControlBlock houses the structured witness input for a taproot spend. This includes the internal taproot key, the leaf version, and finally a nearly complete merkle inclusion proof for the main taproot commitment.

TODO(roasbeef): method to serialize control block that commits to even y-bit, which pops up everywhere even tho 32 byte keys

func ParseControlBlock

func ParseControlBlock(ctrlBlock []byte) (*ControlBlock, error)

ParseControlBlock attempts to parse the raw bytes of a control block. An error is returned if the control block isn't well formed, or can't be parsed.

func (*ControlBlock) RootHash

func (c *ControlBlock) RootHash(revealedScript []byte) []byte

RootHash calculates the root hash of a tapscript given the revealed script.

func (*ControlBlock) ToBytes

func (c *ControlBlock) ToBytes() ([]byte, error)

ToBytes returns the control block in a format suitable for using as part of a witness spending a tapscript output.

type Engine

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

Engine is the virtual machine that executes scripts.

func NewDebugEngine

func NewDebugEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int,
	flags ScriptFlags, sigCache *SigCache, hashCache *TxSigHashes,
	inputAmount int64, assets wire.TxAssets, prevOutFetcher PrevOutputFetcher,
	stepCallback func(*StepInfo) error) (*Engine, error)

NewEngine returns a new script engine with a script execution callback set. This is useful for debugging script execution.

func NewEngine

func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags,
	sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64, assets wire.TxAssets,
	prevOutFetcher PrevOutputFetcher) (*Engine, error)

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) error

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, error)

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, error)

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. In the case of pay-to-script-hash, index 2 is the redeem script once the execution has progressed far enough to have successfully verified script hash and thus add the script to the scripts to execute.

func (*Engine) Execute

func (vm *Engine) Execute() (err error)

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

func (*Engine) GetAltStack

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

GetAltStack returns the contents of the alternate stack as an array where the last item in the array is the top of the stack.

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) SetAltStack

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

SetAltStack sets the contents of the alternate stack to the contents of the provided array where the last item in the array will be 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 error)

Step executes the next instruction and moves 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 ErrScriptNotCanonical

type ErrScriptNotCanonical string

ErrScriptNotCanonical identifies a non-canonical script. The caller can use a type assertion to detect this error type.

func (ErrScriptNotCanonical) Error

func (e ErrScriptNotCanonical) Error() string

Error implements the error interface.

type Error

type Error struct {
	ErrorCode   ErrorCode
	Description string
}

Error identifies a script-related error. It is used to indicate three classes of errors:

  1. Script execution failures due to violating one of the many requirements imposed by the script engine or evaluating to false
  2. Improper API usage by callers
  3. Internal consistency check failures

The caller can use type assertions on the returned errors to access the ErrorCode field to ascertain the specific reason for the error. As an additional convenience, the caller may make use of the IsErrorCode function to check for a specific error code.

func (Error) Error

func (e Error) Error() string

Error satisfies the error interface and prints human-readable errors.

type ErrorCode

type ErrorCode int

ErrorCode identifies a kind of script error.

const (
	// ErrInternal is returned if internal consistency checks fail.  In
	// practice this error should never be seen as it would mean there is an
	// error in the engine logic.
	ErrInternal ErrorCode = iota

	// ErrInvalidFlags is returned when the passed flags to NewEngine
	// contain an invalid combination.
	ErrInvalidFlags

	// ErrInvalidIndex is returned when an out-of-bounds index is passed to
	// a function.
	ErrInvalidIndex

	// ErrUnsupportedAddress is returned when a concrete type that
	// implements a btcutil.Address is not a supported type.
	ErrUnsupportedAddress

	// ErrNotMultisigScript is returned from CalcMultiSigStats when the
	// provided script is not a multisig script.
	ErrNotMultisigScript

	// ErrTooManyRequiredSigs is returned from MultiSigScript when the
	// specified number of required signatures is larger than the number of
	// provided public keys.
	ErrTooManyRequiredSigs

	// ErrTooMuchNullData is returned from NullDataScript when the length of
	// the provided data exceeds MaxDataCarrierSize.
	ErrTooMuchNullData

	// ErrUnsupportedScriptVersion is returned when an unsupported script
	// version is passed to a function which deals with script analysis.
	ErrUnsupportedScriptVersion

	// ErrEarlyReturn is returned when OP_RETURN is executed in the script.
	ErrEarlyReturn

	// ErrEmptyStack is returned when the script evaluated without error,
	// but terminated with an empty top stack element.
	ErrEmptyStack

	// ErrEvalFalse is returned when the script evaluated without error but
	// terminated with a false top stack element.
	ErrEvalFalse

	// ErrScriptUnfinished is returned when CheckErrorCondition is called on
	// a script that has not finished executing.
	ErrScriptUnfinished

	// ErrScriptDone is returned when an attempt to execute an opcode is
	// made once all of them have already been executed.  This can happen
	// due to things such as a second call to Execute or calling Step after
	// all opcodes have already been executed.
	ErrInvalidProgramCounter

	// ErrScriptTooBig is returned if a script is larger than MaxScriptSize.
	ErrScriptTooBig

	// ErrElementTooBig is returned if the size of an element to be pushed
	// to the stack is over MaxScriptElementSize.
	ErrElementTooBig

	// ErrTooManyOperations is returned if a script has more than
	// MaxOpsPerScript opcodes that do not push data.
	ErrTooManyOperations

	// ErrStackOverflow is returned when stack and altstack combined depth
	// is over the limit.
	ErrStackOverflow

	// ErrInvalidPubKeyCount is returned when the number of public keys
	// specified for a multsig is either negative or greater than
	// MaxPubKeysPerMultiSig.
	ErrInvalidPubKeyCount

	// ErrInvalidSignatureCount is returned when the number of signatures
	// specified for a multisig is either negative or greater than the
	// number of public keys.
	ErrInvalidSignatureCount

	// ErrNumberTooBig is returned when the argument for an opcode that
	// expects numeric input is larger than the expected maximum number of
	// bytes.  For the most part, opcodes that deal with stack manipulation
	// via offsets, arithmetic, numeric comparison, and boolean logic are
	// those that this applies to.  However, any opcode that expects numeric
	// input may fail with this code.
	ErrNumberTooBig

	// ErrVerify is returned when OP_VERIFY is encountered in a script and
	// the top item on the data stack does not evaluate to true.
	ErrVerify

	// ErrEqualVerify is returned when OP_EQUALVERIFY is encountered in a
	// script and the top item on the data stack does not evaluate to true.
	ErrEqualVerify

	// ErrNumEqualVerify is returned when OP_NUMEQUALVERIFY is encountered
	// in a script and the top item on the data stack does not evaluate to
	// true.
	ErrNumEqualVerify

	// ErrCheckSigVerify is returned when OP_CHECKSIGVERIFY is encountered
	// in a script and the top item on the data stack does not evaluate to
	// true.
	ErrCheckSigVerify

	// ErrCheckSigVerify is returned when OP_CHECKMULTISIGVERIFY is
	// encountered in a script and the top item on the data stack does not
	// evaluate to true.
	ErrCheckMultiSigVerify

	// ErrDisabledOpcode is returned when a disabled opcode is encountered
	// in a script.
	ErrDisabledOpcode

	// ErrReservedOpcode is returned when an opcode marked as reserved
	// is encountered in a script.
	ErrReservedOpcode

	// ErrMalformedPush is returned when a data push opcode tries to push
	// more bytes than are left in the script.
	ErrMalformedPush

	// ErrInvalidStackOperation is returned when a stack operation is
	// attempted with a number that is invalid for the current stack size.
	ErrInvalidStackOperation

	// ErrUnbalancedConditional is returned when an OP_ELSE or OP_ENDIF is
	// encountered in a script without first having an OP_IF or OP_NOTIF or
	// the end of script is reached without encountering an OP_ENDIF when
	// an OP_IF or OP_NOTIF was previously encountered.
	ErrUnbalancedConditional

	// ErrMinimalData is returned when the ScriptVerifyMinimalData flag
	// is set and the script contains push operations that do not use
	// the minimal opcode required.
	ErrMinimalData

	// ErrInvalidSigHashType is returned when a signature hash type is not
	// one of the supported types.
	ErrInvalidSigHashType

	// ErrSigTooShort is returned when a signature that should be a
	// canonically-encoded DER signature is too short.
	ErrSigTooShort

	// ErrSigTooLong is returned when a signature that should be a
	// canonically-encoded DER signature is too long.
	ErrSigTooLong

	// ErrSigInvalidSeqID is returned when a signature that should be a
	// canonically-encoded DER signature does not have the expected ASN.1
	// sequence ID.
	ErrSigInvalidSeqID

	// ErrSigInvalidDataLen is returned a signature that should be a
	// canonically-encoded DER signature does not specify the correct number
	// of remaining bytes for the R and S portions.
	ErrSigInvalidDataLen

	// ErrSigMissingSTypeID is returned a signature that should be a
	// canonically-encoded DER signature does not provide the ASN.1 type ID
	// for S.
	ErrSigMissingSTypeID

	// ErrSigMissingSLen is returned when a signature that should be a
	// canonically-encoded DER signature does not provide the length of S.
	ErrSigMissingSLen

	// ErrSigInvalidSLen is returned a signature that should be a
	// canonically-encoded DER signature does not specify the correct number
	// of bytes for the S portion.
	ErrSigInvalidSLen

	// ErrSigInvalidRIntID is returned when a signature that should be a
	// canonically-encoded DER signature does not have the expected ASN.1
	// integer ID for R.
	ErrSigInvalidRIntID

	// ErrSigZeroRLen is returned when a signature that should be a
	// canonically-encoded DER signature has an R length of zero.
	ErrSigZeroRLen

	// ErrSigNegativeR is returned when a signature that should be a
	// canonically-encoded DER signature has a negative value for R.
	ErrSigNegativeR

	// ErrSigTooMuchRPadding is returned when a signature that should be a
	// canonically-encoded DER signature has too much padding for R.
	ErrSigTooMuchRPadding

	// ErrSigInvalidSIntID is returned when a signature that should be a
	// canonically-encoded DER signature does not have the expected ASN.1
	// integer ID for S.
	ErrSigInvalidSIntID

	// ErrSigZeroSLen is returned when a signature that should be a
	// canonically-encoded DER signature has an S length of zero.
	ErrSigZeroSLen

	// ErrSigNegativeS is returned when a signature that should be a
	// canonically-encoded DER signature has a negative value for S.
	ErrSigNegativeS

	// ErrSigTooMuchSPadding is returned when a signature that should be a
	// canonically-encoded DER signature has too much padding for S.
	ErrSigTooMuchSPadding

	// ErrSigHighS is returned when the ScriptVerifyLowS flag is set and the
	// script contains any signatures whose S values are higher than the
	// half order.
	ErrSigHighS

	// ErrNotPushOnly is returned when a script that is required to only
	// push data to the stack performs other operations.  A couple of cases
	// where this applies is for a pay-to-script-hash signature script when
	// bip16 is active and when the ScriptVerifySigPushOnly flag is set.
	ErrNotPushOnly

	// ErrSigNullDummy is returned when the ScriptStrictMultiSig flag is set
	// and a multisig script has anything other than 0 for the extra dummy
	// argument.
	ErrSigNullDummy

	// ErrPubKeyType is returned when the ScriptVerifyStrictEncoding
	// flag is set and the script contains invalid public keys.
	ErrPubKeyType

	// ErrCleanStack is returned when the ScriptVerifyCleanStack flag
	// is set, and after evaluation, the stack does not contain only a
	// single element.
	ErrCleanStack

	// ErrNullFail is returned when the ScriptVerifyNullFail flag is
	// set and signatures are not empty on failed checksig or checkmultisig
	// operations.
	ErrNullFail

	// ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a
	// native p2wsh program is encountered which has a non-empty sigScript.
	ErrWitnessMalleated

	// ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set
	// and the validation logic for nested p2sh encounters a sigScript
	// which isn't *exactyl* a datapush of the witness program.
	ErrWitnessMalleatedP2SH

	// ErrDiscourageUpgradableNOPs is returned when the
	// ScriptDiscourageUpgradableNops flag is set and a NOP opcode is
	// encountered in a script.
	ErrDiscourageUpgradableNOPs

	// ErrNegativeLockTime is returned when a script contains an opcode that
	// interprets a negative lock time.
	ErrNegativeLockTime

	// ErrUnsatisfiedLockTime is returned when a script contains an opcode
	// that involves a lock time and the required lock time has not been
	// reached.
	ErrUnsatisfiedLockTime

	// ErrMinimalIf is returned if ScriptVerifyWitness is set and the
	// operand of an OP_IF/OP_NOF_IF are not either an empty vector or
	// [0x01].
	ErrMinimalIf

	// ErrDiscourageUpgradableWitnessProgram is returned if
	// ScriptVerifyWitness is set and the version of an executing witness
	// program is outside the set of currently defined witness program
	// versions.
	ErrDiscourageUpgradableWitnessProgram

	// ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and
	// the witness stack itself is empty.
	ErrWitnessProgramEmpty

	// ErrWitnessProgramMismatch is returned if ScriptVerifyWitness is set
	// and the witness itself for a p2wkh witness program isn't *exactly* 2
	// items or if the witness for a p2wsh isn't the sha255 of the witness
	// script.
	ErrWitnessProgramMismatch

	// ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is
	// set and the length of the witness program violates the length as
	// dictated by the current witness version.
	ErrWitnessProgramWrongLength

	// ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
	// transaction includes witness data but doesn't spend an which is a
	// witness program (nested or native).
	ErrWitnessUnexpected

	// ErrWitnessPubKeyType is returned if ScriptVerifyWitness is set and
	// the public key used in either a check-sig or check-multi-sig isn't
	// serialized in a compressed format.
	ErrWitnessPubKeyType

	// ErrDiscourageOpSuccess is returned if
	// ScriptVerifyDiscourageOpSuccess is active, and a OP_SUCCESS op code
	// is encountered during tapscript validation.
	ErrDiscourageOpSuccess

	// ErrDiscourageUpgradeableTaprootVersion is returned if
	// ScriptVerifyDiscourageUpgradeableTaprootVersion is active and a leaf
	// version encountered isn't the base leaf version.
	ErrDiscourageUpgradeableTaprootVersion

	// ErrTapscriptCheckMultisig is returned if a script attempts to use
	// OP_CHECKMULTISIGVERIFY or OP_CHECKMULTISIG during tapscript
	// execution.
	ErrTapscriptCheckMultisig

	// ErrDiscourageUpgradeableTaprootVersion is returned if during
	// tapscript execution, we encounter a public key that isn't 0 or 32
	// bytes.
	ErrDiscourageUpgradeablePubKeyType

	// ErrTaprootSigInvalid is returned when an invalid taproot key spend
	// signature is encountered.
	ErrTaprootSigInvalid

	// ErrTaprootMerkleProofInvalid is returned when the revealed script
	// merkle proof for a taproot spend is found to be invalid.
	ErrTaprootMerkleProofInvalid

	// ErrTaprootOutputKeyParityMismatch is returned when the control block
	// proof is valid, but the parity of the y-coordinate of the derived
	// key doesn't match the value encoded in the control block.
	ErrTaprootOutputKeyParityMismatch

	// ErrControlBlockTooSmall is returned when a parsed control block is
	// less than 33 bytes.
	ErrControlBlockTooSmall

	// ErrControlBlockTooLarge is returned when the control block is larger
	// than the largest possible proof for a merkle script tree.
	ErrControlBlockTooLarge

	// ErrControlBlockInvalidLength is returned when the control block,
	// without the public key isn't a multiple of 32.
	ErrControlBlockInvalidLength

	// ErrWitnessHasNoAnnex is returned when a caller attempts to extract
	// an annex, but the witness has no annex present.
	ErrWitnessHasNoAnnex

	// ErrInvalidTaprootSigLen is returned when taproot signature isn't 64
	// or 65 bytes.
	ErrInvalidTaprootSigLen

	// ErrTaprootPubkeyIsEmpty is returned when a signature checking op
	// code encounters an empty public key.
	ErrTaprootPubkeyIsEmpty

	// ErrTaprootMaxSigOps is returned when the number of allotted sig ops
	// is exceeded during taproot execution.
	ErrTaprootMaxSigOps

	// ErrNonConstScriptCode is returned when a signature match is found when
	// calling removeOpcodeByData in a non-segwit script.
	ErrNonConstScriptCode

	// ErrCodeSeparator is returned when OP_CODESEPARATOR is used in a
	// non-segwit script.
	ErrCodeSeparator
)

These constants are used to identify a specific Error.

func (ErrorCode) String

func (e ErrorCode) String() string

String returns the ErrorCode as a human-readable name.

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,
	inputFetcher PrevOutputFetcher)

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 IndexedTapScriptTree

type IndexedTapScriptTree struct {
	// RootNode is the root of the tapscript tree. RootNode.TapHash() can
	// be used to extract the hash needed to derive the taptweak committed
	// to in the taproot output.
	RootNode TapNode

	// LeafMerkleProofs is a slice that houses the series of merkle
	// inclusion proofs for each leaf based on the input order of the
	// leaves.
	LeafMerkleProofs []TapscriptProof

	// LeafProofIndex maps the TapHash() of a given leaf node to the index
	// within the LeafMerkleProofs array above. This can be used to
	// retrieve the inclusion proof for a given script when constructing
	// the witness stack and control block for spending a tapscript path.
	LeafProofIndex map[chainhash.Hash]int
}

IndexedTapScriptTree reprints a fully contracted tapscript tree. The RootNode can be used to traverse down the full tree. In addition, complete inclusion proofs for each leaf are included as well, with an index into the slice of proof based on the tap leaf hash of a given leaf.

func AssembleTaprootScriptTree

func AssembleTaprootScriptTree(leaves ...TapLeaf) *IndexedTapScriptTree

AssembleTaprootScriptTree constructs a new fully indexed tapscript tree given a series of leaf nodes. A combination of a recursive data structure, and an array-based representation are used to both generate the tree and also accumulate all the necessary inclusion proofs in the same path. See the comment of blockchain.BuildMerkleTreeStore for further details.

func NewIndexedTapScriptTree

func NewIndexedTapScriptTree(numLeaves int) *IndexedTapScriptTree

NewIndexedTapScriptTree creates a new empty tapscript tree that has enough space to hold information for the specified amount of leaves.

type KeyClosure

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

KeyClosure implements KeyDB with a closure.

func (KeyClosure) GetKey

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

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

type KeyDB

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

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

type MultiPrevOutFetcher

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

MultiPrevOutFetcher is a custom implementation of the PrevOutputFetcher backed by a key-value map of prevouts to outputs.

func NewMultiPrevOutFetcher

func NewMultiPrevOutFetcher(prevOuts map[wire.OutPoint]*wire.TxOut) *MultiPrevOutFetcher

NewMultiPrevOutFetcher returns an instance of a PrevOutputFetcher that's backed by an optional map which is used as an input source. The

func (*MultiPrevOutFetcher) AddPrevOut

func (m *MultiPrevOutFetcher) AddPrevOut(op wire.OutPoint, txOut *wire.TxOut)

AddPrevOut adds a new prev out, tx out pair to the backing map.

func (*MultiPrevOutFetcher) FetchPrevOutput

func (m *MultiPrevOutFetcher) FetchPrevOutput(op wire.OutPoint) *wire.TxOut

FetchPrevOutput attempts to fetch the previous output referenced by the passed outpoint.

NOTE: This is a part of the CannedPrevOutputFetcher interface.

func (*MultiPrevOutFetcher) Merge

func (m *MultiPrevOutFetcher) Merge(other *MultiPrevOutFetcher)

Merge merges two instances of a MultiPrevOutFetcher into a single source.

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, error)

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, error)

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, error)

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 PrevOutputFetcher

type PrevOutputFetcher interface {
	// FetchPrevOutput attempts to fetch the previous output referenced by
	// the passed outpoint. A nil value will be returned if the passed
	// outpoint doesn't exist.
	FetchPrevOutput(wire.OutPoint) *wire.TxOut
}

PrevOutputFetcher is an interface used to supply the sighash cache with the previous output information needed to calculate the pre-computed sighash midstate for taproot transactions.

type ScriptBuilder

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

ScriptBuilder provides a facility for building custom scripts. It allows you to push opcodes, ints, and data while respecting canonical encoding. In general it does not ensure the script will execute correctly, however any data pushes which would exceed the maximum allowed script engine limits and are therefore guaranteed not to execute will not be pushed and will result in the Script function returning an error.

For example, the following would build a 2-of-3 multisig script for usage in a pay-to-script-hash (although in this situation MultiSigScript() would be a better choice to generate the script):

builder := txscript.NewScriptBuilder()
builder.AddOp(txscript.OP_2).AddData(pubKey1).AddData(pubKey2)
builder.AddData(pubKey3).AddOp(txscript.OP_3)
builder.AddOp(txscript.OP_CHECKMULTISIG)
script, err := builder.Script()
if err != nil {
	// Handle the error.
	return
}
fmt.Printf("Final multi-sig script: %x\n", script)

func NewScriptBuilder

func NewScriptBuilder(opts ...ScriptBuilderOpt) *ScriptBuilder

NewScriptBuilder returns a new instance of a script builder. See ScriptBuilder for details.

func (*ScriptBuilder) AddData

func (b *ScriptBuilder) AddData(data []byte) *ScriptBuilder

AddData pushes the passed data to the end of the script. It automatically chooses canonical opcodes depending on the length of the data. A zero length buffer will lead to a push of empty data onto the stack (OP_0) and any push of data greater than MaxScriptElementSize will not modify the script since that is not allowed by the script engine. Also, the script will not be modified if pushing the data would cause the script to exceed the maximum allowed script engine size.

func (*ScriptBuilder) AddFullData

func (b *ScriptBuilder) AddFullData(data []byte) *ScriptBuilder

AddFullData should not typically be used by ordinary users as it does not include the checks which prevent data pushes larger than the maximum allowed sizes which leads to scripts that can't be executed. This is provided for testing purposes such as regression tests where sizes are intentionally made larger than allowed.

Use AddData instead.

func (*ScriptBuilder) AddInt64

func (b *ScriptBuilder) AddInt64(val int64) *ScriptBuilder

AddInt64 pushes the passed integer to the end of the script. The script will not be modified if pushing the data would cause the script to exceed the maximum allowed script engine size.

func (*ScriptBuilder) AddOp

func (b *ScriptBuilder) AddOp(opcode byte) *ScriptBuilder

AddOp pushes the passed opcode to the end of the script. The script will not be modified if pushing the opcode would cause the script to exceed the maximum allowed script engine size.

func (*ScriptBuilder) AddOps

func (b *ScriptBuilder) AddOps(opcodes []byte) *ScriptBuilder

AddOps pushes the passed opcodes to the end of the script. The script will not be modified if pushing the opcodes would cause the script to exceed the maximum allowed script engine size.

func (*ScriptBuilder) Reset

func (b *ScriptBuilder) Reset() *ScriptBuilder

Reset resets the script so it has no content.

func (*ScriptBuilder) Script

func (b *ScriptBuilder) Script() ([]byte, error)

Script returns the currently built script. When any errors occurred while building the script, the script will be returned up the point of the first error along with the error.

type ScriptBuilderOpt

type ScriptBuilderOpt func(*scriptBuilderConfig)

ScriptBuilderOpt is a functional option type which is used to modify the initialization of a ScriptBuilder.

func WithScriptAllocSize

func WithScriptAllocSize(size int) ScriptBuilderOpt

WithScriptAllocSize specifies the initial size of the backing array for the script builder.

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).
	WitnessV1TaprootTy                       // Taproot output
	WitnessUnknownTy                         // Witness unknown
)

Classes of script payment known about in the blockchain.

func ExtractPkScriptAddrs

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

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/sat20-labs/satsnet_btcd/chaincfg"
	"github.com/sat20-labs/satsnet_btcd/txscript"
)

func main() {
	// Start with a standard pay-to-pubkey-hash script.
	scriptHex := "76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
	script, err := hex.DecodeString(scriptHex)
	if err != nil {
		fmt.Println(err)
		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 NewScriptClass

func NewScriptClass(name string) (*ScriptClass, error)

NewScriptClass returns the ScriptClass corresponding to the string name provided as argument. ErrUnsupportedScriptType error is returned if the name doesn't correspond to any known ScriptClass.

Not to be confused with GetScriptClass.

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, error)

ScriptClosure implements ScriptDB with a closure.

func (ScriptClosure) GetScript

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

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

type ScriptDB

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

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

	// ScriptVerifyTaproot defines whether or not to verify a transaction
	// output using the new taproot validation rules.
	ScriptVerifyTaproot

	// ScriptVerifyDiscourageUpgradeableWitnessProgram defines whether or
	// not to consider any new/unknown taproot leaf versions as
	// non-standard.
	ScriptVerifyDiscourageUpgradeableTaprootVersion

	// ScriptVerifyDiscourageOpSuccess defines whether or not to consider
	// usage of OP_SUCCESS op codes during tapscript execution as
	// non-standard.
	ScriptVerifyDiscourageOpSuccess

	// ScriptVerifyDiscourageUpgradeablePubkeyType defines if unknown
	// public key versions (during tapscript execution) is non-standard.
	ScriptVerifyDiscourageUpgradeablePubkeyType

	// ScriptVerifyConstScriptCode fails non-segwit scripts if a signature
	// match is found in the script code or if OP_CODESEPARATOR is used.
	ScriptVerifyConstScriptCode
)

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, error)

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

NOTE: This function is only valid for version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.

DEPRECATED. This will be removed in the next major version bump.

type ScriptTokenizer

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

ScriptTokenizer provides a facility for easily and efficiently tokenizing transaction scripts without creating allocations. Each successive opcode is parsed with the Next function, which returns false when iteration is complete, either due to successfully tokenizing the entire script or encountering a parse error. In the case of failure, the Err function may be used to obtain the specific parse error.

Upon successfully parsing an opcode, the opcode and data associated with it may be obtained via the Opcode and Data functions, respectively.

The ByteIndex function may be used to obtain the tokenizer's current offset into the raw script.

Example

This example demonstrates creating a script tokenizer instance and using it to count the number of opcodes a script contains.

package main

import (
	"fmt"

	"github.com/sat20-labs/satsnet_btcd/btcutil"
	"github.com/sat20-labs/satsnet_btcd/txscript"
)

func main() {
	// Create a script to use in the example.  Ordinarily this would come from
	// some other source.
	hash160 := btcutil.Hash160([]byte("example"))
	script, err := txscript.NewScriptBuilder().AddOp(txscript.OP_DUP).
		AddOp(txscript.OP_HASH160).AddData(hash160).
		AddOp(txscript.OP_EQUALVERIFY).AddOp(txscript.OP_CHECKSIG).Script()
	if err != nil {
		fmt.Printf("failed to build script: %v\n", err)
		return
	}

	// Create a tokenizer to iterate the script and count the number of opcodes.
	const scriptVersion = 0
	var numOpcodes int
	tokenizer := txscript.MakeScriptTokenizer(scriptVersion, script)
	for tokenizer.Next() {
		numOpcodes++
	}
	if tokenizer.Err() != nil {
		fmt.Printf("script failed to parse: %v\n", err)
	} else {
		fmt.Printf("script contains %d opcode(s)\n", numOpcodes)
	}

}
Output:

script contains 5 opcode(s)

func MakeScriptTokenizer

func MakeScriptTokenizer(scriptVersion uint16, script []byte) ScriptTokenizer

MakeScriptTokenizer returns a new instance of a script tokenizer. Passing an unsupported script version will result in the returned tokenizer immediately having an err set accordingly.

See the docs for ScriptTokenizer for more details.

func (*ScriptTokenizer) ByteIndex

func (t *ScriptTokenizer) ByteIndex() int32

ByteIndex returns the current offset into the full script that will be parsed next and therefore also implies everything before it has already been parsed.

func (*ScriptTokenizer) Data

func (t *ScriptTokenizer) Data() []byte

Data returns the data associated with the most recently successfully parsed opcode.

func (*ScriptTokenizer) Done

func (t *ScriptTokenizer) Done() bool

Done returns true when either all opcodes have been exhausted or a parse failure was encountered and therefore the state has an associated error.

func (*ScriptTokenizer) Err

func (t *ScriptTokenizer) Err() error

Err returns any errors currently associated with the tokenizer. This will only be non-nil in the case a parsing error was encountered.

func (*ScriptTokenizer) Next

func (t *ScriptTokenizer) Next() bool

Next attempts to parse the next opcode and returns whether or not it was successful. It will not be successful if invoked when already at the end of the script, a parse failure is encountered, or an associated error already exists due to a previous parse failure.

In the case of a true return, the parsed opcode and data can be obtained with the associated functions and the offset into the script will either point to the next opcode or the end of the script if the final opcode was parsed.

In the case of a false return, the parsed opcode and data will be the last successfully parsed values (if any) and the offset into the script will either point to the failing opcode or the end of the script if the function was invoked when already at the end of the script.

Invoking this function when already at the end of the script is not considered an error and will simply return false.

func (*ScriptTokenizer) Opcode

func (t *ScriptTokenizer) Opcode() byte

Opcode returns the current opcode associated with the tokenizer.

func (*ScriptTokenizer) OpcodePosition

func (t *ScriptTokenizer) OpcodePosition() int32

OpcodePosition returns the current op code counter. Unlike the ByteIndex above (referred to as the program counter or pc at times), this is incremented with each node op code, and isn't incremented more than once for push datas.

NOTE: If no op codes have been parsed, this returns -1.

func (*ScriptTokenizer) Script

func (t *ScriptTokenizer) Script() []byte

Script returns the full script associated with the tokenizer.

type SegwitSigHashMidstate

type SegwitSigHashMidstate struct {
	HashPrevOutsV0 chainhash.Hash
	HashSequenceV0 chainhash.Hash
	HashOutputsV0  chainhash.Hash
}

SegwitSigHashMidstate is the sighash midstate used in the base segwit sighash calculation as defined in BIP 143.

type SigCache

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

SigCache implements an Schnorr+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.

TODO(roasbeef): use type params here after Go 1.18

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 []byte, pubKey []byte)

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 []byte, pubKey []byte) 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 SigHashType

type SigHashType uint32

SigHashType represents hash type bits at the end of a signature.

const (
	SigHashDefault      SigHashType = 0x00
	SigHashOld          SigHashType = 0x0
	SigHashAll          SigHashType = 0x1
	SigHashNone         SigHashType = 0x2
	SigHashSingle       SigHashType = 0x3
	SigHashAnyOneCanPay SigHashType = 0x80
)

Hash type bits from the end of a signature.

type StepInfo

type StepInfo struct {
	// ScriptIndex is the index of the script currently being executed by
	// the Engine.
	ScriptIndex int

	// OpcodeIndex is the index of the next opcode that will be executed.
	// In case the execution has completed, the opcode index will be
	// incrementet beyond the number of the current script's opcodes. This
	// indicates no new script is being executed, and execution is done.
	OpcodeIndex int

	// Stack is the Engine's current content on the stack:
	Stack [][]byte

	// AltStack is the Engine's current content on the alt stack.
	AltStack [][]byte
}

StepInfo houses the current VM state information that is passed back to the stepCallback during script execution.

type TapBranch

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

TapBranch represents an internal branch in the tapscript tree. The left or right nodes may either be another branch, leaves, or a combination of both.

func NewTapBranch

func NewTapBranch(l, r TapNode) TapBranch

NewTapBranch creates a new internal branch from a left and right node.

func (TapBranch) Left

func (t TapBranch) Left() TapNode

Left is the left node of the branch, this might be a leaf or another branch.

func (TapBranch) Right

func (t TapBranch) Right() TapNode

Right is the right node of a branch, this might be a leaf or another branch.

func (TapBranch) TapHash

func (t TapBranch) TapHash() chainhash.Hash

TapHash returns the hash digest of the taproot internal branch given a left and right node. The final hash digest is: h_tapbranch(leftNode || rightNode), where leftNode is the lexicographically smaller of the two nodes.

type TapLeaf

type TapLeaf struct {
	// LeafVersion is the leaf version of this leaf.
	LeafVersion TapscriptLeafVersion

	// Script is the script to be validated based on the specified leaf
	// version.
	Script []byte
}

TapLeaf represents a leaf in a tapscript tree. A leaf has two components: the leaf version, and the script associated with that leaf version.

func NewBaseTapLeaf

func NewBaseTapLeaf(script []byte) TapLeaf

NewBaseTapLeaf returns a new TapLeaf for the specified script, using the current base leaf version (BIP 342).

func NewTapLeaf

func NewTapLeaf(leafVersion TapscriptLeafVersion, script []byte) TapLeaf

NewTapLeaf returns a new TapLeaf with the given leaf version and script to be committed to.

func (TapLeaf) Left

func (t TapLeaf) Left() TapNode

Left rights the left node for this leaf. As this is a leaf the left node is nil.

func (TapLeaf) Right

func (t TapLeaf) Right() TapNode

Right rights the right node for this leaf. As this is a leaf the right node is nil.

func (TapLeaf) TapHash

func (t TapLeaf) TapHash() chainhash.Hash

TapHash returns the hash digest of the target taproot script leaf. The digest is computed as: h_tapleaf(leafVersion || compactSizeof(script) || script).

type TapNode

type TapNode interface {
	// TapHash returns the hash of the node. This will either be a tagged
	// hash derived from a branch, or a leaf.
	TapHash() chainhash.Hash

	// Left returns the left node. If this is a leaf node, this may be nil.
	Left() TapNode

	// Right returns the right node. If this is a leaf node, this may be
	// nil.
	Right() TapNode
}

TapNode represents an abstract node in a tapscript merkle tree. A node is either a branch or a leaf.

type TaprootSigHashMidState

type TaprootSigHashMidState struct {
	HashPrevOutsV1     chainhash.Hash
	HashSequenceV1     chainhash.Hash
	HashOutputsV1      chainhash.Hash
	HashInputScriptsV1 chainhash.Hash
	HashInputAmountsV1 chainhash.Hash
}

TaprootSigHashMidState is the sighash midstate used to compute taproot and tapscript signatures as defined in BIP 341.

type TaprootSigHashOption

type TaprootSigHashOption func(*taprootSigHashOptions)

TaprootSigHashOption defines a set of functional param options that can be used to modify the base sighash message with optional extensions.

func WithAnnex

func WithAnnex(annex []byte) TaprootSigHashOption

WithAnnex is a functional option that allows the caller to specify the existence of an annex in the final witness stack for the taproot/tapscript spends.

func WithBaseTapscriptVersion

func WithBaseTapscriptVersion(codeSepPos uint32,
	tapLeafHash []byte) TaprootSigHashOption

WithBaseTapscriptVersion is a functional option that specifies that the sighash digest should include the extra information included as part of the base tapscript version.

type TapscriptLeafVersion

type TapscriptLeafVersion uint8

TapscriptLeafVersion represents the various possible versions of a tapscript leaf version. Leaf versions are used to define, or introduce new script semantics, under the base taproot execution model.

TODO(roasbeef): add validation here as well re proper prefix, etc?

const (
	// BaseLeafVersion is the base tapscript leaf version. The semantics of
	// this version are defined in BIP 342.
	BaseLeafVersion TapscriptLeafVersion = 0xc0
)

type TapscriptProof

type TapscriptProof struct {
	// TapLeaf is the leaf that we want to prove inclusion for.
	TapLeaf

	// RootNode is the root of the tapscript tree, this will be used to
	// compute what the final output key looks like.
	RootNode TapNode

	// InclusionProof is the tail end of the control block that contains
	// the series of hashes (the sibling hashes up the tree), that when
	// hashed together allow us to re-derive the top level taproot output.
	InclusionProof []byte
}

TapscriptProof is a proof of inclusion that a given leaf (a script and leaf version) is included within a top-level taproot output commitment.

func (*TapscriptProof) ToControlBlock

func (t *TapscriptProof) ToControlBlock(internalKey *btcec.PublicKey) ControlBlock

ToControlBlock maps the tapscript proof into a fully valid control block that can be used as a witness item for a tapscript spend.

type TxSigHashes

type TxSigHashes struct {
	SegwitSigHashMidstate

	TaprootSigHashMidState
}

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,
	inputFetcher PrevOutputFetcher) *TxSigHashes

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

Jump to

Keyboard shortcuts

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