当前位置: 首页 > news >正文

【钱包】Tron签名总结

👻前言

我在使用rawDataHex和privateKeyHex进行签名的时候,是可以正常签名的,但是一广播就失败,无法上链,以下是我签名的方法

/// Tron签名函数,返回 r + s + v 的 65字节签名String signTronTx(Uint8List rawData, String privateKeyHex) {// 1. SHA256 哈希final hash = sha256.convert(rawData).bytes;// 2. 私钥 hex -> bytesfinal privateKeyBytes = web3.hexToBytes(privateKeyHex);// 3. 签名final sig = web3.sign(Uint8List.fromList(hash), privateKeyBytes);// 4. 拼接 r(32) + s(32) + v(1)final r = sig.r.toBytesPadded(32);// final r = bigIntToBytes(sig.r, 32);// final s = bigIntToBytes(sig.s, 32);final s = sig.s.toBytesPadded(32);final v = Uint8List.fromList([sig.v]);final sigList = Uint8List.fromList([...r, ...s, ...v]);return hex.encode(sigList);}

后来查询了大量文档才知道,我这个是r + s + v格式的字节签名,能上链的签名是v + r + s 格式的 65 字节签名,所以导致失败。

🧠 背景知识:椭圆曲线签名(ECDSA)

在 ECDSA(用于 Tron、Ethereum 等链)中,签名的结构是:

r(32字节) + s(32字节) + v(1字节)

注意:但是这个顺序并不是所有链都一样,不同链对签名的顺序有细微要求。

✅正确格式:v + r + s

Tron 的签名顺序是:

[1 byte v] + [32 byte r] + [32 byte s] = 65 字节

✏️ 修改 signTronTx 函数

String signTronTx(Uint8List rawData, String privateKeyHex) {// 1. SHA256 哈希final hash = sha256.convert(rawData).bytes;// 2. 私钥 hex -> bytesfinal privateKeyBytes = web3.hexToBytes(privateKeyHex);// 3. 签名final sig = web3.sign(Uint8List.fromList(hash), privateKeyBytes);// 4. 拼接成 [v, r, s]final r = sig.r.toBytesPadded(32);final s = sig.s.toBytesPadded(32);final v = Uint8List.fromList([sig.v]); // 注意,这里是 1 字节// ✅ 顺序改成 v + r + sfinal sigList = Uint8List.fromList([...v, ...r, ...s]);return hex.encode(sigList);
}

🧪 为什么 Tron 使用 v + r + s?

这是 Tron 在其 Protobuf 结构 Transaction.raw_data.contract.parameter 中对签名的要求,确保节点验证签名时能正确地解析和恢复公钥。

不同链对 v 的使用方式略有不同:

v的位置v的值
Ethereum最后(r+s+v)27/28 或 0/1
Tron最前(v+r+s)27/28

📌 总结

项目正确方式错误方式
签名顺序✅ v + r + s❌ r + s + v
为什么顺序重要?Tron 验签是按这个顺序解析的错序会导致签名无效
如何修复?用 Uint8List.fromList([…v, …r, …s]) 拼接-
v 是否要加 27/28?通常要,如果是 0/1 就加 27否则恢复公钥会失败

相关文章:

  • c# 数据结构 链表篇 有关双向链表的一切
  • Vue el-from的el-form-item v-for循环表单如何校验rules(一)
  • TMS320F28P550SJ9学习笔记15:Lin通信SCI模式结构体寄存器
  • 【Java学习】Knife4j使用流程
  • MongoDB常见语句
  • dsp的主码流,子码流是指什么,有什么区别和作用
  • 实践001-Gitlab基础项目准备
  • [MySQL] 事务管理(一) 事务的基本概念
  • Python基础知识(基础语法二)
  • 【ROS2】行为树 BehaviorTree(六):各种各样的节点
  • 循环神经网络 - 扩展到图结构之递归神经网络
  • AI核心概念之“Function Calling” - 来自DeepSeek
  • 4-15记录(冒泡排序,快速选择排序)
  • 电路(b站石群老师主讲,持续更新中...)
  • OpenGL学习笔记(几何着色器、实例化、抗锯齿)
  • Spring 是如何解决循环依赖的
  • 火山引擎旗下防御有哪些
  • 东方博宜OJ ——2395 - 部分背包问题
  • 游戏引擎学习第228天
  • Mysql的查询
  • 我国与沙特签署《核能发展安全与安保合作谅解备忘录》
  • 解放日报:订单不撤,中国工程师有能力
  • 上海崇明“人鸟争食”何解?检察机关推动各方寻找最优解
  • 错失两局领先浪费赛点,王楚钦不敌雨果无缘世界杯男单决赛
  • 能源央企资产重组大提速,专业化整合掀起新热潮
  • 在历史上遭到起诉的杀人动物记录中,为什么猪如此普遍?