tip-157.md
April 3, 2025 ยท View on GitHub
tip: 157
title: Freeze instructions in TVM
author: taihao.fu@gmail.com
status: Final
type: Standards Track
category: VM
created: 2020-06-03
Simple Summary
To provide freeze related operations in TVM.
Abstract
Freeze & Unfreeze operation in system contract are introduced, smart contract can freeze and get resource from the system.
Motivation
Common user can freeze TRX to get resource, such as TRON power, bandwidth, energy. However, none privatekey accounts, like smart contracts, can't get resources from the staking mechanism. This TIP provide instructions to get resource, so that smart contracts can provide tron power for voting and also provide resource delegation to others.
Specification
New instructions in TVM
0xd5: FREEZE
The FREEZE takes 3 operands pop up from stack:
receiverAddress: account address to receive generated resource.
freezeAmount: amount to freeze in SUN.
resourceType: 0 as bandwidth, 1 as energy.
If operation succeed, push 1 to stack, otherwise push 0 to stack.
0xd6: UNFREEZE
The UNFREEZE takes 2 operands pop up from stack.
receiverAddress: account address which received resource.
resourceType: 0 as bandwidth, 1 as energy.
If operation succeed, push 1 to stack, otherwise push 0 to stack.
0xd7: FREEZEEXPIRETIME
The FREEZEEXPIRETIME takes 2 operands pop up from stack.
targetAddress: target account address.
resourceType: 0 as bandwidth, 1 as energy.
If operation succeed, push the expire time to stack, otherwise push 0 to stack.
Notice
For FREEZE or UNFREEZE, if receiverAddress == contractAddress, means that contract freeze or unfreeze for itself.
For FREEZE or UNFREEZE, if receiverAddress != contractAddress, receiverAddress must not be address of contract.
For FREEZE, automatically active non-existent account and consume additional energy.
For FREEZE, amount must not be less than 1 TRX = 10e6 SUN.
For FREEZEEXPIRETIME, return value is in seconds.
Solidity example
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.17 || ^0.6.2 || ^0.7.0 || ^0.8.0;
contract TestFreeze {
/**
* @dev Contract can accept value while creating.
*/
constructor() public payable {}
/**
* @dev Freeze `amount` balance of contract to get resource for `receiver`
* which type is `res` (0 for bandwidth, 1 for energy).
*
* Below situations can cause `revert` excepiton:
* 1. `amount` is greater than long.max_value or contract balance.
* 2. `amount` is less than 10e6 sun (1 trx).
* 3. `res` is not zero or one.
* 4. `receiver` is contract address (exclude this contract).
*
* Caution:
* 1. Balance freezing is also at least three days.
* 2. Contract can never use its bandwidth or energy.
* 3. If `receiver` account does not exist, the operation will create it.
* 4. If contract still has delegated frozen balance for other account,
* suicide can not be excuted and throw a revert exception.
*/
function freezeBalance(address payable receiver, uint amount, uint res) payable external {
receiver.freeze(amount, res);
}
/**
* @dev Unfreeze specific balance to get corresponding balance.You can use
* `receiver' and 'res' (0 for bandwidth, 1 for energy) parameters to
* unfreeze specific balance.
*
* Below situations can cause `revert` excepiton:
* 1. `res` is not zero or one.
* 2. Frozen relationship between contract and `receiver` does not exist.
* 3. It is not time to unfreeze the specific balance.
*
* Caution:
* 1. If contract does not have enough tron power to support its votes after unfreezing
* this part of frozen balance, the operation will auto clear votes and extract
* reward to contract allowance.
*/
function unfreezeBalance(address payable receiver, uint res) external {
receiver.unfreeze(res);
}
/**
* @dev Query the timestamp which the specific balance can be unfreezed.
*/
function queryExpireTime(address payable target, uint res) external view returns(uint) {
return target.freezeExpireTime(res);
}
/**
* @dev Execute self destruct and transfer all balance and asset of contract to target address.
*
* Below situations can cause `revert` excepiton:
* 1. There are still delegated frozen balance for other account address.
*/
function killme(address payable target) external {
selfdestruct(target);
}
}
Notice
receiver or target must have address payable type, means that calling those methods on non-payable address will cause a complier error.
Rationale
Tier
FREEZE tier.ExtTier
UNFREEZE tier.ExtTier
FREEZEEXPIRETIME tier.ExtTier
Energy cost
FREEZE: 20000 energy
UNFREEZE: 20000 energy
FREEZEEXPIRETIME: 50 energy
New account while freezing: 25000 energy
Selfdestruct
If contract still has unfreezed balance for others, selfdestruct will case REVERT exception.
Unfreezed balance for contract itself will be unfreezed and transfer to inheritor`s balance after selfdesturct executed.
Copyright
Copyright and related rights waived via CC0.