news 2026/8/19 19:51:18

以太坊交易签名实战:token-core-android 中 RLP 编码与 EIP-155 全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
以太坊交易签名实战:token-core-android 中 RLP 编码与 EIP-155 全流程

以太坊交易签名实战:token-core-android 中 RLP 编码与 EIP-155 全流程

【免费下载链接】token-core-androida blockchain private key management library on android项目地址: https://gitcode.com/gh_mirrors/to/token-core-android

对于刚接触区块链开发的 Android 工程师来说,以太坊交易签名往往是一道绕不开的门槛:非对称加密、Keccak-256、RLP 编码、EIP-155……一系列名词扑面而来。而token-core-android正是一个专注于区块链私钥管理与离线签名的 Android 库,它用不到两百行核心代码,把"构造交易 → 编码 → 签名 → 广播"的完整链路封装得清晰易懂。本文将以源码为线索,带你一步步拆解以太坊交易签名全流程,彻底搞懂 RLP 编码与 EIP-155 重放保护背后的原理。

一次以太坊交易签名,到底经历了哪几步?

以太坊交易签名绝不是"给字符串加个密"这么简单。在 token-core-android 中,一次完整的签名流程分为四个阶段:

  1. RLP 编码:把 nonce、gasPrice、gasLimit、to、value、data 六个字段按固定顺序编码为字节流;
  2. 哈希与 ECDSA 签名:对编码结果做 Keccak-256 哈希,再用私钥生成 (v, r, s) 签名;
  3. EIP-155 二次编码:把链 ID 折叠进 v 值,重新 RLP 编码得到可广播的原始交易;
  4. 计算交易哈希:对签名后的交易再做一次 Keccak-256,得到可查询的 txHash。

这四步分别对应四个核心类,下面逐一深入。

第一步:交易字段的 RLP 编码规则

RLP(Recursive Length Prefix)是以太坊底层通用的序列化格式,它的规则很简单:

  • 单个字节且值在 0x00~0x7f 之间,直接原样输出;
  • 长度不超过 55 字节的字符串,前缀0x80 + 长度
  • 更长的字符串,前缀标记长度字段本身的字节数;
  • 列表(List)在拼接所有元素后,前缀0xc0 + 总长度

token-core-android 把这三条规则完整实现在 RlpEncoder.java 中,配合 RlpString.java 与 RlpList.java 两个数据类型,构成一套简洁的 RLP 工具箱。

// RlpEncoder.java 核心逻辑 public static byte[] encode(RlpType value) { if (value instanceof RlpString) { return encodeString((RlpString) value); } else { return encodeList((RlpList) value); } }

第二步:六个字段如何按顺序入列?

以太坊规定交易的 RLP 结构必须严格按nonce → gasPrice → gasLimit → to → value → data排列。在 EthereumTransaction.java 的asRlpValues()方法中,你可以看到几个非常讲究的细节:

  • to 地址为空时(合约创建交易),编码为空字符串,而不是数字 0;
  • to 地址带前导零时,必须按字节原样编码,防止被当作数值截断;
  • data 字段需要先从十六进制字符串还原成字节数组再编码;
  • 非负数、零值都有专门的处理分支,避免出现多余的前导零。

这些细节正是"看着简单、做起来容易出错"的地方,token-core-android 已经帮你全部处理妥当。

第三步:Keccak-256 哈希与 ECDSA 可恢复签名

RLP 编码完成后,签名正式开始。核心逻辑在 EthereumSign.java 中:

static SignatureData signMessage(byte[] message, byte[] prvKeyBytes) { ECKey ecKey = ECKey.fromPrivate(prvKeyBytes); byte[] messageHash = Hash.keccak256(message); return signAsRecoverable(messageHash, ecKey); }

这里有两个关键点:

  • Keccak-256与常见的 SHA-256 并不相同,项目在 Hash.java 中提供了原生实现;
  • 可恢复签名(recoverable signature):签名结果会额外携带 recovery ID,用于反推公钥,这也是后续ecRecover验签、恢复地址的基础。signAsRecoverable()会遍历 0~3 四个候选 ID,找到能恢复出当前公钥的那一个,最终得到 (v, r, s) 三件套,封装在 SignatureData.java 中。

第四步:EIP-155 如何防止跨链重放攻击?

早期以太坊交易只有 v = 27/28 两种取值,同一笔签名交易可以原封不动地在其他链(比如 ETC)上重放。EIP-155 提案的解决方案是:把链 ID 编码进 v 值

