如何将以太坊合约迁移至 TRON
主要差异 - 以太坊(EVM)vs TRON (TVM)
| 以太坊 (EVM) | TRON (TVM) | |
|---|---|---|
| 虚拟机 | EVM (支持 Solidity/Vyper) | TVM(支持Solidity,兼容 EVM,但有差异) |
| Gas 机制 | ETH 支付 Gas 费(动态市场) | 带宽/能量(可通过质押 TRX 获取) |
| 原生代币 | ETH(18 位小数) | TRX(6 位小数) |
TVM 和 EVM 的兼容
TVM 兼容 EVM,大部分以太坊上的 Solidity 合约可以直接迁移到 TRON 上,但需要使用 TRON 上的 solc 进行编译。
EVM 上和 TVM 不同的指令:
以下操作码在 TVM 和 EVM 之间表现出不同的行为:
| 指令 | TVM Behavior | EVM Behavior |
|---|---|---|
DIFFICULTY (0x44) | 返回 0 | 返回当前区块难度 |
GASLIMIT (0x45) | 返回 0 | 返回当前区块的 gaslimit。 |
GASPRICE (0x3A) | 返回 energyPrice,主网为100 sun。 | 返回当前的gasPrice。 |
BASEFEE (0x48) | 返回 energyPrice, 主网为100 sun。 | 返回当前区块的baseFee。 |
CREATE2 (0xf5) | 前缀为0x41。 | 前缀为0xff。 |
当合约逻辑涉及上面的指令时,开发人员需要注意 TVM 和 EVM 的差异。
对于 CREATE2 指令,如果是使用 new 来创建合约,使用 salt 表示是以 CREATE2 的方式生成地址,TRON 的编译器会自动在 CREATE2 的计算中使用前缀 0xff,所以代码直接迁移即可,无需改动。
示例:注意:ContractCreated 事件未在源代码片段中定义,但出于功能说明的目的将其包含在内。
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.20;
contract Token1{
uint256 public value;
constructor(uint256 _value) {
value = _value;
}
}
contract Factory {
/// 使用 CREATE2 创建合约
function createContract(bytes32 _salt,uint _x) external{
Token1 _contract = new Token1{salt: _salt}(_x);
emit ContractCreated(address(_contract));
}
}
但是如果是引用了其它库,比如 open-zeppelin 的 CREATE2 计算地址的逻辑,则需要注意把前缀 0xff 修改为 0x41。
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0x41
mstore8(start, 0x41) //此处需要改成0x41
addr := keccak256(start, 85)
}
}
预编译合约差异
下表概述了特定地址的预编译合约的功能差异。
| 预编译合约地址 | TVM | EVM |
|---|---|---|
Ripemd160 (0x03) | 计算 SHA-256 两次 | 计算 SHA-256 一次 |
0x09 | [BatchValidateSign](https://github.com/tronprotocol/tips/blob/master/tip-43.md), 用来做多签的验证 | [Blake2F](https://eips.ethereum.org/EIPS/eip-152) compression function. |
需要注意预编译合约的不同,如果合约代码中有使用以上的预编译合约地址,则需要修改,保证逻辑无误之后再迁移。
原生代币精度差异
需要注意 ETH 上的最小单位为 1/1e18,而 TRX 的最小单位为 1/1e6。如果合约中涉及原生代币最小单位的计算,则需要修改合约,保证计算无误。
SDK and Tooling Equivalents
SDKs
要与波场(TRON)网络进行交互,开发者可以针对不同的编程语言使用多种SDK:
开发工具
波场(TRON)生态系统同样提供了一套开发工具,对应以太坊生态中的常用工具。
Updated 7 months ago