github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/cmd/action/xrc20.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package action 7 8 import ( 9 "encoding/hex" 10 "fmt" 11 "math/big" 12 "strconv" 13 14 "github.com/iotexproject/iotex-address/address" 15 "github.com/spf13/cobra" 16 17 "github.com/iotexproject/iotex-core/ioctl/cmd/alias" 18 "github.com/iotexproject/iotex-core/ioctl/config" 19 "github.com/iotexproject/iotex-core/ioctl/output" 20 "github.com/iotexproject/iotex-core/ioctl/util" 21 ) 22 23 // Multi-language support 24 var ( 25 _xrc20CmdShorts = map[config.Language]string{ 26 config.English: "Support ERC20 standard command-line", 27 config.Chinese: "使ioctl命令行支持ERC20标准", 28 } 29 _flagContractAddressUsages = map[config.Language]string{ 30 config.English: "set contract address", 31 config.Chinese: "设定合约地址", 32 } 33 _flagXrc20EndPointUsages = map[config.Language]string{ 34 config.English: "set endpoint for once", 35 config.Chinese: "一次设置端点", 36 } 37 _flagXrc20InsecureUsages = map[config.Language]string{ 38 config.English: "insecure connection for once (default false)", 39 config.Chinese: "一次不安全的连接(默认为false)", 40 } 41 ) 42 43 // Xrc20Cmd represent xrc20 standard command-line 44 var Xrc20Cmd = &cobra.Command{ 45 Use: "xrc20", 46 Short: config.TranslateInLang(_xrc20CmdShorts, config.UILanguage), 47 } 48 49 var _xrc20ContractAddress string 50 51 func xrc20Contract() (address.Address, error) { 52 addr, err := alias.IOAddress(_xrc20ContractAddress) 53 if err != nil { 54 return nil, output.NewError(output.FlagError, "invalid xrc20 address flag", err) 55 } 56 return addr, nil 57 } 58 59 type amountMessage struct { 60 RawData string `json:"rawData"` 61 Decimal string `json:"decimal"` 62 } 63 64 func (m *amountMessage) String() string { 65 if output.Format == "" { 66 return fmt.Sprintf("Raw output: %s\nOutput in decimal: %s", m.RawData, m.Decimal) 67 } 68 return output.FormatString(output.Result, m) 69 } 70 71 func init() { 72 Xrc20Cmd.AddCommand(_xrc20TotalSupplyCmd) 73 Xrc20Cmd.AddCommand(_xrc20BalanceOfCmd) 74 Xrc20Cmd.AddCommand(_xrc20TransferCmd) 75 Xrc20Cmd.AddCommand(_xrc20TransferFromCmd) 76 Xrc20Cmd.AddCommand(_xrc20ApproveCmd) 77 Xrc20Cmd.AddCommand(_xrc20AllowanceCmd) 78 Xrc20Cmd.PersistentFlags().StringVarP(&_xrc20ContractAddress, "contract-address", "c", "", 79 config.TranslateInLang(_flagContractAddressUsages, config.UILanguage)) 80 Xrc20Cmd.PersistentFlags().StringVar(&config.ReadConfig.Endpoint, "endpoint", 81 config.ReadConfig.Endpoint, config.TranslateInLang(_flagXrc20EndPointUsages, config.UILanguage)) 82 Xrc20Cmd.PersistentFlags().BoolVar(&config.Insecure, "insecure", config.Insecure, 83 config.TranslateInLang(_flagXrc20InsecureUsages, config.UILanguage)) 84 if err := cobra.MarkFlagRequired(Xrc20Cmd.PersistentFlags(), "contract-address"); err != nil { 85 fmt.Printf("failed to mark flag: %v\n", err) 86 } 87 } 88 89 func parseAmount(contract address.Address, amount string) (*big.Int, error) { 90 decimalBytecode, err := hex.DecodeString("313ce567") 91 if err != nil { 92 return nil, output.NewError(output.ConvertError, "failed to decode 313ce567", err) 93 } 94 result, err := Read(contract, "0", decimalBytecode) 95 if err != nil { 96 return nil, output.NewError(0, "failed to read contract", err) 97 } 98 99 var decimal int64 100 if result != "" { 101 decimal, err = strconv.ParseInt(result, 16, 8) 102 if err != nil { 103 return nil, output.NewError(output.ConvertError, "failed to convert string into int64", err) 104 } 105 } else { 106 decimal = int64(0) 107 } 108 109 return util.StringToRau(amount, int(decimal)) 110 }