1 个不稳定版本
0.1.0 | 2023年5月9日 |
---|
在 #descriptor 中排名 #46
48KB
1K SLoC
Tappy
不要在主网络上使用真实货币!只适用于regtest或testnet网络!
命令行上的开发者友好Taproot-only描述符钱包,与Bitcoin Core协同工作。
创建自定义密钥或脚本花费。使用手工交易调试和测试应用程序。了解Taproot、描述符、Miniscript、时间锁和其他交易内部结构。
命令
- init
- 创建空状态
- print
- 打印当前状态
- key
- Schnorr密钥对
- img
- SHA-256 (预)图像对
- addr
- 创建UTXOs的临时接收地址
- utxo
- 未花费交易输出 (UTXO)
- in
- 交易输入
- out
- 交易输出
- locktime
- 更新锁定时间
- fee
- 更新交易费用
- spend
- 创建交易见证并打印原始交易十六进制以通过Bitcoin Core发送
- final
- 最终化交易并将交易输出保存为UTXOs
构建
cargo build
Bitcoin Core配置
- 安装Bitcoin Core(已测试版本24.0.1)
- 在regtest或testnet上运行bitcoind
- 确保您有一个有资金的钱包
状态
tappy通过当前目录中的文件 state.json
跟踪其状态。秘密存储在硬盘上!按如下方式生成初始状态:
$ tappy init
您可以按如下方式查看当前状态:
$ tappy print
密钥存储
tappy保存了一组Schnorr密钥对。通过调用 tappy key gen
后跟密钥数量来生成新密钥。
$ tappy key gen 5
默认情况下,密钥禁用花费。通过调用 tappy key en
后跟xpub来启用密钥对。
$ tappy key en 1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f
通过 tappy key dis
加上xpub来禁用。
$ tappy key dis 1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f
图像存储
tappy还保存了一组SHA-256(预)图像对。通过调用 tappy img gen
后跟对数来生成一对。
$ tappy img gen 5
通过调用 tappy img en
后跟图像来启用(预)图像对进行花费。
$ tappy img en d166f218267103b44f1102a3ef05e87a9911b9f7cc7f0887f91e198e6a7d3fc4
通过 tappy img dis
加上图像来禁用。
$ tappy img dis d166f218267103b44f1102a3ef05e87a9911b9f7cc7f0887f91e198e6a7d3fc4
创建交易
在tappy中,您可以从utxos(未花费的交易输出)、输入和输出创建比特币交易。这表示在当前状态中。输入和输出由Taproot描述符指定,这些描述符使用来自密钥/图像存储或它们的组合的密钥/图像(与、或、阈、多、...)。
UTXO集合
tappy维护一组可以花费的UTXOs(未花费的交易输出)。交易输入引用它们想要花费的一些独特的UTXO。
手动UTXO
tappy最初没有任何UTXOs,因此我们必须手动添加它们。硬币必须进入系统。我们设置一个临时接收地址来创建具有我们选择的锁定脚本的UTXO。使用tappy addr set
后跟一个描述符。使用策略到Miniscript编译器生成有效的Miniscript。
$ tappy addr set "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f)"
: Fund this address: bcrt1pwkjuv2laefk6wqnhmqqurxnuhsc8jmmyn4xa48l4v26z3q4z6gjs5wymts
使用bitcoin-cli为此地址提供资金。在这个例子中,我们发送1 BTC = 100000000 sat。RPC返回交易ID。
$ bitcoin-cli sendtoaddress bcrt1pwkjuv2laefk6wqnhmqqurxnuhsc8jmmyn4xa48l4v26z3q4z6gjs5wymts 1
: 3e59661081cbdbfa69e68a9e679a88f3d9070e209aeb11ff424ea06c806a1e7a
使用bitcoin-cli获取完整交易十六进制。
$ bitcoin-cli getrawtransaction 3e59661081cbdbfa69e68a9e679a88f3d9070e209aeb11ff424ea06c806a1e7a
: <TX_HEX>
为人类可读格式添加1
。
$ bitcoin-cli getrawtransaction 3e59661081cbdbfa69e68a9e679a88f3d9070e209aeb11ff424ea06c806a1e7a 1
我们建议使用hal进行更好的格式化。在众多其他功能中,hal显示以satoshi为单位的值,这是tappy utxos所需格式。
$ hal tx decode <TX_HEX>
根据这些信息,通过调用tappy addr utxo
后跟交易ID、输出索引(vout)和satoshi中的值将接收地址转换为UTXO。
$ tappy addr utxo 3e59661081cbdbfa69e68a9e679a88f3d9070e209aeb11ff424ea06c806a1e7a 0 100000000
自动UTXO
哇,手动输入所有这些内容真是太辛苦了。幸运的是,tappy可以几乎自动添加您交易产生的UTXOs。有关更多信息,请参阅下面的最终化。
交易输入
通过调用tappy in
后跟输入索引、new
和utxo索引来添加新的交易输入。
$ tappy in 0 new 0
调用tappy utxo list
来列出所有带有其索引的UTXOs。
$ tappy utxo list
交易输出
通过调用tappy out
后跟输出索引、描述符和satoshi中的值来添加新的交易输出。
$ tappy out 0 "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f)" 99999000
省略值以表示所有输入资金减去其他输出和费用都应该转到此输出。这对于最多一个输出有效。
$ tappy out 0 "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f)"
费用
将费用设置为似乎合理的值。它不应该为零。在花费过程中将显示费率,因此如果Bitcoin Core拒绝您的交易,您可以增加费用。调用tappy fee
后跟satoshi中的值。
$ tappy fee 1000
锁定时间
具有绝对时间锁(after(n)
)的交易输入强制执行至少为n
的交易锁定时间。如果其包含的块的高度严格大于其锁定时间,则交易是有效的。
通过调用tappy locktime
后跟块高度来设置锁定时间。不支持Unix时间锁定时间。
$ tappy locktime 785572
如果所有输入都具有默认序列,则锁定时间将禁用。时间锁操作码将失败,锁定时间将被忽略。将任何输入的序列更改为相对锁定时间(可能为零)以启用锁定时间。不支持其他启用锁定时间的方法。
$ tappy in 0 seq enable 0
序列
虽然锁时(locktime)适用于整个交易,但序列号(sequence)只适用于单个输入。带有相对时间锁(older(n)
)的交易输入强制要求该输入的序列号至少为 n
的相对时间锁。如果包含该交易的区块的高度严格大于utxo区块的高度加上 n
,则该交易有效。
通过调用 tappy in
后跟输入索引、seq enable
和相对区块高度来为输入设置相对时间锁。不支持以Unix时间表示的相对时间锁。
$ tappy in 0 seq enable 10
通过调用 tappy in
后跟输入索引和 seq disable
来禁用输入的相对时间锁。
$ tappy in 0 seq disable
支出
设置完成后,通过调用 tappy spend
尝试创建支出交易。请记住启用所需的密钥/图像,并注意输入的时间锁。启用的密钥/图像会影响可能的支出路径。tappy将返回一个交易十六进制数。
$ tappy spend
: <TX_HEX>
使用bitcoin-cli广播此交易。如果成功,您将收到一个交易ID。
$ bitcoin-cli sendrawtransaction <TX_HEX>
: <TXID>
最终化
请确保通过广播支出交易来保存您刚刚创建的UTXOs。通过调用 tappy final
后跟交易ID来执行此操作。
$ tappy final 3e59661081cbdbfa69e68a9e679a88f3d9070e209aeb11ff424ea06c806a1e7a
所有交易输出都将自动转换并添加到UTXO集中。当前交易被清除,并为下一次支出创建一个新的交易。默认情况下,旧交易的第一输出成为新交易的第一输入。
密钥支出
$ tappy in 0 new 0
$ tappy out 0 new "tr(9fb5213dd37f61c98629500a436ae8f390b03d37d3609af2f01d515d4e899800)"
$ tappy fee 1000
$ tappy spend
$ tappy final f4a5f64b1552803ee93db9f35d2faa67be82bd1d508c1e16045112aa6f77d468
多重签名
$ tappy in 0 new 0
$ tappy out 0 new "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f,multi_a(2,816945ddf16d3a568644d5fe174dca7d68ed2931d3ee4edefbd96d09ae30ec2e,75910f6c72d67cd2530d17ecba4bce9058d003564887925d46201e18513d804a,9fb5213dd37f61c98629500a436ae8f390b03d37d3609af2f01d515d4e899800))"
$ tappy fee 1000
$ tappy spend
$ tappy final f4a5f64b1552803ee93db9f35d2faa67be82bd1d508c1e16045112aa6f77d468
绝对时间锁
$ tappy in 0 new 0
$ tappy out 0 new "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f,and_v(v:pk(+++816945ddf16d3a568644d5fe174dca7d68ed2931d3ee4edefbd96d09ae30ec2e),after(10)))"
$ tappy fee 1000
$ tappy spend
$ tappy final f4a5f64b1552803ee93db9f35d2faa67be82bd1d508c1e16045112aa6f77d468
相对时间锁
$ tappy in 0 new 0
$ tappy out 0 new "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f,and_v(v:pk(+++816945ddf16d3a568644d5fe174dca7d68ed2931d3ee4edefbd96d09ae30ec2e),older(10)))"
$ tappy fee 1000
$ tappy spend
$ tappy final f4a5f64b1552803ee93db9f35d2faa67be82bd1d508c1e16045112aa6f77d468
多个输入,多个输出
$ tappy in 0 new 0
$ tappy in 1 new 1
$ tappy out 0 new "tr(1ffa25da651d709df36d7563fffb5416a54ff2a9702ac66d8fde4c9d029d4c2f)" 50000000
$ tappy out 1 new "tr(9fb5213dd37f61c98629500a436ae8f390b03d37d3609af2f01d515d4e899800)"
$ tappy fee 1000
$ tappy spend
$ tappy final f4a5f64b1552803ee93db9f35d2faa67be82bd1d508c1e16045112aa6f77d468
依赖项
~15MB
~192K SLoC