Skip to content

Latest commit

 

History

History
113 lines (72 loc) · 6.89 KB

tip-272.md

File metadata and controls

113 lines (72 loc) · 6.89 KB
tip: 272
title: Compatible with EVM
author: yanghang8612<[email protected]>
status: Final
type: Standards Track
category: VM
created: 2021-06-01

Simple Summary

To provide compatibility with Ethereum Virtual Machine.

Motivation

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.

Specifications

Define version for smart contracts

Add version field to smart contract defination in tron protocol

After proposal for compatibility taking effect:

  • Field version of old deployed contracts is set to 0 by default
  • Field version of newly created contracts by transactions is set to 1 by default
  • Field version of newly created contracts by create or create2 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.

Differences between old version and new version

  • GASPRICE opcode

    • For old version contracts: push zero to the stack
    • For new version contracts: push tron net parameter energy_fee to the stack
  • CALL* and CREATE* 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 as N - 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 via triggerSmartContract with callvalue and this operation will invoke fallback function if defined and no function selector parsing from calldata is matched.

Precompile contracts address

  • Ripemd160: this contract is at 0x03 in EVM, but TVM implement a TwiceHash function which algorithm formula is sha256(sha256(data)[:20]). So in order to provide Ripemd160 hash algorithm for developers, TVM implment it at 0x20003.
  • Blake2F: this contract is at 0x09 in EVM, but TVM implement a BatchValidateSign function which can be used to batch validate signatures generated by Elliptic Curve Algorithm. So in order to provide BLAKE2 cryptographic hashing algorithm for developers, TVM implement it at 0x20009.

Rationale

GASPRICE opcode

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)) .

CALL* and CREATE* opcodes

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.

SendCoin system contract

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.

Clarifications

Contracts which already deployed are not affected from this TIP, becasue their version field are set to zero by default.

Backwards Compatibility

There are no backwards compatibility concerns.