TRON 私链
搭建独立的 TRON 私有测试网络,包括至少一个超级代表(SR)出块节点与一个普通全节点。适用于本地开发、集成测试及对齐主网链参数的治理提议流程。
前置阅读
TRON 私链是 TRON 协议的完全隔离运行实例——拥有独立的创世区块、独立的超级代表(SR)集合以及专属的账本记录。私链的典型用途包括:端到端集成测试、智能合约上线前的预发布演练,以及需要在链上频繁执行操作但不想消耗主网真实 TRX 的开发场景。
最小规模的私链通常由一个出块 SR 全节点与至少一个普通同步全节点(负责同步区块、广播交易)组成。本文以双节点最小配置为例展开说明,若要扩展到包含多个超级代表的集群网络,只需沿用相同的配置模式即可。
准备工作
在开始部署前,请确保具备以下条件:
- 根据部署平台,安装 Oracle JDK 8(x86_64)或 17(ARM64)环境。
- 准备至少两个 TRON 账户地址及其对应的私钥:一个用作超级代表账户,另一个或多个作为预充值的测试账户。可使用 TronWeb、命令行工具 wallet-cli 或 TronLink 钱包生成这些地址。
由于该私链完全隔离,创世区块中配置的超级代表地址将作为网络唯一的区块生产者,直到通过标准的超级代表选举流程选出更多 SR。
部署步骤
部署私链节点的基本流程与主网全节点一致,唯一的区别在于配置文件。两个节点运行相同的 FullNode.jar,仅在创世块定义、节点发现种子以及链上参数覆盖上有差异。
1. 创建部署目录
为超级代表(SR)和普通全节点分别创建独立的存放目录,以防数据库和配置文件冲突:
mkdir SR FullNode2. 将 FullNode.jar 放入对应目录
两个节点使用完全相同的 JAR 包。可根据部署节点中的指导自行编译或下载发布版:
cp FullNode.jar SR/
cp FullNode.jar FullNode/3. 将配置文件放入对应目录
将主网默认配置文件模板复制到两个目录中,并进行重命名以示区分:
cp config.conf SR/supernode.conf
cp config.conf FullNode/fullnode.conf4. 编辑各配置文件
请分别修改两份配置文件中的以下关键参数项:
| 配置文件键名 | SR 节点(supernode.conf) | 普通全节点(fullnode.conf) | 修改原因 |
|---|---|---|---|
localwitness | SR 地址的私钥 | (保留为空列表) | SR 节点必须加载此私钥以对区块进行共识签名 |
genesis.block.witnesses | SR 地址 | 与 SR 相同 | 创世块的初始出块代表,两端配置必须一致 |
genesis.block.Assets | 预充值账户及其初始 TRX 余额 | 与 SR 相同 | 创世块的初始资金分配,两端配置必须一致 |
p2p.version | 任意正整数(切勿使用 11111) | 与 SR 相同 | 11111 是主网的 P2P 版本;自定义值可隔离网络,两端必须一致 |
seed.node | (留空) | SR 节点的 IP 地址和 listen.port | 引导全节点去连接并发现 SR 节点 |
needSyncCheck | false | true | 首个启动的出块节点需跳过同步检查,普通节点则需进行同步 |
node.discovery.enable | true | true | 启用节点发现,以便节点间能正常建立 P2P 握手连接 |
block.proposalExpireTime | 600000(10 分钟) | 与 SR 相同 | 缩短治理提议的过期时间以加快测试进度(主网默认值为 3 天) |
block.maintenanceTimeInterval | 300000(5 分钟) | 与 SR 相同 | 缩短维护周期以加快投票生效(主网默认值为 6 小时) |
committee.allowSameTokenName | 1 | 1 | 允许存在同名的 TRC-10 Token |
committee.allowTvmTransferTrc10 | 1 | 1 | 允许 TVM 转移 TRC-10 Token |
5. 单机部署时的端口调整
如果超级代表节点和普通全节点运行在同一台服务器上,为避免端口冲突,请为各自配置独立的端口:
listen.port:P2P 网络监听端口http端口组:HTTP RPC 端口rpc端口组:gRPC 端口
如果两个节点部署在不同的服务器上,可以直接使用配置文件中的默认端口。
6. 启动节点
# 启动超级代表(SR)出块节点
cd SR
java -Xmx6g -XX:+HeapDumpOnOutOfMemoryError -jar FullNode.jar --witness -c supernode.conf
# 启动普通全节点
cd ../FullNode
java -Xmx6g -XX:+HeapDumpOnOutOfMemoryError -jar FullNode.jar -c fullnode.conf启动几秒钟后,全节点日志中应能看到节点成功连接至 SR 节点并开始同步新产生的区块。
将链参数与主网对齐
全新启动的私链会采用初始默认参数,这与主网当前的实际运行环境(如能量单价、出块奖励、智能合约执行上限、动态能量模型等)不同。为了让私链测试行为更接近主网,需要以超级代表(SR)身份提交两笔链上治理提议来更新这些参数。
之所以要将修改拆分为两笔治理提议,是因为诸如 #30 和 #70 这类基础开关参数必须先被激活生效,链才会接受依赖于它们的具体参数值。因此第一笔治理提议负责激活开关,第二笔治理提议在开关激活后的基础上设置具体数值。
以下是使用 TronWeb 提交和批准治理提议的示例脚本:
const { TronWeb } = require('tronweb');
const tronWeb = new TronWeb({
fullHost: 'http://localhost:16887', // 替换为 SR 节点的实际 HTTP 端口(主网默认为 8090)
privateKey: 'c741f5c0...7d220dc' // 超级代表(SR)账户的 Hex 格式私钥
});
// 治理提议 1 — 必须首先执行,以激活基础链参数和功能开关
const parametersForProposal1 = [
{ key: 9, value: 1 }, { key: 10, value: 1 }, { key: 11, value: 420 },
{ key: 19, value: 90000000000 }, { key: 15, value: 1 }, { key: 18, value: 1 },
{ key: 16, value: 1 }, { key: 20, value: 1 }, { key: 26, value: 1 },
{ key: 30, value: 1 }, { key: 5, value: 16000000 }, { key: 31, value: 160000000 },
{ key: 32, value: 1 }, { key: 39, value: 1 }, { key: 41, value: 1 },
{ key: 3, value: 1000 }, { key: 47, value: 10000000000 }, { key: 49, value: 1 },
{ key: 13, value: 80 }, { key: 7, value: 1000000 }, { key: 61, value: 600 },
{ key: 63, value: 1 }, { key: 65, value: 1 }, { key: 66, value: 1 },
{ key: 67, value: 1 }, { key: 68, value: 1000000 }, { key: 69, value: 1 },
{ key: 70, value: 14 }, { key: 71, value: 1 }, { key: 76, value: 1 }
];
// 治理提议 2 — 必须在治理提议 1 获批并到期生效后才能执行
const parametersForProposal2 = [
{ key: 47, value: 15000000000 }, { key: 59, value: 1 }, { key: 72, value: 1 },
{ key: 73, value: 3000000000 }, { key: 74, value: 2000 }, { key: 75, value: 12000 },
{ key: 77, value: 1 }, { key: 78, value: 864000 }
];
async function modifyChainParameters(parameters, proposalID) {
parameters.sort((a, b) => a.key - b.key);
const unsignedTxn = await tronWeb.transactionBuilder.createProposal(
parameters,
'41D0B696...5C593C00F0' // 超级代表(SR)的 42 位 Hex 格式地址
);
const signedTxn = await tronWeb.trx.sign(unsignedTxn);
const receipt = await tronWeb.trx.sendRawTransaction(signedTxn);
console.log('治理提议已提交:', receipt);
setTimeout(async () => {
console.log('批准治理提议,提议 ID:', proposalID);
const unsignedVote = await tronWeb.transactionBuilder.voteProposal(
proposalID, true, tronWeb.defaultAddress.hex
);
const signedVote = await tronWeb.trx.sign(unsignedVote);
await tronWeb.trx.sendRawTransaction(signedVote);
}, 1000);
}
// 步骤 1:提交并批准治理提议 1
modifyChainParameters(parametersForProposal1, 1);运行治理提议 1 的脚本后,可使用接口 wallet/listproposals 查询其过期时间。在 expiration_time 截止后,如果该治理提议的状态(state)变为 APPROVED,说明参数已正式并入链状态。此时即可运行治理提议 2:
modifyChainParameters(parametersForProposal2, 2);当两个治理提议均生效后,私链参数即与目标配置对齐。可随时通过 wallet/getchainparameters 接口验证当前参数值。
完整的链上参数定义及各自的作用说明,请参阅网络参数。
相关资源
- 部署节点——节点的单机端到端部署流程
- 成为超级代表——超级代表的竞选与参选指南
- 超级代表 (SR) 最佳实践——生产环境超级代表节点的运维规范
- 网络参数——链上所有可通过治理提议修改的参数列表参考
- 资源模型:带宽与能量——TRON 的三类核心系统资源介绍
Updated 26 days ago