-
Notifications
You must be signed in to change notification settings - Fork 79
/
convert.go
148 lines (142 loc) · 5.27 KB
/
convert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package util
import (
"encoding/base64"
"encoding/hex"
"fmt"
"os"
"github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/cli/options"
"github.com/nspcc-dev/neo-go/cli/txctx"
vmcli "github.com/nspcc-dev/neo-go/cli/vm"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/urfave/cli"
)
// NewCommands returns util commands for neo-go CLI.
func NewCommands() []cli.Command {
txDumpFlags := append([]cli.Flag{}, options.RPC...)
txSendFlags := append(txDumpFlags, txctx.AwaitFlag)
txCancelFlags := append([]cli.Flag{
flags.AddressFlag{
Name: "address, a",
Usage: "address to use as conflicting transaction signee (and gas source)",
},
txctx.GasFlag,
txctx.AwaitFlag,
}, options.RPC...)
txCancelFlags = append(txCancelFlags, options.Wallet...)
return []cli.Command{
{
Name: "util",
Usage: "Various helper commands",
Subcommands: []cli.Command{
{
Name: "convert",
Usage: "Convert provided argument into other possible formats",
UsageText: `convert <arg>
<arg> is an argument which is tried to be interpreted as an item of different types
and converted to other formats. Strings are escaped and output in quotes.`,
Action: handleParse,
},
{
Name: "sendtx",
Usage: "Send complete transaction stored in a context file",
UsageText: "sendtx [-r <endpoint>] <file.in> [--await]",
Description: `Sends the transaction from the given context file to the given RPC node if it's
completely signed and ready. This command expects a ContractParametersContext
JSON file for input, it can't handle binary (or hex- or base64-encoded)
transactions. If the --await flag is included, the command waits for the
transaction to be included in a block before exiting.
`,
Action: sendTx,
Flags: txSendFlags,
},
{
Name: "canceltx",
Usage: "Cancel transaction by sending conflicting transaction",
UsageText: "canceltx <txid> -r <endpoint> --wallet <wallet> [--account <account>] [--wallet-config <path>] [--gas <gas>] [--await]",
Description: `Aims to prevent a transaction from being added to the blockchain by dispatching a more
prioritized conflicting transaction to the specified RPC node. The input for this command should
be the transaction hash. If another account is not specified, the conflicting transaction is
automatically generated and signed by the default account in the wallet. If the target transaction
is in the memory pool of the provided RPC node, the NetworkFee value of the conflicting transaction
is set to the target transaction's NetworkFee value plus one (if it's sufficient for the
conflicting transaction itself), the ValidUntilBlock value of the conflicting transaction is set to the
target transaction's ValidUntilBlock value. If the target transaction is not in the memory pool, standard
NetworkFee calculations are performed based on the calculatenetworkfee RPC request. If the --gas
flag is included, the specified value is added to the resulting conflicting transaction network fee
in both scenarios. When the --await flag is included, the command waits for one of the conflicting
or target transactions to be included in a block.`,
Action: cancelTx,
Flags: txCancelFlags,
},
{
Name: "txdump",
Usage: "Dump transaction stored in file",
UsageText: "txdump [-r <endpoint>] <file.in>",
Action: txDump,
Flags: txDumpFlags,
Description: `Dumps the transaction from the given parameter context file to
the output. This command expects a ContractParametersContext JSON file for input, it can't handle
binary (or hex- or base64-encoded) transactions. If --rpc-endpoint flag is specified the result
of the given script after running it true the VM will be printed. Otherwise only transaction will
be printed.`,
},
{
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",
},
},
},
},
},
}
}
func handleParse(ctx *cli.Context) error {
res, err := vmcli.Parse(ctx.Args())
if err != nil {
return cli.NewExitError(err, 1)
}
fmt.Fprint(ctx.App.Writer, res)
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
}