diff --git a/Makefile b/Makefile index 71cce087..c2d9687e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean generate regenerate test docs redocs hardhat bindings -build: hardhat bindings bin/game7 +build: hardhat bindings bin/game7 bin/chainprof rebuild: clean generate build @@ -8,6 +8,10 @@ bin/game7: mkdir -p bin go build -o bin/game7 ./cmd/game7 +bin/chainprof: + mkdir -p bin + go build -o bin/chainprof ./cmd/chainprof + bindings/Game7Token/Game7Token.go: hardhat mkdir -p bindings/Game7Token seer evm generate --package Game7Token --output bindings/Game7Token/Game7Token.go --hardhat web3/artifacts/contracts/Token/Game7Token.sol/Game7Token.json --cli --struct Game7Token diff --git a/bindings/Game7Token/Game7Token.go b/bindings/Game7Token/Game7Token.go index 8a2d5820..0bf64eed 100644 --- a/bindings/Game7Token/Game7Token.go +++ b/bindings/Game7Token/Game7Token.go @@ -1304,145 +1304,15 @@ func CreateApproveCommand() *cobra.Command { var simulate bool var timeout uint var contractAddress common.Address - var timeout uint - - var blockNumberRaw, fromAddressRaw string - var pending bool - - var capture0 string - - cmd := &cobra.Command{ - Use: "symbol", - Short: "Call the Symbol view method on a Game7Token contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - contract, contractErr := NewGame7Token(contractAddress, client) - if contractErr != nil { - return contractErr - } - - callOpts := bind.CallOpts{} - SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) - - session := Game7TokenCallerSession{ - Contract: &contract.Game7TokenCaller, - CallOpts: callOpts, - } - - var callErr error - capture0, callErr = session.Symbol() - if callErr != nil { - return callErr - } - - cmd.Printf("0: %s\n", capture0) - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") - cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") - - return cmd -} -func CreateTotalSupplyCommand() *cobra.Command { - var contractAddressRaw, rpc string - var contractAddress common.Address - var timeout uint - - var blockNumberRaw, fromAddressRaw string - var pending bool - - var capture0 *big.Int - - cmd := &cobra.Command{ - Use: "total-supply", - Short: "Call the TotalSupply view method on a Game7Token contract", - PreRunE: func(cmd *cobra.Command, args []string) error { - if contractAddressRaw == "" { - return fmt.Errorf("--contract not specified") - } else if !common.IsHexAddress(contractAddressRaw) { - return fmt.Errorf("--contract is not a valid Ethereum address") - } - contractAddress = common.HexToAddress(contractAddressRaw) - - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - client, clientErr := NewClient(rpc) - if clientErr != nil { - return clientErr - } - - contract, contractErr := NewGame7Token(contractAddress, client) - if contractErr != nil { - return contractErr - } - - callOpts := bind.CallOpts{} - SetCallParametersFromArgs(&callOpts, pending, fromAddressRaw, blockNumberRaw) - - session := Game7TokenCallerSession{ - Contract: &contract.Game7TokenCaller, - CallOpts: callOpts, - } - - var callErr error - capture0, callErr = session.TotalSupply() - if callErr != nil { - return callErr - } - - cmd.Printf("0: %s\n", capture0.String()) - - return nil - }, - } - - cmd.Flags().StringVar(&rpc, "rpc", "", "URL of the JSONRPC API to use") - cmd.Flags().StringVar(&blockNumberRaw, "block", "", "Block number at which to call the view method") - cmd.Flags().BoolVar(&pending, "pending", false, "Set this flag if it's ok to call the view method against pending state") - cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") - cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&fromAddressRaw, "from", "", "Optional address for caller of the view method") - return cmd -} - -func CreateTransferCommand() *cobra.Command { - var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string - var gasLimit uint64 - var simulate bool - var timeout uint - var contractAddress common.Address - - var to0 common.Address - var to0Raw string + var spender common.Address + var spenderRaw string var value0 *big.Int var value0Raw string cmd := &cobra.Command{ - Use: "transfer", - Short: "Execute the Transfer method on a Game7Token contract", + Use: "approve", + Short: "Execute the Approve method on a Game7Token contract", PreRunE: func(cmd *cobra.Command, args []string) error { if keyfile == "" { return fmt.Errorf("--keystore not specified") @@ -1455,12 +1325,12 @@ func CreateTransferCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) - if to0Raw == "" { - return fmt.Errorf("--to-0 argument not specified") - } else if !common.IsHexAddress(to0Raw) { - return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + if spenderRaw == "" { + return fmt.Errorf("--spender argument not specified") + } else if !common.IsHexAddress(spenderRaw) { + return fmt.Errorf("--spender argument is not a valid Ethereum address") } - to0 = common.HexToAddress(to0Raw) + spender = common.HexToAddress(spenderRaw) if value0Raw == "" { return fmt.Errorf("--value-0 argument not specified") @@ -1505,8 +1375,8 @@ func CreateTransferCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Transfer( - to0, + transaction, transactionErr := session.Approve( + spender, value0, ) if transactionErr != nil { @@ -1557,28 +1427,26 @@ func CreateTransferCommand() *cobra.Command { cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") + cmd.Flags().StringVar(&spenderRaw, "spender", "", "spender argument") cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") return cmd } -func CreateTransferFromCommand() *cobra.Command { +func CreateTransferCommand() *cobra.Command { var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address - var from0 common.Address - var from0Raw string var to0 common.Address var to0Raw string var value0 *big.Int var value0Raw string cmd := &cobra.Command{ - Use: "transfer-from", - Short: "Execute the TransferFrom method on a Game7Token contract", + Use: "transfer", + Short: "Execute the Transfer method on a Game7Token contract", PreRunE: func(cmd *cobra.Command, args []string) error { if keyfile == "" { return fmt.Errorf("--keystore not specified") @@ -1591,13 +1459,6 @@ func CreateTransferFromCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) - if from0Raw == "" { - return fmt.Errorf("--from-0 argument not specified") - } else if !common.IsHexAddress(from0Raw) { - return fmt.Errorf("--from-0 argument is not a valid Ethereum address") - } - from0 = common.HexToAddress(from0Raw) - if to0Raw == "" { return fmt.Errorf("--to-0 argument not specified") } else if !common.IsHexAddress(to0Raw) { @@ -1648,8 +1509,7 @@ func CreateTransferFromCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.TransferFrom( - from0, + transaction, transactionErr := session.Transfer( to0, value0, ) @@ -1701,27 +1561,28 @@ func CreateTransferFromCommand() *cobra.Command { cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument") cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") return cmd } -func CreateApproveCommand() *cobra.Command { +func CreateTransferFromCommand() *cobra.Command { var keyfile, nonce, password, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas, rpc, contractAddressRaw string var gasLimit uint64 var simulate bool var timeout uint var contractAddress common.Address - var spender common.Address - var spenderRaw string + var from0 common.Address + var from0Raw string + var to0 common.Address + var to0Raw string var value0 *big.Int var value0Raw string cmd := &cobra.Command{ - Use: "approve", - Short: "Execute the Approve method on a Game7Token contract", + Use: "transfer-from", + Short: "Execute the TransferFrom method on a Game7Token contract", PreRunE: func(cmd *cobra.Command, args []string) error { if keyfile == "" { return fmt.Errorf("--keystore not specified") @@ -1734,12 +1595,19 @@ func CreateApproveCommand() *cobra.Command { } contractAddress = common.HexToAddress(contractAddressRaw) - if spenderRaw == "" { - return fmt.Errorf("--spender argument not specified") - } else if !common.IsHexAddress(spenderRaw) { - return fmt.Errorf("--spender argument is not a valid Ethereum address") + if from0Raw == "" { + return fmt.Errorf("--from-0 argument not specified") + } else if !common.IsHexAddress(from0Raw) { + return fmt.Errorf("--from-0 argument is not a valid Ethereum address") } - spender = common.HexToAddress(spenderRaw) + from0 = common.HexToAddress(from0Raw) + + if to0Raw == "" { + return fmt.Errorf("--to-0 argument not specified") + } else if !common.IsHexAddress(to0Raw) { + return fmt.Errorf("--to-0 argument is not a valid Ethereum address") + } + to0 = common.HexToAddress(to0Raw) if value0Raw == "" { return fmt.Errorf("--value-0 argument not specified") @@ -1784,8 +1652,9 @@ func CreateApproveCommand() *cobra.Command { TransactOpts: *transactionOpts, } - transaction, transactionErr := session.Approve( - spender, + transaction, transactionErr := session.TransferFrom( + from0, + to0, value0, ) if transactionErr != nil { @@ -1836,7 +1705,8 @@ func CreateApproveCommand() *cobra.Command { cmd.Flags().UintVar(&timeout, "timeout", 60, "Timeout (in seconds) for interactions with the JSONRPC API") cmd.Flags().StringVar(&contractAddressRaw, "contract", "", "Address of the contract to interact with") - cmd.Flags().StringVar(&spenderRaw, "spender", "", "spender argument") + cmd.Flags().StringVar(&from0Raw, "from-0", "", "from-0 argument") + cmd.Flags().StringVar(&to0Raw, "to-0", "", "to-0 argument") cmd.Flags().StringVar(&value0Raw, "value-0", "", "value-0 argument") return cmd @@ -1995,15 +1865,15 @@ func CreateGame7TokenCommand() *cobra.Command { cmdViewTotalSupply.GroupID = ViewGroup.ID cmd.AddCommand(cmdViewTotalSupply) + cmdTransactApprove := CreateApproveCommand() + cmdTransactApprove.GroupID = TransactGroup.ID + cmd.AddCommand(cmdTransactApprove) cmdTransactTransfer := CreateTransferCommand() cmdTransactTransfer.GroupID = TransactGroup.ID cmd.AddCommand(cmdTransactTransfer) cmdTransactTransferFrom := CreateTransferFromCommand() cmdTransactTransferFrom.GroupID = TransactGroup.ID cmd.AddCommand(cmdTransactTransferFrom) - cmdTransactApprove := CreateApproveCommand() - cmdTransactApprove.GroupID = TransactGroup.ID - cmd.AddCommand(cmdTransactApprove) return cmd } diff --git a/chainprof/cmd.go b/chainprof/cmd.go index 1789ca82..7f8e24be 100644 --- a/chainprof/cmd.go +++ b/chainprof/cmd.go @@ -13,24 +13,6 @@ import ( "github.com/spf13/cobra" ) -func CreateChainprofCommand() *cobra.Command { - chainprofCmd := &cobra.Command{ - Use: "chainprof", - Short: "Chain profiler", - Long: "Chain profiler which can be used to profile the performance of a rollup.", - Run: func(cmd *cobra.Command, args []string) { - cmd.Help() - }, - } - - accountsCmd := CreateAccountsCommand() - evaluateCmd := CreateEvaluateCommand() - - chainprofCmd.AddCommand(accountsCmd, evaluateCmd) - - return chainprofCmd -} - func CreateEvaluateCommand() *cobra.Command { var accountsDir, calldataRaw, outfile, rpc, toRaw, valueRaw, password string var transactionsPerAccount uint diff --git a/cmd/chainprof/cmd.go b/cmd/chainprof/cmd.go new file mode 100644 index 00000000..48b6773b --- /dev/null +++ b/cmd/chainprof/cmd.go @@ -0,0 +1,102 @@ +package main + +import ( + "os" + + "github.com/spf13/cobra" + + "github.com/G7DAO/protocol/chainprof" + "github.com/G7DAO/protocol/cmd/chainprof/version" +) + +func CreateRootCommand() *cobra.Command { + // rootCmd represents the base command when called without any subcommands + rootCmd := &cobra.Command{ + Use: "chainprof", + Short: "Chain profiler", + Long: "Chain profiler which can be used to profile the performance of a rollup.", + Run: func(cmd *cobra.Command, args []string) { + cmd.Help() + }, + } + + completionCmd := CreateCompletionCommand(rootCmd) + versionCmd := CreateVersionCommand() + + accountsCmd := chainprof.CreateAccountsCommand() + evaluateCmd := chainprof.CreateEvaluateCommand() + + rootCmd.AddCommand(completionCmd, versionCmd, accountsCmd, evaluateCmd) + + // By default, cobra Command objects write to stderr. We have to forcibly set them to output to + // stdout. + rootCmd.SetOut(os.Stdout) + + return rootCmd +} + +func CreateCompletionCommand(rootCmd *cobra.Command) *cobra.Command { + completionCmd := &cobra.Command{ + Use: "completion", + Short: "Generate shell completion scripts for chainprof", + Long: `Generate shell completion scripts for chainprof. + +The command for each shell will print a completion script to stdout. You can source this script to get +completions in your current shell session. You can add this script to the completion directory for your +shell to get completions for all future sessions. + +For example, to activate bash completions in your current shell: + $ . <(chainprof completion bash) + +To add chainprof completions for all bash sessions: + $ chainprof completion bash > /etc/bash_completion.d/chainprof_completions`, + } + + bashCompletionCmd := &cobra.Command{ + Use: "bash", + Short: "bash completions for chainprof", + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenBashCompletion(cmd.OutOrStdout()) + }, + } + + zshCompletionCmd := &cobra.Command{ + Use: "zsh", + Short: "zsh completions for chainprof", + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenZshCompletion(cmd.OutOrStdout()) + }, + } + + fishCompletionCmd := &cobra.Command{ + Use: "fish", + Short: "fish completions for chainprof", + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenFishCompletion(cmd.OutOrStdout(), true) + }, + } + + powershellCompletionCmd := &cobra.Command{ + Use: "powershell", + Short: "powershell completions for chainprof", + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenPowerShellCompletion(cmd.OutOrStdout()) + }, + } + + completionCmd.AddCommand(bashCompletionCmd, zshCompletionCmd, fishCompletionCmd, powershellCompletionCmd) + + return completionCmd +} + +func CreateVersionCommand() *cobra.Command { + versionCmd := &cobra.Command{ + Use: "version", + Short: "Print the version of chainprof that you are currently using", + Run: func(cmd *cobra.Command, args []string) { + cmd.Println(version.ChainprofVersion) + }, + } + + return versionCmd +} diff --git a/cmd/chainprof/main.go b/cmd/chainprof/main.go new file mode 100644 index 00000000..1e05a86f --- /dev/null +++ b/cmd/chainprof/main.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" + "os" +) + +func main() { + command := CreateRootCommand() + err := command.Execute() + if err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } +} diff --git a/cmd/chainprof/version/version.go b/cmd/chainprof/version/version.go new file mode 100644 index 00000000..90724468 --- /dev/null +++ b/cmd/chainprof/version/version.go @@ -0,0 +1,3 @@ +package version + +var ChainprofVersion string = "0.0.1" diff --git a/cmd/game7/cmd.go b/cmd/game7/cmd.go index b9128374..ad444df7 100644 --- a/cmd/game7/cmd.go +++ b/cmd/game7/cmd.go @@ -13,7 +13,6 @@ import ( "github.com/G7DAO/protocol/bindings/ERC20Inbox" "github.com/G7DAO/protocol/bindings/Game7Token" - "github.com/G7DAO/protocol/chainprof" "github.com/G7DAO/protocol/cmd/game7/version" ) @@ -51,9 +50,7 @@ func CreateRootCommand() *cobra.Command { erc20InboxCmd := ERC20Inbox.CreateERC20InboxCommand() erc20InboxCmd.Use = "erc20-inbox" - chainprofCmd := chainprof.CreateChainprofCommand() - - rootCmd.AddCommand(completionCmd, versionCmd, tokenCmd, arbitrumL1OrbitCustomGatewayCmd, arbitrumL2CustomGatewayCmd, arbitrumUpgradeExecutorCmd, arbitrumL1OrbitGatewayRouterCmd, arbSysCmd, erc20InboxCmd, chainprofCmd) + rootCmd.AddCommand(completionCmd, versionCmd, tokenCmd, arbitrumL1OrbitCustomGatewayCmd, arbitrumL2CustomGatewayCmd, arbitrumUpgradeExecutorCmd, arbitrumL1OrbitGatewayRouterCmd, arbSysCmd, erc20InboxCmd) // By default, cobra Command objects write to stderr. We have to forcibly set them to output to // stdout.