8d33206bb8
Add PublicKey() API to the Account and use it as appropriate, avoid creating additional references to the private key.
115 lines
2.8 KiB
Go
115 lines
2.8 KiB
Go
package smartcontract
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/nspcc-dev/neo-go/cli/cmdargs"
|
|
"github.com/nspcc-dev/neo-go/cli/flags"
|
|
"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"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
func manifestAddGroup(ctx *cli.Context) error {
|
|
if err := cmdargs.EnsureNone(ctx); err != nil {
|
|
return err
|
|
}
|
|
sender, err := flags.ParseAddress(ctx.String("sender"))
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("invalid sender: %w", err), 1)
|
|
}
|
|
|
|
nf, _, err := readNEFFile(ctx.String("nef"))
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("can't read NEF file: %w", err), 1)
|
|
}
|
|
|
|
mPath := ctx.String("manifest")
|
|
m, _, err := readManifest(mPath, util.Uint160{})
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("can't read contract manifest: %w", err), 1)
|
|
}
|
|
|
|
h := state.CreateContractHash(sender, nf.Checksum, m.Name)
|
|
|
|
gAcc, _, err := getAccFromContext(ctx)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("can't get account to sign group with: %w", err), 1)
|
|
}
|
|
|
|
var found bool
|
|
|
|
sig := gAcc.PrivateKey().Sign(h.BytesBE())
|
|
pub := gAcc.PublicKey()
|
|
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 {
|
|
return cli.NewExitError(fmt.Errorf("can't marshal manifest: %w", err), 1)
|
|
}
|
|
|
|
err = os.WriteFile(mPath, rawM, os.ModePerm)
|
|
if err != nil {
|
|
return cli.NewExitError(fmt.Errorf("can't write manifest file: %w", err), 1)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func readNEFFile(filename string) (*nef.File, []byte, error) {
|
|
if len(filename) == 0 {
|
|
return nil, nil, errors.New("no nef file was provided")
|
|
}
|
|
|
|
f, err := os.ReadFile(filename)
|
|
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
|
|
}
|
|
|
|
// 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) {
|
|
if len(filename) == 0 {
|
|
return nil, nil, errNoManifestFile
|
|
}
|
|
|
|
manifestBytes, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
m := new(manifest.Manifest)
|
|
err = json.Unmarshal(manifestBytes, m)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
if err := m.IsValid(hash); err != nil {
|
|
return nil, nil, fmt.Errorf("manifest is invalid: %w", err)
|
|
}
|
|
return m, manifestBytes, nil
|
|
}
|