Best way about Data Segregation Pattern Contract

Hello everyone.
I’d like to ask or discuss you which Data Segregation pattern contract is best in Scilla.
Data Segregation Pattern is the design pattern in Ethereum that separates contract logic from its underlying data.
You can see more detail in Design Patterns for Smart Contracts in the Ethereum Ecosystem ( D-1. Data Segregation) .
We are in the process of smart contract designing in Scilla and adopt this pattern with out project.
However Scilla’s contract cannot call and receive the data from other contract within one transition. (Solidity’s contract can do that.)
Because Scilla’s contract need the receive transition if it receive the data from other one. (like following image)

So I’d like to proposed an idea of Data Segregation Pattern such as following code.

(* Logic Contract *)
field tmp_data: Map ByStr20 TmpData = Emp ByStr20 Uint128

transition GetStorageData (input: Uint128)
  bnum <- & BLOCKNUMBER;
  tmp_tx_id =
    let t1 = builtin ripemd160hash input in
    let t2 = builtin ripemd160hash _sender in
    let t3 = builtin ripemd160hash bnum in
    let sum1 = builtin concat t1 t2 in
    let sum2 = builtin concat sum1 t3 in
    builtin ripemd160hash sum2;
  tmp_data[tmp_tx_id] := input;
  msg = { _tag: "SendData"; _recipient: data_storage_addr; _amount : zero; tmp_tx_id: tmp_tx_id };
  message = one_msg msg;
end

transition OutputOtherContract (storage_data: Uint128)
  get_tmp <- tmp_data[tmp_tx_id];
  (* calculate LOGIC_OUTPUT from input and storage_data and clean tmp_data[tmp_tx_id] *)
end


(* Storage Contract *)
field data: Uint128 = zero

transition SendData (tmp_tx_id: ByStr20)
  storage_data <- data;
  msg = { _tag: "OutputOtherContract"; _recipient: _sender; _amount : zero; storage_data: storage_data; tmp_tx_id: tmp_tx_id };
  message = one_msg msg;
  send message
end

This contract create temporary transaction id and save input data with the temporary transaction id in mutable field. And it is possible to fetch temporary input data by using temporary transaction id.
Also temporary transaction id must be included in the input of all transitions in order to fetch temporary input data.
I have only this idea, so any feedback and suggestions are highly appreciated. thank you so much :smile:

1 Like

Hello! Yes, this looks like the right pattern. However, I have a couple of questions:

  1. I don’t follow the purpose of tmp_tx_id. Wouldn’t it make sense to have it only when the call to SendData is asynchronous, i.e., if the chain call SendData -> OutputOtherContract -> OtherContract_ProcessLogicOutput doesn’t happen within a single transaction?

  2. Storage Contract seems to only allow read operations. It should also provide a write transition that can only be invoked by the LogicContract. tmp_tx_id can be important in this case though.

Thank you for your reply!

I don’t follow the purpose of tmp_tx_id . Wouldn’t it make sense to have it only when the call to SendData is asynchronous, i.e., if the chain call SendData -> OutputOtherContract -> OtherContract_ProcessLogicOutput doesn’t happen within a single transaction?

This purpose was to prevent rewriting temporary field by two transactions.
I was thinking that the temporary field is rewritten by second transaction if two transactions issue at the same time.
But it may not happen because transaction has an atomicity.

Storage Contract seems to only allow read operations. It should also provide a write transition that can only be invoked by the LogicContract . tmp_tx_id can be important in this case though.

You’re right! It should need write transition. But I don’t have any idea to need tmp_tx_id in write transition.

1 Like