txscript

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2021 License: MIT Imports: 18 Imported by: 0

README

txscript

[Build Status] (https://travis-ci.org/btcsuite/btcd) ![ISC License] (http://img.shields.io/badge/license-ISC-blue.svg) [GoDoc] (http://godoc.org/btcd/txscript)

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 langauge 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 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 pushing and popping data to and from the stack, performing basic and bitwise arithmetic, conditional branching, comparing hashes, and checking cryptographic signatures. Scripts are processed from left to right and intentionally do not provide loops.

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

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

Errors

Errors returned by this package are of the form txscript.ErrStackX where X indicates the specific error. See Variables in the package documentation for a full list.

Index

Constants

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.

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

These are the constants specified for maximums in individual scripts.

View Source
const (
	WitnessV0ScriptHashDataSize = 32 // Length of witness script hash
	// WitnessV0PoCPubKeyHashDataSize = 20 // Length of poc public key hash
	WitnessV0FrozenPeriodDataSize = 8 // Length of byte slice of frozen period
)
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_UNKNOWN186          = 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_SMALLDATA           = 0xf9 // 249 - bitcoin core internal
	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 (
	// 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.  However, if the field is interpreted as a timestamp, given
	// the lock time is a uint32, the max is sometime around 2106.
	LockTimeThreshold uint64 = 5e8 // Tue Nov 5 00:53:20 1985 UTC
)
View Source
const (
	// 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
	StandardVerifyFlags = ScriptDiscourageUpgradableNops
)

Variables

View Source
var (
	// ErrStackShortScript is returned if the script has an opcode that is
	// too long for the length of the script.
	ErrStackShortScript = errors.New("execute past end of script")

	// ErrStackLongScript is returned if the script has an opcode that is
	// too long for the length of the script.
	ErrStackLongScript = errors.New("script is longer than maximum allowed")

	// ErrStackUnderflow is returned if an opcode requires more items on the
	// stack than is present.f
	ErrStackUnderflow = errors.New("stack underflow")

	// ErrStackInvalidArgs is returned if the argument for an opcode is out
	// of acceptable range.
	ErrStackInvalidArgs = errors.New("invalid argument")

	// ErrStackOpDisabled is returned when a disabled opcode is encountered
	// in the script.
	ErrStackOpDisabled = errors.New("disabled opcode")

	// ErrStackVerifyFailed is returned when one of the OP_VERIFY or
	// OP_*VERIFY instructions is executed and the conditions fails.
	ErrStackVerifyFailed = errors.New("verify failed")

	// ErrStackNumberTooBig is returned when the argument for an opcode that
	// should be an offset is obviously far too large.
	ErrStackNumberTooBig = errors.New("number too big")

	// ErrStackInvalidOpcode is returned when an opcode marked as invalid or
	// a completely undefined opcode is encountered.
	ErrStackInvalidOpcode = errors.New("invalid opcode")

	// ErrStackReservedOpcode is returned when an opcode marked as reserved
	// is encountered.
	ErrStackReservedOpcode = errors.New("reserved opcode")

	// ErrTooManyOperations is returned if an OP_CHECKMULTISIG is
	// encountered with more than MaxOpsPerScript OpCodes present.
	ErrTooManyOperations = errors.New("too many operations")

	// ErrStackEarlyReturn is returned when OP_RETURN is executed in the
	// script.
	ErrStackEarlyReturn = errors.New("script returned early")

	// ErrStackNoIf is returned if an OP_ELSE or OP_ENDIF is encountered
	// without first having an OP_IF or OP_NOTIF in the script.
	ErrStackNoIf = errors.New("OP_ELSE or OP_ENDIF with no matching OP_IF")

	// ErrStackMissingEndif is returned if the end of a script is reached
	// without and OP_ENDIF to correspond to a conditional expression.
	ErrStackMissingEndif = fmt.Errorf("execute fail, in conditional execution")

	// ErrStackTooManyPubKeys is returned if an OP_CHECKMULTISIG is
	// encountered with more than MaxPubKeysPerMultiSig pubkeys present.
	ErrStackTooManyPubKeys = errors.New("invalid pubkey count in OP_CHECKMULTISIG")

	// ErrStackTooManyOperations is returned if a script has more than
	// MaxOpsPerScript opcodes that do not push data.
	ErrStackTooManyOperations = errors.New("too many operations in script")

	// ErrStackElementTooBig is returned if the size of an element to be
	// pushed to the stack is over MaxScriptElementSize.
	ErrStackElementTooBig = errors.New("element in script too large")

	// ErrStackUnknownAddress is returned when ScriptToAddrHash does not
	// recognise the pattern of the script and thus can not find the address
	// for payment.
	ErrStackUnknownAddress = errors.New("non-recognised address")

	// ErrStackScriptFailed is returned when at the end of a script the
	// boolean on top of the stack is false signifying that the script has
	// failed.
	ErrStackScriptFailed = errors.New("execute fail, fail on stack")

	// ErrStackScriptUnfinished is returned when CheckErrorCondition is
	// called on a script that has not finished executing.
	ErrStackScriptUnfinished = errors.New("error check when script unfinished")

	// ErrStackEmptyStack is returned when the stack is empty at the end of
	// execution. Normal operation requires that a boolean is on top of the
	// stack when the scripts have finished executing.
	ErrStackEmptyStack = errors.New("stack empty at end of execution")

	// ErrStackP2SHNonPushOnly is returned when a Pay-to-Script-Hash
	// transaction is encountered and the ScriptSig does operations other
	// than push data (in violation of bip16).
	ErrStackP2SHNonPushOnly = errors.New("pay to script hash with non " +
		"pushonly input")

	// ErrStackInvalidParseType is an internal error returned from
	// ScriptToAddrHash ony if the internal data tables are wrong.
	ErrStackInvalidParseType = errors.New("internal error: invalid parsetype found")

	// ErrStackInvalidAddrOffset is an internal error returned from
	// ScriptToAddrHash ony if the internal data tables are wrong.
	ErrStackInvalidAddrOffset = errors.New("internal error: invalid offset found")

	// ErrStackInvalidIndex is returned when an out-of-bounds index was
	// passed to a function.
	ErrStackInvalidIndex = errors.New("invalid script index")

	// ErrStackNonPushOnly is returned when ScriptInfo is called with a
	// pkScript that peforms operations other that pushing data to the stack.
	ErrStackNonPushOnly = errors.New("SigScript is non pushonly")

	// ErrStackOverflow is returned when stack and altstack combined depth
	// is over the limit.
	ErrStackOverflow = errors.New("stack overflow")

	// ErrStackInvalidLowSSignature is returned when the ScriptVerifyLowS
	// flag is set and the script contains any signatures whose S values
	// are higher than the half order.
	ErrStackInvalidLowSSignature = errors.New("invalid low s signature")

	// ErrStackInvalidPubKey is returned when the ScriptVerifyScriptEncoding
	// flag is set and the script contains invalid pubkeys.
	ErrStackInvalidPubKey = errors.New("invalid strict pubkey")

	// ErrStackCleanStack is returned when the ScriptVerifyCleanStack flag
	// is set and after evalution the stack does not contain only one element,
	// which also must be true if interpreted as a boolean.
	ErrStackCleanStack = errors.New("stack is not clean")

	// ErrStackMinimalData is returned when the ScriptVerifyMinimalData flag
	// is set and the script contains push operations that do not use
	// the minimal opcode required.
	ErrStackMinimalData = errors.New("non-minimally encoded script number")

	ErrWitnessProgramEmpty = errors.New("witness program is empty")

	ErrWitnessProgramMismatch = errors.New("witness program hash mismatch")

	ErrWitnessPubKeyType = errors.New("only uncompressed keys are accepted post-segwit")

	ErrWitnessProgramLength = errors.New("incorrect witness program length")

	ErrWitnessExtProgramLength = errors.New("incorrect witness extension program length")

	ErrDiscourageUpgradableWitnessProgram = errors.New("version of witness program is invalid")

	ErrInvalidFlags = errors.New("P2SH must be enabled to do witness verification")

	ErrWitnessUnexpected = errors.New("non-witness inputs cannot have a witness")

	ErrWitnessMalleated = errors.New("native witness program cannot also have a signature script")

	ErrWitnessLength = errors.New("invalid witness length")

	ErrwitnessProgramFormat = errors.New("script is not a witness program, unable to extract version or witness program")

	ErrUnsupportedAddress = errors.New("unsupport address")
	// ErrBadNumRequired is returned from MultiSigScript when nrequired is
	// larger than the number of provided public keys.
	ErrBadNumRequired = errors.New("more signatures required than keys present")

	ErrNullFail = errors.New("not all signatures empty on failed checkmultisig")

	ErrInvalidBindingScript = errors.New("input script is not a binding script")

	ErrBindingUnexpected = errors.New("null binding script")

	ErrFrozenPeriod = errors.New("invalid frozen period")

	ErrScriptTooBig = errors.New("script size is too large")

	ErrWitnessExtProgUnknown = errors.New("unknown witness extension program")
)
View Source
var OpcodeByName = make(map[string]byte)

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

Functions

func CalcMultiSigStats

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

func DisasmString

func DisasmString(buf []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.

func ExtractWitnessProgramInfo

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

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

func GetBindingScriptHash

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

func GetParsedBindingOpcode

func GetParsedBindingOpcode(pops []parsedOpcode) ([]byte, []byte, error)

func GetParsedOpcode

func GetParsedOpcode(pops []parsedOpcode, class ScriptClass) (uint64, [32]byte, error)

func GetSigOpCount

func GetSigOpCount(script []byte) int

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

func GetWitnessSigOpCount

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

func IsMASSWitnessProgram

func IsMASSWitnessProgram(script []byte) bool

func IsPayToBindingScriptHash

func IsPayToBindingScriptHash(script []byte) bool

func IsPayToStakingScriptHash

func IsPayToStakingScriptHash(script []byte) bool

func IsPayToWitnessScriptHash

func IsPayToWitnessScriptHash(script []byte) bool

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

func IsPushOnlyScript

func IsPushOnlyScript(script []byte) bool

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

False will be returned when the script does not parse.

func IsUnspendable

func IsUnspendable(pkScript []byte) bool

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

func IsWitnessProgram

func IsWitnessProgram(script []byte) bool

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

func MultiSigScript

func MultiSigScript(pubkeys []*massutil.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 ErrBadNumRequired will be returned if nrequired is larger than the number of keys provided.

Redeem script can be generated by this func

func PayToAddrScript

func PayToAddrScript(addr massutil.Address) ([]byte, error)

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

func PayToBindingScriptHashScript

func PayToBindingScriptHashScript(scriptHash1 []byte, scriptHash2 []byte) ([]byte, error)

func PayToStakingAddrScript

func PayToStakingAddrScript(addr massutil.Address, frozenPeriod uint64) ([]byte, error)

PayToStakingAddrScript creates a new script to pay a transaction output to a stakingTx address.

func PayToWitnessScriptHashScript

func PayToWitnessScriptHashScript(scriptHash []byte) ([]byte, error)

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 RawTxInWitnessSignature

func RawTxInWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
	amt int64, subScript []byte, hashType SigHashType,
	pubkey *btcec.PublicKey, kdb GetSignDB) ([]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 SignTxOutputWit

func SignTxOutputWit(chainParams *config.Params, tx *wire.MsgTx, idx int, value int64, pkScript []byte, sigHashes *TxSigHashes, hashType SigHashType, kdb GetSignDB, sdb ScriptDB) (wire.TxWitness, error)

Types

type Engine

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

Engine is the virtual machine that executes scripts.

func NewEngine

func NewEngine(pkScript []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags,
	sigCache *SigCache, hashCache *TxSigHashes, inputAmount int64) (*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.

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

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

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

func (*Engine) SetStack

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

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

func (*Engine) Step

func (vm *Engine) Step() (done bool, err error)

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

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

type 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 GetSignDB

type GetSignDB interface {
	GetSign(*btcec.PublicKey, []byte) (*btcec.Signature, error)
}

type HashCache

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

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

func NewHashCache

func NewHashCache(maxSize uint) *HashCache

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

func (*HashCache) AddSigHashes

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

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

func (*HashCache) ContainsHashes

func (h *HashCache) ContainsHashes(txid *wire.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 *wire.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 *wire.Hash)

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

type MockWallet

type MockWallet struct {
	WitnessMap      map[string][]byte            // witness address -> redeemscript
	PubKeyToPrivKey map[string]*btcec.PrivateKey // map key is string(pub key bytes)
}

func NewMockWallet

func NewMockWallet() *MockWallet

func (*MockWallet) BuildBindingPkScript

func (w *MockWallet) BuildBindingPkScript(nRequire, nTotal int, pocPkHash []byte) ([]byte, error)

func (*MockWallet) BuildP2WSHScript

func (w *MockWallet) BuildP2WSHScript(nRequire, nTotal int) ([]byte, error)

func (*MockWallet) BuildStakingPkScript

func (w *MockWallet) BuildStakingPkScript(nRequire, nTotal int, frozenPeriod uint64) ([]byte, error)

func (*MockWallet) FindRedeemScript

func (w *MockWallet) FindRedeemScript(addr massutil.Address) []byte

func (*MockWallet) GetPrivKey

func (w *MockWallet) GetPrivKey(pk *btcec.PublicKey) *btcec.PrivateKey

func (*MockWallet) NewPublicKeys

func (w *MockWallet) NewPublicKeys(n int) ([]*btcec.PublicKey, error)

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() *ScriptBuilder

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

func (*ScriptBuilder) AddCoinbaseHeight

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

AddCoinbaseHeight is used because block height between 1 and 16 can not be encoded correctly

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) 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 occured while building the script, the script will be returned up the point of the first error along with the error.

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.
	WitnessV0ScriptHashTy                    // Pay to witness script hash.
	StakingScriptHashTy                      // Pay to staking script hash.
	BindingScriptHashTy                      //pay to binding script hash
	MultiSigTy                               // Multi signature.
	NullDataTy                               // Empty data-only (provably prunable).
)

Classes of script payment known about in the blockchain.

func ExtractPkScriptAddrs

func ExtractPkScriptAddrs(pkScript []byte, chainParams *config.Params) (ScriptClass, []massutil.Address, []*btcec.PublicKey, 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.

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 GetScriptInfo

func GetScriptInfo(script []byte) (ScriptClass, []parsedOpcode)

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(massutil.Address) ([]byte, error)

ScriptClosure implements ScriptDB with a closure.

func (ScriptClosure) GetScript

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

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

type ScriptDB

type ScriptDB interface {
	GetScript(massutil.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 (
	// 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 ScriptFlags = 1 << iota

	// ScriptMASSip2 defines whether to verify that a binding transaction
	// output is spendable after a fixed freezing period.
	ScriptMASSip2
)

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(pkScript []byte, witness wire.TxWitness) (*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

type SigCache

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

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

func NewSigCache

func NewSigCache(maxEntries uint) *SigCache

NewSigCache creates and initializes a new instance of SigCache. Its sole parameter 'maxEntries' represents the maximum number of entries allowed to exist in the SigCache and 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 wire.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey)

Add adds an entry for a signature over 'sigHash' under public key 'pubKey' to the signature cache. In the event that the SigCache is 'full', an existing entry it 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 wire.Hash, sig *btcec.Signature, pubKey *btcec.PublicKey) bool

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

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

type SigHashType

type SigHashType uint32

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

const (
	// 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 SignClosure

type SignClosure func(*btcec.PublicKey, []byte) (*btcec.Signature, error)

func (SignClosure) GetSign

func (kc SignClosure) GetSign(pubkey *btcec.PublicKey, hash []byte) (*btcec.Signature,
	error)

type TxSigHashes

type TxSigHashes struct {
	HashPrevOuts wire.Hash
	HashSequence wire.Hash
	HashOutputs  wire.Hash
	TxVersion    [4]byte
	TxLockTime   [8]byte
}

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

func NewTxSigHashes

func NewTxSigHashes(tx *wire.MsgTx) *TxSigHashes

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

Jump to

Keyboard shortcuts

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