createEip155SignatureData()方法中可以看到那条经典的公式:

private static SignatureData createEip155SignatureData(SignatureData signatureData, int chainId) { int v = signatureData.getV() + (chainId * 2) + 8; return new SignatureData(v, signatureData.getR(), signatureData.getS()); }

v = 35 + chainId * 2 + recoveryId(其中 recoveryId 范围为 0~1)。这样一来,为以太坊主网签名的交易,其 v 值天然与以太坊经典(ETC)不兼容,重放攻击被从数学上杜绝。项目在 ChainId.java 中预置了常用链 ID:以太坊主网 1、Ropsten 3、Kovan 42、ETC 主网 61 等,直接引用即可。

💡 冷知识:EIP-155 签名要求先带链 ID 编码一次(此时 v 占位为链 ID、r/s 为空),哈希签名后再把真实 v 值代入重新编码。这个过程在signTransaction(int chainId, byte[] privateKey)中完整呈现,两轮编码一步不差。

第五步:得到可广播的 signedTx 与 txHash

签名与二次编码完成后,signTransaction()返回一个 TxSignResult.java 对象,包含两个关键字段:

  • signedTx:十六进制编码的原始交易(Raw Transaction),直接交给节点或钱包广播;
  • txHash:对 signedTx 再做一次 Keccak-256 得到的交易哈希,用于在区块浏览器中查询交易状态。
String calcTxHash(String signedTx) { return NumericUtil.prependHexPrefix(Hash.keccak256(signedTx)); }

项目在 EthereumTransactionTest.java 中保留了 EIP-155 官方测试向量,可以用固定私钥0x4646...4646验证你的实现输出是否与预期完全一致,非常适合作为自测基准。

在 Android 项目中如何快速落地?

在真实 App 中,私钥通常保存在加密 keystore 中,因此对外暴露的 API 是"密码 + 钱包"而非裸私钥:

EthereumTransaction tx = new EthereumTransaction( nonce, gasPrice, gasLimit, toAddress, value, data); TxSignResult result = tx.signTransaction( ChainId.ETHEREUM_MAINNET, password, ethereumWallet); String signedTx = result.getSignedTx(); // 广播用 String txHash = result.getTxHash(); // 查询用

私钥的加解密在 Wallet.java 的decryptMainKey()中完成,签名全程在本地设备离线进行,私钥永不触网——这也是移动钱包安全性的根基。

总结:一条链路,四个关键文件

  • 交易模型与 EIP-155 逻辑:EthereumTransaction.java
  • Keccak-256 哈希与 ECDSA 签名:EthereumSign.java
  • RLP 编码实现:RlpEncoder.java
  • 签名结果载体:SignatureData.java

以太坊交易签名并不神秘:它无非是"固定字段顺序 + RLP 序列化 + Keccak-256 哈希 + ECDSA 签名 + 链 ID 防重放"的组合拳。借助 token-core-android 这份简洁的开源实现,你不仅能快速在自己的 Android 项目中接入离线签名能力,更能通过源码真正吃透底层原理,为后续深入智能合约交互、多链钱包开发打下扎实基础。😊

【免费下载链接】token-core-androida blockchain private key management library on android项目地址: https://gitcode.com/gh_mirrors/to/token-core-android

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/19 19:49:32

当“想飞“的念头撞上ESP32:新手造开源无人机的一周实录

当"想飞"的念头撞上ESP32:新手造开源无人机的一周实录 【免费下载链接】esp-drone Mini Drone/Quadcopter Firmware for ESP32 and ESP32-S Series SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-drone 想拥有自己的无人机&#xf…

作者头像 李华
网站建设 2026/8/19 19:47:43

免费解锁三星耳机全部隐藏功能:Galaxy Buds Client 完整上手指南

免费解锁三星耳机全部隐藏功能:Galaxy Buds Client 完整上手指南 【免费下载链接】GalaxyBudsClient Unofficial Galaxy Buds Manager for Windows, macOS, Linux, and Android 项目地址: https://gitcode.com/gh_mirrors/ga/GalaxyBudsClient 你刚拆开一副 …

作者头像 李华
网站建设 2026/8/19 19:46:49

librealsense 全解析:从零上手 RealSense 深度相机的完整开发攻略

librealsense 全解析:从零上手 RealSense 深度相机的完整开发攻略 【免费下载链接】librealsense RealSense SDK 项目地址: https://gitcode.com/GitHub_Trending/li/librealsense 深度相机是机器人、AR、3D 扫描领域的"标配眼睛",而 l…

作者头像 李华