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  }