tip: 272
title: Compatible with EVM
author: yanghang8612<[email protected]>
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
version
of old deployed contracts is set to0
by default - Field
version
of newly created contracts by transactions is set to1
by default - Field
version
of newly created contracts bycreate
orcreate2
is 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.
-
GASPRICE
opcode- For old version contracts: push
zero
to the stack - For new version contracts: push tron net parameter
energy_fee
to 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
N
asN - 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
-
-
SendCoin
system 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 viatriggerSmartContract
with callvalue and this operation will invokefallback
function if defined and no function selector parsing from calldata is matched.
Ripemd160
: this contract is at0x03
in EVM, but TVM implement aTwiceHash
function 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 at0x09
in EVM, but TVM implement aBatchValidateSign
function 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.