native: allow to overload native methods

This commit is contained in:
Evgeniy Stratonikov 2021-01-28 15:36:37 +03:00
parent 818d5988f5
commit 849385a533
2 changed files with 24 additions and 4 deletions

View file

@ -104,7 +104,13 @@ type ContractMD struct {
ContractID int32 ContractID int32
NEF nef.File NEF nef.File
Hash util.Uint160 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. // NewContractMD returns Contract with the specified list of methods.
@ -112,7 +118,7 @@ func NewContractMD(name string, id int32) *ContractMD {
c := &ContractMD{ c := &ContractMD{
Name: name, Name: name,
ContractID: id, ContractID: id,
Methods: make(map[string]MethodAndPrice), Methods: make(map[MethodAndArgCount]MethodAndPrice),
} }
// NEF is now stored in contract state and affects state dump. // 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) c.Manifest.ABI.Methods = append(c.Manifest.ABI.Methods, *desc)
md.MD = desc md.MD = desc
desc.Safe = md.RequiredFlags&(callflag.All^callflag.ReadOnly) == 0 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. // AddEvent adds new event to a native contract.

View file

@ -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") 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() operation := ic.VM.Estack().Pop().String()
m, ok := c.Metadata().Methods[operation] m, ok := c.Metadata().GetMethod(operation, ic.VM.Estack().Len())
if !ok { if !ok {
return fmt.Errorf("method %s not found", operation) return fmt.Errorf("method %s not found", operation)
} }