HomeGuidesAPI ReferenceChangelog
GuidesAPI ReferenceCommunityDiscordBlogFAQBug BountyAnnouncementsChange Log
Guides

Virtual Machine Introduction

TRON Virtual Machine (TVM)

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 connects seamlessly with the existing development ecosystem and supports DPOS. TVM is initially compatible with the EVM environment so that instead of learning a new programming language, developers can develop, debug, and compile smart contracts in a Remix environment using Solidity and other languages. Once you’ve built and uploaded your smart contract to TRON’s mainnet, it will be executed on the TVM of the SR node to be isolated from external connections.

Furthermore, TVM employs the concept of Bandwidth. Different from the gas mechanism on Ethereum’s EVM, transaction operations or smart contracts on TVM are free, consuming no tokens. Technically, the total token holding does not restrict executable computation capacity on TVM.

Features of TVM

1. Lightweight

TVM adopts a lightweight architecture with the aim of reducing resource consumption to guarantee system performance.

2. Stability and security

With a meticulous design paradigm and fine-grained underlying operation code, TVM can guarantee the preciseness of every step of a computation, diminishing ambiguity to the largest extent. Out of security reasons, transfers and smart contract running cost only bandwidth points, not TRX, which exempts TRON from being attacked similarly to Ethereum for its mode of gas consumption. Stability of bandwidth consumption is achieved while the cost of each computational step is fixed.

3. Compatibility

Currently, TVM is compatible with EVM and will be with more mainstream VMs in the future. Thereby, all smart contracts on EVM are executable on TVM. By connecting seamlessly to existing development ecosystem, higher efficiency can be achieved by developers. Needless to learn a new programming language, they can use mainstream programming languages for smart contracts such as Solidity to develop, debug and compile smart contracts in the Remix environment, which greatly reduces development costs.

4. Developer-friendly

Thanks to TVM’s bandwidth setup, development costs are reduced and developers can focus on the logic of their contract code. TVM also offers all-in-one interfaces for contract deployment, triggering and viewing, for the convenience of developers.
The following interfaces are available in Tron Wallet-CLI:

  • deploycontract(password, contractAddress, ABI, code, data, value)
  • triggercontract(password, contractAddress, selector, data, value)
  • getcontract(contractAddress)
    Developers can call these interfaces to deploy, trigger or check smart contracts.

How TVM Works

865

Flowchart of Tron Virtual Machine

The above flowchart shows how TVM works:
Compilation of Tron smart contract→execution and computing engines of VM→Interoperation service layer for external interfaces

Put simply, the flow is as follows:

  • Currently, TVM is compatible mainly with Solidity. The compiler translates Solidity smart contract into bytecode readable and executable on TVM.
  • A virtual machine processes data through opcode, which is equivalent to operating a logic of a stack-based finite state machine.
  • TVM accesses blockchain data and invokes External Data Interface through the Interoperation layer.

Internal Transactions

Background

Internal Transactions represent all transactions that have occurred in a smart contract call. Some important information included in the transaction are sender/receiver address in a token/trx transfer transaction, trx/token amount, and transfer status. Users can check all information about Internal Transactions in an internalTransaction list, which contains all transactions in a single triggerSmartContract or createSmartContract call.

Internal Transaction Information Structure

message InternalTransaction {
  bytes hash = 1;
  // the one send trx or token via function
  bytes caller_address = 2;
  // the one recieve trx or token via function
  bytes transferTo_address = 3;
  message CallValueInfo {
    // trx or token value
    int64 callValue = 1;
    // tokenId, trx should be empty
    string tokenId = 2;
  }
  repeated CallValueInfo callValueInfo = 4;
  bytes note = 5;
  bool rejected = 6;
}
ParameterDescription
hashHash is a unique identifier for an internal transaction. There should not exist the same hash across all Internal Transactions or transactions.
caller_addressThe address to send TRX or TRC10 token.
transferTo_addressThe address to receive TRX or TRC10 token.
CallValueInfoIndicates the amount and type of asset and TRX transfer. It could be a list of pairs.

callvalue: The amount of TRX or TRC10 token
tokenID: the TRC10 tokenID. An empty value represents trx.
noteNote can have 3 types of values, which are call, create, and suicide, which represent the internal transaction type.

Call: Internal Transaction which happened within a contract call contract case.
Create: Internal Transaction which happened within a contract create contract case.
Suicide: Internal Transaction which happened within a contract self destruct case.
rejectedRejected is a boolean value of either true or false. For true, the internal transaction is rejected and not executed. For false, the internal transaction is successfully executed.

Obtaining Internal Transaction

Calling the RPC API gettransactioninfobyid with a transaction ID input parameter on an Internal Transaction supported node, returns a list of internal transactions.

The searching node config.conf should have saveInternalTx = true. Use the RPC example: in Wallet-CLI, you can use command gettransactioninfobyid <transactionId> to check all the Internal Transaction info in internal_transactions field.

📘

Note

You may not be able to obtain the internal transaction for early transaction ID, since the node hasn't switched on saveInternalTx = true at that time. If you wish to obtain the full data of Internal Transactions, you need a Full Node, which turns saveInternalTx = true on from the very beginning when TRON launched the TVM.

Wallet-CLI Result Example

InternalTransactionList: 
[
  hash:
  a07aaf40f35b42344d4909e8f739b32463c21a0c543fa212335f5d0d35f4db9d16  
  caller_address:
  4145867eff384dd351003dffc38fe6e25549fac58  
  transferTo_address:
  41537144c324033c5dc51759872f76e8f00f2edfa6  
  callValueInfo:
  [
    TokenName(Default trx):
    TRX(SUN)    
    callValue:
    10000000  
  ]
    
  note:
  create  
  rejected:
  false  
]
[
  hash:
  28fbeeeab85eda244cf83172380b1f26da07ad7a34bb90abdb75dff905736ab1c  
  caller_address:
  4143144c324033c5dc51776572f76e8f00f2edfa6  
  transferTo_address:
  412301d22dd9c7533b3d9c006f4279a823af41456  
  callValueInfo:
  [
    TokenName(Default trx):
    TRX(SUN)    
    callValue:
    10000000  
  ]
    
  note:
  call  
  rejected:
  false 
]