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

比特币交易签名实战:token-core-android 的 UTXO 模型、找零与多输入签名

比特币交易签名实战:token-core-android 的 UTXO 模型、找零与多输入签名

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

比特币交易签名与以太坊式的"扣余额"完全不同:它要做的不是减少账户数字,而是把历史 UTXO 一枚枚花掉。token-core-android 是一款面向 Android 平台的区块链私钥管理库,它把 UTXO 模型、找零输出与多输入签名封装成统一且简洁的 API。本文以BitcoinTransaction为切入点,用最通俗的语言拆解比特币交易签名的完整流程,帮你快速上手,避开新手常见的大坑。

为什么说比特币交易签名是"花硬币"而不是"扣余额"?🧐

比特币里根本没有"账户余额"这个概念。每个地址拥有的,是一堆未花费的交易输出(Unspent Transaction Output,UTXO)。你可以把它们想象成钱包里的一枚枚硬币:每枚都有固定面值、有来路记录,花的时候必须整枚花掉——面值不够就得多拿几枚凑,花不完的部分就要"找零"回来。

UTXO 由哪些字段组成?

在 token-core-android 中,UTXO 被建模为BitcoinTransaction.UTXO这个内部类,定义于app/src/main/java/org/consenlabs/tokencore/wallet/transaction/BitcoinTransaction.java

