账户权限管理交易示例
以 2-of-3 多签账户为例,演示如何配置权限、构建交易、收集签名、检查权重并广播。
本文用一个 2-of-3 Owner 权限账户演示完整多签流程。Alice、Bob、Carol 三个地址共同控制账户,任意两方签名即可授权转账;任意一方单独签名都不能通过校验。
流程分为五步:配置权限、构建待签交易、收集签名、广播前检查签名权重、广播交易。
前置阅读
场景
目标账户的 Owner 权限配置如下:
threshold: 2
keys:
- Alice, weight: 1
- Bob, weight: 1
- Carol, weight: 1Alice + Bob、Alice + Carol、Bob + Carol 都能授权交易;单个签名者不能授权。
第 1 步:配置 2-of-3 权限
第一次配置多签时,需要提交 AccountPermissionUpdateContract。这笔交易必须由账户当前生效的 Owner 权限签名;如果账户仍是默认单签状态,通常由原始账户私钥签名。
const updateTxn = await tronWeb.transactionBuilder.updateAccountPermissions(
"TAccount...XX", // owner_address: 要更新权限的账户
{
threshold: 2,
keys: [
{ address: "TAlice...AA", weight: 1 },
{ address: "TBob1...BB", weight: 1 },
{ address: "TCarol...CC", weight: 1 }
]
},
null, // witness permission: 普通非 SR 账户传 null
[] // active permissions: 本示例不创建 Active 权限
);
const signedUpdate = await tronWeb.trx.sign(updateTxn, originalOwnerKey);
const updateResult = await tronWeb.trx.sendRawTransaction(signedUpdate);
console.log(updateResult.txid);交易确认并固化后,账户 Owner 权限即变为 2-of-3 多签。
第 2 步:构建待共签交易
假设多签账户要向供应商转账 100 TRX。任意签名者都可以先构建一笔未完成签名的交易:
const txn = await tronWeb.transactionBuilder.sendTrx(
"TVendor...DD", // 接收方
100_000_000, // 100 TRX,单位为 sun
"TAccount...XX" // 发送方:多签账户
);
// 显式指定使用 Owner 权限签名。省略时通常也会走 Owner,但多签流程建议明确写出。
txn.raw_data.contract[0].Permission_id = 0;Permission_id = 0 表示这笔交易使用 Owner 权限校验。若要使用 Active 权限,应填写对应的 Permission_id(通常为 2 到 9),并确保该 Active 权限的 operations 位图允许当前合约类型。
第 3 步:收集签名
多签签名可以逐个追加。每个签名者拿到同一笔交易对象,用自己的私钥签名后,把部分签名交易交给下一位签名者。
Alice 先签名:
const signedByAlice = await tronWeb.trx.multiSign(txn, aliceKey, 0);
// signedByAlice.signature 现在包含 Alice 的签名第三个参数 0 仍是 Permission_id,必须与交易希望使用的权限一致。
Bob 在 Alice 已签名的交易上继续追加签名:
const signedByAliceAndBob = await tronWeb.trx.multiSign(signedByAlice, bobKey, 0);
// signedByAliceAndBob.signature 现在包含 Alice 和 Bob 两个签名此时签名权重为 1 + 1 = 2,已达到 Owner 权限阈值。Carol 不需要再签名。
第 4 步:广播前检查签名权重
广播前可以调用 wallet/getsignweight 检查交易是否已经满足权限阈值。这个接口不会广播交易,只返回当前签名集合的校验结果。
BASE_URL=https://api.trongrid.io
POST ${BASE_URL}/wallet/getsignweight
{
"transaction": <signedByAliceAndBob 序列化结果>
}典型响应如下:
{
"approved_list": ["TAlice...AA", "TBob1...BB"],
"current_weight": 2,
"permission": {
"threshold": 2,
"keys": [...]
},
"result": {
"code": "ENOUGH_PERMISSION"
}
}当 current_weight 大于或等于 permission.threshold,且 result.code 为 ENOUGH_PERMISSION 时,交易可以广播。若仍缺签名,通常会返回 NOT_ENOUGH_PERMISSION。如果签名格式错误、权限不匹配或签名者不在目标权限的 keys 列表中,应先修正交易对象再广播。
第 5 步:广播交易
const result = await tronWeb.trx.sendRawTransaction(signedByAliceAndBob);
console.log(result.txid);转账进入区块后,建议等待区块固化再视为最终完成。区块固化机制参见共识与 DPoS。
多签附加费当一笔交易携带多个签名时, TRON 会对第一个签名之外的每个额外签名收取多签附加费。主网默认值为每个额外签名 1 TRX,由链参数
#23getMultiSignFee控制。上面的 2 签名交易除普通转账成本外,还会额外支付 1 TRX。
常见变体
Carol 替代 Bob 签名
Alice + Carol 与 Alice + Bob 等价。只要签名者都在 Owner 权限的 keys 列表中,且权重总和达到 2,交易即可通过。
添加第三个签名
Alice、Bob 已经达到阈值后,再追加 Carol 的签名不会让交易失败。总权重变为 3,仍然满足阈值。
不过,多出的签名会带来额外多签附加费。对高频业务路径而言,应避免收集超过阈值所需的签名。
出现权限外签名
如果一个不在 Owner 权限 keys 列表中的地址签了这笔交易,节点不会把它当成 0 权重忽略,而是会拒绝整笔交易。重复签名者、签名数量超过权限密钥数量等情况也会导致校验失败。
因此,多签系统在传递交易对象时应控制签名者集合,并在广播前调用 wallet/getsignweight。
使用 Active 权限授权日常操作
日常付款不一定要动用 Owner 权限。可以创建一个只允许 TransferContract 的 Active 权限,并把 Permission_id 设置为该 Active 权限的 ID。这样,日常转账可由热密钥完成,权限变更、合约部署等高风险操作仍由 Owner 多签控制。
Active 权限配置参见账户权限管理。
API
| API | 说明 |
|---|---|
wallet/accountpermissionupdate | 配置或更新账户权限 |
wallet/getsignweight | 检查部分签名交易的当前权重 |
wallet/getapprovedlist | 查看已经签名的地址 |
wallet/broadcasttransaction | 广播完整签名交易 |
相关资源
- 账户权限管理 — 权限类型、权重、合约类型限制
- 签名校验 — 签名恢复与多签聚合规则
- 多签交易 recipe — 包含完整 SDK 示例的代码 recipe
Updated 26 days ago