Cleos: Specifying Optional Action Parameters

by SLV Team 45 views
Specifying Optional Action Parameters for Cleos

Hey guys! Ever wondered how to handle optional parameters when calling your smart contract actions using cleos? It's a common scenario, especially when you want to provide flexibility in how your actions are executed. Let's dive into how you can define and use optional parameters in your EOSIO smart contracts and then correctly call them using cleos. This guide will cover everything you need to know, from defining the action in your contract to executing it with cleos, ensuring you can handle optional data like a pro.

Defining Optional Parameters in Your Smart Contract

First, let's talk about defining optional parameters in your smart contracts. In EOSIO, you can use std::optional to specify that an action parameter is optional. This allows you to create actions that can be called with or without certain parameters, making your contracts more versatile. To effectively define optional parameters, you need to understand how the ABI (Application Binary Interface) represents these optional values and how cleos interprets them.

When you define an action with an optional parameter, the ABI will describe this parameter's type and whether it's optional. Here's an example of how you might define an action with an optional parameter in your contract:

[[eosio::action]]
void foo(name user, const std::optional<name>& recipient) {
  // Action logic here
  if (recipient) {
    // Do something with the recipient
    eosio::print_name(*recipient);
  } else {
    // Handle the case where recipient is not provided
    eosio::print_str("No recipient provided");
  }
}

In this example, the foo action takes a mandatory user parameter and an optional recipient parameter. The std::optional<name> indicates that the recipient is optional. When the ABI is generated for this contract, it will include information about the recipient parameter, specifying that it is an optional name type. Understanding this setup is crucial because it dictates how you must format your cleos commands.

Why is this important? Well, the ABI is the bridge between your contract and external tools like cleos. It tells cleos what parameters an action expects and how they should be formatted. If the ABI says a parameter is optional, cleos needs to know how to handle the case where that parameter isn't provided. Let's dive deeper into how cleos handles these optional parameters.

Calling Actions with Optional Parameters Using Cleos

Now, let's move on to the exciting part: calling your action with optional parameters using cleos. When dealing with optional parameters, cleos offers a straightforward way to either include or omit the parameter. If you want to include the optional parameter, you simply provide its value as part of the JSON data. If you want to omit it, you just leave it out of the JSON data. Here’s how:

Including the Optional Parameter

To include the optional parameter, you need to provide its value in the JSON object that you pass to cleos. For example, if you want to call the foo action with both the user and recipient parameters, your cleos command might look like this:

cleos push action yourcontract foo '{"user":"youraccount", "recipient":"someotheraccount"}' -p youraccount

In this command, yourcontract is the name of your contract, foo is the action you're calling, and the JSON object provides values for both the user and recipient parameters. The -p youraccount specifies the permission for the transaction. When you execute this command, the foo action will be called with the provided user and recipient values.

Omitting the Optional Parameter

To omit the optional parameter, you simply leave it out of the JSON object. In this case, your cleos command might look like this:

cleos push action yourcontract foo '{"user":"youraccount"}' -p youraccount

Notice that the recipient parameter is not included in the JSON object. When you execute this command, the foo action will be called with only the user parameter. The recipient parameter will be treated as if it were not provided, and your contract logic should handle this case accordingly. Remember, the beauty of std::optional is that it allows your contract to gracefully handle missing parameters, providing a more flexible and user-friendly interface.

Important Considerations

  • Data Types: Ensure that the data type you provide for the optional parameter matches the type defined in your contract. For example, if the parameter is defined as name, provide a valid account name string.
  • JSON Format: Make sure your JSON is correctly formatted. Incorrect JSON can lead to parsing errors and failed transactions.
  • Error Handling: Always include robust error handling in your contract to manage cases where the optional parameter is missing or invalid.

ABI Representation of Optional Parameters

Understanding how optional parameters are represented in the ABI is crucial for ensuring that your cleos commands are correctly interpreted. The ABI is a JSON file that describes the structure of your contract, including the types and names of actions and tables. When you define an action with an optional parameter, the ABI will include a field indicating that the parameter is optional. This field tells cleos how to handle the parameter when it's not provided.

Here’s an example of what the ABI might look like for the foo action we defined earlier:

{
  "actions": [
    {
      "name": "foo",
      "type": "foo_type",
      "ricardian_contract": ""
    }
  ],
  "structs": [
    {
      "name": "foo_type",
      "base": "",
      "fields": [
        {
          "name": "user",
          "type": "name"
        },
        {
          "name": "recipient",
          "type": "name?"
        }
      ]
    }
  ]
}

In this example, notice the type field for the recipient parameter: `