neoneo-go/pkg/smartcontract/manifest/manifest.go

137 lines
3.5 KiB
Go
Raw Normal View History

package manifest
import (
"encoding/json"
2020-06-09 09:12:56 +00:00
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
)
const (
// MaxManifestSize is a max length for a valid contract manifest.
MaxManifestSize = 4096
// MethodInit is a name for default initialization method.
MethodInit = "_initialize"
// MethodDeploy is a name for default method called during contract deployment.
MethodDeploy = "_deploy"
// MethodVerify is a name for default verification method.
MethodVerify = "verify"
// NEP5StandardName represents the name of NEP5 smartcontract standard.
NEP5StandardName = "NEP-5"
// NEP10StandardName represents the name of NEP10 smartcontract standard.
NEP10StandardName = "NEP-10"
)
// ABI represents a contract application binary interface.
type ABI struct {
Hash util.Uint160 `json:"hash"`
Methods []Method `json:"methods"`
Events []Event `json:"events"`
}
// Manifest represens contract metadata.
type Manifest struct {
2020-11-20 08:02:58 +00:00
// Name is a contract's name.
Name string `json:"name"`
// ABI is a contract's ABI.
2020-11-13 18:46:26 +00:00
ABI ABI `json:"abi"`
// Groups is a set of groups to which a contract belongs.
2020-11-13 18:46:26 +00:00
Groups []Group `json:"groups"`
Permissions []Permission `json:"permissions"`
// SupportedStandards is a list of standards supported by the contract.
2020-11-13 18:46:26 +00:00
SupportedStandards []string `json:"supportedstandards"`
// Trusts is a set of hashes to a which contract trusts.
2020-11-13 18:46:26 +00:00
Trusts WildUint160s `json:"trusts"`
// SafeMethods is a set of names of safe methods.
2020-11-13 18:46:26 +00:00
SafeMethods WildStrings `json:"safemethods"`
// Extra is an implementation-defined user data.
2020-11-13 18:46:26 +00:00
Extra interface{} `json:"extra"`
}
// NewManifest returns new manifest with necessary fields initialized.
2020-11-20 08:02:58 +00:00
func NewManifest(h util.Uint160, name string) *Manifest {
m := &Manifest{
2020-11-20 08:02:58 +00:00
Name: name,
ABI: ABI{
Hash: h,
Methods: []Method{},
Events: []Event{},
},
Groups: []Group{},
SupportedStandards: []string{},
}
m.Trusts.Restrict()
m.SafeMethods.Restrict()
return m
}
// DefaultManifest returns default contract manifest.
2020-11-20 08:02:58 +00:00
func DefaultManifest(h util.Uint160, name string) *Manifest {
m := NewManifest(h, name)
m.Permissions = []Permission{*NewPermission(PermissionWildcard)}
return m
}
// GetMethod returns methods with the specified name.
func (a *ABI) GetMethod(name string) *Method {
for i := range a.Methods {
if a.Methods[i].Name == name {
return &a.Methods[i]
}
}
return nil
}
// CanCall returns true is current contract is allowed to call
// method of another contract.
func (m *Manifest) CanCall(toCall *Manifest, method string) bool {
// this if is not present in the original code but should probably be here
if toCall.SafeMethods.Contains(method) {
return true
}
for i := range m.Permissions {
if m.Permissions[i].IsAllowed(toCall, method) {
return true
}
}
return false
}
// IsValid checks whether the given hash is the one specified in manifest and
// verifies it against all the keys in manifest groups.
func (m *Manifest) IsValid(hash util.Uint160) bool {
if m.ABI.Hash != hash {
return false
}
for _, g := range m.Groups {
if !g.IsValid(hash) {
return false
}
}
return true
}
2020-06-09 09:12:56 +00:00
// EncodeBinary implements io.Serializable.
func (m *Manifest) EncodeBinary(w *io.BinWriter) {
data, err := json.Marshal(m)
if err != nil {
w.Err = err
return
}
w.WriteVarBytes(data)
}
// DecodeBinary implements io.Serializable.
func (m *Manifest) DecodeBinary(r *io.BinReader) {
2020-10-07 15:29:19 +00:00
data := r.ReadVarBytes(MaxManifestSize)
2020-06-09 09:12:56 +00:00
if r.Err != nil {
return
} else if err := json.Unmarshal(data, m); err != nil {
r.Err = err
}
}