Skip to main content

How to Return Values from Actions

Overview​

This article demonstrates how a smart contract developer implements return values from an action.

In order to accomplish this, we use the return statement and pass the desired returned value, which can be of any C++ primitive type, a standard library type, or a user defined type.

Prerequisites​

REMINDER

The install process has already set up the wallet for the root user. To interact with clio, ensure you are on the root user. Run sudo su - to switch to the root user.

Steps​

Create the project​

mkdir namecheck-contract && cd namecheck-contract && mkdir include src namecheck && touch include/namecheck.hpp && touch src/namecheck.cpp

Write the code​

In the include/namecheck.hpp file, define the namecheck contract and the action_response structure. The action_response structure contains two data members: id of type uint16_t and status of type std::pair<int, std::string>.

include/namecheck.hpp
#pragma once
#include <sysio/sysio.hpp>
#include <sysio/print.hpp>

#include <utility>
#include <string>

using namespace sysio;

struct action_response {
uint16_t id;
std::pair<int, std::string> status;

};

class [[sysio::contract("namecheck")]] namecheck : public contract {
public:
using contract::contract;

/**
* checkwithrv — Validate the supplied name.
*
* @param nm The name to compare against.
* @return
*/
[[sysio::action]]
action_response checkwithrv( name nm );
};

In the src/namecheck.cpp file, implement the checkwithrv action. The action takes a name as input and returns an instance of the action_response structure.

src/namecheck.cpp
#include "namecheck.hpp"

[[sysio::action]]
action_response namecheck::checkwithrv( name nm ) {
print_f("Name : %\n", nm);

// create instance of the action response structure
action_response results;
// initialize its data members
results.id = 1;

if (nm == "hello"_n) {
results.status = { 0, "Validation has passed." };
} else {
results.status = { 1, "Input param `name` is not \"hello\"." };
}

// use return statement
return results; // the `set_action_return_value` intrinsic is invoked automatically here
}

Build & Deploy the contract​

Create an account​

clio create account sysio namecheck PUB_K1_6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5BoDq63 -p sysio@active

Issue a policy​

clio push action sysio.roa addpolicy '{"owner": namecheck, "issuer": nodeownera, "net_weight": "0.0100 SYS", "cpu_weight": "0.0100 SYS", "ram_weight": "0.0050 SYS", "time_block": 1, "network_gen": 0 }' -p nodeownera@active

Build & Deploy​

cdt-cpp --abigen -contract=namecheck -I=./include -o=./namecheck/namecheck.wasm src/namecheck.cpp

clio set contract namecheck ./namecheck -p namecheck@active -x 3600

Invoke the actions​

To invoke the checkwithrv action, use the clio CLI tool.

clio push action namecheck checkwithrv '["hello"]' -p namecheck@active

Example Output:

executed transaction: ...  104 bytes  200 us
# namecheck <= namecheck::checkwithrv {"nm":"hello"}
=> return value: {"id":1,"status":{"first":0,"second":"Validation has passed."}}

Try with a different name:

clio push action namecheck checkwithrv '["world"]' -p namecheck@active

Example Output:

executed transaction: ...  104 bytes  200 us
# namecheck <= namecheck::checkwithrv {"nm":"world"}
=> return value: {"id":1,"status":{"first":1,"second":"Input param `name` is not \"hello\"."}}

Notice the different return values based on the input