Pattern (viewer)
The viewer pattern is a standardised way of implementing functions that return a value without using callbacks.
Contract A is the calling contract. User calls Call_and_read_return_value
which does two things. Firstly, it calls a transition on contract B called View_function
which then sets some state. Secondly, control is passed back to contract A, and then calls a transition on itself called Read_Return_value
which then can access the state field amended on contract B to use for onwards processing.
scilla_version 0
library Lib
let compute_the_value = fun (input_1 : ...) => fun (input_2 : ...) => ... => ...
contract ContractWithReturnValues()
field state_field_1 : Uint128 = ...field state_field_2 : String = ......
field return_value_1 : ... = ...field return_value_2 : ... = ...
(* Perform a computation and state updates, and store the result in the field return_value_1 for the caller to read *)transition Function_with_return_value(param1 : ..., param2 : ..., ...) <compute whatever needs to be computed, including state updates>; res = <the result that needs to be returned>; return_value_1 := resend
(* Perform a computation without state updates, and store the result in the field return_value_2 for the caller to read *)transition View_function(param1 : ..., param2 : ..., ...) (* A view function always follows this exact pattern *) (* Read the state fields needed to do the computation*) s1 <- state_field_1; s2 <- state_field_2; ... sn <- state_field_n; res = compute_the_value param1 param2 ... s1 s2 ...; return_value_2 := resend
(* *********************************************************************************************** *)
scilla_version 0
contract CallingContract(contract_with_return_values : ByStr20 with contract field return_value_2 : ... end)
transition Call_and_read_return_value(...) remote <- contract_with_return_values; msg1 = { _recipient : remote; _tag : "View_function"; param1 : ... ; param2 : ...; ...}; send msg1; msg2 = { _recipient : _this_address; _tag : "Read_Return_value"; ...}; send msg2end
transition Read_Return_value(...) return_value <-& contract_with_return_values.return_value_2; <use the returned value for further computation>end