Merge pull request #1907 from nspcc-dev/cli/deploy_with_data

cli: allow to provide 'data' for 'contract deploy' command
This commit is contained in:
Roman Khimov 2021-04-19 13:16:00 +03:00 committed by GitHub
commit 6be5d69fb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 4 deletions

View file

@ -168,6 +168,64 @@ func TestDeployBigContract(t *testing.T) {
"--in", nefName, "--manifest", manifestName) "--in", nefName, "--manifest", manifestName)
} }
func TestContractDeployWithData(t *testing.T) {
e := newExecutor(t, true)
// For proper nef generation.
config.Version = "0.90.0-test"
tmpDir := path.Join(os.TempDir(), "neogo.test.deployfail")
require.NoError(t, os.Mkdir(tmpDir, os.ModePerm))
t.Cleanup(func() {
os.RemoveAll(tmpDir)
})
nefName := path.Join(tmpDir, "deploy.nef")
manifestName := path.Join(tmpDir, "deploy.manifest.json")
e.Run(t, "neo-go", "contract", "compile",
"--in", "testdata/deploy/main.go", // compile single file
"--config", "testdata/deploy/neo-go.yml",
"--out", nefName, "--manifest", manifestName)
e.In.WriteString("one\r")
e.Run(t, "neo-go", "contract", "deploy",
"--rpc-endpoint", "http://"+e.RPC.Addr,
"--wallet", validatorWallet, "--address", validatorAddr,
"--in", nefName, "--manifest", manifestName,
"[", "key1", "12", "key2", "take_me_to_church", "]")
line, err := e.Out.ReadString('\n')
require.NoError(t, err)
line = strings.TrimSpace(strings.TrimPrefix(line, "Contract: "))
h, err := util.Uint160DecodeStringLE(line)
require.NoError(t, err)
e.checkTxPersisted(t)
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
h.StringLE(),
"getValueWithKey", "key1",
)
res := new(result.Invoke)
require.NoError(t, json.Unmarshal(e.Out.Bytes(), res))
require.Equal(t, vm.HaltState.String(), res.State, res.FaultException)
require.Len(t, res.Stack, 1)
require.Equal(t, []byte{12}, res.Stack[0].Value())
e.Run(t, "neo-go", "contract", "testinvokefunction",
"--rpc-endpoint", "http://"+e.RPC.Addr,
h.StringLE(),
"getValueWithKey", "key2",
)
res = new(result.Invoke)
require.NoError(t, json.Unmarshal(e.Out.Bytes(), res))
require.Equal(t, vm.HaltState.String(), res.State, res.FaultException)
require.Len(t, res.Stack, 1)
require.Equal(t, []byte("take_me_to_church"), res.Stack[0].Value())
}
func TestComlileAndInvokeFunction(t *testing.T) { func TestComlileAndInvokeFunction(t *testing.T) {
e := newExecutor(t, true) e := newExecutor(t, true)

View file

@ -171,8 +171,10 @@ func NewCommands() []cli.Command {
{ {
Name: "deploy", Name: "deploy",
Usage: "deploy a smart contract (.nef with description)", Usage: "deploy a smart contract (.nef with description)",
UsageText: "neo-go contract deploy -r endpoint -w wallet [-a address] [-g gas] --in contract.nef --manifest contract.manifest.json [--out file] [data]",
Description: `Deploys given contract into the chain. The gas parameter is for additional Description: `Deploys given contract into the chain. The gas parameter is for additional
gas to be added as a network fee to prioritize the transaction. gas to be added as a network fee to prioritize the transaction. The data
parameter is an optional parameter to be passed to '_deploy' method.
`, `,
Action: contractDeploy, Action: contractDeploy,
Flags: deployFlags, Flags: deployFlags,
@ -836,6 +838,15 @@ func contractDeploy(ctx *cli.Context) error {
return cli.NewExitError(fmt.Errorf("failed to restore manifest file: %w", err), 1) return cli.NewExitError(fmt.Errorf("failed to restore manifest file: %w", err), 1)
} }
data, extErr := GetDataFromContext(ctx)
if extErr != nil {
return extErr
}
appCallParams := []interface{}{f, manifestBytes}
if data != nil {
appCallParams = append(appCallParams, data)
}
gctx, cancel := options.GetTimeoutContext(ctx) gctx, cancel := options.GetTimeoutContext(ctx)
defer cancel() defer cancel()
@ -851,7 +862,7 @@ func contractDeploy(ctx *cli.Context) error {
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
emit.AppCall(buf.BinWriter, mgmtHash, "deploy", emit.AppCall(buf.BinWriter, mgmtHash, "deploy",
callflag.ReadStates|callflag.WriteStates|callflag.AllowNotify, callflag.ReadStates|callflag.WriteStates|callflag.AllowNotify,
f, manifestBytes) appCallParams...)
if buf.Err != nil { if buf.Err != nil {
return cli.NewExitError(fmt.Errorf("failed to create deployment script: %w", buf.Err), 1) return cli.NewExitError(fmt.Errorf("failed to create deployment script: %w", buf.Err), 1)
} }

View file

@ -23,6 +23,13 @@ func _deploy(data interface{}, isUpdate bool) {
value = "on create" value = "on create"
sh := runtime.GetCallingScriptHash() sh := runtime.GetCallingScriptHash()
storage.Put(ctx, mgmtKey, sh) storage.Put(ctx, mgmtKey, sh)
if data != nil {
arr := data.([]interface{})
for i := 0; i < len(arr)-1; i += 2 {
storage.Put(ctx, arr[i], arr[i+1])
}
}
} }
storage.Put(ctx, key, value) storage.Put(ctx, key, value)
@ -48,6 +55,12 @@ func GetValue() string {
return val1.(string) + "|" + val2.(string) return val1.(string) + "|" + val2.(string)
} }
// GetValueWithKey returns stored value with the specified key.
func GetValueWithKey(key string) string {
ctx := storage.GetReadOnlyContext()
return storage.Get(ctx, key).(string)
}
// TestFind finds items with the specified prefix. // TestFind finds items with the specified prefix.
func TestFind(f storage.FindFlags) []interface{} { func TestFind(f storage.FindFlags) []interface{} {
ctx := storage.GetContext() ctx := storage.GetContext()