Add flag bitmask to NewScript for canonical sig checks.
This removes the bip16 bool from NewScript and adds it to flags (with the constant ScriptBip16), and also adds a new flag, ScriptCanonicalSignatures, which will call btcec.ParseDERSignature parsing a signature during an Execute. This is needed to emulate bitcoind behavior, as bitcoind performs canonical signature validation (DER format) in some places (like mempool acceptance) but not others (like block validation). Updated tests and test coverage file to reflect changes.
This commit is contained in:
parent
40c75b27ac
commit
8eead5217d
5 changed files with 286 additions and 25 deletions
22
opcode.go
22
opcode.go
|
@ -1682,7 +1682,12 @@ func opcodeCheckSig(op *parsedOpcode, s *Script) error {
|
|||
return err
|
||||
}
|
||||
|
||||
signature, err := btcec.ParseSignature(sigStr, btcec.S256())
|
||||
var signature *btcec.Signature
|
||||
if s.der {
|
||||
signature, err = btcec.ParseDERSignature(sigStr, btcec.S256())
|
||||
} else {
|
||||
signature, err = btcec.ParseSignature(sigStr, btcec.S256())
|
||||
}
|
||||
if err != nil {
|
||||
log.Warnf("can't parse signature from string: %v", err)
|
||||
return err
|
||||
|
@ -1761,10 +1766,17 @@ func opcodeCheckMultiSig(op *parsedOpcode, s *Script) error {
|
|||
return err
|
||||
}
|
||||
// skip off the last byte for hashtype
|
||||
signatures[i], err =
|
||||
btcec.ParseSignature(
|
||||
sigStrings[i][:len(sigStrings[i])-1],
|
||||
btcec.S256())
|
||||
if s.der {
|
||||
signatures[i], err =
|
||||
btcec.ParseDERSignature(
|
||||
sigStrings[i][:len(sigStrings[i])-1],
|
||||
btcec.S256())
|
||||
} else {
|
||||
signatures[i], err =
|
||||
btcec.ParseSignature(
|
||||
sigStrings[i][:len(sigStrings[i])-1],
|
||||
btcec.S256())
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
// All run on a fake tx with a single in, single out.
|
||||
type opcodeTest struct {
|
||||
script []byte
|
||||
canonical bool
|
||||
shouldPass bool
|
||||
shouldFail error
|
||||
}
|
||||
|
@ -384,6 +385,18 @@ var opcodeTests = []opcodeTest{
|
|||
0x8a, 0x06, 0x26, 0xf1, 0xba, 0xde, 0xd5, 0xc7, 0x2a, 0x70,
|
||||
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
|
||||
btcscript.OP_1, btcscript.OP_CHECK_MULTISIG},
|
||||
canonical: false,
|
||||
shouldPass: false},
|
||||
{script: []byte{btcscript.OP_1, btcscript.OP_1, btcscript.OP_DATA_65,
|
||||
0x04, 0xae, 0x1a, 0x62, 0xfe, 0x09, 0xc5, 0xf5, 0x1b, 0x13,
|
||||
0x90, 0x5f, 0x07, 0xf0, 0x6b, 0x99, 0xa2, 0xf7, 0x15, 0x9b,
|
||||
0x22, 0x25, 0xf3, 0x74, 0xcd, 0x37, 0x8d, 0x71, 0x30, 0x2f,
|
||||
0xa2, 0x84, 0x14, 0xe7, 0xaa, 0xb3, 0x73, 0x97, 0xf5, 0x54,
|
||||
0xa7, 0xdf, 0x5f, 0x14, 0x2c, 0x21, 0xc1, 0xb7, 0x30, 0x3b,
|
||||
0x8a, 0x06, 0x26, 0xf1, 0xba, 0xde, 0xd5, 0xc7, 0x2a, 0x70,
|
||||
0x4f, 0x7e, 0x6c, 0xd8, 0x4c,
|
||||
btcscript.OP_1, btcscript.OP_CHECK_MULTISIG},
|
||||
canonical: true,
|
||||
shouldPass: false},
|
||||
/* up here because no defined error case. */
|
||||
{script: []byte{btcscript.OP_1, btcscript.OP_1, btcscript.OP_DATA_65,
|
||||
|
@ -468,7 +481,7 @@ var opcodeTests = []opcodeTest{
|
|||
{script: []byte{252}, shouldPass: false},
|
||||
}
|
||||
|
||||
func testScript(t *testing.T, script []byte) (err error) {
|
||||
func testScript(t *testing.T, script []byte, canonical bool) (err error) {
|
||||
// mock up fake tx.
|
||||
tx := &btcwire.MsgTx{
|
||||
Version: 1,
|
||||
|
@ -493,8 +506,13 @@ func testScript(t *testing.T, script []byte) (err error) {
|
|||
|
||||
tx.TxOut[0].PkScript = script
|
||||
|
||||
var flags btcscript.ScriptFlags
|
||||
if canonical {
|
||||
flags = btcscript.ScriptCanonicalSignatures
|
||||
}
|
||||
|
||||
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript,
|
||||
tx.TxOut[0].PkScript, 0, tx, false)
|
||||
tx.TxOut[0].PkScript, 0, tx, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -514,7 +532,7 @@ func TestScripts(t *testing.T) {
|
|||
for i := range opcodeTests {
|
||||
shouldPass := opcodeTests[i].shouldPass
|
||||
shouldFail := opcodeTests[i].shouldFail
|
||||
err := testScript(t, opcodeTests[i].script)
|
||||
err := testScript(t, opcodeTests[i].script, opcodeTests[i].canonical)
|
||||
if shouldFail != nil {
|
||||
if err == nil {
|
||||
t.Errorf("test %d passed should fail with %v", i, err)
|
||||
|
@ -4279,7 +4297,7 @@ func testOpcode(t *testing.T, test *detailedTest) {
|
|||
tx.TxOut[0].PkScript = test.script
|
||||
|
||||
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript,
|
||||
tx.TxOut[0].PkScript, 0, tx, false)
|
||||
tx.TxOut[0].PkScript, 0, tx, 0)
|
||||
if err != nil {
|
||||
if err != test.expectedReturn {
|
||||
t.Errorf("Error return not expected %s: %v %v",
|
||||
|
|
62
script.go
62
script.go
|
@ -159,6 +159,7 @@ type Script struct {
|
|||
condStack []int
|
||||
numOps int
|
||||
bip16 bool // treat execution as pay-to-script-hash
|
||||
der bool // enforce DER encoding
|
||||
savedFirstStack [][]byte // stack from first script for bip16 scripts
|
||||
}
|
||||
|
||||
|
@ -361,11 +362,35 @@ func unparseScript(pops []parsedOpcode) ([]byte, error) {
|
|||
return script, nil
|
||||
}
|
||||
|
||||
// ScriptFlags is a bitmask defining additional operations or
|
||||
// tests that will be done when executing a Script.
|
||||
type ScriptFlags uint32
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
// 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 NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.MsgTx, bip16 bool) (*Script, error) {
|
||||
func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.MsgTx, flags ScriptFlags) (*Script, error) {
|
||||
var m Script
|
||||
scripts := [][]byte{scriptSig, scriptPubKey}
|
||||
m.scripts = make([][]parsedOpcode, len(scripts))
|
||||
|
@ -385,6 +410,8 @@ func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.Msg
|
|||
}
|
||||
}
|
||||
|
||||
// Parse flags.
|
||||
bip16 := flags&ScriptBip16 == ScriptBip16
|
||||
if bip16 && isScriptHash(m.scripts[1]) {
|
||||
// if we are pay to scripthash then we only accept input
|
||||
// scripts that push data
|
||||
|
@ -393,6 +420,9 @@ func NewScript(scriptSig []byte, scriptPubKey []byte, txidx int, tx *btcwire.Msg
|
|||
}
|
||||
m.bip16 = true
|
||||
}
|
||||
if flags&ScriptCanonicalSignatures == ScriptCanonicalSignatures {
|
||||
m.der = true
|
||||
}
|
||||
|
||||
m.tx = *tx
|
||||
m.txidx = txidx
|
||||
|
@ -964,19 +994,39 @@ func signatureScriptCustomReader(reader io.Reader, tx *btcwire.MsgTx, idx int,
|
|||
//
|
||||
// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
|
||||
func sigDER(r, s *big.Int) []byte {
|
||||
// In DER format, a leading 0x00 octet must be prepended to
|
||||
// the byte slice so it cannot be interpreted as a negative
|
||||
// big-endian number. This is only done if the sign bit on
|
||||
// the first byte is set.
|
||||
var rb, sb []byte
|
||||
if r.Bytes()[0]&0x80 != 0 {
|
||||
paddedBytes := make([]byte, len(r.Bytes())+1)
|
||||
copy(paddedBytes[1:], r.Bytes())
|
||||
rb = paddedBytes
|
||||
} else {
|
||||
rb = r.Bytes()
|
||||
}
|
||||
if s.Bytes()[0]&0x80 != 0 {
|
||||
paddedBytes := make([]byte, len(s.Bytes())+1)
|
||||
copy(paddedBytes[1:], s.Bytes())
|
||||
sb = paddedBytes
|
||||
} else {
|
||||
sb = s.Bytes()
|
||||
}
|
||||
|
||||
// total length of returned signature is 1 byte for each magic and
|
||||
// length (6 total), plus lengths of r and s
|
||||
length := 6 + len(r.Bytes()) + len(s.Bytes())
|
||||
length := 6 + len(rb) + len(sb)
|
||||
b := make([]byte, length, length)
|
||||
|
||||
b[0] = 0x30
|
||||
b[1] = byte(length - 2)
|
||||
b[2] = 0x02
|
||||
b[3] = byte(len(r.Bytes()))
|
||||
offset := copy(b[4:], r.Bytes()) + 4
|
||||
b[3] = byte(len(rb))
|
||||
offset := copy(b[4:], rb) + 4
|
||||
b[offset] = 0x02
|
||||
b[offset+1] = byte(len(s.Bytes()))
|
||||
copy(b[offset+2:], s.Bytes())
|
||||
b[offset+1] = byte(len(sb))
|
||||
copy(b[offset+2:], sb)
|
||||
return b
|
||||
}
|
||||
|
||||
|
|
189
script_test.go
189
script_test.go
|
@ -20,6 +20,7 @@ type txTest struct {
|
|||
pkScript []byte // output script of previous tx
|
||||
idx int // tx idx to be run.
|
||||
bip16 bool // is bip16 active?
|
||||
canonicalSigs bool // should signatures be validated as canonical?
|
||||
parseErr error // failure of NewScript
|
||||
err error // Failure of Executre
|
||||
shouldFail bool // Execute should fail with nonspecified error.
|
||||
|
@ -566,6 +567,178 @@ var txTests = []txTest{
|
|||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
txTest{
|
||||
name: "Non-canonical signature: R value negative",
|
||||
tx: &btcwire.MsgTx{
|
||||
Version: 1,
|
||||
TxIn: []*btcwire.TxIn{
|
||||
&btcwire.TxIn{
|
||||
PreviousOutpoint: btcwire.OutPoint{
|
||||
Hash: btcwire.ShaHash([32]byte{
|
||||
0xfe, 0x15, 0x62, 0xc4,
|
||||
0x8b, 0x3a, 0xa6, 0x37,
|
||||
0x3f, 0x42, 0xe9, 0x61,
|
||||
0x51, 0x89, 0xcf, 0x73,
|
||||
0x32, 0xd7, 0x33, 0x5c,
|
||||
0xbe, 0xa7, 0x80, 0xbe,
|
||||
0x69, 0x6a, 0xc6, 0xc6,
|
||||
0x50, 0xfd, 0xda, 0x4a,
|
||||
}),
|
||||
Index: 1,
|
||||
},
|
||||
SignatureScript: []byte{
|
||||
btcscript.OP_DATA_71,
|
||||
0x30, 0x44, 0x02, 0x20, 0xa0,
|
||||
0x42, 0xde, 0xe5, 0x52, 0x6b,
|
||||
0xf2, 0x29, 0x4d, 0x3f, 0x3e,
|
||||
0xb9, 0x5a, 0xa7, 0x73, 0x19,
|
||||
0xd3, 0xff, 0x56, 0x7b, 0xcf,
|
||||
0x36, 0x46, 0x07, 0x0c, 0x81,
|
||||
0x12, 0x33, 0x01, 0xca, 0xce,
|
||||
0xa9, 0x02, 0x20, 0xea, 0x48,
|
||||
0xae, 0x58, 0xf5, 0x54, 0x10,
|
||||
0x96, 0x3f, 0xa7, 0x03, 0xdb,
|
||||
0x56, 0xf0, 0xba, 0xb2, 0x70,
|
||||
0xb1, 0x08, 0x22, 0xc5, 0x1c,
|
||||
0x68, 0x02, 0x6a, 0x97, 0x5c,
|
||||
0x7d, 0xae, 0x11, 0x2e, 0x4f,
|
||||
0x01,
|
||||
btcscript.OP_DATA_65,
|
||||
0x04, 0x49, 0x45, 0x33, 0x18,
|
||||
0xbd, 0x5e, 0xcf, 0xea, 0x5f,
|
||||
0x86, 0x32, 0x8c, 0x6d, 0x8e,
|
||||
0xd4, 0x12, 0xb4, 0xde, 0x2c,
|
||||
0xab, 0xd7, 0xb8, 0x56, 0x51,
|
||||
0x2f, 0x8c, 0xb7, 0xfd, 0x25,
|
||||
0xf6, 0x03, 0xb0, 0x55, 0xc5,
|
||||
0xdf, 0xe6, 0x22, 0x4b, 0xc4,
|
||||
0xfd, 0xbb, 0x6a, 0x7a, 0xa0,
|
||||
0x58, 0xd7, 0x5d, 0xad, 0x92,
|
||||
0x99, 0x45, 0x4f, 0x62, 0x1a,
|
||||
0x95, 0xb4, 0xb0, 0x21, 0x0e,
|
||||
0xc4, 0x09, 0x2b, 0xe5, 0x27,
|
||||
},
|
||||
Sequence: 4294967295,
|
||||
},
|
||||
&btcwire.TxIn{
|
||||
PreviousOutpoint: btcwire.OutPoint{
|
||||
Hash: btcwire.ShaHash([32]byte{
|
||||
0x2a, 0xc7, 0xee, 0xf8,
|
||||
0xa9, 0x62, 0x2d, 0xda,
|
||||
0xec, 0x18, 0x3b, 0xba,
|
||||
0xa9, 0x92, 0xb0, 0x7a,
|
||||
0x70, 0x3b, 0x48, 0x86,
|
||||
0x27, 0x9c, 0x46, 0xac,
|
||||
0x25, 0xeb, 0x91, 0xec,
|
||||
0x4c, 0x86, 0xd2, 0x9c,
|
||||
}),
|
||||
Index: 1,
|
||||
},
|
||||
SignatureScript: []byte{
|
||||
btcscript.OP_DATA_71,
|
||||
0x30, 0x44, 0x02, 0x20, 0xc3,
|
||||
0x02, 0x3b, 0xed, 0x85, 0x0d,
|
||||
0x94, 0x27, 0x8e, 0x06, 0xd2,
|
||||
0x37, 0x92, 0x21, 0x55, 0x28,
|
||||
0xdd, 0xdb, 0x63, 0xa4, 0xb6,
|
||||
0x88, 0x33, 0x92, 0x06, 0xdd,
|
||||
0xf9, 0xee, 0x72, 0x97, 0xa3,
|
||||
0x08, 0x02, 0x20, 0x25, 0x00,
|
||||
0x42, 0x8b, 0x26, 0x36, 0x45,
|
||||
0x54, 0xcb, 0x11, 0xd3, 0x3e,
|
||||
0x85, 0x35, 0x23, 0x49, 0x65,
|
||||
0x82, 0x8e, 0x33, 0x6e, 0x1a,
|
||||
0x4a, 0x72, 0x73, 0xeb, 0x5b,
|
||||
0x8d, 0x1d, 0xd7, 0x02, 0xcc,
|
||||
0x01,
|
||||
btcscript.OP_DATA_65,
|
||||
0x04, 0x49, 0x5c, 0x8f, 0x66,
|
||||
0x90, 0x0d, 0xb7, 0x62, 0x69,
|
||||
0x0b, 0x54, 0x49, 0xa1, 0xf4,
|
||||
0xe7, 0xc2, 0xed, 0x1f, 0x4b,
|
||||
0x34, 0x70, 0xfd, 0x42, 0x79,
|
||||
0x68, 0xa1, 0x31, 0x76, 0x0c,
|
||||
0x25, 0xf9, 0x12, 0x63, 0xad,
|
||||
0x51, 0x73, 0x8e, 0x19, 0xb6,
|
||||
0x07, 0xf5, 0xcf, 0x5f, 0x94,
|
||||
0x27, 0x4a, 0x8b, 0xbc, 0x74,
|
||||
0xba, 0x4b, 0x56, 0x0c, 0xe0,
|
||||
0xb3, 0x08, 0x8f, 0x7f, 0x5c,
|
||||
0x5f, 0xcf, 0xd6, 0xa0, 0x4b,
|
||||
},
|
||||
Sequence: 4294967295,
|
||||
},
|
||||
},
|
||||
TxOut: []*btcwire.TxOut{
|
||||
&btcwire.TxOut{
|
||||
Value: 630320000,
|
||||
PkScript: []byte{
|
||||
btcscript.OP_DUP,
|
||||
btcscript.OP_HASH160,
|
||||
btcscript.OP_DATA_20,
|
||||
0x43, 0xdc, 0x32, 0x1b, 0x66,
|
||||
0x00, 0x51, 0x1f, 0xe0, 0xa9,
|
||||
0x6a, 0x97, 0xc2, 0x59, 0x3a,
|
||||
0x90, 0x54, 0x29, 0x74, 0xd6,
|
||||
btcscript.OP_EQUALVERIFY,
|
||||
btcscript.OP_CHECKSIG,
|
||||
},
|
||||
},
|
||||
&btcwire.TxOut{
|
||||
Value: 100000181,
|
||||
PkScript: []byte{
|
||||
btcscript.OP_DUP,
|
||||
btcscript.OP_HASH160,
|
||||
btcscript.OP_DATA_20,
|
||||
0xa4, 0x05, 0xea, 0x18, 0x09,
|
||||
0x14, 0xa9, 0x11, 0xd0, 0xb8,
|
||||
0x07, 0x99, 0x19, 0x2b, 0x0b,
|
||||
0x84, 0xae, 0x80, 0x1e, 0xbd,
|
||||
btcscript.OP_EQUALVERIFY,
|
||||
btcscript.OP_CHECKSIG,
|
||||
},
|
||||
},
|
||||
&btcwire.TxOut{
|
||||
Value: 596516343,
|
||||
PkScript: []byte{
|
||||
btcscript.OP_DUP,
|
||||
btcscript.OP_HASH160,
|
||||
btcscript.OP_DATA_20,
|
||||
0x24, 0x56, 0x76, 0x45, 0x4f,
|
||||
0x6f, 0xff, 0x28, 0x88, 0x39,
|
||||
0x47, 0xea, 0x70, 0x23, 0x86,
|
||||
0x9b, 0x8a, 0x71, 0xa3, 0x05,
|
||||
btcscript.OP_EQUALVERIFY,
|
||||
btcscript.OP_CHECKSIG,
|
||||
},
|
||||
},
|
||||
},
|
||||
LockTime: 0,
|
||||
},
|
||||
// Test input 0
|
||||
pkScript: []byte{
|
||||
btcscript.OP_DUP,
|
||||
btcscript.OP_HASH160,
|
||||
btcscript.OP_DATA_20,
|
||||
0xfd, 0xf6, 0xea, 0xe7, 0x10,
|
||||
0xa0, 0xc4, 0x49, 0x7a, 0x8d,
|
||||
0x0f, 0xd2, 0x9a, 0xf6, 0x6b,
|
||||
0xac, 0x94, 0xaf, 0x6c, 0x98,
|
||||
btcscript.OP_EQUALVERIFY,
|
||||
btcscript.OP_CHECKSIG,
|
||||
},
|
||||
idx: 0,
|
||||
canonicalSigs: true,
|
||||
shouldFail: true,
|
||||
nSigOps: 1,
|
||||
scriptInfo: btcscript.ScriptInfo{
|
||||
PkScriptClass: btcscript.PubKeyHashTy,
|
||||
NumInputs: 2,
|
||||
ExpectedInputs: 2,
|
||||
SigOps: 1,
|
||||
},
|
||||
},
|
||||
|
||||
// tx 51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e
|
||||
// first instance of an AnyoneCanPay signature in the blockchain
|
||||
txTest{
|
||||
|
@ -1265,9 +1438,16 @@ var txTests = []txTest{
|
|||
// nothing in the blockchain that we have yet seen uses them, making it hard
|
||||
// to confirm we implemented the spec correctly.
|
||||
func testTx(t *testing.T, test txTest) {
|
||||
var flags btcscript.ScriptFlags
|
||||
if test.bip16 {
|
||||
flags |= btcscript.ScriptBip16
|
||||
}
|
||||
if test.canonicalSigs {
|
||||
flags |= btcscript.ScriptCanonicalSignatures
|
||||
}
|
||||
engine, err := btcscript.NewScript(
|
||||
test.tx.TxIn[test.idx].SignatureScript, test.pkScript,
|
||||
test.idx, test.tx, test.bip16)
|
||||
test.idx, test.tx, flags)
|
||||
if err != nil {
|
||||
if err != test.parseErr {
|
||||
t.Errorf("Failed to parse %s: got \"%v\" expected "+
|
||||
|
@ -1983,7 +2163,7 @@ func TestBadPC(t *testing.T) {
|
|||
|
||||
for _, test := range pcTests {
|
||||
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript,
|
||||
pkScript, 0, tx, false)
|
||||
pkScript, 0, tx, 0)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create script: %v", err)
|
||||
}
|
||||
|
@ -2053,7 +2233,7 @@ func TestCheckErrorCondition(t *testing.T) {
|
|||
}
|
||||
|
||||
engine, err := btcscript.NewScript(tx.TxIn[0].SignatureScript, pkScript,
|
||||
0, tx, false)
|
||||
0, tx, 0)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create script: %v", err)
|
||||
}
|
||||
|
@ -2460,10 +2640,11 @@ nexttest:
|
|||
}
|
||||
|
||||
// Validate tx input scripts
|
||||
scriptFlags := btcscript.ScriptBip16 | btcscript.ScriptCanonicalSignatures
|
||||
for j, txin := range tx.TxIn {
|
||||
engine, err := btcscript.NewScript(txin.SignatureScript,
|
||||
SigScriptTests[i].inputs[j].txout.PkScript,
|
||||
j, tx, true)
|
||||
j, tx, scriptFlags)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create script vm for test %v: %v",
|
||||
SigScriptTests[i].name, err)
|
||||
|
|
|
@ -4,17 +4,17 @@ github.com/conformal/btcscript/script.go Script.Step 100.00% (37/37)
|
|||
github.com/conformal/btcscript/script.go parseScriptTemplate 100.00% (30/30)
|
||||
github.com/conformal/btcscript/script.go CalcScriptInfo 100.00% (25/25)
|
||||
github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (23/23)
|
||||
github.com/conformal/btcscript/script.go sigDER 100.00% (22/22)
|
||||
github.com/conformal/btcscript/script.go NewScript 100.00% (21/21)
|
||||
github.com/conformal/btcscript/stack.go asInt 100.00% (21/21)
|
||||
github.com/conformal/btcscript/script.go NewScript 100.00% (18/18)
|
||||
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/stack.go Stack.nipN 100.00% (14/14)
|
||||
github.com/conformal/btcscript/script.go GetPreciseSigOpCount 100.00% (13/13)
|
||||
github.com/conformal/btcscript/opcode.go opcodeWithin 100.00% (13/13)
|
||||
github.com/conformal/btcscript/script.go isMultiSig 100.00% (13/13)
|
||||
github.com/conformal/btcscript/script.go GetPreciseSigOpCount 100.00% (13/13)
|
||||
github.com/conformal/btcscript/opcode.go parsedOpcode.print 100.00% (12/12)
|
||||
github.com/conformal/btcscript/opcode.go opcodeNotIf 100.00% (11/11)
|
||||
github.com/conformal/btcscript/script.go sigDER 100.00% (11/11)
|
||||
github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11)
|
||||
github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10)
|
||||
github.com/conformal/btcscript/script.go getSigOpCount 100.00% (10/10)
|
||||
|
@ -140,8 +140,8 @@ github.com/conformal/btcscript/script.go Script.SetStack 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/opcode.go opcodeRot 100.00% (1/1)
|
||||
github.com/conformal/btcscript/opcode.go opcodeCheckMultiSig 98.21% (55/56)
|
||||
github.com/conformal/btcscript/opcode.go opcodeCheckSig 96.15% (25/26)
|
||||
github.com/conformal/btcscript/opcode.go opcodeCheckMultiSig 98.28% (57/58)
|
||||
github.com/conformal/btcscript/opcode.go opcodeCheckSig 96.55% (28/29)
|
||||
github.com/conformal/btcscript/script.go calcScriptHash 82.05% (32/39)
|
||||
github.com/conformal/btcscript/script.go Script.CheckErrorCondition 78.57% (11/14)
|
||||
github.com/conformal/btcscript/opcode.go opcodeCheckSigVerify 75.00% (3/4)
|
||||
|
@ -149,5 +149,5 @@ github.com/conformal/btcscript/script.go Script.Execute 44.44% (8/18)
|
|||
github.com/conformal/btcscript/log.go SetLogWriter 0.00% (0/7)
|
||||
github.com/conformal/btcscript/script.go IsPushOnlyScript 0.00% (0/4)
|
||||
github.com/conformal/btcscript/log.go logClosure.String 0.00% (0/1)
|
||||
github.com/conformal/btcscript --------------------------- 96.52% (970/1005)
|
||||
github.com/conformal/btcscript --------------------------- 96.58% (989/1024)
|
||||
|
||||
|
|
Loading…
Reference in a new issue