pragma ever-solidity >= 0.68.0; pragma AbiHeader time; pragma AbiHeader expire; pragma AbiHeader pubkey; import "locklift/src/console.tsol"; import "../../../contracts/access/abstract/Ownable.tsol"; import "../../../contracts/libraries/UtilityErrors.tsol"; import "../../../contracts/libraries/MsgFlag.tsol"; import "../../../contracts/libraries/UtilityGas.tsol"; import "../../../contracts/upgrade/abstract/Upgradable.tsol"; contract UpgradableExample is Upgradable, Ownable { uint32 private static _nonce; function _getTargetBalanceInternal() internal view override returns (uint128) { return UtilityGas.INITIAL_BALANCE; } constructor( optional(address) _initialOwner, optional(address) _remainingGasTo ) public reserveAcceptAndRefund(_getTargetBalanceInternal(), _remainingGasTo, msg.sender) validAddressOrNull(_initialOwner, UtilityErrors.INVALID_NEW_OWNER) { address initialOwner = _initialOwner.hasValue() ? _initialOwner.get() : msg.sender; _setOwnerInternal(initialOwner); _setCurrentVersionInternal(1, 0); } function upgrade( TvmCell _code, optional(uint32) _version, optional(address) _remainingGasTo ) external override reserve(_getTargetBalanceInternal()) onlyOwner validTvmCell(_code, UtilityErrors.INVALID_CODE) { address remainingGasTo = _remainingGasTo.hasValue() ? _remainingGasTo.get() : msg.sender; TvmCell data = abi.encode( _nonce, _getCurrentVersionInternal(), _version, _getOwnerInternal(), remainingGasTo ); tvm.setcode(_code); tvm.setCurrentCode(_code); onCodeUpgrade(data); } function onCodeUpgrade(TvmCell _data) private { tvm.resetStorage(); ( uint32 nonce, uint32 previousVersion, optional(uint32) currentVersion, address owner, address remainingGasTo ) = abi.decode(_data, ( uint32, uint32, optional(uint32), address, address )); _nonce = nonce; _setOwnerSilent(owner); _setCurrentVersionInternal( currentVersion.hasValue() ? currentVersion.get() : previousVersion + 1, previousVersion ); console.log(format("New version: {}", _getCurrentVersionInternal())); remainingGasTo.transfer({ value: 0, flag: MsgFlag.ALL_NOT_RESERVED + MsgFlag.IGNORE_ERRORS, bounce: false }); } }