From 88f3c73ad1c2501386cf90942d6c1ea5e3727870 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Fri, 21 Feb 2014 00:20:24 +0000 Subject: [PATCH] Add MultiSigScript to provide a canonical script for a multisig transaction. --- script.go | 23 +++++++ script_test.go | 148 +++++++++++++++++++++++++++++++++++++++++++ scriptbuilder.go | 3 +- test_coverage.txt | 157 +++++++++++++++++++++++----------------------- 4 files changed, 252 insertions(+), 79 deletions(-) diff --git a/script.go b/script.go index 0ab0b36d..469a7962 100644 --- a/script.go +++ b/script.go @@ -1050,6 +1050,29 @@ func PayToAddrScript(addr btcutil.Address) ([]byte, error) { return nil, ErrUnsupportedAddress } +// ErrBadNumRequired is returned from MultiSigScript when nrequired is larger +// than the number of provided public keys. +var ErrBadNumRequired = errors.New("more signatures required than keys present") + +// 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 MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error) { + if len(pubkeys) < nrequired { + return nil, ErrBadNumRequired + } + + builder := NewScriptBuilder().AddInt64(int64(nrequired)) + for _, key := range pubkeys { + builder.AddData(key.ScriptAddress()) + } + builder.AddInt64(int64(len(pubkeys))) + builder.AddOp(OP_CHECKMULTISIG) + + return builder.Script(), nil +} + // 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 diff --git a/script_test.go b/script_test.go index 003818a8..0b59070c 100644 --- a/script_test.go +++ b/script_test.go @@ -3016,3 +3016,151 @@ func TestPayToAddrScript(t *testing.T) { } } } + +func TestMultiSigScript(t *testing.T) { + // mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg + p2pkCompressedMain, err := btcutil.NewAddressPubKey([]byte{ + 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94 , 0x34, 0x4c, 0x95, + 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, 0x3d , 0x8d, 0x79, 0x03, + 0xc3, 0xeb, 0xec, 0x3a, 0x95, 0x77, 0x24 , 0x89, 0x5d, 0xca, + 0x52, 0xc6, 0xb4}, btcwire.MainNet) + if err != nil { + t.Errorf("Unable to create pubkey address (compressed): %v", + err) + return + } + p2pkCompressed2Main, err := btcutil.NewAddressPubKey([]byte{ + 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, + 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, 0x61, 0xcf, 0x43, 0xe0, + 0x01, 0xf9, 0x13, 0x7f, 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, + 0xb1, 0x6e, 0x65}, btcwire.MainNet) + if err != nil { + t.Errorf("Unable to create pubkey address (compressed 2): %v", + err) + return + } + + p2pkUncompressedMain, err := btcutil.NewAddressPubKey([]byte{ + 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, + 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e, 0xb6, 0x8a, 0x38, + 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, + 0x90, 0x9a, 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, + 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, + 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, + 0xf6, 0x56, 0xb4, 0x12, 0xa3}, btcwire.MainNet) + if err != nil { + t.Errorf("Unable to create pubkey address (uncompressed): %v", + err) + return + } + + tests := []struct { + keys []*btcutil.AddressPubKey + nrequired int + expected []byte + err error + }{ + { + []*btcutil.AddressPubKey{ + p2pkCompressedMain, + p2pkCompressed2Main, + }, + 1, + []byte{ + btcscript.OP_1, + btcscript.OP_DATA_33, + 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, + 0x4c, 0x95, 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, + 0x3d, 0x8d, 0x79, 0x03, 0xc3, 0xeb, 0xec, 0x3a, + 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 0x52, 0xc6, + 0xb4, + btcscript.OP_DATA_33, + 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, + 0x1b, 0xa1, 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, + 0x61, 0xcf, 0x43, 0xe0, 0x01, 0xf9, 0x13, 0x7f, + 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 0xb1, 0x6e, + 0x65, + btcscript.OP_2, btcscript.OP_CHECKMULTISIG, + }, + nil, + }, + { + []*btcutil.AddressPubKey{ + p2pkCompressedMain, + p2pkCompressed2Main, + }, + 2, + []byte{ + btcscript.OP_2, + btcscript.OP_DATA_33, + 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, + 0x4c, 0x95, 0x69, 0xc2, 0xe7, 0x79, 0x01, 0x57, + 0x3d, 0x8d, 0x79, 0x03, 0xc3, 0xeb, 0xec, 0x3a, + 0x95, 0x77, 0x24, 0x89, 0x5d, 0xca, 0x52, 0xc6, + 0xb4, + btcscript.OP_DATA_33, + 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, + 0x1b, 0xa1, 0xe9, 0x86, 0xe8, 0x84, 0x18, 0x5c, + 0x61, 0xcf, 0x43, 0xe0, 0x01, 0xf9, 0x13, 0x7f, + 0x23, 0xc2, 0xc4, 0x09, 0x27, 0x3e, 0xb1, 0x6e, + 0x65, + btcscript.OP_2, btcscript.OP_CHECKMULTISIG, + }, + nil, + }, + { + []*btcutil.AddressPubKey{ + p2pkCompressedMain, + p2pkCompressed2Main, + }, + 3, + []byte{}, + btcscript.ErrBadNumRequired, + }, + { + []*btcutil.AddressPubKey{ + p2pkUncompressedMain, + }, + 1, + []byte{ + btcscript.OP_1, btcscript.OP_DATA_65, + 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, + 0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, + 0x1e, 0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, + 0x2e, 0xca, 0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, + 0x5c, 0xb2, 0xe0, 0xea, 0xdd, 0xfb, 0x84, 0xcc, + 0xf9, 0x74, 0x44, 0x64, 0xf8, 0x2e, 0x16, 0x0b, + 0xfa, 0x9b, 0x8b, 0x64, 0xf9, 0xd4, 0xc0, 0x3f, + 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56, 0xb4, 0x12, + 0xa3, + btcscript.OP_1, btcscript.OP_CHECKMULTISIG, + }, + nil, + }, + { + []*btcutil.AddressPubKey{ + p2pkUncompressedMain, + }, + 2, + []byte{}, + btcscript.ErrBadNumRequired, + }, + } + + t.Logf("Running %d tests", len(tests)) + for i, test := range tests { + script, err := btcscript.MultiSigScript(test.keys, + test.nrequired) + if err != test.err { + t.Errorf("MultiSigScript #%d unexpected error - "+ + "got %v, want %v", i, err, test.err) + continue + } + + if !bytes.Equal(script, test.expected) { + t.Errorf("MultiSigScript #%d got: %x\nwant: %x", + i, script, test.expected) + continue + } + } +} diff --git a/scriptbuilder.go b/scriptbuilder.go index b623dde3..c20a0446 100644 --- a/scriptbuilder.go +++ b/scriptbuilder.go @@ -23,7 +23,8 @@ const ( // 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: +// 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) diff --git a/test_coverage.txt b/test_coverage.txt index c74cda29..5e3c2c9d 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -9,148 +9,149 @@ github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (23/23) github.com/conformal/btcscript/stack.go asInt 100.00% (21/21) github.com/conformal/btcscript/script.go NewScript 100.00% (21/21) github.com/conformal/btcscript/opcode.go parsedOpcode.print 100.00% (16/16) -github.com/conformal/btcscript/script.go signatureScriptCustomReader 100.00% (15/15) github.com/conformal/btcscript/stack.go Stack.nipN 100.00% (15/15) +github.com/conformal/btcscript/script.go signatureScriptCustomReader 100.00% (15/15) github.com/conformal/btcscript/stack.go fromInt 100.00% (14/14) +github.com/conformal/btcscript/script.go isMultiSig 100.00% (13/13) github.com/conformal/btcscript/opcode.go opcodeWithin 100.00% (13/13) github.com/conformal/btcscript/script.go GetPreciseSigOpCount 100.00% (13/13) -github.com/conformal/btcscript/script.go isMultiSig 100.00% (13/13) -github.com/conformal/btcscript/script.go Script.CheckErrorCondition 100.00% (11/11) github.com/conformal/btcscript/script.go PayToAddrScript 100.00% (11/11) -github.com/conformal/btcscript/script.go typeOfScript 100.00% (11/11) -github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11) +github.com/conformal/btcscript/script.go Script.CheckErrorCondition 100.00% (11/11) github.com/conformal/btcscript/opcode.go opcodeNotIf 100.00% (11/11) -github.com/conformal/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeBoolOr 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeNumEqual 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) -github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11) +github.com/conformal/btcscript/script.go typeOfScript 100.00% (11/11) github.com/conformal/btcscript/opcode.go opcodeMin 100.00% (10/10) github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeBoolOr 100.00% (10/10) github.com/conformal/btcscript/script.go getSigOpCount 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeNumEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10) github.com/conformal/btcscript/stack.go Stack.Tuck 100.00% (10/10) -github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9) +github.com/conformal/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10) +github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10) github.com/conformal/btcscript/stack.go Stack.RotN 100.00% (9/9) github.com/conformal/btcscript/stack.go Stack.OverN 100.00% (9/9) github.com/conformal/btcscript/stack.go Stack.SwapN 100.00% (9/9) -github.com/conformal/btcscript/opcode.go opcodeEqual 100.00% (8/8) -github.com/conformal/btcscript/script.go Script.Execute 100.00% (8/8) -github.com/conformal/btcscript/stack.go Stack.DupN 100.00% (8/8) +github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9) github.com/conformal/btcscript/opcode.go opcodeAdd 100.00% (8/8) +github.com/conformal/btcscript/script.go Script.Execute 100.00% (8/8) +github.com/conformal/btcscript/script.go MultiSigScript 100.00% (8/8) +github.com/conformal/btcscript/stack.go Stack.DupN 100.00% (8/8) +github.com/conformal/btcscript/opcode.go opcodeEqual 100.00% (8/8) github.com/conformal/btcscript/opcode.go opcodeSub 100.00% (8/8) github.com/conformal/btcscript/stack.go Stack.DropN 100.00% (7/7) -github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.AddInt64 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodeNot 100.00% (7/7) github.com/conformal/btcscript/opcode.go opcode0NotEqual 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7) +github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.AddInt64 100.00% (7/7) github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.AddUint64 100.00% (7/7) -github.com/conformal/btcscript/opcode.go opcodeElse 100.00% (6/6) +github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7) +github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7) +github.com/conformal/btcscript/opcode.go opcodeNot 100.00% (7/7) github.com/conformal/btcscript/opcode.go opcodeEndif 100.00% (6/6) -github.com/conformal/btcscript/opcode.go opcodeIfDup 100.00% (6/6) github.com/conformal/btcscript/opcode.go opcodeVerify 100.00% (6/6) +github.com/conformal/btcscript/opcode.go opcodeIfDup 100.00% (6/6) +github.com/conformal/btcscript/opcode.go opcodeElse 100.00% (6/6) github.com/conformal/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6) +github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5) +github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeToAltStack 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeFromAltStack 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcode1Add 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcode1Sub 100.00% (5/5) +github.com/conformal/btcscript/opcode.go opcodeNegate 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeAbs 100.00% (5/5) -github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5) -github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5) -github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5) -github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeRipemd160 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeSha1 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeSha256 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeHash160 100.00% (5/5) github.com/conformal/btcscript/opcode.go opcodeHash256 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeFromAltStack 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeToAltStack 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcode1Add 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcode1Sub 100.00% (5/5) -github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5) -github.com/conformal/btcscript/opcode.go opcodeNegate 100.00% (5/5) -github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5) github.com/conformal/btcscript/script.go Script.DisasmScript 100.00% (5/5) -github.com/conformal/btcscript/stack.go Stack.PeekInt 100.00% (4/4) +github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5) +github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5) +github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5) +github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5) +github.com/conformal/btcscript/script.go isPushOnly 100.00% (4/4) +github.com/conformal/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4) +github.com/conformal/btcscript/opcode.go opcodeNumEqualVerify 100.00% (4/4) github.com/conformal/btcscript/script.go getStack 100.00% (4/4) github.com/conformal/btcscript/script.go GetScriptClass 100.00% (4/4) -github.com/conformal/btcscript/stack.go Stack.PopInt 100.00% (4/4) -github.com/conformal/btcscript/script.go Script.DisasmPC 100.00% (4/4) -github.com/conformal/btcscript/opcode.go opcodeNumEqualVerify 100.00% (4/4) -github.com/conformal/btcscript/stack.go asBool 100.00% (4/4) github.com/conformal/btcscript/opcode.go opcodeCheckMultiSigVerify 100.00% (4/4) -github.com/conformal/btcscript/stack.go Stack.PopBool 100.00% (4/4) github.com/conformal/btcscript/stack.go Stack.PeekBool 100.00% (4/4) +github.com/conformal/btcscript/stack.go asBool 100.00% (4/4) +github.com/conformal/btcscript/stack.go Stack.PeekInt 100.00% (4/4) +github.com/conformal/btcscript/stack.go Stack.PeekByteArray 100.00% (4/4) +github.com/conformal/btcscript/stack.go Stack.PopBool 100.00% (4/4) github.com/conformal/btcscript/opcode.go opcodePushData 100.00% (4/4) github.com/conformal/btcscript/script.go Script.curPC 100.00% (4/4) -github.com/conformal/btcscript/stack.go Stack.PeekByteArray 100.00% (4/4) github.com/conformal/btcscript/script.go IsPayToScriptHash 100.00% (4/4) -github.com/conformal/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4) +github.com/conformal/btcscript/stack.go Stack.PopInt 100.00% (4/4) +github.com/conformal/btcscript/script.go Script.DisasmPC 100.00% (4/4) github.com/conformal/btcscript/script.go isNullData 100.00% (4/4) -github.com/conformal/btcscript/script.go isPushOnly 100.00% (4/4) github.com/conformal/btcscript/script.go scriptUInt8 100.00% (3/3) +github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3) github.com/conformal/btcscript/script.go ScriptClass.String 100.00% (3/3) github.com/conformal/btcscript/script.go isSmallInt 100.00% (3/3) github.com/conformal/btcscript/script.go scriptUInt32 100.00% (3/3) github.com/conformal/btcscript/script.go asSmallInt 100.00% (3/3) github.com/conformal/btcscript/stack.go fromBool 100.00% (3/3) github.com/conformal/btcscript/script.go setStack 100.00% (3/3) -github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3) -github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2) -github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2) github.com/conformal/btcscript/script.go GetSigOpCount 100.00% (2/2) -github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2) -github.com/conformal/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2) -github.com/conformal/btcscript/opcode.go opcodeN 100.00% (2/2) -github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2) github.com/conformal/btcscript/opcode.go opcodeFalse 100.00% (2/2) -github.com/conformal/btcscript/opcode.go opcode1Negate 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2) +github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2) github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.AddOp 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcode1Negate 100.00% (2/2) +github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2) +github.com/conformal/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2) +github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2) github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.Reset 100.00% (2/2) -github.com/conformal/btcscript/script.go isPubkeyHash 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDup 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeNip 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeOver 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeSwap 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeTuck 100.00% (1/1) -github.com/conformal/btcscript/log.go init 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode2Swap 100.00% (1/1) -github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1) -github.com/conformal/btcscript/script.go isScriptHash 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1) -github.com/conformal/btcscript/script.go parseScript 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeN 100.00% (2/2) github.com/conformal/btcscript/opcode.go opcodeReserved 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1) github.com/conformal/btcscript/script.go isPubkey 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeOver 100.00% (1/1) +github.com/conformal/btcscript/script.go isScriptHash 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeNip 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDup 100.00% (1/1) +github.com/conformal/btcscript/script.go parseScript 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode2Swap 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode2Rot 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode2Over 100.00% (1/1) +github.com/conformal/btcscript/script.go isPubkeyHash 100.00% (1/1) github.com/conformal/btcscript/script.go Script.disasm 100.00% (1/1) github.com/conformal/btcscript/script.go Script.subScript 100.00% (1/1) +github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcscript/log.go init 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode3Dup 100.00% (1/1) github.com/conformal/btcscript/script.go Script.GetStack 100.00% (1/1) github.com/conformal/btcscript/script.go Script.SetStack 100.00% (1/1) github.com/conformal/btcscript/script.go Script.GetAltStack 100.00% (1/1) github.com/conformal/btcscript/script.go Script.SetAltStack 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode2Dup 100.00% (1/1) github.com/conformal/btcscript/script.go payToPubKeyHashScript 100.00% (1/1) github.com/conformal/btcscript/script.go payToScriptHashScript 100.00% (1/1) github.com/conformal/btcscript/script.go payToPubKeyScript 100.00% (1/1) -github.com/conformal/btcscript/opcode.go init 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcode2Drop 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeReturn 100.00% (1/1) github.com/conformal/btcscript/script.go SignatureScript 100.00% (1/1) -github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode2Rot 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1) github.com/conformal/btcscript/scriptbuilder.go ScriptBuilder.Script 100.00% (1/1) github.com/conformal/btcscript/scriptbuilder.go NewScriptBuilder 100.00% (1/1) -github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PushByteArray 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PushInt 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PushBool 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcodeReturn 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode2Drop 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode2Dup 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode3Dup 100.00% (1/1) -github.com/conformal/btcscript/opcode.go opcode2Over 100.00% (1/1) github.com/conformal/btcscript/stack.go Stack.PopByteArray 100.00% (1/1) +github.com/conformal/btcscript/opcode.go init 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeTuck 100.00% (1/1) +github.com/conformal/btcscript/opcode.go opcodeSwap 100.00% (1/1) +github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1) +github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1) github.com/conformal/btcscript/opcode.go opcodeCheckSig 93.10% (27/29) github.com/conformal/btcscript/script.go unparseScript 85.71% (6/7) github.com/conformal/btcscript/script.go expectedInputs 85.71% (6/7) @@ -166,5 +167,5 @@ github.com/conformal/btcscript/script.go @573:34 0.00% (0/3) github.com/conformal/btcscript/log.go logClosure.String 0.00% (0/1) github.com/conformal/btcscript/opcode.go @1741:33 0.00% (0/1) github.com/conformal/btcscript/log.go UseLogger 0.00% (0/1) -github.com/conformal/btcscript --------------------------- 95.16% (1041/1094) +github.com/conformal/btcscript --------------------------- 95.19% (1049/1102)