返回介绍

5.使用 TransactionBuilder

发布于 2024-12-29 22:37:18 字数 4268 浏览 0 评论 0 收藏 0

当你对第一个 P2SH 和多重签名交易签名的时候,你就知道 TransactionBuillder 是如何工作的了。

我们将看到利用它的强大力量,可以对更加复杂的交易签名。 通过 TransactionBuillder 你可以:

  • 支付任意的 P2PK, P2PKH, Multi Sig
  • 在前面的 redeem script 中支付任意的 P2SH
  • 支付 Stealth (黑暗钱包)
  • 发行和传送颜色币(开放式资产,在下面的章节中有介绍)
  • 联合部分签名的交易
  • 评估未签名交易的最终大小和费用
  • 验证一个交易是否被完全签名了

TransactionBuilder 的目标就是把 Coin 和 Keys 作为输入,返回一个经过签名的,或者部分签名的交易。

TransactionBuilder 将会弄明白应该使用什么币,签什么名。

成器的使用包括 4 个步骤:

  • 收集用于支付的货币
  • 收集你拥有的秘钥
  • 列出你需要向什么 scriptPubKey 发送多少钱
  • 创建并对交易签名
  • 可选:你把交易交给其他人,然后他签名或者继续创建它。

我们先收集一些比特币吧,然后就可以在这些比特币上创建一个虚假的交易。

假设这个交易拥有一个 P2PKH, P2PK 和关于 Bob 和 Alice 多重签名的币。

var bob = new Key();
var alice = new Key();
var bobAlice = PayToMultiSigTemplate
    .Instance
    .GenerateScriptPubKey(2, bob.PubKey, alice.PubKey);

Transaction init = new Transaction();
init.Outputs.Add(new TxOut(Money.Coins(1.0m), alice.PubKey));
init.Outputs.Add(new TxOut(Money.Coins(1.0m), bob.PubKey.Hash));
init.Outputs.Add(new TxOut(Money.Coins(1.0m), bobAlice));

现在假设他们想要将这个交易中的比特币支付给中本聪,他们首先得获得这些比特币。

var satoshi = new Key();
Coin[] coins = init.Outputs.AsCoins().ToArray();

现在假设 bob 想要支付 0.2BTC,Alice 想要支付 0.3BTC,他们一致同意以 bobAlice 名义支付 0.5BTC 。

var builder = new TransactionBuilder();
Transaction tx = builder
    .AddCoins(bobCoin)
    .AddKeys(bob)
    .Send(satoshi, Money.Coins(0.2m))
    .SetChange(bob)
    .Then()
    .AddCoins(aliceCoin)
    .AddKeys(alice)
    .Send(satoshi, Money.Coins(0.3m))
    .SetChange(alice)
    .Then()
    .AddCoins(bobAliceCoin)
    .AddKeys(bob, alice)
    .Send(satoshi, Money.Coins(0.5m))
    .SetChange(bobAlice)
    .SendFees(Money.Coins(0.0001m))
    .BuildTransaction(sign: true);

你可以验证一下,它已经被完整签名了,并且已经准备好被发送到网络上了。

Console.WriteLine(builder.Verify(tx));

这个模型比较好的地方是它对 P2SH 的工作方法是一样的,除了你需要创建 ScriptCoin。

nit = new Transaction();
init.Outputs.Add(new TxOut(Money.Coins(1.0m), bobAlice.Hash));

coins = init.Outputs.AsCoins().ToArray();
ScriptCoin bobAliceScriptCoin = coins[0].ToScriptCoin(bobAlice);

然后是签名:

builder = new TransactionBuilder();
tx = builder
    .AddCoins(bobAliceScriptCoin)
    .AddKeys(bob, alice)
    .Send(satoshi, Money.Coins(1.0m))
    .SetChange(bobAlice.Hash)
    .BuildTransaction(true);
Console.WriteLine(builder.Verify(tx));

对 Stealth Coin 来说,这基本上是一样的。除了一件事情,如果你记得关于黑暗钱包的介绍的话,我说你需要一个 ScanKey 用以观察 StealthCoin。

我们就像签名章节一样创建 darkAliceBob 的秘密地址:

Key scanKey = new Key();
BitcoinStealthAddress darkAliceBob =
new BitcoinStealthAddress
(
    scanKey: scanKey.PubKey,
    pubKeys: new[] { alice.PubKey, bob.PubKey },
    signatureCount: 2,
    bitfield: null,
    network: Network.Main
    );

假设某人发送了这个交易:

/Someone sent to darkAliceBob
init = new Transaction();
darkAliceBob
.SendTo(init, Money.Coins(1.0m));

scanner 将发现 StealthCoin:

//Get the stealth coin with the scanKey
StealthCoin stealthCoin
= StealthCoin.Find(init, darkAliceBob, scanKey);

然后发送给 bob 和 alice,让他们签名 :

//Spend it
tx = builder
    .AddCoins(stealthCoin)
    .AddKeys(bob, alice, scanKey)
    .Send(satoshi, Money.Coins(1.0m))
    .SetChange(bobAlice.Hash)
    .BuildTransaction(true);
Console.WriteLine(builder.Verify(tx));

提示:你需要 scanKey 用以支付一个 StealthCoin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文