I can't understand why actions can't return values.
A simple use case is for adding records in multi_index
.
I need to return the primary key to link that to my off-chain data.
Your smart contract can have as many functions as you like. They don't all have to be actions. Only actions are required to return void, every other function can return whatever you like.
If you need to return the data from within an action to an off chain process, then you can create a new action that is empty, but contains the appropriate information in the arguments. This way you can store the primary key of a new table entry by using a history plugin on nodeos to read the argument of the new action. Example:
void mycontract::createentry(\*arguments here\*)
{
uint64_t primary_key(0);
// Make table entry here and change primary key to match table entry
eosio::action(
//permission_level,
_self,
eosio::name("entryresult"),
std::tuple(primary_key)
).send();
}
void mycontract::entryresult(uint64_t primary_key){ }
In your example, your best bet is to generate the primary key off chain and send it as part of the transaction to the action. It has the benefit of giving you more flexibility of the uniqueness of it (e.g. a GUID
) and will consume less resources on chain. The contract can still give you the robust check that any primary key passed in is unique.