core: add ScriptFromWitness function

Extracting verification script from witness became a common task.
This commit adds such a possibility.
This commit is contained in:
Evgenii Stratonikov 2019-12-25 18:18:17 +03:00
parent 9cc0fca9d2
commit 714c466c2c
2 changed files with 41 additions and 8 deletions

View file

@ -1372,21 +1372,30 @@ func (bc *Blockchain) GetTestVM() (*vm.VM, storage.Store) {
return vm, tmpStore
}
// verifyHashAgainstScript verifies given hash against the given witness.
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interopContext, useKeys bool) error {
// ScriptFromWitness returns verification script for provided witness.
// If hash is not equal to the witness script hash, error is returned.
func ScriptFromWitness(hash util.Uint160, witness *transaction.Witness) ([]byte, error) {
verification := witness.VerificationScript
if len(verification) == 0 {
bb := new(bytes.Buffer)
err := vm.EmitAppCall(bb, hash, false)
if err != nil {
return err
return nil, err
}
verification = bb.Bytes()
} else {
if h := witness.ScriptHash(); hash != h {
return errors.New("witness hash mismatch")
}
} else if h := witness.ScriptHash(); hash != h {
return nil, errors.New("witness hash mismatch")
}
return verification, nil
}
// verifyHashAgainstScript verifies given hash against the given witness.
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, checkedHash util.Uint256, interopCtx *interopContext, useKeys bool) error {
verification, err := ScriptFromWitness(hash, witness)
if err != nil {
return err
}
vm := bc.spawnVMWithInterops(interopCtx)
@ -1396,7 +1405,7 @@ func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transa
if useKeys && bc.keyCache[hash] != nil {
vm.SetPublicKeys(bc.keyCache[hash])
}
err := vm.Run()
err = vm.Run()
if vm.HasFailed() {
return errors.Errorf("vm failed to execute the script with error: %s", err)
}

View file

@ -4,7 +4,10 @@ import (
"testing"
"github.com/CityOfZion/neo-go/pkg/core/storage"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
"github.com/CityOfZion/neo-go/pkg/io"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -65,6 +68,27 @@ func TestAddBlock(t *testing.T) {
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
}
func TestScriptFromWitness(t *testing.T) {
witness := &transaction.Witness{}
h := util.Uint160{1, 2, 3}
res, err := ScriptFromWitness(h, witness)
require.NoError(t, err)
require.NotNil(t, res)
witness.VerificationScript = []byte{4, 8, 15, 16, 23, 42}
h = hash.Hash160(witness.VerificationScript)
res, err = ScriptFromWitness(h, witness)
require.NoError(t, err)
require.NotNil(t, res)
h[0] = ^h[0]
res, err = ScriptFromWitness(h, witness)
require.Error(t, err)
require.Nil(t, res)
}
func TestGetHeader(t *testing.T) {
bc := newTestChain(t)
block := newBlock(1, newMinerTX())