tip: 272
title: Compatible with EVM
author: yanghang8612<yanghang8612@163.com>
status: Final
type: Standards Track
category: VM
created: 2021-06-01
To provide compatibility with Ethereum Virtual Machine.
TRON Virtual Machine (TVM) is a lightweight, Turing complete virtual machine developed for the TRON's ecosystem. Its goal is to provide millions of global developers with a custom-built blockchain system that is efficient, convenient, stable, secure and scalable.
TVM is basically compatible with EVM. The instruction set and execution model are the same as EVM. However, there still are some differences between TVM and EVM in some specific features and details because of the design and mechanism of blockchain. So in order to provide convenience for Ethereum developers, this TIP introduce compatibility details in TVM.
Add version field to smart contract defination in tron protocol
After proposal for compatibility taking effect:
- Field
versionof old deployed contracts is set to0by default - Field
versionof newly created contracts by transactions is set to1by default - Field
versionof newly created contracts bycreateorcreate2is set to the version of execution context contract - If the version of executing contract is non-zero, TVM will execute new logic. Otherwise, TVM will execute just like before.
-
GASPRICEopcode- For old version contracts: push
zeroto the stack - For new version contracts: push tron net parameter
energy_feeto the stack
- For old version contracts: push
-
CALL*andCREATE*opcodes-
Define "the maximum allowed amount" of energy as the total amount of energy remaining in the
call*context after subtracting the energy cost of the call opcode, new account creation(if needed), value transfer(if value > 0) and memory expansion -
Define "all but one 64th" of
NasN - floor(N / 64) -
For old version contracts: If a call asks for more energy than "the maximum allowed amount", do not return an out of energy exception. Instead, if a call asks for more energy than "the maximum allowed amount", call with "the maximum allowed amount" of energy; otherwise, call with asked amount of energy. CREATE provides all of the parent energy to the child call. Sub-call energy calucation formula is as follow:
extra_energy = (not account_exists(to)) * energycost.NEW_ACC_CALL + (value > 0) * energycost.VT_CALL + mem_energy(oldSize, newSize) if extra_energy > energy_left(): return vm_exception('OUT OF ENERGY') sub_call_energy = min(required_energy, energy_left() - extra_energy) + (value > 0) * energy.STIPEND_CALL -
For new version contract: If a call asks for more energy than "the maximum allowed amount", do not return an out of energy exception. Instead, if a call asks for more energy than "the maximum allowed amount", call with "all but one 64th" of "the maximum allowed amount" of energy. CREATE only provides "all but one 64th" of the parent energy to the child call. Sub call energy calucation formula is as follow:
def all_but_one_64th(energy): return energy - (energy // 64) extra_energy = (not account_exists(to)) * energycost.NEW_ACC_CALL + (value > 0) * energycost.VT_CALL + mem_energy(oldSize, newSize) if extra_energy > energy_left(): return vm_exception('OUT OF ENERGY') sub_call_energy = min(required_energy, all_but_one_64th(energy_left() - extra_energy)) + (value > 0) * energy.STIPEND_CALL
-
-
SendCoinsystem contract: After proposal for compatibility taking effect, forbid directly sending trx to new version smart contracts. Instead, private-key users can send trx to those smart contracts viatriggerSmartContractwith callvalue and this operation will invokefallbackfunction if defined and no function selector parsing from calldata is matched.
Ripemd160: this contract is at0x03in EVM, but TVM implement aTwiceHashfunction which algorithm formula issha256(sha256(data)[:20]). So in order to provide Ripemd160 hash algorithm for developers, TVM implment it at0x20003.Blake2F: this contract is at0x09in EVM, but TVM implement aBatchValidateSignfunction which can be used to batch validate signatures generated byElliptic Curve Algorithm. So in order to provide BLAKE2 cryptographic hashing algorithm for developers, TVM implement it at0x20009.
Change of return result for GASPRICE aims to provide fee estimation for sub calls. Developer can estimate fee by calculation formula fee = gasprice() * (energy_left(before) - energy_left(after)) .
Till August 12 2021, there are 779650 contracts deployed on tron main net, the analysis result of contract runtime code which contains INVALID(0xfe) is as below.
| Total | Contains INVALID |
|---|---|
| 779650 | 498521 |
There are over 60% contracts deployed on tron main net which runtime code contains INVALID opcode. Both TVM and EVM encounter this opcode during execution, will throw a INVALID_OPCODE_EXCEPTION and skip energy or gas refunding step. For TVM, beacause of all energy passing into sub call, the parent call will not have any left energy to keep executing next opcode after CALL* if sub call throws any runtime exception such as mostly INVALID_OPCODE_EXCEPTION mentioned above.
So we can not simply adjust sub call energy calculation formula into EVM implemention regardless of deployed contracts, because the change may potentially break these old contracts.
Therefore, backwards compatibility for deployed contracts is necessary. In order to achieve this purpose and also provide compatibility with EVM, we introduced version for contract as mentioned in Specifications section.
This system contract now allows private-key users sending trx to smart contracts. But it would not invoke fallback function if defined in smart contracts.
If automatically invoking fallback funtion for deployed smart contracts while sending trx to them, a revert exception may be thrown and trx will not be received, because fallback funtion can be non-payable. Some wallets or apps may be confused to this situation since those operations are always successful before.
So backwards compatibility for deployed contracts is also necessary. Sending trx to old version smart contracts is still allowed and will not invoke fallback funtion. But sending trx to new version smart contracts is forbidden after proposal for compatibility taking effect.
Contracts which already deployed are not affected from this TIP, becasue their version field are set to zero by default.
There are no backwards compatibility concerns.
Copyright and related rights waived via CC0.