tact
tact copied to clipboard
Explicit contract state saving mechanism
The commit() function is usually used in conjunction with persisting the contract state, although not always. For example, Wallet v5 uses commit() conditionally after persisting the contract state.
Tact implicitly persists the contract state at the end of executing a receiver, but there is no native explicit mechanism in Tact to trigger early contract state saves.
Note: we need to deal with the lazy deployment flag in init is used.
Option 1: setData(self.toCell())
This could be done with either with
asm fun setData(data: Cell) { c4 POP }
setData(self.toCell()); // self refers to the contract here, although currently .toCell() methods are not supported for contracts
commit();
Can be named persistState() instead, up for discussion.
Option 2: persist statement
Or, this could be supported in the language with a persist statement:
persist;
commit();
Even commit() can be supported as a statement.
Also, there needs to be a combination of commit and persist, because one usually needs both following each other.
There is a workaround for now: use a struct as the only contract parameter (it's important it's not a contract field, but a parameter, otherwise, it needs to be adjusted to account for the lazy deployment bit):
struct ContractState {
seqno: Int as uint32;
walletId: Int as int32;
publicKey: Int as uint256;
extensions: map<Address, Bool>;
}
contract WalletV4(state: ContractState) {
receive() {
setData(self.state.toCell());
commit();
}
}