github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/smartcontract/manifest/method.go (about)

     1  package manifest
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
     7  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
     8  )
     9  
    10  // Method represents method's metadata.
    11  type Method struct {
    12  	Name       string                  `json:"name"`
    13  	Offset     int                     `json:"offset"`
    14  	Parameters []Parameter             `json:"parameters"`
    15  	ReturnType smartcontract.ParamType `json:"returntype"`
    16  	Safe       bool                    `json:"safe"`
    17  }
    18  
    19  // IsValid checks Method consistency and correctness.
    20  func (m *Method) IsValid() error {
    21  	if m.Name == "" {
    22  		return errors.New("empty or absent name")
    23  	}
    24  	if m.Offset < 0 {
    25  		return errors.New("negative offset")
    26  	}
    27  	_, err := smartcontract.ConvertToParamType(int(m.ReturnType))
    28  	if err != nil {
    29  		return err
    30  	}
    31  	return Parameters(m.Parameters).AreValid()
    32  }
    33  
    34  // ToStackItem converts Method to stackitem.Item.
    35  func (m *Method) ToStackItem() stackitem.Item {
    36  	params := make([]stackitem.Item, len(m.Parameters))
    37  	for i := range m.Parameters {
    38  		params[i] = m.Parameters[i].ToStackItem()
    39  	}
    40  	return stackitem.NewStruct([]stackitem.Item{
    41  		stackitem.Make(m.Name),
    42  		stackitem.Make(params),
    43  		stackitem.Make(int(m.ReturnType)),
    44  		stackitem.Make(m.Offset),
    45  		stackitem.Make(m.Safe),
    46  	})
    47  }
    48  
    49  // FromStackItem converts stackitem.Item to Method.
    50  func (m *Method) FromStackItem(item stackitem.Item) error {
    51  	var err error
    52  	if item.Type() != stackitem.StructT {
    53  		return errors.New("invalid Method stackitem type")
    54  	}
    55  	method := item.Value().([]stackitem.Item)
    56  	if len(method) != 5 {
    57  		return errors.New("invalid Method stackitem length")
    58  	}
    59  	m.Name, err = stackitem.ToString(method[0])
    60  	if err != nil {
    61  		return err
    62  	}
    63  	if method[1].Type() != stackitem.ArrayT {
    64  		return errors.New("invalid Params stackitem type")
    65  	}
    66  	params := method[1].Value().([]stackitem.Item)
    67  	m.Parameters = make([]Parameter, len(params))
    68  	for i := range params {
    69  		p := new(Parameter)
    70  		if err := p.FromStackItem(params[i]); err != nil {
    71  			return err
    72  		}
    73  		m.Parameters[i] = *p
    74  	}
    75  	rTyp, err := method[2].TryInteger()
    76  	if err != nil {
    77  		return err
    78  	}
    79  	m.ReturnType, err = smartcontract.ConvertToParamType(int(rTyp.Int64()))
    80  	if err != nil {
    81  		return err
    82  	}
    83  	offset, err := method[3].TryInteger()
    84  	if err != nil {
    85  		return err
    86  	}
    87  	m.Offset = int(offset.Int64())
    88  	safe, err := method[4].TryBool()
    89  	if err != nil {
    90  		return err
    91  	}
    92  	m.Safe = safe
    93  	return nil
    94  }