github.com/aergoio/aergo@v1.3.1/cmd/brick/exec/callContract.go (about)

     1  package exec
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/rs/zerolog"
     8  
     9  	"github.com/aergoio/aergo/cmd/brick/context"
    10  	"github.com/aergoio/aergo/contract"
    11  )
    12  
    13  func init() {
    14  	registerExec(&callContract{})
    15  }
    16  
    17  type callContract struct{}
    18  
    19  func (c *callContract) Command() string {
    20  	return "call"
    21  }
    22  
    23  func (c *callContract) Syntax() string {
    24  	return fmt.Sprintf("%s %s %s %s %s %s", context.AccountSymbol,
    25  		context.AmountSymbol, context.ContractSymbol,
    26  		context.FunctionSymbol, context.ContractArgsSymbol, context.ExpectedErrSymbol)
    27  }
    28  
    29  func (c *callContract) Usage() string {
    30  	return fmt.Sprintf("call <sender_name> <amount> <contract_name> <func_name> `[call_json_str]` `[expected_error_str]`")
    31  }
    32  
    33  func (c *callContract) Describe() string {
    34  	return "call to execute a smart contract"
    35  }
    36  
    37  func (c *callContract) Validate(args string) error {
    38  
    39  	// is chain is loaded?
    40  	if context.Get() == nil {
    41  		return fmt.Errorf("load chain first")
    42  	}
    43  
    44  	_, _, _, _, _, _, err := c.parse(args)
    45  
    46  	return err
    47  }
    48  
    49  func (c *callContract) parse(args string) (string, *big.Int, string, string, string, string, error) {
    50  	splitArgs := context.SplitSpaceAndAccent(args, false)
    51  	if len(splitArgs) < 4 {
    52  		return "", nil, "", "", "", "", fmt.Errorf("need at least 4 arguments. usage: %s", c.Usage())
    53  	}
    54  
    55  	amount, success := new(big.Int).SetString(splitArgs[1].Text, 10)
    56  	if success == false {
    57  		return "", nil, "", "", "", "", fmt.Errorf("fail to parse number %s", splitArgs[1].Text)
    58  	}
    59  
    60  	callCode := "[]"
    61  	if len(splitArgs) >= 5 {
    62  		callCode = splitArgs[4].Text
    63  	}
    64  
    65  	expectedError := ""
    66  	if len(splitArgs) == 6 {
    67  		expectedError = splitArgs[5].Text
    68  	} else if len(splitArgs) > 6 {
    69  		return "", nil, "", "", "", "", fmt.Errorf("too many arguments. usage: %s", c.Usage())
    70  	}
    71  
    72  	return splitArgs[0].Text, //accountName
    73  		amount, //amount
    74  		splitArgs[2].Text, //contractName
    75  		splitArgs[3].Text, //funcName
    76  		callCode, //callCode
    77  		expectedError, //expectedError
    78  		nil
    79  }
    80  
    81  func (c *callContract) Run(args string) (string, error) {
    82  
    83  	accountName, amount, contractName, funcName, callCode, expectedError, _ := c.parse(args)
    84  
    85  	formattedQuery := fmt.Sprintf("{\"name\":\"%s\",\"args\":%s}", funcName, callCode)
    86  
    87  	callTx := contract.NewLuaTxCallBig(accountName, contractName, amount, formattedQuery)
    88  
    89  	logLevel := zerolog.GlobalLevel()
    90  
    91  	if expectedError != "" {
    92  		callTx.Fail(expectedError)
    93  		zerolog.SetGlobalLevel(zerolog.ErrorLevel) // turn off log
    94  	}
    95  	err := context.Get().ConnectBlock(callTx)
    96  
    97  	if expectedError != "" {
    98  		zerolog.SetGlobalLevel(logLevel) // restore log level
    99  	}
   100  	if err != nil {
   101  		return "", err
   102  	}
   103  
   104  	if expectedError == "" {
   105  		events := context.Get().GetEvents(callTx)
   106  		for _, event := range events {
   107  			logger.Info().Str("args", event.GetJsonArgs()).Msg(event.GetEventName())
   108  		}
   109  	} else {
   110  		Index(context.ExpectedErrSymbol, expectedError)
   111  	}
   112  
   113  	return "call a smart contract successfully", nil
   114  }