btcscript

package
v0.0.0-...-ca6883d Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2014 License: ISC, ISC Imports: 19 Imported by: 0

README

btcscript

[Build Status] (https://travis-ci.org/conformal/btcscript)

Package btcscript implements the bitcoin transaction scripts. There is a comprehensive test suite. test_coverage.txt contains the current coverage statistics (generated using gocov). On a UNIX-like OS, the script cov_report.sh can be used to generate the report. Package btcscript is licensed under the liberal ISC license.

This package is one of the core packages from btcd, an alternative full-node implementation of bitcoin which is under active development by Conformal. Although it was primarily written for btcd, this package has intentionally been designed so it can be used as a standalone package for any projects needing to use or validate bitcoin transaction scripts.

Bitcoin Scripts

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

Documentation

[GoDoc] (http://godoc.org/github.com/conformal/btcscript)

Full go doc style documentation for the project can be viewed online without installing this package by using the GoDoc site here.

You can also view the documentation locally once the package is installed with the godoc tool by running godoc -http=":6060" and pointing your browser to http://localhost:6060/pkg/github.com/conformal/btcscript

Installation

$ go get github.com/conformal/btcscript

Examples

TODO

  • Increase test coverage to 100%

GPG Verification Key

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

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

  • Import the public key into your GPG keyring:

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

    git tag -v TAG_NAME
    

License

Package btcscript is licensed under the liberal ISC License.

Documentation

Overview

Package btcscript implements bitcoin transaction scripts.

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 btcscript.StackErrX where X indicates the specific error. See Variables in the package documentation for a full list.

Index

Examples

Constants

View Source
const (
	OP_FALSE               = 0 // AKA OP_0
	OP_0                   = 0
	OP_DATA_1              = 1
	OP_DATA_2              = 2
	OP_DATA_3              = 3
	OP_DATA_4              = 4
	OP_DATA_5              = 5
	OP_DATA_6              = 6
	OP_DATA_7              = 7
	OP_DATA_8              = 8
	OP_DATA_9              = 9
	OP_DATA_10             = 10
	OP_DATA_11             = 11
	OP_DATA_12             = 12
	OP_DATA_13             = 13
	OP_DATA_14             = 14
	OP_DATA_15             = 15
	OP_DATA_16             = 16
	OP_DATA_17             = 17
	OP_DATA_18             = 18
	OP_DATA_19             = 19
	OP_DATA_20             = 20
	OP_DATA_21             = 21
	OP_DATA_22             = 22
	OP_DATA_23             = 23
	OP_DATA_24             = 24
	OP_DATA_25             = 25
	OP_DATA_26             = 26
	OP_DATA_27             = 27
	OP_DATA_28             = 28
	OP_DATA_29             = 29
	OP_DATA_30             = 30
	OP_DATA_31             = 31
	OP_DATA_32             = 32
	OP_DATA_33             = 33
	OP_DATA_34             = 34
	OP_DATA_35             = 35
	OP_DATA_36             = 36
	OP_DATA_37             = 37
	OP_DATA_38             = 38
	OP_DATA_39             = 39
	OP_DATA_40             = 40
	OP_DATA_41             = 41
	OP_DATA_42             = 42
	OP_DATA_43             = 43
	OP_DATA_44             = 44
	OP_DATA_45             = 45
	OP_DATA_46             = 46
	OP_DATA_47             = 47
	OP_DATA_48             = 48
	OP_DATA_49             = 49
	OP_DATA_50             = 50
	OP_DATA_51             = 51
	OP_DATA_52             = 52
	OP_DATA_53             = 53
	OP_DATA_54             = 54
	OP_DATA_55             = 55
	OP_DATA_56             = 56
	OP_DATA_57             = 57
	OP_DATA_58             = 58
	OP_DATA_59             = 59
	OP_DATA_60             = 60
	OP_DATA_61             = 61
	OP_DATA_62             = 62
	OP_DATA_63             = 63
	OP_DATA_64             = 64
	OP_DATA_65             = 65
	OP_DATA_66             = 66
	OP_DATA_67             = 67
	OP_DATA_68             = 68
	OP_DATA_69             = 69
	OP_DATA_70             = 70
	OP_DATA_71             = 71
	OP_DATA_72             = 72
	OP_DATA_73             = 73
	OP_DATA_74             = 74
	OP_DATA_75             = 75
	OP_PUSHDATA1           = 76
	OP_PUSHDATA2           = 77
	OP_PUSHDATA4           = 78
	OP_1NEGATE             = 79
	OP_RESERVED            = 80
	OP_1                   = 81 // AKA OP_TRUE
	OP_TRUE                = 81
	OP_2                   = 82
	OP_3                   = 83
	OP_4                   = 84
	OP_5                   = 85
	OP_6                   = 86
	OP_7                   = 87
	OP_8                   = 88
	OP_9                   = 89
	OP_10                  = 90
	OP_11                  = 91
	OP_12                  = 92
	OP_13                  = 93
	OP_14                  = 94
	OP_15                  = 95
	OP_16                  = 96
	OP_NOP                 = 97
	OP_VER                 = 98
	OP_IF                  = 99
	OP_NOTIF               = 100
	OP_VERIF               = 101
	OP_VERNOTIF            = 102
	OP_ELSE                = 103
	OP_ENDIF               = 104
	OP_VERIFY              = 105
	OP_RETURN              = 106
	OP_TOALTSTACK          = 107
	OP_FROMALTSTACK        = 108
	OP_2DROP               = 109
	OP_2DUP                = 110
	OP_3DUP                = 111
	OP_2OVER               = 112
	OP_2ROT                = 113
	OP_2SWAP               = 114
	OP_IFDUP               = 115
	OP_DEPTH               = 116
	OP_DROP                = 117
	OP_DUP                 = 118
	OP_NIP                 = 119
	OP_OVER                = 120
	OP_PICK                = 121
	OP_ROLL                = 122
	OP_ROT                 = 123
	OP_SWAP                = 124
	OP_TUCK                = 125
	OP_CAT                 = 126
	OP_SUBSTR              = 127
	OP_LEFT                = 128
	OP_RIGHT               = 129
	OP_SIZE                = 130
	OP_INVERT              = 131
	OP_AND                 = 132
	OP_OR                  = 133
	OP_XOR                 = 134
	OP_EQUAL               = 135
	OP_EQUALVERIFY         = 136
	OP_RESERVED1           = 137
	OP_RESERVED2           = 138
	OP_1ADD                = 139
	OP_1SUB                = 140
	OP_2MUL                = 141
	OP_2DIV                = 142
	OP_NEGATE              = 143
	OP_ABS                 = 144
	OP_NOT                 = 145
	OP_0NOTEQUAL           = 146
	OP_ADD                 = 147
	OP_SUB                 = 148
	OP_MUL                 = 149
	OP_DIV                 = 150
	OP_MOD                 = 151
	OP_LSHIFT              = 152
	OP_RSHIFT              = 153
	OP_BOOLAND             = 154
	OP_BOOLOR              = 155
	OP_NUMEQUAL            = 156
	OP_NUMEQUALVERIFY      = 157
	OP_NUMNOTEQUAL         = 158
	OP_LESSTHAN            = 159
	OP_GREATERTHAN         = 160
	OP_LESSTHANOREQUAL     = 161
	OP_GREATERTHANOREQUAL  = 162
	OP_MIN                 = 163
	OP_MAX                 = 164
	OP_WITHIN              = 165
	OP_RIPEMD160           = 166
	OP_SHA1                = 167
	OP_SHA256              = 168
	OP_HASH160             = 169
	OP_HASH256             = 170
	OP_CODESEPARATOR       = 171
	OP_CHECKSIG            = 172
	OP_CHECKSIGVERIFY      = 173
	OP_CHECKMULTISIG       = 174
	OP_CHECKMULTISIGVERIFY = 175
	OP_NOP1                = 176
	OP_NOP2                = 177
	OP_NOP3                = 178
	OP_NOP4                = 179
	OP_NOP5                = 180
	OP_NOP6                = 181
	OP_NOP7                = 182
	OP_NOP8                = 183
	OP_NOP9                = 184
	OP_NOP10               = 185
	OP_UNKNOWN186          = 186
	OP_UNKNOWN187          = 187
	OP_UNKNOWN188          = 188
	OP_UNKNOWN189          = 189
	OP_UNKNOWN190          = 190
	OP_UNKNOWN191          = 191
	OP_UNKNOWN192          = 192
	OP_UNKNOWN193          = 193
	OP_UNKNOWN194          = 194
	OP_UNKNOWN195          = 195
	OP_UNKNOWN196          = 196
	OP_UNKNOWN197          = 197
	OP_UNKNOWN198          = 198
	OP_UNKNOWN199          = 199
	OP_UNKNOWN200          = 200
	OP_UNKNOWN201          = 201
	OP_UNKNOWN202          = 202
	OP_UNKNOWN203          = 203
	OP_UNKNOWN204          = 204
	OP_UNKNOWN205          = 205
	OP_UNKNOWN206          = 206
	OP_UNKNOWN207          = 207
	OP_UNKNOWN208          = 208
	OP_UNKNOWN209          = 209
	OP_UNKNOWN210          = 210
	OP_UNKNOWN211          = 211
	OP_UNKNOWN212          = 212
	OP_UNKNOWN213          = 213
	OP_UNKNOWN214          = 214
	OP_UNKNOWN215          = 215
	OP_UNKNOWN216          = 216
	OP_UNKNOWN217          = 217
	OP_UNKNOWN218          = 218
	OP_UNKNOWN219          = 219
	OP_UNKNOWN220          = 220
	OP_UNKNOWN221          = 221
	OP_UNKNOWN222          = 222
	OP_UNKNOWN223          = 223
	OP_UNKNOWN224          = 224
	OP_UNKNOWN225          = 225
	OP_UNKNOWN226          = 226
	OP_UNKNOWN227          = 227
	OP_UNKNOWN228          = 228
	OP_UNKNOWN229          = 229
	OP_UNKNOWN230          = 230
	OP_UNKNOWN231          = 231
	OP_UNKNOWN232          = 232
	OP_UNKNOWN233          = 233
	OP_UNKNOWN234          = 234
	OP_UNKNOWN235          = 235
	OP_UNKNOWN236          = 236
	OP_UNKNOWN237          = 237
	OP_UNKNOWN238          = 238
	OP_UNKNOWN239          = 239
	OP_UNKNOWN240          = 240
	OP_UNKNOWN241          = 241
	OP_UNKNOWN242          = 242
	OP_UNKNOWN243          = 243
	OP_UNKNOWN244          = 244
	OP_UNKNOWN245          = 245
	OP_UNKNOWN246          = 246
	OP_UNKNOWN247          = 247
	OP_UNKNOWN248          = 248
	OP_UNKNOWN249          = 249
	OP_UNKNOWN250          = 250
	OP_UNKNOWN251          = 251
	OP_UNKNOWN252          = 252
	OP_PUBKEYHASH          = 253 // bitcoind internal, for completeness
	OP_PUBKEY              = 254 // bitcoind internal, for completeness
	OP_INVALIDOPCODE       = 255 // bitcoind internal, for completeness
)

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

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

conditional execution constants

View Source
const (
	SigHashOld          = 0x0
	SigHashAll          = 0x1
	SigHashNone         = 0x2
	SigHashSingle       = 0x3
	SigHashAnyOneCanPay = 0x80
)

Hash type bits from the end of a signature.

View Source
const (
	MaxOpsPerScript       = 201 // Max number of non-push operations.
	MaxPubKeysPerMultiSig = 20  // Multisig can't have more sigs than this.
	MaxScriptElementSize  = 520 // Max bytes pushable to the stack.
)

These are the constants specified for maximums in individual scripts.

Variables

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// StackErrEmpyStack 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.
	StackErrEmptyStack = errors.New("Stack empty at end of execution")

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

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

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

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

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

	// StackErrOverflow is returned when stack and altstack combined depth
	// is over the limit.
	StackErrOverflow = errors.New("Stacks overflowed")
)
View Source
var Bip16Activation = time.Unix(1333238400, 0)

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

View Source
var ErrBadNumRequired = errors.New("more signatures required than keys present")

ErrBadNumRequired is returned from MultiSigScript when nrequired is larger than the number of provided public keys.

View Source
var ErrUnsupportedAddress = errors.New("unsupported address type")

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

View Source
var ScriptClassToName = scriptClassToName

Map payment types to their names.

Functions

func CalcMultiSigStats

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

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

func CalcScriptHash

func CalcScriptHash(script []parsedOpcode, hashType byte, tx *btcwire.MsgTx, idx int) []byte

CalcScriptHash will, given the a script and hashtype for the current scriptmachine, calculate the doubleSha256 hash of the transaction and script to be used for signature signing and verification.

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

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

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

func GetPreciseSigOpCount

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

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

func GetSigOpCount

func GetSigOpCount(script []byte) int

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

func HasCanonicalPushes

func HasCanonicalPushes(script []byte) bool

HasCanonicalPushes returns whether or not the passed script only contains canonical data pushes. A canonical data push one where the fewest number of bytes possible to encode the size of the data being pushed is used. This includes using the small integer opcodes for single byte data that can be represented directly.

func IsPayToScriptHash

func IsPayToScriptHash(script []byte) bool

IsPayToScriptHash returns true if the script is in the standard Pay-To-Script-Hash format, false otherwise.

func IsPushOnlyScript

func IsPushOnlyScript(script []byte) bool

IsPushOnlyScript returns whether or not the passed script only pushes data. If the script does not parse false will be returned.

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

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

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

Example

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

package main

import (
	"fmt"

	"github.com/conformal/btcnet"
	"github.com/conformal/btcscript"
	"github.com/conformal/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, &btcnet.MainNetParams)
	if err != nil {
		fmt.Println(err)
		return
	}

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

	disasm, err := btcscript.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

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

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

func RemoveOpcodeByData

func RemoveOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode

RemoveOpcodeByData will return the pkscript minus any opcodes that would push the data in “data” to the stack.

func SetLogWriter

func SetLogWriter(w io.Writer, level string) error

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(net *btcnet.Params, tx *btcwire.MsgTx, idx int,
	pkScript []byte, hashType byte, 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 lookedu p 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.

func SignatureScript

func SignatureScript(tx *btcwire.MsgTx, idx int, subscript []byte, hashType byte, privKey *ecdsa.PrivateKey, compress bool) ([]byte, error)

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

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type KeyClosure

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

KeyClosure implements KeyDB with a closure

func (KeyClosure) GetKey

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

GetKey implements KeyDB by returning the result of calling the closure

type KeyDB

type KeyDB interface {
	GetKey(btcutil.Address) (*ecdsa.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 Script

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

Script is the virtual machine that executes btcscripts.

func NewScript

func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.MsgTx, flags ScriptFlags) (*Script, error)

NewScript returns a new script engine for the provided tx and input idx with a signature script scriptSig and a pubkeyscript scriptPubKey. If bip16 is true then it will be treated as if the bip16 threshhold has passed and thus pay-to-script hash transactions will be fully validated.

func (*Script) CheckErrorCondition

func (s *Script) CheckErrorCondition() (err error)

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

func (*Script) DisasmPC

func (m *Script) DisasmPC() (disstr string, err error)

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

func (*Script) DisasmScript

func (m *Script) DisasmScript(idx int) (disstr string, err error)

DisasmScript returns the disassembly string for the script at offset “idx”. Where 0 is the scriptSig and 1 is the scriptPubKey.

func (*Script) Execute

func (s *Script) Execute() (err error)

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

func (*Script) GetAltStack

func (s *Script) GetAltStack() [][]byte

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 (*Script) GetStack

func (s *Script) GetStack() [][]byte

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

func (*Script) Next

func (s *Script) Next() byte

Next will return the value of the next opcode to be executed

func (*Script) SetAltStack

func (s *Script) SetAltStack(data [][]byte)

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 (*Script) SetStack

func (s *Script) SetStack(data [][]byte)

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

func (*Script) Step

func (m *Script) Step() (done bool, err error)

Step will execute the next instruction and move the program counter to the next opcode in the script, or the next script if the curent has ended. Step will return true in the case that the last opcode was successfully executed. if an error is returned then the result of calling Step or any other method is undefined.

func (*Script) SubScript

func (s *Script) SubScript() []parsedOpcode

SubScript will return the script since the last OP_CODESEPARATOR

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. It does not ensure the script will execute correctly.

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 := btcscript.NewScriptBuilder()
builder.AddOp(btcscript.OP_2).AddData(pubKey1).AddData(pubKey2)
builder.AddData(pubKey3).AddOp(btcscript.OP_3)
builder.AddOp(btcscript.OP_CHECKMULTISIG)
fmt.Printf("Final multi-sig script: %x\n", builder.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.

func (*ScriptBuilder) AddInt64

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

AddInt64 pushes the passed integer to the end of the script.

func (*ScriptBuilder) AddOp

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

AddOp pushes the passed opcode to the end of the script.

func (*ScriptBuilder) AddUint64

func (b *ScriptBuilder) AddUint64(val uint64) *ScriptBuilder

AddUint64 pushes the passed integer to the end of the script.

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

Script returns the currently built script.

type ScriptClass

type ScriptClass byte

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

const (
	NonStandardTy ScriptClass = iota // None of the recognized forms.
	PubKeyTy                         // Pay pubkey.
	PubKeyHashTy                     // Pay pubkey hash.
	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, net *btcnet.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/conformal/btcnet"
	"github.com/conformal/btcscript"
)

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 := btcscript.ExtractPkScriptAddrs(
		script, &btcnet.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. If the script does not parse then NonStandardTy will be returned.

func (ScriptClass) String

func (t ScriptClass) String() string

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

type ScriptClosure

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

ScriptClosure implements ScriptDB with a closure

func (ScriptClosure) GetScript

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

GetScript implements ScriptDB by returning the result of calling the closure

type ScriptDB

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

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

type ScriptFlags

type ScriptFlags uint32

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

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

	// ScriptCanonicalSignatures defines whether additional canonical
	// signature checks are performed when parsing a signature.
	//
	// Canonical (DER) signatures are not required in the tx rules for
	// block acceptance, but are checked in recent versions of bitcoind
	// when accepting transactions to the mempool.  Non-canonical (valid
	// BER but not valid DER) transactions can potentially be changed
	// before mined into a block, either by adding extra padding or
	// flipping the sign of the R or S value in the signature, creating a
	// transaction that still validates and spends the inputs, but is not
	// recognized by creator of the transaction.  Performing a canonical
	// check enforces script signatures use a unique DER format.
	ScriptCanonicalSignatures

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

type ScriptInfo

type ScriptInfo struct {
	// The class of the sigscript, equivalent to calling GetScriptClass
	// on the sigScript.
	PkScriptClass ScriptClass
	// the number of inputs provided by the pkScript
	NumInputs int
	// the number of outputs required by sigScript and any
	// pay-to-script-hash scripts. The number will be -1 if unknown.
	ExpectedInputs int
	// The nubmer of signature operations in the scriptpair.
	SigOps int
}

func CalcScriptInfo

func CalcScriptInfo(sigscript, pkscript []byte, bip16 bool) (*ScriptInfo, error)

CalcScriptInfo returns a structure providing data about the scriptpair that are provided as arguments. 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 Stack

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

Stack represents a stack of immutable objects to be used with bitcoin scripts Objects may be shared, therefore in usage if a value is to be changed it *must* be deep-copied first to avoid changing other values on the stack.

func (*Stack) Depth

func (s *Stack) Depth() (sz int)

Depth returns the number of items on the stack.

func (*Stack) DropN

func (s *Stack) DropN(n int) error

DropN removes the top N items from the stack. e.g. DropN(1): 1,2,3 -> 1,2 DropN(2): 1,2,3 -> 1

func (*Stack) DupN

func (s *Stack) DupN(n int) error

DupN duplicates the top N items on the stack. e.g. DupN(1): 1,2,3 -> 1,2,3,3 DupN(2): 1,2,3 -> 1,2,3,2,3

func (*Stack) NipN

func (s *Stack) NipN(idx int) error

NipN removes the Nth object on the stack

func (*Stack) OverN

func (s *Stack) OverN(n int) error

OverN copies N items N spaces back to the top of the stack. e.g.: OverN(1): 1,2 -> 1,2,1 OverN(2): 1,2,3,4 -> 1,2,3,4,1,2

func (*Stack) PeekBool

func (s *Stack) PeekBool(idx int) (i bool, err error)

PeekBool returns the nth item on the stack as a bool without removing it.

func (*Stack) PeekByteArray

func (s *Stack) PeekByteArray(idx int) (so []byte, err error)

PeekByteArray returns the nth item on the stack without removing it.

func (*Stack) PeekInt

func (s *Stack) PeekInt(idx int) (i *big.Int, err error)

PeekInt returns the nth item on the stack as a bignum without removing it.

func (*Stack) PickN

func (s *Stack) PickN(n int) error

PickN copies the item N items back in the stack to the top. e.g.: PickN(1): 1,2,3 -> 1,2,3,2 PickN(2): 1,2,3 -> 1,2,3,1

func (*Stack) PopBool

func (s *Stack) PopBool() (bool, error)

PopBool pops the value off the top of the stack, converts it into a bool and returns it.

func (*Stack) PopByteArray

func (s *Stack) PopByteArray() ([]byte, error)

PopByteArray pops the value off the top of the stack and returns it.

func (*Stack) PopInt

func (s *Stack) PopInt() (*big.Int, error)

PopInt pops the value off the top of the stack, converts it into a bignum and returns it.

func (*Stack) PushBool

func (s *Stack) PushBool(val bool)

PushBool converts the provided boolean to a suitable byte array then pushes it onto the top of the stack.

func (*Stack) PushByteArray

func (s *Stack) PushByteArray(so []byte)

PushByteArray adds the given back array to the top of the stack.

func (*Stack) PushInt

func (s *Stack) PushInt(val *big.Int)

PushInt converts the provided bignum to a suitable byte array then pushes it onto the top of the stack.

func (*Stack) RollN

func (s *Stack) RollN(n int) error

RollN moves the item N items back in the stack to the top. e.g.: RollN(1): 1,2,3 -> 1,3,2 RollN(2): 1,2,3 -> 2,3,1

func (*Stack) RotN

func (s *Stack) RotN(n int) error

RotN rotates the top 3N items on the stack to the left e.g. RotN(1): 1,2,3 -> 2,3,1

func (*Stack) String

func (s *Stack) String() string

String returns the stack in a readable format.

func (*Stack) SwapN

func (s *Stack) SwapN(n int) error

SwapN swaps the top N items on the stack with those below them. E.g.: SwapN(1): 1,2 -> 2,1 SwapN(2): 1,2,3,4 -> 3,4,1,2

func (*Stack) Tuck

func (s *Stack) Tuck() error

Tuck copies the item at the top of the stack and inserts it before the 2nd to top item. e.g.: 2,1 -> 2,1,2

Jump to

Keyboard shortcuts

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