diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 59e4bc5b5..0365c2517 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1045,14 +1045,17 @@ func (bc *Blockchain) VerifyWitnesses(t *transaction.Transaction) error { if vm.HasFailed() { return errors.Errorf("vm failed to execute the script") } - res := vm.PopResult() - switch res.(type) { - case bool: - if !(res.(bool)) { + resEl := vm.Estack().Pop() + if resEl != nil { + res, err := resEl.TryBool() + if err != nil { + return err + } + if !res { return errors.Errorf("signature check failed") } - default: - return errors.Errorf("vm returned non-boolean result") + } else { + return errors.Errorf("no result returned from the script") } } diff --git a/pkg/vm/stack.go b/pkg/vm/stack.go index c9ce195be..5dd5b2dd1 100644 --- a/pkg/vm/stack.go +++ b/pkg/vm/stack.go @@ -80,30 +80,40 @@ func (e *Element) BigInt() *big.Int { } } -// Bool attempts to get the underlying value of the element as a boolean. -// Will panic if the assertion failed which will be caught by the VM. -func (e *Element) Bool() bool { +// TryBool attempts to get the underlying value of the element as a boolean. +// Returns error if can't convert value to boolean type. +func (e *Element) TryBool() (bool, error) { switch t := e.value.(type) { case *BigIntegerItem: - return t.value.Int64() != 0 + return t.value.Int64() != 0, nil case *BoolItem: - return t.value + return t.value, nil case *ArrayItem, *StructItem: - return true + return true, nil case *ByteArrayItem: for _, b := range t.value { if b != 0 { - return true + return true, nil } } - return false + return false, nil case *InteropItem: - return t.value != nil + return t.value != nil, nil default: - panic("can't convert to bool: " + t.String()) + return false, fmt.Errorf("can't convert to bool: " + t.String()) } } +// Bool attempts to get the underlying value of the element as a boolean. +// Will panic if the assertion failed which will be caught by the VM. +func (e *Element) Bool() bool { + val, err := e.TryBool() + if err != nil { + panic(err) + } + return val +} + // Bytes attempts to get the underlying value of the element as a byte array. // Will panic if the assertion failed which will be caught by the VM. func (e *Element) Bytes() []byte {