diff --git a/cli/wallet/multisig.go b/cli/wallet/multisig.go index ddb18f54d..762b61e10 100644 --- a/cli/wallet/multisig.go +++ b/cli/wallet/multisig.go @@ -47,7 +47,7 @@ func signStoredTransaction(ctx *cli.Context) error { } } if len(ctx.String(options.RPCEndpointFlag)) != 0 { - w, err := c.GetWitness(acc.Contract) + w, err := c.GetWitness(acc.Contract.ScriptHash()) if err != nil { return cli.NewExitError(err, 1) } diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index b22c9cb22..9fc7b88e3 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -51,8 +51,11 @@ func NewParameterContext(typ string, verif crypto.VerifiableDecodable) *Paramete } // GetWitness returns invocation and verification scripts for the specified contract. -func (c *ParameterContext) GetWitness(ctr *wallet.Contract) (*transaction.Witness, error) { - item := c.getItemForContract(ctr) +func (c *ParameterContext) GetWitness(h util.Uint160) (*transaction.Witness, error) { + item, ok := c.Items[h] + if !ok { + return nil, errors.New("witness not found") + } bw := io.NewBufBinWriter() for i := range item.Parameters { if item.Parameters[i].Type != smartcontract.SignatureType { @@ -64,13 +67,13 @@ func (c *ParameterContext) GetWitness(ctr *wallet.Contract) (*transaction.Witnes } return &transaction.Witness{ InvocationScript: bw.Bytes(), - VerificationScript: ctr.Script, + VerificationScript: item.Script, }, nil } // AddSignature adds a signature for the specified contract and public key. func (c *ParameterContext) AddSignature(ctr *wallet.Contract, pub *keys.PublicKey, sig []byte) error { - item := c.getItemForContract(ctr) + item := c.getItemForContract(ctr.ScriptHash(), ctr) if _, pubs, ok := vm.ParseMultiSigContract(ctr.Script); ok { if item.GetSignature(pub) != nil { return errors.New("signature is already added") @@ -125,16 +128,16 @@ func (c *ParameterContext) AddSignature(ctr *wallet.Contract, pub *keys.PublicKe return nil } -func (c *ParameterContext) getItemForContract(ctr *wallet.Contract) *Item { - h := ctr.ScriptHash() - if item, ok := c.Items[h]; ok { +func (c *ParameterContext) getItemForContract(h util.Uint160, ctr *wallet.Contract) *Item { + item, ok := c.Items[ctr.ScriptHash()] + if ok { return item } params := make([]smartcontract.Parameter, len(ctr.Parameters)) for i := range params { params[i].Type = ctr.Parameters[i].Type } - item := &Item{ + item = &Item{ Script: ctr.Script, Parameters: params, Signatures: make(map[string][]byte), diff --git a/pkg/smartcontract/context/context_test.go b/pkg/smartcontract/context/context_test.go index 2be84eb03..98de00b2d 100644 --- a/pkg/smartcontract/context/context_test.go +++ b/pkg/smartcontract/context/context_test.go @@ -58,13 +58,21 @@ func TestParameterContext_AddSignatureSimpleContract(t *testing.T) { require.Equal(t, sig, item.Parameters[0].Value) t.Run("GetWitness", func(t *testing.T) { - w, err := c.GetWitness(ctr) + w, err := c.GetWitness(ctr.ScriptHash()) require.NoError(t, err) v := newTestVM(w, tx) require.NoError(t, v.Run()) require.Equal(t, 1, v.Estack().Len()) require.Equal(t, true, v.Estack().Pop().Value()) }) + t.Run("not found", func(t *testing.T) { + ctr := &wallet.Contract{ + Script: []byte{byte(opcode.DROP), byte(opcode.PUSHT)}, + Parameters: []wallet.ContractParam{newParam(smartcontract.SignatureType, "parameter0")}, + } + _, err := c.GetWitness(ctr.ScriptHash()) + require.Error(t, err) + }) } func TestParameterContext_AddSignatureMultisig(t *testing.T) { @@ -101,7 +109,7 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) { } t.Run("GetWitness", func(t *testing.T) { - w, err := c.GetWitness(ctr) + w, err := c.GetWitness(ctr.ScriptHash()) require.NoError(t, err) v := newTestVM(w, tx) require.NoError(t, v.Run())