mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-23 13:41:37 +00:00
123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
|
package smartcontract
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
|
||
|
"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/wallet"
|
||
|
"github.com/urfave/cli"
|
||
|
)
|
||
|
|
||
|
func manifestAddGroup(ctx *cli.Context) error {
|
||
|
walletPath := ctx.String("wallet")
|
||
|
if len(walletPath) == 0 {
|
||
|
return cli.NewExitError(errNoWallet, 1)
|
||
|
}
|
||
|
|
||
|
w, err := wallet.NewWalletFromFile(walletPath)
|
||
|
if err != nil {
|
||
|
return cli.NewExitError(err, 1)
|
||
|
}
|
||
|
defer w.Close()
|
||
|
|
||
|
addr, err := flags.ParseAddress(ctx.String("account"))
|
||
|
if err != nil {
|
||
|
return cli.NewExitError(errors.New("address is missing"), 1)
|
||
|
}
|
||
|
|
||
|
sender, err := flags.ParseAddress(ctx.String("sender"))
|
||
|
if err != nil {
|
||
|
return cli.NewExitError("invalid sender", 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)
|
||
|
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 := getUnlockedAccount(w, addr)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var found bool
|
||
|
|
||
|
sig := gAcc.PrivateKey().Sign(h.BytesBE())
|
||
|
pub := gAcc.PrivateKey().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 = ioutil.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 := ioutil.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
|
||
|
}
|
||
|
|
||
|
func readManifest(filename string) (*manifest.Manifest, []byte, error) {
|
||
|
if len(filename) == 0 {
|
||
|
return nil, nil, errNoManifestFile
|
||
|
}
|
||
|
|
||
|
manifestBytes, err := ioutil.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
|
||
|
}
|
||
|
return m, manifestBytes, nil
|
||
|
}
|