区块链

BSV 交易入门:手动指定输入(Inputs)的正确姿势

在 BSV 的 UTXO 模型中,手动指定交易输入是进阶开发的必备技能。本文深入解析输入的本质、所需信息、代码示例和常见误区,帮你避开“地址扣款”的思维陷阱。

林知衡

林知衡

technical_editor

发布于 2026年6月18日3 分钟阅读

一句话理解

手动指定输入,就是明确告诉交易:“我要花掉哪一笔历史交易里的哪一个输出(output)。”

在钱包自动选择输入的阶段之后,你终将面对手动构造交易的需求。此时,一笔新交易的输入不是随便填入一个地址,而是引用一个已经存在、尚未花费的 UTXO。

BSV 交易入门:手动指定输入(Inputs)的正确姿势 文章封面

输入引用的不是地址

新手最容易犯的错误,是以为输入写的是“从哪个地址扣钱”。在比特币的 UTXO 模型里,没有账户余额扣减这一层。

输入引用的是一个 outpoint,它由两部分组成:

  • 上一笔交易的 txid
  • 那笔交易里的 output index

例如:

TEXT
1txid: 9f...ab
2output index: 0

这样表达的意思是:我要花掉交易 9f...ab 里的第 0 个输出。

地址只是在很多普通支付场景中帮助钱包生成锁定脚本(locking script)。真正被花掉的是一笔输出,而不是某个地址账户。

手动输入需要哪些信息

要手动构造一个输入,通常至少需要以下内容:

  1. 上一笔交易本身
    你需要知道被花费的 UTXO 来自哪笔交易。在低层 SDK 示例中,常见做法是提供 sourceTransaction,也就是上一笔交易的完整原始数据。

  2. 输出索引(output index)
    一笔交易可以有多个输出,只知道 txid 不够,必须指明你要花费哪一个输出。

  3. 上一笔输出的锁定脚本(locking script)
    签名和验证时需要知道它原本锁定的条件。P2PKH 输出和 OP_RETURN 输出的性质完全不同。

  4. 上一笔输出的金额
    手续费计算和签名验证都可能需要金额信息。

  5. 解锁方式
    对 P2PKH 来说,解锁通常需要签名和公钥。SDK 可以通过 new P2PKH().unlock(privateKey) 创建解锁模板。

用 SDK 表达输入

官方低层交易示例中,手动输入的构造方式类似这样:

TypeScript
1import { Transaction, PrivateKey, P2PKH } from '@bsv/sdk'
2
3const privateKey = PrivateKey.fromWif('your_private_key_here')
4const sourceTxHex = '...' // 包含可花费 output 的上一笔交易 hex
5
6const tx = new Transaction()
7
8tx.addInput({
9 sourceTransaction: Transaction.fromHex(sourceTxHex),
10 sourceOutputIndex: 0,
11 unlockingScriptTemplate: new P2PKH().unlock(privateKey)
12})

这段代码表达的是:

  • 我要花掉 sourceTransaction 里的第 0 个输出。
  • 如果它是 P2PKH 输出,就用 privateKey 生成对应的解锁脚本。

注意,这只是输入部分。交易还不能完成,因为它还没有输出、费用、签名和广播。

为什么需要上一笔交易

签名不是只对“当前交易”随便签一个名字。签名要证明:你有权花费被引用的上一笔输出,并且你认可当前交易的输出安排。

验证者需要知道上一笔输出的锁定脚本,才能把当前输入提供的解锁脚本(unlocking script)与它组合执行。

简化流程:

TEXT
1当前输入提供 unlocking script
2上一笔输出提供 locking script
3两者组合执行
4结果为真 -> 这个输入的解锁条件满足

如果你只提供 txid,但没有上一笔输出的脚本和金额,很多低层操作无法正确完成。

输入数量会影响交易大小

一个输入通常包含:

  • 上一笔交易哈希
  • 输出索引
  • 解锁脚本
  • sequence

输入越多,交易越大,手续费通常也越高。

这也是为什么钱包自动选输入不是简单凑够金额。它还要考虑交易大小、找零、费用、隐私和 UTXO 管理。

不能重复花同一个 UTXO

一个 UTXO 一旦被某笔有效交易花费,就不能再被另一笔交易花费。

如果两笔交易都引用同一个 UTXO,它们互相冲突,网络和矿工最终只能接受其中一笔。这个问题就是双花风险的基础。

所以手动指定输入时,必须确认这个 UTXO 确实未花费。如果你使用过期的 UTXO 列表,很容易构造出无效交易。

在 BSV 技术栈里的位置

BSV 上的应用协议经常把业务状态绑定到特定 UTXO。

例如,一个代币(token)状态可能由某个输出表示。转移代币时,不是随便找一个同金额 UTXO,而是必须花掉代表这个代币的具体 UTXO。

再例如,一个合约式状态机可能要求你花掉上一状态输出,再创建下一状态输出。

这就是为什么高级 BSV 应用不能永远依赖钱包默认选择输入。默认选择适合普通付款,但应用协议经常需要精确选择。

新手常见误解

  • 只有 txid 不够:还要知道输出索引。
  • 输入不是地址:输入引用的是上一笔交易的某个输出。
  • UTXO 已花费后不能再用:重复使用会造成冲突交易。
  • 手动指定输入带来责任:你要保证金额、脚本、解锁方式和状态都正确。
  • OP_RETURN 数据输出通常不可花费:不能把所有输出都当作可用输入。

参考来源

推荐文章