github.com/iotexproject/iotex-core@v1.14.1-rc1/ioctl/newcmd/contract/contracttestfunction.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 contract
     7  
     8  import (
     9  	"math/big"
    10  
    11  	"github.com/iotexproject/iotex-address/address"
    12  	"github.com/pkg/errors"
    13  	"github.com/spf13/cobra"
    14  
    15  	"github.com/iotexproject/iotex-core/ioctl"
    16  	"github.com/iotexproject/iotex-core/ioctl/config"
    17  	"github.com/iotexproject/iotex-core/ioctl/flag"
    18  	"github.com/iotexproject/iotex-core/ioctl/newcmd/action"
    19  	"github.com/iotexproject/iotex-core/ioctl/util"
    20  )
    21  
    22  // Multi-language support
    23  var (
    24  	_testFunctionCmdUses = map[config.Language]string{
    25  		config.English: "function (CONTRACT_ADDRESS|ALIAS) ABI_PATH FUNCTION_NAME [AMOUNT_IOTX] " +
    26  			"[--with-arguments INVOKE_INPUT]",
    27  		config.Chinese: "function (合约地址|别名) ABI文件路径 函数名 [IOTX数量] [--with-arguments 调用输入]",
    28  	}
    29  	_testFunctionCmdShorts = map[config.Language]string{
    30  		config.English: "test smart contract on IoTeX blockchain with function name",
    31  		config.Chinese: "调用函数测试IoTeX区块链上的智能合约",
    32  	}
    33  )
    34  
    35  // NewContractTestFunctionCmd represents the contract test function cmd
    36  func NewContractTestFunctionCmd(client ioctl.Client) *cobra.Command {
    37  	use, _ := client.SelectTranslation(_testFunctionCmdUses)
    38  	short, _ := client.SelectTranslation(_testFunctionCmdShorts)
    39  
    40  	cmd := &cobra.Command{
    41  		Use:   use,
    42  		Short: short,
    43  		Args:  cobra.RangeArgs(3, 4),
    44  		RunE: func(cmd *cobra.Command, args []string) error {
    45  			cmd.SilenceUsage = true
    46  			return contractTestFunction(client, cmd, args)
    47  		},
    48  	}
    49  	action.RegisterWriteCommand(client, cmd)
    50  	flag.WithArgumentsFlag.RegisterCommand(cmd)
    51  	return cmd
    52  }
    53  
    54  func contractTestFunction(client ioctl.Client, cmd *cobra.Command, args []string) error {
    55  	addr, err := client.Address(args[0])
    56  	if err != nil {
    57  		return errors.WithMessage(err, "failed to get contract address")
    58  	}
    59  
    60  	contract, err := address.FromString(addr)
    61  	if err != nil {
    62  		return errors.WithMessage(err, "failed to convert string into address")
    63  	}
    64  
    65  	abi, err := readAbiFile(args[1])
    66  	if err != nil {
    67  		return errors.WithMessage(err, "failed to read abi file "+args[1])
    68  	}
    69  
    70  	methodName := args[2]
    71  
    72  	amount := big.NewInt(0)
    73  	if len(args) == 4 {
    74  		amount, err = util.StringToRau(args[3], util.IotxDecimalNum)
    75  		if err != nil {
    76  			return errors.Wrap(err, "invalid amount")
    77  		}
    78  	}
    79  
    80  	bytecode, err := packArguments(abi, methodName, flag.WithArgumentsFlag.Value().(string))
    81  	if err != nil {
    82  		return errors.WithMessage(err, "failed to pack given arguments")
    83  	}
    84  
    85  	_, signer, _, _, gasLimit, _, err := action.GetWriteCommandFlag(cmd)
    86  	if err != nil {
    87  		return errors.WithMessage(err, "failed to get command flag")
    88  	}
    89  
    90  	rowResult, err := action.Read(client, contract, amount.String(), bytecode, signer, gasLimit)
    91  	if err != nil {
    92  		return err
    93  	}
    94  
    95  	result, err := parseOutput(abi, methodName, rowResult)
    96  	if err != nil {
    97  		result = rowResult
    98  	}
    99  
   100  	cmd.Println("return: " + result)
   101  	return nil
   102  }