Does it make sense for a non-pure/non-view external function to return any values at all? This is especially when this external function is likely going to be called off-chain.
Since they are likely to be called off-chain, whatever value is returned cannot really be returned to the off-chain caller. These functions in the contract are going to run some operations, perhaps updating some states, and then return some calculated values from the new state and also emit an event of that calculated value. When calling these functions off-chain, I could only rely on the event for that value. The returned value directly from the function is not going to be available to me.
Then, when making design decisions for an interface with external functions, should external non-pure/non-view functions even have any return values since they can't be accessed? Otherwise, in what cases should these external functions should and should not have return values?
Best Answer
An
external
function with mutability that is notview
orpure
(i.e. it ispayable
or non-payable) may or may not have areturns
. This is an example of one that does, from UniswapV1:You send it an amount of ETH and specify the minimum amount of ERC-20 tokens to buy with those ETH, and it updates the blockchain state to reflect the new token and Ether balances after the swap, it emits a
TokenPurchase
event (that has atokens_bought
field), and it also returns thetokens_bought
as a return value.It this particular case, since the exact amount of tokens your ETH will buy you will depends on the market conditions at the moment of the swap, it is useful to be able to know
tokens_bought
, the exact number of tokens you actually ended up with after the swap.If you’re calling this function from an externally-owned account (from “outside”, from a “normal” non-contract account, which you control with a private key), you will not have access to the
return
value, but you can readtokens_bought
from the emittedTokenPurchase
event.If on the other hand you’re buying these tokens with ETH on Uniswap from within a contract, the contract will not be able to see the
TokenPurchase
event, but it will receive the amount of tokens bought via the return value, and can then go on to do something useful with it.So if your function will be called from a contract, and you would like your function to do an action and then return to the calling contract some value resulting from that action, then declare
returns
, otherwise there is no need to.