2021-08-02 08:10:26 +00:00
|
|
|
package smartcontract
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
2022-08-05 10:32:37 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
2021-08-02 08:10:26 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
2023-12-04 14:02:44 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/cli/options"
|
2021-08-02 08:10:26 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
2022-08-22 10:41:57 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2024-07-09 18:24:39 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
2021-08-02 08:10:26 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func manifestAddGroup(ctx *cli.Context) error {
|
2022-08-05 10:32:37 +00:00
|
|
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-07-12 08:57:59 +00:00
|
|
|
sender := ctx.Generic("sender").(*flags.Address)
|
2021-08-02 08:10:26 +00:00
|
|
|
nf, _, err := readNEFFile(ctx.String("nef"))
|
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("can't read NEF file: %w", err), 1)
|
2021-08-02 08:10:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mPath := ctx.String("manifest")
|
2022-08-22 10:41:57 +00:00
|
|
|
m, _, err := readManifest(mPath, util.Uint160{})
|
2021-08-02 08:10:26 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("can't read contract manifest: %w", err), 1)
|
2021-08-02 08:10:26 +00:00
|
|
|
}
|
|
|
|
|
2024-07-12 08:57:59 +00:00
|
|
|
h := state.CreateContractHash(sender.Uint160(), nf.Checksum, m.Name)
|
2021-08-02 08:10:26 +00:00
|
|
|
|
2023-12-04 14:02:44 +00:00
|
|
|
gAcc, w, err := options.GetAccFromContext(ctx)
|
2021-08-02 08:10:26 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("can't get account to sign group with: %w", err), 1)
|
2021-08-02 08:10:26 +00:00
|
|
|
}
|
2022-09-01 18:44:49 +00:00
|
|
|
defer w.Close()
|
2021-08-02 08:10:26 +00:00
|
|
|
|
|
|
|
var found bool
|
|
|
|
|
|
|
|
sig := gAcc.PrivateKey().Sign(h.BytesBE())
|
2022-09-01 14:52:44 +00:00
|
|
|
pub := gAcc.PublicKey()
|
2021-08-02 08:10:26 +00:00
|
|
|
for i := range m.Groups {
|
|
|
|
if m.Groups[i].PublicKey.Equal(pub) {
|
|
|
|
m.Groups[i].Signature = sig
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !found {
|
|
|
|
m.Groups = append(m.Groups, manifest.Group{
|
|
|
|
PublicKey: pub,
|
|
|
|
Signature: sig,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
rawM, err := json.Marshal(m)
|
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("can't marshal manifest: %w", err), 1)
|
2021-08-02 08:10:26 +00:00
|
|
|
}
|
|
|
|
|
2022-02-22 16:27:32 +00:00
|
|
|
err = os.WriteFile(mPath, rawM, os.ModePerm)
|
2021-08-02 08:10:26 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(fmt.Errorf("can't write manifest file: %w", err), 1)
|
2021-08-02 08:10:26 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func readNEFFile(filename string) (*nef.File, []byte, error) {
|
2022-02-22 16:27:32 +00:00
|
|
|
f, err := os.ReadFile(filename)
|
2021-08-02 08:10:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
nefFile, err := nef.FileFromBytes(f)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, fmt.Errorf("can't parse NEF file: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &nefFile, f, nil
|
|
|
|
}
|
|
|
|
|
2022-08-22 10:41:57 +00:00
|
|
|
// readManifest unmarshalls manifest got from the provided filename and checks
|
|
|
|
// it for validness against the provided contract hash. If empty hash is specified
|
|
|
|
// then no hash-related manifest groups check is performed.
|
|
|
|
func readManifest(filename string, hash util.Uint160) (*manifest.Manifest, []byte, error) {
|
2022-02-22 16:27:32 +00:00
|
|
|
manifestBytes, err := os.ReadFile(filename)
|
2021-08-02 08:10:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
m := new(manifest.Manifest)
|
|
|
|
err = json.Unmarshal(manifestBytes, m)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
2023-11-22 17:15:43 +00:00
|
|
|
if err := m.IsValid(hash, true); err != nil {
|
2022-08-22 10:41:57 +00:00
|
|
|
return nil, nil, fmt.Errorf("manifest is invalid: %w", err)
|
|
|
|
}
|
2021-08-02 08:10:26 +00:00
|
|
|
return m, manifestBytes, nil
|
|
|
|
}
|