Witness 权限分离

使用 TRON 的账户权限管理,让 SR 所有者密钥保持离线,同时由热密钥签署区块。

📘

前置阅读

默认配置下,SR 账户的三大核心权限(witness_permission、active_permission 与 owner_permission)由同一个地址私钥控制。该私钥同时负责区块生产签名和资金支配签名,一旦泄露,区块生产与奖励资金同时面临风险。 TRON 的账户权限管理可把出块能力分离到专用密钥:Owner 密钥存于冷端,热签名密钥只负责签署区块。

本文说明账户权限变更、节点侧的 localwitness 配置,以及如何验证代理是否生效。

📘

Witness 权限边界:仅限区块签名

Witness 权限本身只授权区块签名;如果同一地址还出现在 Owner 或 Active 权限中,该密钥也拥有相应权限。涉及资金转移与账户变更的操作由 Owner/Active 权限 决定。请使用不同密钥,并以最高安全级别(冷存储级别)妥善保管 Owner/Active 密钥。完整权限模型请参阅账户权限管理。

为什么要分离出块权限

  • Owner 密钥保持离线。 分离 Witness 权限后,Owner 密钥无需参与日常出块,通常只在更新账户权限等 Owner 级操作中启用;日常资金或治理操作可另行配置最小权限的 Active 密钥。
  • 限制热签名密钥的影响范围。 如果 Witness 密钥未在 Owner 或 Active 权限中复用,泄露后无法转移 TRX、投票或更新权限。发现泄露时,应停止出块,并使用当前可用的权限授权路径把 witness_permission 更新为新的签名地址。
  • 生产环境标准做法。 生产环境中运营的 SR 通常会代理出块权限。参见 SR 最佳实践。

更新 SR 的账户权限

⚠️

提示

更新 SR 账户权限之前,请先停止出块节点。权限变更期间继续出块,可能导致节点使用不被网络认可的旧密钥进行签名,进而引发丢块的风险。

⚠️

这笔交易会全量替换 Owner 和 Active 权限,SR 账户还必须提交 Witness 权限。 如果更新后的 Owner 权限无法达到阈值,且没有可用并开放 AccountPermissionUpdateContract(ID 46)的 Active 权限,账户权限将无法再次修改。此时是否还能转移 TRX、领取奖励或继续出块,取决于剩余可用的 Active 和 Witness 权限。提交前先阅读更新权限结构中的检查清单。

通过 TRONSCAN 的权限界面或提交 AccountPermissionUpdateContract 即可更新 SR 的权限:

验证 witness_permission 权限

用 wallet/getaccount 查询 SR 账户,检查 witness_permission 块:

BASE_URL=https://api.trongrid.io   # 示例——替换为任意 TRON 节点(TronGrid、第三方或自托管)
curl -X POST "${BASE_URL}/wallet/getaccount" \
  -H 'Content-Type: application/json' \
  -d '{"address":"TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj","visible":true}'
{
    "address": "TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj",
    ...
    "witness_permission": {
        "type": "Witness",
        "id": 1,
        "threshold": 1,
        "keys": [
            {
                "address": "TXXvArisGf7YL9TfUbwYj5i16htm8ZjMUs",
                "weight": 1
            }
        ]
    },
    ...
}

上面的查询结果显示,SR TTxrh3...AUQj 已将出块权限授予地址 TXXvAr...jMUs,且该地址未出现在该账户的 Owner 或 Active 权限中。实际配置前请查询自己的 SR 账户并检查完整权限对象,确认签名地址没有被其他权限复用。

在节点配置中设置分离出的密钥

在 SR 节点的 config.conf 中设置以下两个字段:

# 当 SR 已代理 Witness 权限时,设置:
#   localWitnessAccountAddress = SR 账户地址
#   localwitnesskeystore       = 保存代理签名私钥的加密密钥库

localWitnessAccountAddress = TTxrh32VJveqiYRwbLEX2wLTMFCfbpAUQj

localwitnesskeystore = [
  "localwitnesskeystore.json"
]
字段设置为
localWitnessAccountAddressSR 的账户地址(在活跃 27 名中按投票排名的那个地址)。
localwitnesskeystore保存代理签名私钥的加密密钥库。生产环境部署应优先使用此方式(参见 SR 最佳实践:保护密钥库文件)。
localwitness代理签名地址的明文私钥,仅应在无法使用密钥库时配置。节点使用该密钥签署区块。

如果未分离 Witness 权限——即 SR 账户的 witness_permission 仍授权给自身地址、与 owner_permission 共用同一密钥——则将 localWitnessAccountAddress 留空,用 SR 账户自身的私钥配置 localwitness(或 localwitnesskeystore)。

启动节点

使用 --witness 参数启动全节点以启用区块生产功能。请根据 CPU 架构选择对应的 JDK 和 JVM 参数;以下命令以推荐配置为 64 GB 内存的 SR 主机为例:

# x86_64 / amd64:JDK 8
java -Xms9G -Xmx24G -XX:+UseConcMarkSweepGC -jar FullNode.jar --witness -c config.conf

# ARM64 / aarch64:JDK 17
java -Xmx24G -XX:+UseZGC -jar FullNode.jar --witness -c config.conf

长期运行时还应配置对应架构的完整 JVM 参数。请参阅部署全节点或超级节点。

节点出块时,会使用通过 localwitness 或 localwitnesskeystore 加载的 Witness 密钥签署区块,并将签名写入 block_header.witness_signature。

验证区块生产

确认 witness 配置已生效:

  • 节点日志。 在自己的出块槽位查找 produce block successfully 日志行。
  • 链上查询。 用 wallet/getblockbylimitnext 获取最近区块,检查自己出块槽位产生的区块中 witness_address 是否与 SR 账户地址匹配。
  • TronScan。 SR 的 TronScan 资料会显示近期出块率和产块详情。

相关资源