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
- Before proceeding forward, ensure that you have completed Getting Started section and that you have followed Getting Started Documentation Diagram.
- This page assumes you are familiar with Smart Contract Basics.
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>.
#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.
#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