帖子
分享您的知识。
为All Things Web3Dec 23, 2023
讨论
如何将比特币从 1 个 Taproot 地址发送到另一个地址?
我创建了一个 taproot 比特币地址(bech32m),然后从 segwit 的非 taproot 地址(bech32)向 taproot 地址发送了 1 个 UTXO 到这个主根地址. 我将如何编写 c# 脚本来将这个 btc 发送到另一个 taproot 地址?我不需要任何太复杂的东西,只需要一个简单的脚本即可将这个 btc 从一个主根地址发送到另一个地址. 我认为 nBitcoin 将是最明智的套餐.
我在比特币的一次测试中发现了这个:
public async Task CanBuildTaprootSingleSigTransactions()
{
using (var nodeBuilder = NodeBuilderEx.Create())
{
var rpc = nodeBuilder.CreateNode().CreateRPCClient();
nodeBuilder.StartAll();
rpc.Generate(102);
var change = new Key();
var rootKey = new ExtKey();
var accountKeyPath = new KeyPath("86'/0'/0'");
var accountRootKeyPath = new RootedKeyPath(rootKey.GetPublicKey().GetHDFingerPrint(), accountKeyPath);
var accountKey = rootKey.Derive(accountKeyPath);
var key = accountKey.Derive(new KeyPath("0/0")).PrivateKey;
var address = key.PubKey.GetAddress(ScriptPubKeyType.TaprootBIP86, nodeBuilder.Network);
var destination = new Key();
var amount = new Money(1, MoneyUnit.BTC);
uint256 id = null;
Transaction tx = null;
ICoin coin = null;
TransactionBuilder builder = null;
var rate = new FeeRate(Money.Satoshis(1), 1);
async Task RefreshCoin()
{
id = await rpc.SendToAddressAsync(address, Money.Coins(1));
tx = await rpc.GetRawTransactionAsync(id);
coin = tx.Outputs.AsCoins().Where(o => o.ScriptPubKey == address.ScriptPubKey).Single();
builder = Network.Main.CreateTransactionBuilder(0);
}
await RefreshCoin();
var signedTx = builder
.AddCoins(coin)
.AddKeys(key)
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildTransaction(true);
rpc.SendRawTransaction(signedTx);
await RefreshCoin();
// Let's try again, but this time with PSBT
var psbt = builder
.AddCoins(coin)
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildPSBT(false);
var tk = key.PubKey.GetTaprootFullPubKey();
psbt.Inputs[0].HDTaprootKeyPaths.Add(tk.OutputKey, new TaprootKeyPath(accountRootKeyPath.Derive(KeyPath.Parse("0/0"))));
psbt.SignAll(ScriptPubKeyType.TaprootBIP86, accountKey, accountRootKeyPath);
// Check if we can roundtrip
psbt = CanRoundtripPSBT(psbt);
psbt.Finalize();
rpc.SendRawTransaction(psbt.ExtractTransaction());
// Let's try again, but this time with BuildPSBT(true)
await RefreshCoin();
psbt = builder
.AddCoins(coin)
.AddKeys(key)
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildPSBT(true);
psbt.Finalize();
rpc.SendRawTransaction(psbt.ExtractTransaction());
// Let's try again, this time with a merkle root
var merkleRoot = RandomUtils.GetUInt256();
address = key.PubKey.GetTaprootFullPubKey(merkleRoot).GetAddress(nodeBuilder.Network);
await RefreshCoin();
psbt = builder
.AddCoins(coin)
.AddKeys(key.CreateTaprootKeyPair(merkleRoot))
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildPSBT(true);
Assert.NotNull(psbt.Inputs[0].TaprootMerkleRoot);
Assert.NotNull(psbt.Inputs[0].TaprootInternalKey);
Assert.NotNull(psbt.Inputs[0].TaprootKeySignature);
psbt = CanRoundtripPSBT(psbt);
psbt.Finalize();
rpc.SendRawTransaction(psbt.ExtractTransaction());
// Can we sign the PSBT separately?
await RefreshCoin();
psbt = builder
.AddCoins(coin)
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildPSBT(false);
var taprootKeyPair = key.CreateTaprootKeyPair(merkleRoot);
psbt.Inputs[0].Sign(taprootKeyPair);
Assert.NotNull(psbt.Inputs[0].TaprootMerkleRoot);
Assert.NotNull(psbt.Inputs[0].TaprootInternalKey);
Assert.NotNull(psbt.Inputs[0].TaprootKeySignature);
// This line is useless, we just use it to test the PSBT roundtrip
psbt.Inputs[0].HDTaprootKeyPaths.Add(taprootKeyPair.PubKey,
new TaprootKeyPath(RootedKeyPath.Parse("12345678/86'/0'/0'/0/0"),
new uint256[] { RandomUtils.GetUInt256() }));
psbt = CanRoundtripPSBT(psbt);
psbt.Finalize();
rpc.SendRawTransaction(psbt.ExtractTransaction());
// Can we sign the transaction separately?
await RefreshCoin();
var coin1 = coin;
await RefreshCoin();
var coin2 = coin;
builder = Network.Main.CreateTransactionBuilder(0);
signedTx = builder
.AddCoins(coin1, coin2)
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildTransaction(false);
var unsignedTx = signedTx.Clone();
builder = Network.Main.CreateTransactionBuilder(0);
builder.AddKeys(key.CreateTaprootKeyPair(merkleRoot));
builder.AddCoins(coin1);
var ex = Assert.Throws<InvalidOperationException>(() => builder.SignTransactionInPlace(signedTx));
Assert.Contains("taproot", ex.Message);
builder.AddCoin(coin2);
builder.SignTransactionInPlace(signedTx);
Assert.True(!WitScript.IsNullOrEmpty(signedTx.Inputs.FindIndexedInput(coin2.Outpoint).WitScript));
// Another solution is to set the precomputed transaction data.
signedTx = unsignedTx;
builder = Network.Main.CreateTransactionBuilder(0);
builder.AddKeys(key.CreateTaprootKeyPair(merkleRoot));
builder.AddCoins(coin2);
builder.SetSigningOptions(new SigningOptions() { PrecomputedTransactionData = signedTx.PrecomputeTransactionData(new ICoin[] { coin1, coin2 }) });
builder.SignTransactionInPlace(signedTx);
Assert.True(!WitScript.IsNullOrEmpty(signedTx.Inputs.FindIndexedInput(coin2.Outpoint).WitScript));
// Let's check if we estimate precisely the size of a taproot transaction.
await RefreshCoin();
signedTx = builder
.AddCoins(coin)
.AddKeys(key.CreateTaprootKeyPair(merkleRoot))
.Send(destination, amount)
.SubtractFees()
.SetChange(change)
.SendEstimatedFees(rate)
.BuildTransaction(false);
var actualvsize = builder.EstimateSize(signedTx, true);
builder.SignTransactionInPlace(signedTx);
var expectedvsize = signedTx.GetVirtualSize();
// The estimator can't assume the sighash to be default
// for all inputs, so we likely overestimate 1 bytes per input
Assert.Equal(expectedvsize, actualvsize - 1);
}
}
但是我不知道如何用以下格式编写一个简单的C#控制台应用程序:
class Program
{
static async Task Main()
...
}
我有我用 1 个 UTXO 资助的 taproot 比特币地址(bech32m)的私钥以及私钥的完整助记词. 我将如何编写一个简单的 C# 控制台应用程序,将这个 UTXO 花在另一个主根地址上?
请麻省理工学院将你的解决方案许可给我.
- blockchain
- cryptocurrency
0
0
分享
评论
你知道答案吗?
请登录并分享。
Web3 (also known as Web 3.0) is an idea for a new iteration of the World Wide Web which incorporates concepts such as decentralization, blockchain technologies, and token-based economics.
142帖子198答案

奖励活动六月
- 0xduckmove... SUI+88
1
- harry phan... SUI+61
2
- MiniBob... SUI+57
3
- ... SUIHaGiang+56
- ... SUIRogue+47
- ... SUIRogueRig+44
- ... SUIPeera Admin+25
- ... SUIVens.sui+20
- ... SUIMarlKey+20
- ... SUIdudley_smith+16