Merge pull request #1607 from nspcc-dev/compiler/safe
Set `Safe` flag in emitted manifest
This commit is contained in:
commit
1d529dc5b6
10 changed files with 39 additions and 46 deletions
|
@ -363,6 +363,7 @@ func initSmartContract(ctx *cli.Context) error {
|
|||
m := ProjectConfig{
|
||||
Name: contractName,
|
||||
SupportedStandards: []string{},
|
||||
SafeMethods: []string{},
|
||||
Events: []manifest.Event{
|
||||
{
|
||||
Name: "Hello world!",
|
||||
|
@ -423,6 +424,7 @@ func contractCompile(ctx *cli.Context) error {
|
|||
o.Name = conf.Name
|
||||
o.ContractEvents = conf.Events
|
||||
o.ContractSupportedStandards = conf.SupportedStandards
|
||||
o.SafeMethods = conf.SafeMethods
|
||||
}
|
||||
|
||||
result, err := compiler.CompileAndSave(src, o)
|
||||
|
@ -646,6 +648,7 @@ func testInvokeScript(ctx *cli.Context) error {
|
|||
// ProjectConfig contains project metadata.
|
||||
type ProjectConfig struct {
|
||||
Name string
|
||||
SafeMethods []string
|
||||
SupportedStandards []string
|
||||
Events []manifest.Event
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ func RuntimeNotify(args []interface{}) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
`name: testContract
|
||||
safemethods: []
|
||||
supportedstandards: []
|
||||
events:
|
||||
- name: Hello world!
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: "My awesome token"
|
||||
supportedstandards: ["NEP-17"]
|
||||
safemethods: ["balanceOf", "decimals", "symbol", "totalSupply"]
|
||||
events:
|
||||
- name: Transfer
|
||||
parameters:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
name: "Awesome NEO Token"
|
||||
supportedstandards: ["NEP-17"]
|
||||
safemethods: ["balanceOf", "decimals", "symbol", "totalSupply"]
|
||||
events:
|
||||
- name: Transfer
|
||||
parameters:
|
||||
|
|
|
@ -62,7 +62,7 @@ func NewDeployTx(name string, sender util.Uint160, r gio.Reader) (*transaction.T
|
|||
return nil, util.Uint160{}, err
|
||||
}
|
||||
|
||||
m, err := di.ConvertToManifest(name, nil)
|
||||
m, err := di.ConvertToManifest(&compiler.Options{Name: name})
|
||||
if err != nil {
|
||||
return nil, util.Uint160{}, err
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ type Options struct {
|
|||
|
||||
// The list of standards supported by the contract.
|
||||
ContractSupportedStandards []string
|
||||
|
||||
// SafeMethods contains list of methods which will be marked as safe in manifest.
|
||||
SafeMethods []string
|
||||
}
|
||||
|
||||
type buildInfo struct {
|
||||
|
@ -219,7 +222,7 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
|
|||
}
|
||||
|
||||
if o.ManifestFile != "" {
|
||||
m, err := di.ConvertToManifest(o.Name, o.ContractEvents, o.ContractSupportedStandards...)
|
||||
m, err := di.ConvertToManifest(o)
|
||||
if err != nil {
|
||||
return b, fmt.Errorf("failed to convert debug info to manifest: %w", err)
|
||||
}
|
||||
|
|
|
@ -334,49 +334,27 @@ func (d *DebugParam) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
|
||||
// ToManifestParameter converts DebugParam to manifest.Parameter
|
||||
func (d *DebugParam) ToManifestParameter() (manifest.Parameter, error) {
|
||||
func (d *DebugParam) ToManifestParameter() manifest.Parameter {
|
||||
return manifest.Parameter{
|
||||
Name: d.Name,
|
||||
Type: d.TypeSC,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ToManifestMethod converts MethodDebugInfo to manifest.Method
|
||||
func (m *MethodDebugInfo) ToManifestMethod() (manifest.Method, error) {
|
||||
func (m *MethodDebugInfo) ToManifestMethod() manifest.Method {
|
||||
var (
|
||||
result manifest.Method
|
||||
err error
|
||||
)
|
||||
parameters := make([]manifest.Parameter, len(m.Parameters))
|
||||
for i, p := range m.Parameters {
|
||||
parameters[i], err = p.ToManifestParameter()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
parameters[i] = p.ToManifestParameter()
|
||||
}
|
||||
result.Name = m.Name.Name
|
||||
result.Offset = int(m.Range.Start)
|
||||
result.Parameters = parameters
|
||||
result.ReturnType = m.ReturnTypeSC
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ToManifestEvent converts EventDebugInfo to manifest.Event
|
||||
func (e *EventDebugInfo) ToManifestEvent() (manifest.Event, error) {
|
||||
var (
|
||||
result manifest.Event
|
||||
err error
|
||||
)
|
||||
parameters := make([]manifest.Parameter, len(e.Parameters))
|
||||
for i, p := range e.Parameters {
|
||||
parameters[i], err = p.ToManifestParameter()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
result.Name = e.Name
|
||||
result.Parameters = parameters
|
||||
return result, nil
|
||||
return result
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
|
@ -425,31 +403,31 @@ func parsePairJSON(data []byte, sep string) (string, string, error) {
|
|||
|
||||
// ConvertToManifest converts contract to the manifest.Manifest struct for debugger.
|
||||
// Note: manifest is taken from the external source, however it can be generated ad-hoc. See #1038.
|
||||
func (di *DebugInfo) ConvertToManifest(name string, events []manifest.Event, supportedStandards ...string) (*manifest.Manifest, error) {
|
||||
if di.MainPkg == "" {
|
||||
return nil, errors.New("no Main method was found")
|
||||
}
|
||||
func (di *DebugInfo) ConvertToManifest(o *Options) (*manifest.Manifest, error) {
|
||||
methods := make([]manifest.Method, 0)
|
||||
for _, method := range di.Methods {
|
||||
if method.IsExported && method.IsFunction && method.Name.Namespace == di.MainPkg {
|
||||
mMethod, err := method.ToManifestMethod()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
mMethod := method.ToManifestMethod()
|
||||
for i := range o.SafeMethods {
|
||||
if mMethod.Name == o.SafeMethods[i] {
|
||||
mMethod.Safe = true
|
||||
break
|
||||
}
|
||||
}
|
||||
methods = append(methods, mMethod)
|
||||
}
|
||||
}
|
||||
|
||||
result := manifest.NewManifest(name)
|
||||
if supportedStandards != nil {
|
||||
result.SupportedStandards = supportedStandards
|
||||
}
|
||||
if events == nil {
|
||||
events = make([]manifest.Event, 0)
|
||||
result := manifest.NewManifest(o.Name)
|
||||
if o.ContractSupportedStandards != nil {
|
||||
result.SupportedStandards = o.ContractSupportedStandards
|
||||
}
|
||||
result.ABI = manifest.ABI{
|
||||
Methods: methods,
|
||||
Events: events,
|
||||
Events: o.ContractEvents,
|
||||
}
|
||||
if result.ABI.Events == nil {
|
||||
result.ABI.Events = make([]manifest.Event, 0)
|
||||
}
|
||||
result.Permissions = []manifest.Permission{
|
||||
{
|
||||
|
|
|
@ -150,7 +150,7 @@ func _deploy(isUpdate bool) {}
|
|||
}
|
||||
|
||||
t.Run("convert to Manifest", func(t *testing.T) {
|
||||
actual, err := d.ConvertToManifest("MyCTR", nil)
|
||||
actual, err := d.ConvertToManifest(&Options{Name: "MyCTR", SafeMethods: []string{"methodInt", "methodString"}})
|
||||
require.NoError(t, err)
|
||||
// note: offsets are hard to predict, so we just take them from the output
|
||||
expected := &manifest.Manifest{
|
||||
|
@ -183,12 +183,14 @@ func _deploy(isUpdate bool) {}
|
|||
},
|
||||
},
|
||||
ReturnType: smartcontract.IntegerType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "methodString",
|
||||
Offset: 101,
|
||||
Parameters: []manifest.Parameter{},
|
||||
ReturnType: smartcontract.StringType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "methodByteArray",
|
||||
|
|
|
@ -128,7 +128,7 @@ func TestAppCall(t *testing.T) {
|
|||
}`
|
||||
barCtr, di, err := compiler.CompileWithDebugInfo("bar.go", strings.NewReader(srcDeep))
|
||||
require.NoError(t, err)
|
||||
mBar, err := di.ConvertToManifest("Bar", nil)
|
||||
mBar, err := di.ConvertToManifest(&compiler.Options{Name: "Bar"})
|
||||
require.NoError(t, err)
|
||||
|
||||
barH := hash.Hash160(barCtr)
|
||||
|
@ -160,7 +160,7 @@ func TestAppCall(t *testing.T) {
|
|||
|
||||
inner, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(srcInner))
|
||||
require.NoError(t, err)
|
||||
m, err := di.ConvertToManifest("Foo", nil)
|
||||
m, err := di.ConvertToManifest(&compiler.Options{Name: "Foo"})
|
||||
require.NoError(t, err)
|
||||
|
||||
ih := hash.Hash160(inner)
|
||||
|
|
|
@ -14,18 +14,22 @@ var nep17 = &manifest.Manifest{
|
|||
{Type: smartcontract.Hash160Type},
|
||||
},
|
||||
ReturnType: smartcontract.IntegerType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "decimals",
|
||||
ReturnType: smartcontract.IntegerType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "symbol",
|
||||
ReturnType: smartcontract.StringType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "totalSupply",
|
||||
ReturnType: smartcontract.IntegerType,
|
||||
Safe: true,
|
||||
},
|
||||
{
|
||||
Name: "transfer",
|
||||
|
|
Loading…
Reference in a new issue