From 115cea21096b2e4464e2f5ae58f1d35cc9a5edcd Mon Sep 17 00:00:00 2001 From: David Hill Date: Thu, 29 Jan 2015 15:30:21 -0500 Subject: [PATCH] Add new flag ScriptVerifySigPushOnly. The ScriptVerifySigPushOnly flag enforces signature scripts to only contain pushed data. This is rule 2 of BIP0062. Mimics Bitcoin Core commit d752ba86c1872f64a4641cf77008826d32bde65f --- data/script_invalid.json | 22 ++++- data/script_valid.json | 16 +++- internal_test.go | 50 ++++++++--- script.go | 8 ++ test_coverage.txt | 180 +++++++++++++++++++-------------------- 5 files changed, 173 insertions(+), 103 deletions(-) diff --git a/data/script_invalid.json b/data/script_invalid.json index 3574b9d1..4f1d5543 100644 --- a/data/script_invalid.json +++ b/data/script_invalid.json @@ -389,5 +389,25 @@ ["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"], ["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"], -["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"] +["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], + +[ + "0 0x47 0x3044022035341cc377b19138f944f90c45772cb06338c6d56a4c0c31a65bf1a8a105fadc022046dd232850b6bacb25879c9da82a7a628982aa19d055f1753468f68047662e0301 DUP", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "SIGPUSHONLY", + "2-of-2 with two identical keys and sigs pushed using OP_DUP" +], +[ + "0x47 0x304402204d8b99eea2f53382fd67e0dbc8ed0596bd614aa0dad6bc6843c7860c79b901c3022062f022a71993013e3d9b22302a8e4b40109d7bb057aeb250b9aab2197b3e96b801 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "", + "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY" +], +[ + "0x47 0x30440220078c887c33abc67fbbd827ceb3f661c1c459e78218161b652f23e3ca76cfabbd022047df245eacb8a88d8c5ca7b5228e3b4d070c102d2f542433362d3f443cd24eda01 0x23 0x2103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640ac", + "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", + "SIGPUSHONLY", + "P2SH(P2PK) with non-push scriptSig" +] + ] diff --git a/data/script_valid.json b/data/script_valid.json index 473bd37b..db62b926 100644 --- a/data/script_valid.json +++ b/data/script_valid.json @@ -522,5 +522,19 @@ "P2SH,STRICTENC", "Basic PUSHDATA1 signedness check"], -["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"] +["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], + +[ + "0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 DUP", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "", + "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY" +], +[ + "0 0x47 0x304402203acf75dd59bbef171aeeedae4f1020b824195820db82575c2b323b8899f95de9022067df297d3a5fad049ba0bb81255d0e495643cbcf9abae9e396988618bc0c6dfe01 0x47 0x304402205f8b859230c1cab7d4e8de38ff244d2ebe046b64e8d3f4219b01e483c203490a022071bdc488e31b557f7d9e5c8a8bec90dc92289ca70fa317685f4f140e38b30c4601", + "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "SIGPUSHONLY", + "2-of-2 with two identical keys and sigs pushed" +] + ] diff --git a/internal_test.go b/internal_test.go index 4f74e1f1..fa2bf539 100644 --- a/internal_test.go +++ b/internal_test.go @@ -3796,6 +3796,32 @@ func ParseShortForm(script string) ([]byte, error) { return builder.Script() } +// createSpendTx generates a basic spending transaction given the passed +// signature and public key scripts. +func createSpendingTx(sigScript, pkScript []byte) (*btcwire.MsgTx, error) { + coinbaseTx := btcwire.NewMsgTx() + + outPoint := btcwire.NewOutPoint(&btcwire.ShaHash{}, ^uint32(0)) + txIn := btcwire.NewTxIn(outPoint, []byte{OP_0, OP_0}) + txOut := btcwire.NewTxOut(0, pkScript) + coinbaseTx.AddTxIn(txIn) + coinbaseTx.AddTxOut(txOut) + + spendingTx := btcwire.NewMsgTx() + coinbaseTxSha, err := coinbaseTx.TxSha() + if err != nil { + return nil, err + } + outPoint = btcwire.NewOutPoint(&coinbaseTxSha, 0) + txIn = btcwire.NewTxIn(outPoint, sigScript) + txOut = btcwire.NewTxOut(0, nil) + + spendingTx.AddTxIn(txIn) + spendingTx.AddTxOut(txOut) + + return spendingTx, nil +} + func TestBitcoindInvalidTests(t *testing.T) { file, err := ioutil.ReadFile("data/script_invalid.json") if err != nil { @@ -3810,7 +3836,6 @@ func TestBitcoindInvalidTests(t *testing.T) { err) return } - tx := btcwire.NewMsgTx() for x, test := range tests { // Skip comments if len(test) == 1 { @@ -3827,19 +3852,21 @@ func TestBitcoindInvalidTests(t *testing.T) { t.Errorf("%s: can't parse scriptSig; %v", name, err) continue } - scriptPubKey, err := ParseShortForm(test[1]) if err != nil { t.Errorf("%s: can't parse scriptPubkey; %v", name, err) continue } - flags, err := parseScriptFlags(test[2]) if err != nil { t.Errorf("%s: %v", name, err) continue } - + tx, err := createSpendingTx(scriptSig, scriptPubKey) + if err != nil { + t.Errorf("createSpendingTx failed on test %s: %v", name, err) + continue + } s, err := NewScript(scriptSig, scriptPubKey, 0, tx, flags) if err == nil { if err := s.Execute(); err == nil { @@ -3865,7 +3892,6 @@ func TestBitcoindValidTests(t *testing.T) { err) return } - tx := btcwire.NewMsgTx() for x, test := range tests { // Skip comments if len(test) == 1 { @@ -3877,31 +3903,31 @@ func TestBitcoindValidTests(t *testing.T) { x) continue } - scriptSig, err := ParseShortForm(test[0]) if err != nil { t.Errorf("%s: can't parse scriptSig; %v", name, err) continue } - scriptPubKey, err := ParseShortForm(test[1]) if err != nil { t.Errorf("%s: can't parse scriptPubkey; %v", name, err) continue } - flags, err := parseScriptFlags(test[2]) if err != nil { t.Errorf("%s: %v", name, err) continue } - + tx, err := createSpendingTx(scriptSig, scriptPubKey) + if err != nil { + t.Errorf("createSpendingTx failed on test %s: %v", name, err) + continue + } s, err := NewScript(scriptSig, scriptPubKey, 0, tx, flags) if err != nil { t.Errorf("%s failed to create script: %v", name, err) continue } - err = s.Execute() if err != nil { t.Errorf("%s failed to execute: %v", name, err) @@ -4205,12 +4231,14 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) { switch flag { case "DISCOURAGE_UPGRADABLE_NOPS": flags |= ScriptDiscourageUpgradableNops - case "NONE": + case "", "NONE": // Nothing. case "NULLDUMMY": flags |= ScriptStrictMultiSig case "P2SH": flags |= ScriptBip16 + case "SIGPUSHONLY": + flags |= ScriptVerifySigPushOnly case "STRICTENC": // This is always set. default: diff --git a/script.go b/script.go index 0a719e69..86d71ea9 100644 --- a/script.go +++ b/script.go @@ -522,6 +522,10 @@ const ( // checks. This flag is only applied when the above opcodes are // executed. ScriptDiscourageUpgradableNops + + // ScriptVerifySigPushOnly defines that signature scripts must contain + // only pushed data. This is rule 2 of BIP0062. + ScriptVerifySigPushOnly ) // NewScript returns a new script engine for the provided tx and input idx with @@ -530,6 +534,10 @@ const ( // pay-to-script hash transactions will be fully validated. func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.MsgTx, flags ScriptFlags) (*Script, error) { var m Script + if flags&ScriptVerifySigPushOnly == ScriptVerifySigPushOnly && !IsPushOnlyScript(scriptSig) { + return nil, ErrStackNonPushOnly + } + scripts := [][]byte{scriptSig, scriptPubKey} m.scripts = make([][]parsedOpcode, len(scripts)) for i, scr := range scripts { diff --git a/test_coverage.txt b/test_coverage.txt index cc8ff18e..972b97c8 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,67 +1,66 @@ github.com/btcsuite/btcscript/script.go calcScriptHash 100.00% (39/39) github.com/btcsuite/btcscript/script.go Script.Step 100.00% (37/37) -github.com/btcsuite/btcscript/script.go parseScriptTemplate 100.00% (29/29) github.com/btcsuite/btcscript/opcode.go opcodeCheckSig 100.00% (29/29) -github.com/btcsuite/btcscript/script.go NewScript 100.00% (27/27) +github.com/btcsuite/btcscript/script.go parseScriptTemplate 100.00% (29/29) +github.com/btcsuite/btcscript/script.go NewScript 100.00% (29/29) github.com/btcsuite/btcscript/address.go ExtractPkScriptAddrs 100.00% (27/27) github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.addData 100.00% (25/25) github.com/btcsuite/btcscript/script.go CalcScriptInfo 100.00% (25/25) -github.com/btcsuite/btcscript/stack.go asInt 100.00% (23/23) github.com/btcsuite/btcscript/opcode.go parsedOpcode.bytes 100.00% (23/23) +github.com/btcsuite/btcscript/stack.go asInt 100.00% (23/23) github.com/btcsuite/btcscript/opcode.go parsedOpcode.disabled 100.00% (17/17) github.com/btcsuite/btcscript/opcode.go parsedOpcode.print 100.00% (16/16) github.com/btcsuite/btcscript/stack.go Stack.nipN 100.00% (15/15) github.com/btcsuite/btcscript/scriptbuilder.go canonicalDataSize 100.00% (14/14) github.com/btcsuite/btcscript/stack.go fromInt 100.00% (14/14) -github.com/btcsuite/btcscript/opcode.go opcodeWithin 100.00% (13/13) github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddUint64 100.00% (13/13) -github.com/btcsuite/btcscript/opcode.go parsedOpcode.exec 100.00% (13/13) -github.com/btcsuite/btcscript/script.go isMultiSig 100.00% (13/13) -github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddInt64 100.00% (13/13) github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddData 100.00% (13/13) +github.com/btcsuite/btcscript/script.go isMultiSig 100.00% (13/13) +github.com/btcsuite/btcscript/opcode.go opcodeWithin 100.00% (13/13) +github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddInt64 100.00% (13/13) +github.com/btcsuite/btcscript/opcode.go parsedOpcode.exec 100.00% (13/13) github.com/btcsuite/btcscript/script.go GetPreciseSigOpCount 100.00% (13/13) -github.com/btcsuite/btcscript/opcode.go opcodeNotIf 100.00% (11/11) -github.com/btcsuite/btcscript/script.go typeOfScript 100.00% (11/11) github.com/btcsuite/btcscript/opcode.go opcodeIf 100.00% (11/11) +github.com/btcsuite/btcscript/opcode.go opcodeNotIf 100.00% (11/11) github.com/btcsuite/btcscript/script.go PayToAddrScript 100.00% (11/11) -github.com/btcsuite/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10) +github.com/btcsuite/btcscript/script.go typeOfScript 100.00% (11/11) +github.com/btcsuite/btcscript/opcode.go opcodeMax 100.00% (10/10) +github.com/btcsuite/btcscript/opcode.go opcodeLessThan 100.00% (10/10) +github.com/btcsuite/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10) +github.com/btcsuite/btcscript/log.go SetLogWriter 100.00% (10/10) github.com/btcsuite/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10) -github.com/btcsuite/btcscript/script.go PushedData 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) github.com/btcsuite/btcscript/opcode.go opcodeMin 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10) +github.com/btcsuite/btcscript/opcode.go opcodeBoolOr 100.00% (10/10) +github.com/btcsuite/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10) github.com/btcsuite/btcscript/stack.go Stack.Tuck 100.00% (10/10) github.com/btcsuite/btcscript/script.go getSigOpCount 100.00% (10/10) -github.com/btcsuite/btcscript/log.go SetLogWriter 100.00% (10/10) +github.com/btcsuite/btcscript/script.go PushedData 100.00% (10/10) github.com/btcsuite/btcscript/opcode.go opcodeNumEqual 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeMax 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeBoolOr 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10) -github.com/btcsuite/btcscript/opcode.go opcodeLessThan 100.00% (10/10) -github.com/btcsuite/btcscript/script.go DisasmString 100.00% (9/9) +github.com/btcsuite/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10) +github.com/btcsuite/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) +github.com/btcsuite/btcscript/stack.go Stack.RotN 100.00% (9/9) +github.com/btcsuite/btcscript/script.go SignatureScript 100.00% (9/9) github.com/btcsuite/btcscript/stack.go Stack.OverN 100.00% (9/9) github.com/btcsuite/btcscript/stack.go Stack.SwapN 100.00% (9/9) -github.com/btcsuite/btcscript/script.go SignatureScript 100.00% (9/9) -github.com/btcsuite/btcscript/stack.go Stack.RotN 100.00% (9/9) +github.com/btcsuite/btcscript/script.go DisasmString 100.00% (9/9) github.com/btcsuite/btcscript/script.go Script.CheckErrorCondition 100.00% (9/9) github.com/btcsuite/btcscript/script.go Script.Execute 100.00% (8/8) -github.com/btcsuite/btcscript/opcode.go opcodeEqual 100.00% (8/8) -github.com/btcsuite/btcscript/script.go MultiSigScript 100.00% (8/8) +github.com/btcsuite/btcscript/stack.go Stack.DupN 100.00% (8/8) github.com/btcsuite/btcscript/script.go CalcMultiSigStats 100.00% (8/8) github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddOp 100.00% (8/8) github.com/btcsuite/btcscript/opcode.go opcodeAdd 100.00% (8/8) github.com/btcsuite/btcscript/opcode.go opcodeSub 100.00% (8/8) -github.com/btcsuite/btcscript/stack.go Stack.DupN 100.00% (8/8) +github.com/btcsuite/btcscript/opcode.go opcodeEqual 100.00% (8/8) +github.com/btcsuite/btcscript/script.go MultiSigScript 100.00% (8/8) +github.com/btcsuite/btcscript/opcode.go opcode0NotEqual 100.00% (7/7) github.com/btcsuite/btcscript/opcode.go opcodeNot 100.00% (7/7) github.com/btcsuite/btcscript/stack.go Stack.DropN 100.00% (7/7) -github.com/btcsuite/btcscript/opcode.go opcodeNop 100.00% (7/7) -github.com/btcsuite/btcscript/opcode.go opcode0NotEqual 100.00% (7/7) github.com/btcsuite/btcscript/script.go HasCanonicalPushes 100.00% (7/7) -github.com/btcsuite/btcscript/opcode.go opcodeElse 100.00% (6/6) -github.com/btcsuite/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6) -github.com/btcsuite/btcscript/opcode.go opcodeIfDup 100.00% (6/6) github.com/btcsuite/btcscript/opcode.go opcodeVerify 100.00% (6/6) +github.com/btcsuite/btcscript/opcode.go opcodeIfDup 100.00% (6/6) +github.com/btcsuite/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6) +github.com/btcsuite/btcscript/opcode.go opcodeElse 100.00% (6/6) github.com/btcsuite/btcscript/opcode.go opcodeEndif 100.00% (6/6) github.com/btcsuite/btcscript/script.go removeOpcode 100.00% (5/5) github.com/btcsuite/btcscript/opcode.go opcodeToAltStack 100.00% (5/5) @@ -83,87 +82,88 @@ github.com/btcsuite/btcscript/script.go Script.DisasmScript 100.00% (5/5) github.com/btcsuite/btcscript/script.go removeOpcodeByData 100.00% (5/5) github.com/btcsuite/btcscript/stack.go Stack.PickN 100.00% (5/5) github.com/btcsuite/btcscript/stack.go Stack.RollN 100.00% (5/5) -github.com/btcsuite/btcscript/script.go Script.curPC 100.00% (4/4) github.com/btcsuite/btcscript/opcode.go opcodeCheckMultiSigVerify 100.00% (4/4) -github.com/btcsuite/btcscript/opcode.go opcodeCheckSigVerify 100.00% (4/4) -github.com/btcsuite/btcscript/opcode.go parsedOpcode.alwaysIllegal 100.00% (4/4) github.com/btcsuite/btcscript/script.go IsPayToScriptHash 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go Stack.PeekBool 100.00% (4/4) github.com/btcsuite/btcscript/script.go isNullData 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go Stack.PeekInt 100.00% (4/4) github.com/btcsuite/btcscript/script.go IsPushOnlyScript 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go Stack.PeekByteArray 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go Stack.PopBool 100.00% (4/4) -github.com/btcsuite/btcscript/script.go GetScriptClass 100.00% (4/4) github.com/btcsuite/btcscript/opcode.go opcodeNumEqualVerify 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go Stack.PopInt 100.00% (4/4) +github.com/btcsuite/btcscript/script.go GetScriptClass 100.00% (4/4) github.com/btcsuite/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4) -github.com/btcsuite/btcscript/stack.go asBool 100.00% (4/4) -github.com/btcsuite/btcscript/script.go getStack 100.00% (4/4) -github.com/btcsuite/btcscript/script.go @1338:17 100.00% (4/4) -github.com/btcsuite/btcscript/script.go isPushOnly 100.00% (4/4) github.com/btcsuite/btcscript/script.go Script.DisasmPC 100.00% (4/4) -github.com/btcsuite/btcscript/script.go ScriptClass.String 100.00% (3/3) -github.com/btcsuite/btcscript/script.go setStack 100.00% (3/3) -github.com/btcsuite/btcscript/script.go isSmallInt 100.00% (3/3) +github.com/btcsuite/btcscript/script.go isPushOnly 100.00% (4/4) +github.com/btcsuite/btcscript/script.go @1346:17 100.00% (4/4) +github.com/btcsuite/btcscript/script.go getStack 100.00% (4/4) +github.com/btcsuite/btcscript/script.go Script.curPC 100.00% (4/4) +github.com/btcsuite/btcscript/opcode.go opcodeNop 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go asBool 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go Stack.PopInt 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go Stack.PopBool 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go Stack.PeekByteArray 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go Stack.PeekInt 100.00% (4/4) +github.com/btcsuite/btcscript/stack.go Stack.PeekBool 100.00% (4/4) +github.com/btcsuite/btcscript/opcode.go parsedOpcode.alwaysIllegal 100.00% (4/4) +github.com/btcsuite/btcscript/opcode.go opcodeCheckSigVerify 100.00% (4/4) github.com/btcsuite/btcscript/script.go asSmallInt 100.00% (3/3) -github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddFullData 100.00% (3/3) -github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.Reset 100.00% (3/3) +github.com/btcsuite/btcscript/script.go ScriptClass.String 100.00% (3/3) github.com/btcsuite/btcscript/stack.go fromBool 100.00% (3/3) -github.com/btcsuite/btcscript/stack.go Stack.NipN 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go calcHash 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go opcodeFalse 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go opcodePushData 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go opcode1Negate 100.00% (2/2) -github.com/btcsuite/btcscript/script.go GetSigOpCount 100.00% (2/2) -github.com/btcsuite/btcscript/stack.go Stack.Depth 100.00% (2/2) -github.com/btcsuite/btcscript/opcode.go opcodeDepth 100.00% (2/2) +github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.Reset 100.00% (3/3) +github.com/btcsuite/btcscript/script.go isSmallInt 100.00% (3/3) +github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.AddFullData 100.00% (3/3) +github.com/btcsuite/btcscript/script.go setStack 100.00% (3/3) github.com/btcsuite/btcscript/opcode.go opcodeN 100.00% (2/2) -github.com/btcsuite/btcscript/script.go Script.SetAltStack 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeDrop 100.00% (1/1) -github.com/btcsuite/btcscript/script.go payToPubKeyHashScript 100.00% (1/1) -github.com/btcsuite/btcscript/script.go payToScriptHashScript 100.00% (1/1) -github.com/btcsuite/btcscript/script.go payToPubKeyScript 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcode2Swap 100.00% (1/1) +github.com/btcsuite/btcscript/stack.go Stack.Depth 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go calcHash 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go opcode1Negate 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2) +github.com/btcsuite/btcscript/stack.go Stack.NipN 100.00% (2/2) +github.com/btcsuite/btcscript/script.go GetSigOpCount 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go opcodeFalse 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go opcodeDepth 100.00% (2/2) +github.com/btcsuite/btcscript/opcode.go opcodePushData 100.00% (2/2) github.com/btcsuite/btcscript/opcode.go opcode2Rot 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcode2Over 100.00% (1/1) -github.com/btcsuite/btcscript/scriptbuilder.go ErrScriptNotCanonical.Error 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcode3Dup 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go init 100.00% (1/1) github.com/btcsuite/btcscript/script.go KeyClosure.GetKey 100.00% (1/1) github.com/btcsuite/btcscript/script.go ScriptClosure.GetScript 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcode2Dup 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeOver 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeNip 100.00% (1/1) +github.com/btcsuite/btcscript/log.go DisableLog 100.00% (1/1) +github.com/btcsuite/btcscript/log.go init 100.00% (1/1) github.com/btcsuite/btcscript/script.go Script.disasm 100.00% (1/1) github.com/btcsuite/btcscript/script.go Script.subScript 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeSwap 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeNip 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcode2Drop 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcodeDup 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeTuck 100.00% (1/1) -github.com/btcsuite/btcscript/log.go UseLogger 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeDrop 100.00% (1/1) github.com/btcsuite/btcscript/script.go Script.GetStack 100.00% (1/1) github.com/btcsuite/btcscript/script.go Script.SetStack 100.00% (1/1) github.com/btcsuite/btcscript/script.go Script.GetAltStack 100.00% (1/1) +github.com/btcsuite/btcscript/script.go Script.SetAltStack 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcode2Swap 100.00% (1/1) +github.com/btcsuite/btcscript/script.go payToPubKeyHashScript 100.00% (1/1) +github.com/btcsuite/btcscript/script.go payToScriptHashScript 100.00% (1/1) +github.com/btcsuite/btcscript/script.go payToPubKeyScript 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcodeInvalid 100.00% (1/1) -github.com/btcsuite/btcscript/script.go isPubkey 100.00% (1/1) +github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.Script 100.00% (1/1) github.com/btcsuite/btcscript/scriptbuilder.go NewScriptBuilder 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcodeReserved 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcode2Dup 100.00% (1/1) -github.com/btcsuite/btcscript/stack.go Stack.PushByteArray 100.00% (1/1) -github.com/btcsuite/btcscript/stack.go Stack.PushInt 100.00% (1/1) -github.com/btcsuite/btcscript/stack.go Stack.PopByteArray 100.00% (1/1) -github.com/btcsuite/btcscript/script.go parseScript 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go calcHash160 100.00% (1/1) -github.com/btcsuite/btcscript/script.go isScriptHash 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go init 100.00% (1/1) github.com/btcsuite/btcscript/log.go newLogClosure 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeOver 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcodeRot 100.00% (1/1) -github.com/btcsuite/btcscript/log.go DisableLog 100.00% (1/1) -github.com/btcsuite/btcscript/log.go init 100.00% (1/1) -github.com/btcsuite/btcscript/stack.go Stack.PushBool 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcode3Dup 100.00% (1/1) +github.com/btcsuite/btcscript/stack.go Stack.PushByteArray 100.00% (1/1) github.com/btcsuite/btcscript/script.go isPubkeyHash 100.00% (1/1) -github.com/btcsuite/btcscript/opcode.go opcode2Drop 100.00% (1/1) -github.com/btcsuite/btcscript/scriptbuilder.go ScriptBuilder.Script 100.00% (1/1) +github.com/btcsuite/btcscript/script.go isScriptHash 100.00% (1/1) +github.com/btcsuite/btcscript/stack.go Stack.PushInt 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go calcHash160 100.00% (1/1) +github.com/btcsuite/btcscript/stack.go Stack.PushBool 100.00% (1/1) +github.com/btcsuite/btcscript/stack.go Stack.PopByteArray 100.00% (1/1) +github.com/btcsuite/btcscript/script.go isPubkey 100.00% (1/1) +github.com/btcsuite/btcscript/log.go UseLogger 100.00% (1/1) +github.com/btcsuite/btcscript/script.go parseScript 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeTuck 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeSwap 100.00% (1/1) +github.com/btcsuite/btcscript/opcode.go opcodeRot 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcodeReturn 100.00% (1/1) +github.com/btcsuite/btcscript/scriptbuilder.go ErrScriptNotCanonical.Error 100.00% (1/1) github.com/btcsuite/btcscript/opcode.go opcodeCheckMultiSig 98.48% (65/66) github.com/btcsuite/btcscript/script.go mergeScripts 95.24% (20/21) github.com/btcsuite/btcscript/script.go signMultiSig 93.33% (14/15) @@ -175,12 +175,12 @@ github.com/btcsuite/btcscript/script.go unparseScript 85.71% (6/7) github.com/btcsuite/btcscript/script.go SignTxOutput 80.00% (12/15) github.com/btcsuite/btcscript/script.go p2pkSignatureScript 75.00% (3/4) github.com/btcsuite/btcscript/script.go sign 69.23% (18/26) -github.com/btcsuite/btcscript/script.go @598:34 0.00% (0/6) -github.com/btcsuite/btcscript/script.go @586:34 0.00% (0/4) +github.com/btcsuite/btcscript/script.go @606:34 0.00% (0/6) +github.com/btcsuite/btcscript/script.go @594:34 0.00% (0/4) github.com/btcsuite/btcscript/stack.go Stack.String 0.00% (0/4) -github.com/btcsuite/btcscript/script.go @631:34 0.00% (0/3) -github.com/btcsuite/btcscript/log.go logClosure.String 0.00% (0/1) -github.com/btcsuite/btcscript/opcode.go @1815:33 0.00% (0/1) +github.com/btcsuite/btcscript/script.go @639:34 0.00% (0/3) github.com/btcsuite/btcscript/opcode.go opcodeDisabled 0.00% (0/1) -github.com/btcsuite/btcscript --------------------------- 96.69% (1285/1329) +github.com/btcsuite/btcscript/log.go logClosure.String 0.00% (0/1) +github.com/btcsuite/btcscript/opcode.go @1810:33 0.00% (0/1) +github.com/btcsuite/btcscript --------------------------- 96.69% (1284/1328)