Documentation ¶
Overview ¶
Package txscript implements the Decred transaction script language.
This package provides data structures and functions to parse and execute decred transaction scripts.
Script Overview ¶
Decred transaction scripts are written in a stack-base, FORTH-like language.
The Decred 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 Decred 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 decreds.
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 ¶
- Constants
- Variables
- func CalcMultiSigStats(script []byte) (int, int, error)
- func CalcSignatureHash(script []byte, hashType SigHashType, tx *wire.MsgTx, idx int, ...) ([]byte, error)
- func CanonicalDataSize(data []byte) int
- func ContainsStakeOpCodes(pkScript []byte) (bool, error)
- func DisasmString(script []byte) (string, error)
- func ExtractCoinbaseNullData(pkScript []byte) ([]byte, error)deprecated
- func ExtractPkScriptAltSigType(pkScript []byte) (dcrec.SignatureType, error)
- func GenerateProvablyPruneableOut(data []byte) ([]byte, error)
- func GenerateSSGenBlockRef(blockHash chainhash.Hash, height uint32) ([]byte, error)
- func GenerateSSGenVotes(votebits uint16) ([]byte, error)
- func GenerateSStxAddrPush(addr dcrutil.Address, amount dcrutil.Amount, limits uint16) ([]byte, error)
- func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte) int
- func GetSigOpCount(script []byte) int
- func IsDERSigError(err error) bool
- func IsErrorCode(err error, c ErrorCode) bool
- func IsMultisigScript(script []byte) bool
- func IsMultisigSigScript(script []byte) bool
- func IsPayToScriptHash(script []byte) bool
- func IsPushOnlyScript(script []byte) bool
- func IsUnspendable(amount int64, pkScript []byte) bool
- func MultiSigScript(pubkeys []*dcrutil.AddressSecpPubKey, nrequired int) ([]byte, error)
- func MultisigRedeemScriptFromScriptSig(script []byte) []byte
- func PayToAddrScript(addr dcrutil.Address) ([]byte, error)
- func PayToSSGen(addr dcrutil.Address) ([]byte, error)
- func PayToSSGenPKHDirect(pkh []byte) ([]byte, error)
- func PayToSSGenSHDirect(sh []byte) ([]byte, error)
- func PayToSSRtx(addr dcrutil.Address) ([]byte, error)
- func PayToSSRtxPKHDirect(pkh []byte) ([]byte, error)
- func PayToSSRtxSHDirect(sh []byte) ([]byte, error)
- func PayToSStx(addr dcrutil.Address) ([]byte, error)
- func PayToSStxChange(addr dcrutil.Address) ([]byte, error)
- func PayToScriptHashScript(scriptHash []byte) ([]byte, error)
- func PushedData(script []byte) ([][]byte, error)
- func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, ...) ([]byte, error)
- func RawTxInSignatureAlt(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, ...) ([]byte, error)
- func SignTxOutput(chainParams dcrutil.AddressParams, tx *wire.MsgTx, idx int, pkScript []byte, ...) ([]byte, error)
- func SignatureScript(tx *wire.MsgTx, idx int, subscript []byte, hashType SigHashType, ...) ([]byte, error)
- func SignatureScriptAlt(tx *wire.MsgTx, idx int, subscript []byte, hashType SigHashType, ...) ([]byte, error)
- func UseLogger(logger slog.Logger)
- type AtomicSwapDataPushes
- 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 Error
- type ErrorCode
- 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) AddOps(opcodes []byte) *ScriptBuilder
- func (b *ScriptBuilder) Reset() *ScriptBuilder
- func (b *ScriptBuilder) Script() ([]byte, error)
- type ScriptClass
- type ScriptClosure
- type ScriptDB
- type ScriptFlags
- type ScriptTokenizer
- type SigCache
- type SigHashSerType
- type SigHashType
Examples ¶
Constants ¶
const ( // MaxStackSize is the maximum combined height of stack and alt stack // during execution. MaxStackSize = 1024 // MaxScriptSize is the maximum allowed length of a raw script. MaxScriptSize = 16384 )
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_ROTR = 0x89 // 137 OP_ROTL = 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_BLAKE256 = 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_SSTX = 0xba // 186 DECRED OP_SSGEN = 0xbb // 187 DECRED OP_SSRTX = 0xbc // 188 DECRED OP_SSTXCHANGE = 0xbd // 189 DECRED OP_CHECKSIGALT = 0xbe // 190 DECRED OP_CHECKSIGALTVERIFY = 0xbf // 191 DECRED OP_SHA256 = 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_INVALID249 = 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 DCR scripts.
const ( OpCondFalse = 0 OpCondTrue = 1 OpCondSkip = 2 )
Conditional execution constants.
const ( MaxOpsPerScript = 255 // Max number of non-push operations. MaxPubKeysPerMultiSig = 20 // Multisig can't have more sigs than this. MaxScriptElementSize = 2048 // Max bytes pushable to the stack. )
These are the constants specified for maximums in individual scripts.
const ( // SigHashSerializePrefix indicates the serialization does not include // any witness data. SigHashSerializePrefix = 1 // SigHashSerializeWitness indicates the serialization only contains // witness data. SigHashSerializeWitness = 3 )
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 )
const ( // MaxDataCarrierSize is the maximum number of bytes allowed in pushed // data to be considered a nulldata transaction. MaxDataCarrierSize = 256 )
Variables ¶
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.
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, cachedPrefix *chainhash.Hash) ([]byte, error)
CalcSignatureHash computes the signature hash for the specified input of the target transaction observing the desired signature hash type. The cached prefix parameter allows the caller to optimize the calculation by providing the prefix hash to be reused in the case of SigHashAll without the SigHashAnyOneCanPay flag 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 CanonicalDataSize ¶
CanonicalDataSize returns the number of bytes the canonical encoding of the data will take.
func ContainsStakeOpCodes ¶
ContainsStakeOpCodes returns whether or not a pkScript contains stake tagging OP codes.
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 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.
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 ExtractCoinbaseNullData
deprecated
ExtractCoinbaseNullData ensures the passed script is a nulldata script as required by the consensus rules for the coinbase output that is used to ensure the coinbase has a unique hash and returns the data it pushes.
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.
func ExtractPkScriptAltSigType ¶
ExtractPkScriptAltSigType returns the signature scheme to use for an alternative check signature script.
NOTE: This function only attempts to identify version 0 scripts. Since the function does not accept a script version, the results are undefined for other script versions.
func GenerateProvablyPruneableOut ¶
GenerateProvablyPruneableOut 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 GenerateSSGenBlockRef ¶
GenerateSSGenBlockRef generates an OP_RETURN push for the block header hash and height which the block votes on.
func GenerateSSGenVotes ¶
GenerateSSGenVotes generates an OP_RETURN push for the vote bits in an SSGen tx.
func GenerateSStxAddrPush ¶
func GenerateSStxAddrPush(addr dcrutil.Address, amount dcrutil.Amount, limits uint16) ([]byte, error)
GenerateSStxAddrPush generates an OP_RETURN push for SSGen payment addresses in an SStx.
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.
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 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.
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 IsDERSigError ¶
IsDERSigError returns whether or not the provided error is a script error with one of the error codes which are caused due to encountering a signature that is not a canonically-encoded DER signature.
func IsErrorCode ¶
IsErrorCode returns whether or not the provided error is a script error with the provided error code.
func IsMultisigScript ¶
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.
func IsMultisigSigScript ¶
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 IsPayToScriptHash ¶
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 IsPushOnlyScript ¶
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 IsUnspendable ¶
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. In Decred, all zero value outputs are unspendable.
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 MultiSigScript ¶
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 MultisigRedeemScriptFromScriptSig ¶
MultisigRedeemScriptFromScriptSig attempts to extract a multi-signature redeem script from a P2SH-redeeming input. The script is expected to already have been checked to be a multisignature script prior to calling this function. The results are undefined for other script types.
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 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 Decred address. It also prints the created script hex and uses the DisasmString function to display the disassembled script.
// Parse the address to send the coins to into a dcrutil.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. mainNetParams := chaincfg.MainNetParams() addressStr := "DsSej1qR3Fyc8kV176DCh9n9cY9nqf9Quxk" address, err := dcrutil.DecodeAddress(addressStr, 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 PayToSSGen ¶
PayToSSGen creates a new script to pay a transaction output to a public key hash or script hash, but tags the output with OP_SSGEN. For use in constructing valid SSGen txs.
func PayToSSGenPKHDirect ¶
PayToSSGenPKHDirect creates a new script to pay a transaction output to a public key hash, but tags the output with OP_SSGEN. For use in constructing valid SSGen txs. Unlike PayToSSGen, this function directly uses the HASH160 pubkeyhash (instead of an address).
func PayToSSGenSHDirect ¶
PayToSSGenSHDirect creates a new script to pay a transaction output to a script hash, but tags the output with OP_SSGEN. For use in constructing valid SSGen txs. Unlike PayToSSGen, this function directly uses the HASH160 script hash (instead of an address).
func PayToSSRtx ¶
PayToSSRtx creates a new script to pay a transaction output to a public key hash, but tags the output with OP_SSRTX. For use in constructing valid SSRtx.
func PayToSSRtxPKHDirect ¶
PayToSSRtxPKHDirect creates a new script to pay a transaction output to a public key hash, but tags the output with OP_SSRTX. For use in constructing valid SSRtx. Unlike PayToSSRtx, this function directly uses the HASH160 pubkeyhash (instead of an address).
func PayToSSRtxSHDirect ¶
PayToSSRtxSHDirect creates a new script to pay a transaction output to a script hash, but tags the output with OP_SSRTX. For use in constructing valid SSRtx. Unlike PayToSSRtx, this function directly uses the HASH160 script hash (instead of an address).
func PayToSStx ¶
PayToSStx creates a new script to pay a transaction output to a script hash or public key hash, but tags the output with OP_SSTX. For use in constructing valid SStxs.
func PayToSStxChange ¶
PayToSStxChange creates a new script to pay a transaction output to a public key hash, but tags the output with OP_SSTXCHANGE. For use in constructing valid SStxs.
func PayToScriptHashScript ¶
PayToScriptHashScript is the exported version of payToScriptHashScript.
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.
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 RawTxInSignature ¶
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, key chainec.PrivateKey) ([]byte, error)
RawTxInSignature returns the serialized ECDSA signature for the input idx of the given transaction, with hashType appended to it.
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 RawTxInSignatureAlt ¶
func RawTxInSignatureAlt(tx *wire.MsgTx, idx int, subScript []byte, hashType SigHashType, key chainec.PrivateKey, sigType dcrec.SignatureType) ([]byte, error)
RawTxInSignatureAlt returns the serialized ECDSA signature for the input idx of the given transaction, with hashType appended to it.
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 SignTxOutput ¶
func SignTxOutput(chainParams dcrutil.AddressParams, tx *wire.MsgTx, idx int, pkScript []byte, hashType SigHashType, kdb KeyDB, sdb ScriptDB, previousScript []byte, sigType dcrec.SignatureType) ([]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.
// 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 := secp256k1.PrivKeyFromBytes(privKeyBytes) pubKeyHash := dcrutil.Hash160(pubKey.SerializeCompressed()) mainNetParams := chaincfg.MainNetParams() addr, err := dcrutil.NewAddressPubKeyHash(pubKeyHash, mainNetParams, dcrec.STEcdsaSecp256k1) 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 DCR. originTx := wire.NewMsgTx() prevOut := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0), wire.TxTreeRegular) txIn := wire.NewTxIn(prevOut, 100000000, []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.TxHash() // 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, wire.TxTreeRegular) txIn = wire.NewTxIn(prevOut, 100000000, 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 dcrutil.Address) (chainec.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(mainNetParams, redeemTx, 0, originTx.TxOut[0].PkScript, txscript.SigHashAll, txscript.KeyClosure(lookupKey), nil, nil, dcrec.STEcdsaSecp256k1) 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.ScriptDiscourageUpgradableNops vm, err := txscript.NewEngine(originTx.TxOut[0].PkScript, redeemTx, 0, flags, 0, 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 chainec.PrivateKey, compress bool) ([]byte, error)
SignatureScript creates an input signature script for tx to spend coins 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 SignatureScriptAlt ¶
func SignatureScriptAlt(tx *wire.MsgTx, idx int, subscript []byte, hashType SigHashType, privKey chainec.PrivateKey, compress bool, sigType dcrec.SignatureType) ([]byte, error)
SignatureScriptAlt creates an input signature script for tx to spend coins 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 the respective format for the ECDSA type. This format must match the same format used to generate the payment address, or the script validation will fail.
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 Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the virtual machine that executes scripts.
func NewEngine ¶
func NewEngine(scriptPubKey []byte, tx *wire.MsgTx, txIdx int, flags ScriptFlags, scriptVersion uint16, sigCache *SigCache) (*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 ¶
CheckErrorCondition returns nil if the running script has ended and was successful, leaving 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. 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 ¶
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 alternate 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 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 ¶
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 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 ¶
Error identifies a script-related error. It is used to indicate three classes of errors:
- Script execution failures due to violating one of the many requirements imposed by the script engine or evaluating to false
- Improper API usage by callers
- 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.
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 // ErrInvalidIndex is returned when an out-of-bounds index is passed to // a function. ErrInvalidIndex // ErrInvalidSigHashSingleIndex is returned when an attempt is // made to sign an input with the SigHashSingle hash type and an // index that is greater than or equal to the number of outputs. ErrInvalidSigHashSingleIndex // ErrUnsupportedAddress is returned when a concrete type that // implements a dcrutil.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 // ErrMalformedCoinbaseNullData is returned when the nulldata output // of a coinbase transaction that is used to ensure the coinbase has a // unique hash is not properly formed. // // Deprecated: This will be removed in the next major version bump. ErrMalformedCoinbaseNullData // 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 // ErrNumOutOfRange 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. ErrNumOutOfRange // 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 // ErrCheckSigAltVerify is returned when OP_CHECKSIGALTVERIFY is // encountered in a script and the top item on the data stack does not // evaluate to true. ErrCheckSigAltVerify // ErrP2SHStakeOpCodes is returned when one or more stake opcodes are // found in the redeem script of a pay-to-script-hash script. ErrP2SHStakeOpCodes // 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 // ErrNegativeSubstrIdx is returned when an OP_SUBSTR, OP_LEFT, or // OP_RIGHT opcode encounters a negative index. ErrNegativeSubstrIdx // ErrOverflowSubstrIdx is returned when an OP_SUBSTR, OP_LEFT, or // OP_RIGHT opcode encounters an index that is larger than the max // allowed index that can operate on the string or the start index // is greater than the end index for OP_SUBSTR. ErrOverflowSubstrIdx // ErrNegativeRotation is returned when an OP_ROTL or OP_ROTR attempts // to perform a rotation with a negative rotation count. ErrNegativeRotation // ErrOverflowRotation is returned when an OP_ROTL or OP_ROTR opcode // encounters a rotation count that is larger than the maximum allowed // value for a uint32 bit rotation. ErrOverflowRotation // ErrDivideByZero is returned when an OP_DIV of OP_MOD attempts to // divide by zero. ErrDivideByZero // ErrNegativeRotation is returned when an OP_LSHIFT or OP_RSHIFT opcode // attempts to perform a shift with a negative count. ErrNegativeShift // ErrOverflowShift is returned when an OP_LSHIFT or OP_RSHIFT opcode // encounters a shift count that is larger than the maximum allowed value // for a shift. ErrOverflowShift // ErrMinimalData is returned when 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 a signature that should be a // canonically-encoded DER signature has an S value that is higher than // the curve 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 // ErrPubKeyType is returned when 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 // 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 )
These constants are used to identify a specific Error.
type KeyClosure ¶
type KeyClosure func(dcrutil.Address) (chainec.PrivateKey, bool, error)
KeyClosure implements KeyDB with a closure.
func (KeyClosure) GetKey ¶
func (kc KeyClosure) GetKey(address dcrutil.Address) (chainec.PrivateKey, bool, error)
GetKey implements KeyDB by returning the result of calling the closure.
type KeyDB ¶
type KeyDB interface {
GetKey(dcrutil.Address) (chainec.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 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) 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 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). StakeSubmissionTy // Stake submission. StakeGenTy // Stake generation StakeRevocationTy // Stake revocation. StakeSubChangeTy // Change for stake submission tx. PubkeyAltTy // Alternative signature pubkey. PubkeyHashAltTy // Alternative signature pubkey hash. )
Classes of script payment known about in the blockchain.
func ExtractPkScriptAddrs ¶
func ExtractPkScriptAddrs(version uint16, pkScript []byte, chainParams dcrutil.AddressParams) (ScriptClass, []dcrutil.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.
NOTE: This function only attempts to identify version 0 scripts. The return value will indicate a nonstandard script type for other script versions along with an invalid script version error.
Example ¶
This example demonstrates extracting information from a standard public key script.
// Start with a standard pay-to-pubkey-hash script. const scriptVersion = 0 scriptHex := "76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac" script, err := hex.DecodeString(scriptHex) if err != nil { fmt.Println(err) return } // Extract and print details from the script. mainNetParams := chaincfg.MainNetParams() scriptClass, addresses, reqSigs, err := txscript.ExtractPkScriptAddrs( scriptVersion, script, 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: [DsSej1qR3Fyc8kV176DCh9n9cY9nqf9Quxk] Required Signatures: 1
func GetScriptClass ¶
func GetScriptClass(version uint16, script []byte) ScriptClass
GetScriptClass returns the class of the script passed.
NonStandardTy will be returned when the script does not parse.
func GetStakeOutSubclass ¶
func GetStakeOutSubclass(pkScript []byte) (ScriptClass, error)
GetStakeOutSubclass extracts the subclass (P2PKH or P2SH) from a stake output.
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 (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.
func (ScriptClosure) GetScript ¶
func (sc ScriptClosure) GetScript(address dcrutil.Address) ([]byte, error)
GetScript implements ScriptDB by returning the result of calling the closure.
type ScriptDB ¶
ScriptDB is an interface type provided to SignTxOutput, it encapsulates any user state required to get the scripts for a 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 // currently unused opcodes in the NOP and UNKNOWN families are reserved // for future 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 // 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. ScriptVerifyCleanStack // ScriptVerifySigPushOnly defines that signature scripts must contain // only pushed data. This is rule 2 of BIP0062. ScriptVerifySigPushOnly // ScriptVerifySHA256 defines whether to treat opcode 192 (previously // OP_UNKNOWN192) as the OP_SHA256 opcode which consumes the top item of // the data stack and replaces it with the sha256 of it. ScriptVerifySHA256 )
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.
// Create a script to use in the example. Ordinarily this would come from // some other source. hash160 := dcrutil.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) Script ¶
func (t *ScriptTokenizer) Script() []byte
Script returns the full script associated with the tokenizer.
type SigCache ¶
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 ¶
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 *secp256k1.Signature, pubKey *secp256k1.PublicKey)
Add adds an entry for a signature over 'sigHash' under public key 'pubKey' to the signature cache. In the event that the SigCache is 'full', an existing entry is randomly chosen to be evicted in order to make space for the new entry.
NOTE: This function is safe for concurrent access. Writers will block simultaneous readers until function execution has concluded.
func (*SigCache) Exists ¶
func (s *SigCache) Exists(sigHash chainhash.Hash, sig *secp256k1.Signature, pubKey *secp256k1.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 SigHashSerType ¶
type SigHashSerType uint16
SigHashSerType represents the serialization type used when calculating signature hashes.
NOTE: These values were originally a part of transaction serialization which is why there is a gap and they are not zero based. The logic for calculating signature hashes has since been decoupled from transaction serialization logic, but these specific values are still required by consensus, so they must remain unchanged.
type SigHashType ¶
type SigHashType byte
SigHashType represents hash type bits at the end of a signature.
const ( SigHashAll SigHashType = 0x1 SigHashNone SigHashType = 0x2 SigHashSingle SigHashType = 0x3 SigHashAnyOneCanPay SigHashType = 0x80 )
Hash type bits from the end of a signature.