Merge pull request #2965 from nspcc-dev/cli-ops
cli: extend `util` with `ops` command
This commit is contained in:
commit
37f7c9d9a7
2 changed files with 91 additions and 0 deletions
|
@ -1,10 +1,14 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/cli/options"
|
"github.com/nspcc-dev/neo-go/cli/options"
|
||||||
vmcli "github.com/nspcc-dev/neo-go/cli/vm"
|
vmcli "github.com/nspcc-dev/neo-go/cli/vm"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,6 +48,22 @@ func NewCommands() []cli.Command {
|
||||||
Action: txDump,
|
Action: txDump,
|
||||||
Flags: txDumpFlags,
|
Flags: txDumpFlags,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "ops",
|
||||||
|
Usage: "Pretty-print VM opcodes of the given base64- or hex- encoded script (base64 is checked first). If the input file is specified, then the script is taken from the file.",
|
||||||
|
UsageText: "ops <base64/hex-encoded script> [-i path-to-file] [--hex]",
|
||||||
|
Action: handleOps,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "in, i",
|
||||||
|
Usage: "input file containing base64- or hex- encoded script representation",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "hex",
|
||||||
|
Usage: "use hex encoding and do not check base64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -57,3 +77,35 @@ func handleParse(ctx *cli.Context) error {
|
||||||
fmt.Fprint(ctx.App.Writer, res)
|
fmt.Fprint(ctx.App.Writer, res)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleOps(ctx *cli.Context) error {
|
||||||
|
var (
|
||||||
|
s string
|
||||||
|
err error
|
||||||
|
b []byte
|
||||||
|
)
|
||||||
|
in := ctx.String("in")
|
||||||
|
if len(in) != 0 {
|
||||||
|
b, err := os.ReadFile(in)
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError(fmt.Errorf("failed to read file: %w", err), 1)
|
||||||
|
}
|
||||||
|
s = string(b)
|
||||||
|
} else {
|
||||||
|
if !ctx.Args().Present() {
|
||||||
|
return cli.NewExitError("missing script", 1)
|
||||||
|
}
|
||||||
|
s = ctx.Args()[0]
|
||||||
|
}
|
||||||
|
b, err = base64.StdEncoding.DecodeString(s)
|
||||||
|
if err != nil || ctx.Bool("hex") {
|
||||||
|
b, err = hex.DecodeString(s)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return cli.NewExitError("unknown encoding: base64 or hex are supported", 1)
|
||||||
|
}
|
||||||
|
v := vm.New()
|
||||||
|
v.LoadScript(b)
|
||||||
|
v.PrintOps(ctx.App.Writer)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package util_test
|
package util_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testcli"
|
"github.com/nspcc-dev/neo-go/internal/testcli"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUtilConvert(t *testing.T) {
|
func TestUtilConvert(t *testing.T) {
|
||||||
|
@ -24,3 +27,39 @@ func TestUtilConvert(t *testing.T) {
|
||||||
e.CheckNextLine(t, "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMDIwMQ==") // string to base64
|
e.CheckNextLine(t, "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzMDIwMQ==") // string to base64
|
||||||
e.CheckEOF(t)
|
e.CheckEOF(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUtilOps(t *testing.T) {
|
||||||
|
e := testcli.NewExecutor(t, false)
|
||||||
|
base64Str := "EUA="
|
||||||
|
hexStr := "1140"
|
||||||
|
|
||||||
|
check := func(t *testing.T) {
|
||||||
|
e.CheckNextLine(t, "INDEX.*OPCODE.*PARAMETER")
|
||||||
|
e.CheckNextLine(t, "PUSH1")
|
||||||
|
e.CheckNextLine(t, "RET")
|
||||||
|
e.CheckEOF(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "util", "ops", base64Str) // base64
|
||||||
|
check(t)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "util", "ops", hexStr) // base64 is checked firstly by default, but it's invalid script if decoded from base64
|
||||||
|
e.CheckNextLine(t, "INDEX.*OPCODE.*PARAMETER")
|
||||||
|
e.CheckNextLine(t, ".*ERROR: incorrect opcode")
|
||||||
|
e.CheckEOF(t)
|
||||||
|
|
||||||
|
e.Run(t, "neo-go", "util", "ops", "--hex", hexStr) // explicitly specify hex encoding
|
||||||
|
check(t)
|
||||||
|
|
||||||
|
e.RunWithError(t, "neo-go", "util", "ops", "%&~*") // unknown encoding
|
||||||
|
|
||||||
|
tmp := filepath.Join(t.TempDir(), "script_base64.txt")
|
||||||
|
require.NoError(t, os.WriteFile(tmp, []byte(base64Str), os.ModePerm))
|
||||||
|
e.Run(t, "neo-go", "util", "ops", "--in", tmp) // base64 from file
|
||||||
|
check(t)
|
||||||
|
|
||||||
|
tmp = filepath.Join(t.TempDir(), "script_hex.txt")
|
||||||
|
require.NoError(t, os.WriteFile(tmp, []byte(hexStr), os.ModePerm))
|
||||||
|
e.Run(t, "neo-go", "util", "ops", "--hex", "--in", tmp) // hex from file
|
||||||
|
check(t)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue