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
- Variables
- func CalcMultiSigStats(script []byte) (int, int, error)
- func DisableLog()
- func DisasmString(buf []byte) (string, error)
- func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int
- func GetSigOpCount(script []byte) int
- func IsPayToScriptHash(script []byte) bool
- func IsPushOnlyScript(script []byte) bool
- func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error)
- func PayToAddrScript(addr btcutil.Address) ([]byte, error)
- func PushedData(script []byte) ([][]byte, error)
- func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, ...) ([]byte, error)
- func SetLogWriter(w io.Writer, level string) error
- func SignTxOutput(chainParams *chaincfg.Params, tx *wire.MsgTx, idx int, pkScript []byte, ...) ([]byte, error)
- func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte, hashType SigHashType, ...) ([]byte, error)
- func UseLogger(logger btclog.Logger)
- type Engine
- func (vm *Engine) CheckErrorCondition(finalScript bool) error
- func (vm *Engine) DisasmPC() (string, error)
- func (vm *Engine) DisasmScript(idx int) (string, error)
- func (vm *Engine) Execute() (err error)
- func (vm *Engine) GetAltStack() [][]byte
- func (vm *Engine) GetStack() [][]byte
- func (vm *Engine) SetAltStack(data [][]byte)
- func (vm *Engine) SetStack(data [][]byte)
- func (vm *Engine) Step() (done bool, err error)
- type ErrScriptNotCanonical
- type KeyClosure
- type KeyDB
- type ScriptBuilder
- func (b *ScriptBuilder) AddData(data []byte) *ScriptBuilder
- func (b *ScriptBuilder) AddFullData(data []byte) *ScriptBuilder
- func (b *ScriptBuilder) AddInt64(val int64) *ScriptBuilder
- func (b *ScriptBuilder) AddOp(opcode byte) *ScriptBuilder
- func (b *ScriptBuilder) Reset() *ScriptBuilder
- func (b *ScriptBuilder) Script() ([]byte, error)
- type ScriptClass
- type ScriptClosure
- type ScriptDB
- type ScriptFlags
- type ScriptInfo
- type SigHashType
Examples ¶
Constants ¶
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_NOP3 = 0xb2 // 178 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.
const ( OpCondFalse = 0 OpCondTrue = 1 OpCondSkip = 2 )
Conditional execution constants.
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.
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 )
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 uint32 = 5e8 // Tue Nov 5 00:53:20 1985 UTC )
Variables ¶
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") // 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("Stacks overflowed") // 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") )
var ( // ErrInvalidFlags is returned when the passed flags to NewScript // contain an invalid combination. ErrInvalidFlags = errors.New("invalid flags combination") // ErrInvalidIndex is returned when the passed input index for the // provided transaction is out of range. ErrInvalidIndex = errors.New("invalid input index") // ErrUnsupportedAddress is returned when a concrete type that // implements a btcutil.Address is not a supported type. ErrUnsupportedAddress = errors.New("unsupported address type") // 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") )
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.
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 ¶
CalcMultiSigStats returns the number of public keys and signatures from a multi-signature transaction script. The passed script MUST already be known to be a multi-signature script.
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until either UseLogger or SetLogWriter are called.
func DisasmString ¶
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 GetPreciseSigOpCount ¶
GetPreciseSigOpCount returns the number of signature operations in scriptPubKey. If bip16 is true then scriptSig may be searched for the Pay-To-Script-Hash script in order to find the precise number of signature operations in the transaction. If the script fails to parse, then the count up to the point of failure is returned.
func GetSigOpCount ¶
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 IsPayToScriptHash ¶
IsPayToScriptHash returns true if the script is in the standard pay-to-script-hash (P2SH) format, false otherwise.
func IsPushOnlyScript ¶
IsPushOnlyScript returns whether or not the passed script only pushes data.
False will be returned when the script does not parse.
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 ErrBadNumRequired will be returned if nrequired is larger than the number of keys provided.
func PayToAddrScript ¶
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/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcutil" ) 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 PushedData ¶
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 SetLogWriter ¶
SetLogWriter uses a specified io.Writer to output package logging info. This allows a caller to direct package logging output without needing a dependency on seelog. If the caller is also using btclog, UseLogger should be used instead.
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-dependant manner with the newly generated. signature script.
Example ¶
This example demonstrates manually creating and signing a redeem transaction.
package main import ( "encoding/hex" "fmt" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" ) 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(btcec.S256(), privKeyBytes) pubKeyHash := btcutil.Hash160(pubKey.SerializeCompressed()) addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, &chaincfg.MainNetParams) if err != nil { fmt.Println(err) return } // For this example, create a fake transaction that represents what // would ordinarily be the real transaction that is being spent. It // contains a single output that pays to address in the amount of 1 BTC. originTx := wire.NewMsgTx() prevOut := wire.NewOutPoint(&wire.ShaHash{}, ^uint32(0)) txIn := wire.NewTxIn(prevOut, []byte{txscript.OP_0, txscript.OP_0}) originTx.AddTxIn(txIn) pkScript, err := txscript.PayToAddrScript(addr) if err != nil { fmt.Println(err) return } txOut := wire.NewTxOut(100000000, pkScript) originTx.AddTxOut(txOut) originTxHash := originTx.TxSha() // Create the transaction to redeem the fake transaction. redeemTx := wire.NewMsgTx() // 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) redeemTx.AddTxIn(txIn) // Ordinarily this would contain that actual destination of the funds, // but for this example don't bother. txOut = wire.NewTxOut(0, nil) redeemTx.AddTxOut(txOut) // Sign the redeeming transaction. lookupKey := func(a btcutil.Address) (*btcec.PrivateKey, bool, 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) 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.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the virtual machine that executes scripts.
func NewEngine ¶
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 ¶
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 ¶
DisasmPC returns the string for the disassembly of the opcode that will be next to execute when Step() is called.
func (*Engine) DisasmScript ¶
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 ¶
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 ¶
GetAltStack 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) GetStack ¶
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 ¶
SetAltStack 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) SetStack ¶
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 ¶
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 KeyClosure ¶
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 ¶
KeyDB is an interface type provided to SignTxOutput, it encapsulates any user state required to get the private keys for an address.
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) 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. PubKeyTy // Pay pubkey. PubKeyHashTy // Pay pubkey hash. ScriptHashTy // Pay to script hash. MultiSigTy // Multi signature. NullDataTy // Empty data-only (provably prunable). )
Classes of script payment known about in the blockchain.
func ExtractPkScriptAddrs ¶
func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, 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/btcsuite/btcd/chaincfg" "github.com/btcsuite/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 (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 ¶
ScriptClosure implements ScriptDB with a closure.
type ScriptDB ¶
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 threshhold 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 // 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. 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 // 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 )
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, bip16 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
type SigHashType ¶
type SigHashType byte
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.