Skip to main content

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.

Docusaurus

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