-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide embedded compiled NeoFS contracts
There is a need to embed NeoFS contracts' executables in NeoFS Inner Ring application. To do this, `contracts` directory is created. The dir contains compiled contracts (per-contract NEF and manifest). Create eponymous Go package that provides embedded `fs.FS` with the contracts. Add `Read` function which reads, decodes and validates all NeoFS contracts from files and returns ready-to-go data for deployment. Refs #2195. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
- Loading branch information
1 parent
93733ff
commit 07f83f7
Showing
23 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name":"NeoFS Alphabet","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":35,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"emit","offset":2900,"parameters":[],"returntype":"Void","safe":false},{"name":"gas","offset":2721,"parameters":[],"returntype":"Integer","safe":true},{"name":"name","offset":3531,"parameters":[],"returntype":"String","safe":true},{"name":"neo","offset":2735,"parameters":[],"returntype":"Integer","safe":true},{"name":"onNEP17Payment","offset":914,"parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"update","offset":2589,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"version","offset":3547,"parameters":[],"returntype":"Integer","safe":true},{"name":"vote","offset":3359,"parameters":[{"name":"epoch","type":"Integer"},{"name":"candidates","type":"Array"}],"returntype":"Void","safe":false}],"events":[]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","transfer","vote"]}],"supportedstandards":[],"trusts":[],"extra":null} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name":"NeoFS Audit","abi":{"methods":[{"name":"_deploy","offset":0,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"get","offset":892,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"list","offset":917,"parameters":[],"returntype":"Array","safe":true},{"name":"listByCID","offset":983,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listByEpoch","offset":951,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"listByNode","offset":1026,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"key","type":"PublicKey"}],"returntype":"Array","safe":true},{"name":"put","offset":745,"parameters":[{"name":"rawAuditResult","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"update","offset":616,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"version","offset":1104,"parameters":[],"returntype":"Integer","safe":true}],"events":[]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update"]}],"supportedstandards":[],"trusts":[],"extra":null} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name":"NeoFS Balance","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":93,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"balanceOf","offset":1104,"parameters":[{"name":"account","type":"Hash160"}],"returntype":"Integer","safe":true},{"name":"burn","offset":1656,"parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"txDetails","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"decimals","offset":1082,"parameters":[],"returntype":"Integer","safe":true},{"name":"lock","offset":1250,"parameters":[{"name":"txDetails","type":"ByteArray"},{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"until","type":"Integer"}],"returntype":"Void","safe":false},{"name":"mint","offset":1516,"parameters":[{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"txDetails","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"newEpoch","offset":1387,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"symbol","offset":1078,"parameters":[],"returntype":"String","safe":true},{"name":"totalSupply","offset":1086,"parameters":[],"returntype":"Integer","safe":true},{"name":"transfer","offset":1123,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","safe":false},{"name":"transferX","offset":1147,"parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"details","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"update","offset":947,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"version","offset":1826,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"Lock","parameters":[{"name":"txID","type":"ByteArray"},{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"until","type":"Integer"}]},{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"TransferX","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"details","type":"ByteArray"}]},{"name":"Mint","parameters":[{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"Burn","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update"]}],"supportedstandards":["NEP-17"],"trusts":[],"extra":null} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name":"NeoFS Container","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":83,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"containersOf","offset":3109,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"InteropInterface","safe":true},{"name":"count","offset":3064,"parameters":[],"returntype":"Integer","safe":true},{"name":"delete","offset":2655,"parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"eACL","offset":3418,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"get","offset":2951,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"getContainerSize","offset":3678,"parameters":[{"name":"id","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"iterateAllContainerSizes","offset":4051,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"InteropInterface","safe":true},{"name":"iterateContainerSizes","offset":3953,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"Hash256"}],"returntype":"InteropInterface","safe":true},{"name":"list","offset":3163,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"listContainerSizes","offset":3792,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Array","safe":true},{"name":"newEpoch","offset":4103,"parameters":[{"name":"epochNum","type":"Integer"}],"returntype":"Void","safe":false},{"name":"onNEP11Payment","offset":1137,"parameters":[{"name":"a","type":"Hash160"},{"name":"b","type":"Integer"},{"name":"c","type":"ByteArray"},{"name":"d","type":"Any"}],"returntype":"Void","safe":false},{"name":"owner","offset":3013,"parameters":[{"name":"containerID","type":"ByteArray"}],"returntype":"ByteArray","safe":true},{"name":"put","offset":1571,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"putContainerSize","offset":3476,"parameters":[{"name":"epoch","type":"Integer"},{"name":"cid","type":"ByteArray"},{"name":"usedSize","type":"Integer"},{"name":"pubKey","type":"PublicKey"}],"returntype":"Void","safe":false},{"name":"putNamed","offset":1587,"parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"},{"name":"name","type":"String"},{"name":"zone","type":"String"}],"returntype":"Void","safe":false},{"name":"setEACL","offset":3259,"parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}],"returntype":"Void","safe":false},{"name":"startContainerEstimation","offset":4133,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"stopContainerEstimation","offset":4214,"parameters":[{"name":"epoch","type":"Integer"}],"returntype":"Void","safe":false},{"name":"update","offset":1438,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"version","offset":4294,"parameters":[],"returntype":"Integer","safe":true}],"events":[{"name":"containerPut","parameters":[{"name":"container","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}]},{"name":"PutSuccess","parameters":[{"name":"containerID","type":"Hash256"},{"name":"publicKey","type":"PublicKey"}]},{"name":"containerDelete","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"token","type":"ByteArray"}]},{"name":"DeleteSuccess","parameters":[{"name":"containerID","type":"ByteArray"}]},{"name":"setEACL","parameters":[{"name":"eACL","type":"ByteArray"},{"name":"signature","type":"Signature"},{"name":"publicKey","type":"PublicKey"},{"name":"token","type":"ByteArray"}]},{"name":"SetEACLSuccess","parameters":[{"name":"containerID","type":"ByteArray"},{"name":"publicKey","type":"PublicKey"}]},{"name":"StartEstimation","parameters":[{"name":"epoch","type":"Integer"}]},{"name":"StopEstimation","parameters":[{"name":"epoch","type":"Integer"}]}]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update","addKey","transferX","register","addRecord","deleteRecords"]}],"supportedstandards":[],"trusts":[],"extra":null} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/* | ||
Package contracts embeds compiled NeoFS contracts and provides access to them. | ||
Contracts' source code is located in https://github.com/nspcc-dev/neofs-contract. | ||
*/ | ||
package contracts | ||
|
||
import ( | ||
"embed" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io/fs" | ||
|
||
"github.com/nspcc-dev/neo-go/pkg/io" | ||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" | ||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" | ||
) | ||
|
||
// Contract represents compiled NeoFS contract. | ||
type Contract struct { | ||
NEF nef.File | ||
Manifest manifest.Manifest | ||
} | ||
|
||
// Contracts groups all compiled NeoFS contracts. | ||
type Contracts struct { | ||
Alphabet Contract | ||
Audit Contract | ||
Balance Contract | ||
Container Contract | ||
NeoFSID Contract | ||
Netmap Contract | ||
NNS Contract | ||
Proxy Contract | ||
Reputation Contract | ||
Subnet Contract | ||
} | ||
|
||
//go:embed *-contract.nef *-contract.manifest.json | ||
var _fs embed.FS | ||
|
||
// Read reads compiled NeoFS contracts stored in the package directory into | ||
// Contracts instance and returns it. | ||
// | ||
// File schema: | ||
// - compiled executables (NEF) are named by pattern '*-contract.nef' | ||
// - manifests are named by pattern '*-contract.manifest.json' | ||
// | ||
// where asterisk stands for contract names: | ||
// - alphabet (NeoFS Alphabet) | ||
// - audit (NeoFS Audit) | ||
// - balance (NeoFS Balance) | ||
// - container (NeoFS Container) | ||
// - neofsid (NeoFS ID) | ||
// - netmap (NeoFS Netmap) | ||
// - nns (NameService) | ||
// - proxy (NeoFS Notary Proxy) | ||
// - reputation (NeoFS Reputation) | ||
// - subnet (NeoFS Subnet) | ||
// | ||
// Read fails if any of the NeoFS contract files is missing, invalid or has | ||
// different name in the manifest. | ||
func Read() (Contracts, error) { | ||
return read(_fs) | ||
} | ||
|
||
var ( | ||
errInvalidNEF = errors.New("invalid NEF") | ||
errInvalidManifest = errors.New("invalid manifest") | ||
errInvalidName = errors.New("invalid name") | ||
) | ||
|
||
// read same as Read by allows to override source fs.FS. | ||
func read(_fs fs.FS) (res Contracts, err error) { | ||
for filePrefix, item := range map[string]struct { | ||
cPtr *Contract | ||
name string | ||
}{ | ||
"alphabet": {&res.Alphabet, "NeoFS Alphabet"}, | ||
"audit": {&res.Audit, "NeoFS Audit"}, | ||
"balance": {&res.Balance, "NeoFS Balance"}, | ||
"container": {&res.Container, "NeoFS Container"}, | ||
"neofsid": {&res.NeoFSID, "NeoFS ID"}, | ||
"netmap": {&res.Netmap, "NeoFS Netmap"}, | ||
"nns": {&res.NNS, "NameService"}, | ||
"proxy": {&res.Proxy, "NeoFS Notary Proxy"}, | ||
"reputation": {&res.Reputation, "NeoFS Reputation"}, | ||
"subnet": {&res.Subnet, "NeoFS Subnet"}, | ||
} { | ||
err = readContractFromFiles(item.cPtr, _fs, filePrefix) | ||
if err != nil { | ||
return res, fmt.Errorf("read contract from '%s*' files: %w", filePrefix, err) | ||
} | ||
|
||
if item.cPtr.Manifest.Name != item.name { | ||
return res, fmt.Errorf("%w: expected '%s', got '%s'", errInvalidName, item.name, item.cPtr.Manifest.Name) | ||
} | ||
} | ||
|
||
return res, nil | ||
} | ||
|
||
func readContractFromFiles(c *Contract, _fs fs.FS, filePrefix string) error { | ||
fNEF, err := _fs.Open(filePrefix + "-contract.nef") | ||
if err != nil { | ||
return fmt.Errorf("open file containing contract NEF: %w", err) | ||
} | ||
defer fNEF.Close() | ||
|
||
fManifest, err := _fs.Open(filePrefix + "-contract.manifest.json") | ||
if err != nil { | ||
return fmt.Errorf("open file containing contract NEF: %w", err) | ||
} | ||
defer fManifest.Close() | ||
|
||
bReader := io.NewBinReaderFromIO(fNEF) | ||
c.NEF.DecodeBinary(bReader) | ||
if bReader.Err != nil { | ||
return fmt.Errorf("%w: %v", errInvalidNEF, bReader.Err) | ||
} | ||
|
||
err = json.NewDecoder(fManifest).Decode(&c.Manifest) | ||
if err != nil { | ||
return fmt.Errorf("%w: %v", errInvalidManifest, err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package contracts | ||
|
||
import ( | ||
"crypto/rand" | ||
"encoding/json" | ||
"io/fs" | ||
"testing" | ||
"testing/fstest" | ||
|
||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" | ||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetDir(t *testing.T) { | ||
cs, err := Read() | ||
require.NoError(t, err) | ||
|
||
for _, item := range []struct { | ||
c Contract | ||
name string | ||
}{ | ||
{cs.Alphabet, "NeoFS Alphabet"}, | ||
{cs.Audit, "NeoFS Audit"}, | ||
{cs.Balance, "NeoFS Balance"}, | ||
{cs.Container, "NeoFS Container"}, | ||
{cs.NeoFSID, "NeoFS ID"}, | ||
{cs.Netmap, "NeoFS Netmap"}, | ||
{cs.NNS, "NameService"}, | ||
{cs.Proxy, "NeoFS Notary Proxy"}, | ||
{cs.Reputation, "NeoFS Reputation"}, | ||
{cs.Subnet, "NeoFS Subnet"}, | ||
} { | ||
require.Equal(t, item.name, item.c.Manifest.Name) | ||
} | ||
} | ||
|
||
func TestGet(t *testing.T) { | ||
_fs := fstest.MapFS{} | ||
|
||
cs := []struct { | ||
filePrefix string | ||
name string | ||
}{ | ||
{"alphabet", "NeoFS Alphabet"}, | ||
{"audit", "NeoFS Audit"}, | ||
{"balance", "NeoFS Balance"}, | ||
{"container", "NeoFS Container"}, | ||
{"neofsid", "NeoFS ID"}, | ||
{"netmap", "NeoFS Netmap"}, | ||
{"nns", "NameService"}, | ||
{"proxy", "NeoFS Notary Proxy"}, | ||
{"reputation", "NeoFS Reputation"}, | ||
{"subnet", "NeoFS Subnet"}, | ||
} | ||
|
||
nefFileWithPrefix := func(prefix string) string { return prefix + "-contract.nef" } | ||
manifestFileWithPrefix := func(prefix string) string { return prefix + "-contract.manifest.json" } | ||
|
||
for _, c := range cs { | ||
script := make([]byte, 32) | ||
rand.Read(script) | ||
|
||
_nef, err := nef.NewFile(script) | ||
require.NoError(t, err) | ||
|
||
bNEF, err := _nef.Bytes() | ||
require.NoError(t, err) | ||
|
||
jManifest, err := json.Marshal(manifest.NewManifest(c.name)) | ||
require.NoError(t, err) | ||
|
||
_fs[nefFileWithPrefix(c.filePrefix)] = &fstest.MapFile{Data: bNEF} | ||
_fs[manifestFileWithPrefix(c.filePrefix)] = &fstest.MapFile{Data: jManifest} | ||
} | ||
|
||
_, err := read(_fs) | ||
require.NoError(t, err) | ||
|
||
for _, c := range cs { | ||
filename := nefFileWithPrefix(c.filePrefix) | ||
fCp := _fs[filename] | ||
|
||
delete(_fs, filename) | ||
|
||
_, err = read(_fs) | ||
require.ErrorIs(t, err, fs.ErrNotExist) | ||
|
||
_fs[filename] = &fstest.MapFile{Data: []byte("invalid NEF")} | ||
|
||
_, err = read(_fs) | ||
require.ErrorIs(t, err, errInvalidNEF) | ||
|
||
_fs[filename] = fCp | ||
|
||
_, err = read(_fs) | ||
require.NoError(t, err) | ||
|
||
filename = manifestFileWithPrefix(c.filePrefix) | ||
fCp = _fs[filename] | ||
|
||
delete(_fs, filename) | ||
|
||
_, err = read(_fs) | ||
require.ErrorIs(t, err, fs.ErrNotExist) | ||
|
||
_fs[filename] = &fstest.MapFile{Data: []byte("invalid manifest")} | ||
|
||
_, err = read(_fs) | ||
require.ErrorIs(t, err, errInvalidManifest) | ||
|
||
jWrongNameManifest, err := json.Marshal(manifest.NewManifest(c.name + "1")) | ||
require.NoError(t, err) | ||
|
||
_fs[filename] = &fstest.MapFile{Data: jWrongNameManifest} | ||
|
||
_, err = read(_fs) | ||
require.ErrorIs(t, err, errInvalidName) | ||
|
||
_fs[filename] = fCp | ||
|
||
_, err = read(_fs) | ||
require.NoError(t, err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"name":"NeoFS ID","abi":{"methods":[{"name":"_initialize","offset":0,"parameters":[],"returntype":"Void","safe":false},{"name":"_deploy","offset":35,"parameters":[{"name":"data","type":"Any"},{"name":"isUpdate","type":"Boolean"}],"returntype":"Void","safe":false},{"name":"addKey","offset":1030,"parameters":[{"name":"owner","type":"ByteArray"},{"name":"keys","type":"Array"}],"returntype":"Void","safe":false},{"name":"key","offset":1442,"parameters":[{"name":"owner","type":"ByteArray"}],"returntype":"Array","safe":true},{"name":"removeKey","offset":1235,"parameters":[{"name":"owner","type":"ByteArray"},{"name":"keys","type":"Array"}],"returntype":"Void","safe":false},{"name":"update","offset":899,"parameters":[{"name":"script","type":"ByteArray"},{"name":"manifest","type":"ByteArray"},{"name":"data","type":"Any"}],"returntype":"Void","safe":false},{"name":"version","offset":1513,"parameters":[],"returntype":"Integer","safe":true}],"events":[]},"features":{},"groups":[],"permissions":[{"contract":"*","methods":["update"]}],"supportedstandards":[],"trusts":[],"extra":null} |
Binary file not shown.
Oops, something went wrong.