smartcontract: use hash in GetWitness()

All necessary info must already be in context.
This commit is contained in:
Evgeniy Stratonikov 2021-03-03 15:56:08 +03:00
parent 20d2386414
commit b9136dbfc0
3 changed files with 22 additions and 11 deletions

View file

@ -47,7 +47,7 @@ func signStoredTransaction(ctx *cli.Context) error {
} }
} }
if len(ctx.String(options.RPCEndpointFlag)) != 0 { if len(ctx.String(options.RPCEndpointFlag)) != 0 {
w, err := c.GetWitness(acc.Contract) w, err := c.GetWitness(acc.Contract.ScriptHash())
if err != nil { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }

View file

@ -51,8 +51,11 @@ func NewParameterContext(typ string, verif crypto.VerifiableDecodable) *Paramete
} }
// GetWitness returns invocation and verification scripts for the specified contract. // GetWitness returns invocation and verification scripts for the specified contract.
func (c *ParameterContext) GetWitness(ctr *wallet.Contract) (*transaction.Witness, error) { func (c *ParameterContext) GetWitness(h util.Uint160) (*transaction.Witness, error) {
item := c.getItemForContract(ctr) item, ok := c.Items[h]
if !ok {
return nil, errors.New("witness not found")
}
bw := io.NewBufBinWriter() bw := io.NewBufBinWriter()
for i := range item.Parameters { for i := range item.Parameters {
if item.Parameters[i].Type != smartcontract.SignatureType { if item.Parameters[i].Type != smartcontract.SignatureType {
@ -64,13 +67,13 @@ func (c *ParameterContext) GetWitness(ctr *wallet.Contract) (*transaction.Witnes
} }
return &transaction.Witness{ return &transaction.Witness{
InvocationScript: bw.Bytes(), InvocationScript: bw.Bytes(),
VerificationScript: ctr.Script, VerificationScript: item.Script,
}, nil }, nil
} }
// AddSignature adds a signature for the specified contract and public key. // AddSignature adds a signature for the specified contract and public key.
func (c *ParameterContext) AddSignature(ctr *wallet.Contract, pub *keys.PublicKey, sig []byte) error { 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 _, pubs, ok := vm.ParseMultiSigContract(ctr.Script); ok {
if item.GetSignature(pub) != nil { if item.GetSignature(pub) != nil {
return errors.New("signature is already added") return errors.New("signature is already added")
@ -125,16 +128,16 @@ func (c *ParameterContext) AddSignature(ctr *wallet.Contract, pub *keys.PublicKe
return nil return nil
} }
func (c *ParameterContext) getItemForContract(ctr *wallet.Contract) *Item { func (c *ParameterContext) getItemForContract(h util.Uint160, ctr *wallet.Contract) *Item {
h := ctr.ScriptHash() item, ok := c.Items[ctr.ScriptHash()]
if item, ok := c.Items[h]; ok { if ok {
return item return item
} }
params := make([]smartcontract.Parameter, len(ctr.Parameters)) params := make([]smartcontract.Parameter, len(ctr.Parameters))
for i := range params { for i := range params {
params[i].Type = ctr.Parameters[i].Type params[i].Type = ctr.Parameters[i].Type
} }
item := &Item{ item = &Item{
Script: ctr.Script, Script: ctr.Script,
Parameters: params, Parameters: params,
Signatures: make(map[string][]byte), Signatures: make(map[string][]byte),

View file

@ -58,13 +58,21 @@ func TestParameterContext_AddSignatureSimpleContract(t *testing.T) {
require.Equal(t, sig, item.Parameters[0].Value) require.Equal(t, sig, item.Parameters[0].Value)
t.Run("GetWitness", func(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) require.NoError(t, err)
v := newTestVM(w, tx) v := newTestVM(w, tx)
require.NoError(t, v.Run()) require.NoError(t, v.Run())
require.Equal(t, 1, v.Estack().Len()) require.Equal(t, 1, v.Estack().Len())
require.Equal(t, true, v.Estack().Pop().Value()) 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) { func TestParameterContext_AddSignatureMultisig(t *testing.T) {
@ -101,7 +109,7 @@ func TestParameterContext_AddSignatureMultisig(t *testing.T) {
} }
t.Run("GetWitness", func(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) require.NoError(t, err)
v := newTestVM(w, tx) v := newTestVM(w, tx)
require.NoError(t, v.Run()) require.NoError(t, v.Run())