core: add ScriptFromWitness function
Extracting verification script from witness became a common task. This commit adds such a possibility.
This commit is contained in:
parent
9cc0fca9d2
commit
714c466c2c
2 changed files with 41 additions and 8 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue