parent
b8dc1b66e5
commit
61d270957e
2 changed files with 60 additions and 0 deletions
35
script.go
35
script.go
|
@ -308,6 +308,41 @@ func IsPushOnlyScript(script []byte) bool {
|
||||||
return isPushOnly(pops)
|
return isPushOnly(pops)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 HasCanonicalPushes(script []byte) bool {
|
||||||
|
pops, err := parseScript(script)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pop := range pops {
|
||||||
|
opcode := pop.opcode.value
|
||||||
|
data := pop.data
|
||||||
|
dataLen := len(pop.data)
|
||||||
|
if opcode > OP_16 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA2 && dataLen <= 0xff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if opcode == OP_PUSHDATA4 && dataLen <= 0xffff {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// GetScriptClass returns the class of the script passed. If the script does not
|
// GetScriptClass returns the class of the script passed. If the script does not
|
||||||
// parse then NonStandardTy will be returned.
|
// parse then NonStandardTy will be returned.
|
||||||
func GetScriptClass(script []byte) ScriptClass {
|
func GetScriptClass(script []byte) ScriptClass {
|
||||||
|
|
|
@ -15,6 +15,31 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestStandardPushes(t *testing.T) {
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
builder := btcscript.NewScriptBuilder()
|
||||||
|
builder.PushInt64(int64(i))
|
||||||
|
if result := btcscript.IsPushOnlyScript(builder.Script()); !result {
|
||||||
|
t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, builder.Script())
|
||||||
|
}
|
||||||
|
if result := btcscript.HasCanonicalPushes(builder.Script()); !result {
|
||||||
|
t.Errorf("StandardPushesTests HasCanonicalPushes test #%d failed: %x\n", i, builder.Script())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
builder := btcscript.NewScriptBuilder()
|
||||||
|
builder.PushData(bytes.Repeat([]byte{0x49}, i))
|
||||||
|
if result := btcscript.IsPushOnlyScript(builder.Script()); !result {
|
||||||
|
t.Errorf("StandardPushesTests IsPushOnlyScript test #%d failed: %x\n", i, builder.Script())
|
||||||
|
}
|
||||||
|
if result := btcscript.HasCanonicalPushes(builder.Script()); !result {
|
||||||
|
t.Errorf("StandardPushesTests HasCanonicalPushes test #%d failed: %x\n", i, builder.Script())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type txTest struct {
|
type txTest struct {
|
||||||
name string
|
name string
|
||||||
tx *btcwire.MsgTx
|
tx *btcwire.MsgTx
|
||||||
|
|
Loading…
Reference in a new issue