2020-08-04 06:40:06 +00:00
package util
import (
2023-04-11 15:45:50 +00:00
"encoding/base64"
"encoding/hex"
2020-08-04 06:40:06 +00:00
"fmt"
2023-04-11 15:45:50 +00:00
"os"
2020-08-04 06:40:06 +00:00
2023-11-27 11:20:18 +00:00
"github.com/nspcc-dev/neo-go/cli/flags"
2021-09-14 12:02:54 +00:00
"github.com/nspcc-dev/neo-go/cli/options"
2023-11-27 11:20:18 +00:00
"github.com/nspcc-dev/neo-go/cli/txctx"
2022-10-05 09:30:54 +00:00
vmcli "github.com/nspcc-dev/neo-go/cli/vm"
2023-04-11 15:45:50 +00:00
"github.com/nspcc-dev/neo-go/pkg/vm"
2020-08-04 06:40:06 +00:00
"github.com/urfave/cli"
)
2020-08-05 10:17:23 +00:00
// NewCommands returns util commands for neo-go CLI.
2020-08-04 06:40:06 +00:00
func NewCommands ( ) [ ] cli . Command {
2021-09-14 12:02:54 +00:00
txDumpFlags := append ( [ ] cli . Flag { } , options . RPC ... )
2023-12-28 11:58:38 +00:00
txSendFlags := append ( txDumpFlags , txctx . AwaitFlag )
2023-11-27 11:20:18 +00:00
txCancelFlags := append ( [ ] cli . Flag {
flags . AddressFlag {
Name : "address, a" ,
Usage : "address to use as conflicting transaction signee (and gas source)" ,
} ,
txctx . GasFlag ,
2023-12-28 11:58:38 +00:00
txctx . AwaitFlag ,
2023-11-27 11:20:18 +00:00
} , options . RPC ... )
txCancelFlags = append ( txCancelFlags , options . Wallet ... )
2020-08-04 06:40:06 +00:00
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 ,
} ,
2022-08-31 19:38:35 +00:00
{
Name : "sendtx" ,
Usage : "Send complete transaction stored in a context file" ,
2023-12-28 11:58:38 +00:00
UsageText : "sendtx [-r <endpoint>] <file.in> [--await]" ,
2022-08-31 19:38:35 +00:00
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 )
2023-12-28 11:58:38 +00:00
transactions . If the -- await flag is included , the command waits for the
transaction to be included in a block before exiting .
2022-08-31 19:38:35 +00:00
` ,
Action : sendTx ,
2023-12-28 11:58:38 +00:00
Flags : txSendFlags ,
2022-08-31 19:38:35 +00:00
} ,
2023-11-27 11:20:18 +00:00
{
Name : "canceltx" ,
Usage : "Cancel transaction by sending conflicting transaction" ,
2023-12-28 11:58:38 +00:00
UsageText : "canceltx <txid> -r <endpoint> --wallet <wallet> [--account <account>] [--wallet-config <path>] [--gas <gas>] [--await]" ,
2023-11-27 11:20:18 +00:00
Description : ` Aims to prevent a transaction from being added to the blockchain by dispatching a more
2023-12-27 09:26:02 +00:00
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
2023-12-28 11:58:38 +00:00
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 . ` ,
2023-11-27 11:20:18 +00:00
Action : cancelTx ,
Flags : txCancelFlags ,
} ,
2021-09-14 12:02:54 +00:00
{
Name : "txdump" ,
Usage : "Dump transaction stored in file" ,
UsageText : "txdump [-r <endpoint>] <file.in>" ,
Action : txDump ,
Flags : txDumpFlags ,
2023-12-28 11:58:38 +00:00
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 . ` ,
2021-09-14 12:02:54 +00:00
} ,
2023-04-11 15:45:50 +00:00
{
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" ,
} ,
} ,
} ,
2020-08-04 06:40:06 +00:00
} ,
} ,
}
}
func handleParse ( ctx * cli . Context ) error {
res , err := vmcli . Parse ( ctx . Args ( ) )
if err != nil {
return cli . NewExitError ( err , 1 )
}
2020-08-28 09:11:19 +00:00
fmt . Fprint ( ctx . App . Writer , res )
2020-08-04 06:40:06 +00:00
return nil
}
2023-04-11 15:45:50 +00:00
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
}