diff --git a/pkg/core/interop/context.go b/pkg/core/interop/context.go index c649d6984..83319f08b 100644 --- a/pkg/core/interop/context.go +++ b/pkg/core/interop/context.go @@ -104,7 +104,13 @@ type ContractMD struct { ContractID int32 NEF nef.File Hash util.Uint160 - Methods map[string]MethodAndPrice + Methods map[MethodAndArgCount]MethodAndPrice +} + +// MethodAndArgCount represents method's signature. +type MethodAndArgCount struct { + Name string + ArgCount int } // NewContractMD returns Contract with the specified list of methods. @@ -112,7 +118,7 @@ func NewContractMD(name string, id int32) *ContractMD { c := &ContractMD{ Name: name, ContractID: id, - Methods: make(map[string]MethodAndPrice), + Methods: make(map[MethodAndArgCount]MethodAndPrice), } // NEF is now stored in contract state and affects state dump. @@ -132,7 +138,21 @@ func (c *ContractMD) AddMethod(md *MethodAndPrice, desc *manifest.Method) { c.Manifest.ABI.Methods = append(c.Manifest.ABI.Methods, *desc) md.MD = desc desc.Safe = md.RequiredFlags&(callflag.All^callflag.ReadOnly) == 0 - c.Methods[desc.Name] = *md + key := MethodAndArgCount{ + Name: desc.Name, + ArgCount: len(desc.Parameters), + } + c.Methods[key] = *md +} + +// GetMethod returns method `name` with specified number of parameters. +func (c *ContractMD) GetMethod(name string, paramCount int) (MethodAndPrice, bool) { + key := MethodAndArgCount{ + Name: name, + ArgCount: paramCount, + } + mp, ok := c.Methods[key] + return mp, ok } // AddEvent adds new event to a native contract. diff --git a/pkg/core/native/interop.go b/pkg/core/native/interop.go index a9af939f2..c4fb5744d 100644 --- a/pkg/core/native/interop.go +++ b/pkg/core/native/interop.go @@ -28,7 +28,7 @@ func Call(ic *interop.Context) error { return errors.New("it is not allowed to use Neo.Native.Call directly to call native contracts. System.Contract.Call should be used") } operation := ic.VM.Estack().Pop().String() - m, ok := c.Metadata().Methods[operation] + m, ok := c.Metadata().GetMethod(operation, ic.VM.Estack().Len()) if !ok { return fmt.Errorf("method %s not found", operation) }