字段含义
txHash这枚硬币来自哪一笔交易(交易哈希)
vout它是该交易的第几个输出(从 0 开始)
amount硬币面值,单位是"聪"(1 BTC = 1 亿聪)
address这枚硬币被锁定在哪个地址
scriptPubKey锁定脚本,证明这枚硬币"属于谁"
derivedPath该地址在 HD 钱包中的派生路径(如0/22
sequence序列号,与 RBF 手续费替换等功能相关

所以一笔比特币交易签名的本质是:选若干 UTXO 作为输入 → 生成"收款输出 + 找零输出" → 对每个输入分别签名

一次转账的完整旅程:输入、输出与找零怎么算?📐

用 token-core-android 发起转账非常简单:构造一个BitcoinTransaction,传入收款地址、找零索引、转账金额、手续费和 UTXO 列表,再调用signTransaction()即可。核心逻辑位于app/src/main/java/org/consenlabs/tokencore/wallet/transaction/BitcoinTransaction.java

输入总和 = Σ 所有 UTXO 的 amount 找零金额 = 输入总和 - 转账金额 - 手续费

这里有个容易忽略的细节:只有找零金额 ≥ 防粉尘阈值(DUST_THRESHOLD = 2730聪)时,才会追加找零输出。如果找零金额低于这个值,就直接放弃找零,把零头留给矿工作手续费。这样做是为了避免产生"粉尘输出"(dust),防止区块链被微小金额交易刷屏。

找零地址:钱包如何安全地收回零钱?🔒

找零地址绝对不能直接用收款地址——那样链上任何人都能顺着地址扒出你的全部资金流水,隐私瞬间归零。token-core-android 的做法是:从 HD 主密钥按 BIP44 规范派生出一个独立的找零分支(change key),再结合你传入的changeIdx定位到具体的找零地址。这段逻辑见app/src/main/java/org/consenlabs/tokencore/wallet/transaction/BitcoinTransaction.java

常用的 BIP44 派生路径定义在app/src/main/java/org/consenlabs/tokencore/wallet/model/BIP44Util.java

钱包类型主网路径测试网路径
普通比特币钱包m/44'/0'/0'm/44'/1'/0'
SegWit 钱包m/49'/0'/0'm/49'/1'/0'

多输入签名实战:一枚硬币不够花怎么办?💰

当转账金额超过单枚 UTXO 的面值时,就需要把多个 UTXO 塞进同一笔交易。测试用例app/src/test/java/org/consenlabs/tokencore/wallet/transaction/BitcoinTransactionTest.java里就演示了同时消费 4 个 UTXO 的场景。

这里的关键在于:每个输入都必须用对应地址的私钥单独签名。token-core-android 会读取每个 UTXO 的derivedPath,从 HD 主密钥逐层派生出对应的子私钥,然后逐个计算签名哈希(hashForSignature)、生成 ECDSA 签名,最后写回每个输入的scriptSig。签名类型固定为SIGHASH_ALL,表示"签名覆盖整个交易,任何改动都会让签名失效"——这也是防篡改的核心。

私钥从哪来?WIF 钱包与 HD 钱包的差异

  • WIF 钱包:从导入的 WIF 私钥直接恢复ECKey,所有 UTXO 共用同一把私钥签名;
  • HD 钱包:从助记词派生出 xprv 主密钥,再按每个 UTXO 的derivedPath分别派生对应子私钥。

SegWit 交易签名:见证数据与 wtxID 是什么?🧩

隔离见证(SegWit)改变了签名的组织方式:签名不再放进scriptSig,而是移入独立的见证数据区(witness),因此交易体积更小、手续费更省。token-core-android 通过signSegWitTransaction()实现 P2WPKH 地址的签名(app/src/main/java/org/consenlabs/tokencore/wallet/transaction/BitcoinTransaction.java),签名前需要预先计算hashPrevoutshashOutputshashSequence等一系列哈希字段。

SegWit 交易还有一个独特现象:wtxID(见证交易 ID)和 txHash 可能不一样。wtxID 的哈希覆盖了见证数据,而 txHash 不含见证数据。这就是为什么签名结果里会同时返回两个哈希。

签名完成后拿到什么?📦

签名结果被封装在TxSignResult中(app/src/main/java/org/consenlabs/tokencore/wallet/transaction/TxSignResult.java):

返回值用途
signedTx序列化后的完整签名交易(十六进制),可直接广播上链
txHash交易哈希,用于查询交易确认状态
wtxID仅 SegWit 交易返回,见证交易 ID

新手避坑指南:5 个最容易踩的坑 ⚠️

  1. 单位换算:金额与手续费都用"聪",别拿 BTC 当单位直接传,差 1 亿倍;
  2. 防粉尘拦截:转账金额低于 2730 聪会直接被拒绝,这是防粉尘保护机制;
  3. 余额不足:输入 UTXO 总和小于转账金额时,会抛出INSUFFICIENT_FUNDS异常;
  4. 测试网隔离:调试务必使用测试网(TestNet)地址和测试网 WIF,别拿主网私钥乱试;
  5. 压缩公钥:SegWit 地址要求压缩公钥,导入非压缩私钥会直接报错。

如何获取源码动手实践?🚀

想要亲手跑一遍多输入签名与找零逻辑,可以克隆源码到本地:

git clone https://gitcode.com/gh_mirrors/to/token-core-android

然后重点阅读BitcoinTransactionTest.java中的测试用例——它们演示了 WIF 钱包、HD 钱包、多 UTXO、SegWit 等多种场景,还附带了可校验的签名结果,是学习比特币交易签名的最佳入门材料。

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

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

http://www.cnnetsun.cn/news/4104345.html

相关文章:

  • 提升 Web 应用性能:如何用 AmplifyJS 实现 AJAX 请求缓存
  • Scroll三层架构深度解析:结算层、排序层与证明层如何协同工作
  • 什么是 PP-OCRv5_server_det?一文读懂 PPHGNetV2 + LKPAN + PFHeadLocal 文本检测架构
  • AIPND项目结构深度解析:从线性代数到图像分类的10大学习模块
  • SceneJS新手避坑手册:10个最常见的WebGL开发错误与解决方案
  • 向量检索中上下文与工具的分工
  • Qwen3.8-27B-Ridge-GGUF API开发指南:如何用llama-server快速搭建OpenAI兼容服务?
  • Bluto 源码解析:DNS 侦察工具的模块化架构与核心实现原理
  • 同城招聘求职小程序系统开发方案
  • instagram-location-search × instagram-scraper联动实战:批量下载指定地点全部照片
  • 全向轮机器人运动学:雅可比矩阵如何连接轮速与世界速度?
  • Templater 插件入门指南:让 Obsidian 模板学会自动填表
  • 中文输出优化攻略:如何调教LFM2.5-1.2B-Instruct-6bit说出地道中文
  • NeoEloquent 软删除详解:如何安全地删除图数据库节点
  • 磁盘空间告急?免费开源工具 czkawka 帮你快速清理重复文件、相似图片与空文件夹
  • 图像格式转换如何一键搞定?oiiotool入门实操全指南
  • 告别丑终端与视觉疲劳:iTerm2配色方案完整指南,450+主题轻松打造专属工作台
  • Bluto性能调优:3个技巧缩短子域名爆破扫描时间
  • Teable日历视图:3个关键动作,把排期从电子表格搬进可拖拽的调度台
  • 计算机毕业设计之基于Python的宠物托管系统
  • 保姆级Kindle漫画转换指南:我用KCC把漫画装进墨水屏的完整旅程
  • 游戏串流入门到精通:用Sunshine自建串流服务器,低配设备也能玩3A大作
  • 奇点智能大会从个人提效到团队级 AI 原生研发流程:组织面对的 5 个具体挑战
  • 零基础ExplorerPatcher安装教程:让Windows 11找回Windows 10经典体验
  • Harper 语法检查工具完整指南:离线、开源、毫秒级反馈的英文写作助手
  • HomeAssistant 蓝牙室内定位终极指南:Bermuda 从零到一实现房间级追踪
  • 【单片机毕业设计】基于 DHT11 传感器的单片机温湿度智能预警系统设计 基于 STM32 或 51 单片机的温湿度参数可调报警装置与 APP 开发(024403)
  • 写作压力小了!2026年最值得拥有的专业降AI率软件
  • AI Agent 是怎么选中正确 Skill 的?一文拆解“意图理解→向量检索→LLM 决策”全流程
  • 3个技巧,用Loop径向菜单把Mac窗口管理效率翻倍