Bài viết
Chia sẻ kiến thức của bạn.
Làm cách nào để gửi Bitcoin từ 1 địa chỉ Taproot sang Địa chỉ khác?
Tôi đã tạo một địa chỉ bitcoin taproot (bech32m) và gửi 1 UTXO từ địa chỉ segwit không phải taproot (bech32) đến địa chỉ taproot này. Làm thế nào tôi có thể viết một tập lệnh c # để gửi btc này đến một địa chỉ taproot khác? Tôi không cần bất cứ điều gì quá phức tạp, chỉ cần một tập lệnh đơn giản để gửi btc này từ địa chỉ taproot này sang địa chỉ khác. Tôi nghĩ nBitcoin sẽ là gói hợp lý nhất để sử dụng.
Tôi tìm thấy điều này trong một trong những bài kiểm tra 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);
}
}
Nhưng tôi không thể tìm ra cách viết một ứng dụng bảng điều khiển C # đơn giản ở định dạng:
class Program
{
static async Task Main()
...
}
Tôi có khóa riêng, cũng như cụm từ ghi nhớ đầy đủ cho khóa riêng, của địa chỉ bitcoin taproot (bech32m) mà tôi đã tài trợ bằng 1 UTXO. Làm cách nào để viết một ứng dụng bảng điều khiển C # đơn giản dành UTXO này đến một địa chỉ taproot khác?
Và xin vui lòng MIT cấp phép giải pháp của bạn cho tôi.
- blockchain
- cryptocurrency
Bạn có biết câu trả lời không?
Hãy đăng nhập và chia sẻ nó.
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.
Kiếm phần của bạn từ 1000 Sui
Tích lũy điểm danh tiếng và nhận phần thưởng khi giúp cộng đồng Sui phát triển.

- 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