dgarage / NBXplorer

NBitcoin Explorer
MIT License
322 stars 213 forks source link

How to spend only confirmed coins? #16

Closed bazooka70 closed 6 years ago

bazooka70 commented 6 years ago

From the docs: https://programmingblockchain.gitbooks.io/programmingblockchain/wallet/web-api.html

If you want to spend those UTXOs:

var coins = utxos.GetUnspentCoins();
var keys = utxos.GetKeys(userExtKey);
TransactionBuilder builder = new TransactionBuilder();
builder.AddCoins(coins);
builder.AddKeys(keys);
builder.Send(new Key(), Money.Coins(0.5m));
builder.SetChange(changeAddress.ScriptPubKey);

// Set the fee rate
var fallbackFeeRate = new FeeRate(Money.Satoshis(100), 1);
var feeRate = tester.Client.GetFeeRate(1, fallbackFeeRate).FeeRate;
builder.SendEstimatedFees(feeRate);
/////

var tx = builder.BuildTransaction(true);
Console.WriteLine(client.Broadcast(tx));

If I understand correctly this will spend unconfirmed coins also. how do I get only the confirmed coins (and the number of confirmations) from: var coins = utxos.GetUnspentCoins();

Also, how to get Balance of confirmed and unconfirmed coins, same as QBitNinjaClient.GetBalanceSummary?

NicolasDorier commented 6 years ago

I just pushed 1.0.1.11 to nuget, which add a parameter to GetUnspentCoins to specify if you want only what is confirmed or not. For the balance use coins.Select(c => c.Amount).Sum().

bazooka70 commented 6 years ago

@NicolasDorier Thanks! Do I also need to update/recompile the server? Also, shouldn't the onlyConfirmed parameter needs to be added to the var keys = utxos.GetKeys(extMasterKey); also?

BTW, for now I resolved this problem like this:

            var utxos = client.GetUTXOs(userDerivationScheme, null, false);
            var coins = utxos.GetUnspentCoins(); // include unConfirmed
            var balance = coins.Sum(x => x.Amount.ToDecimal(MoneyUnit.BTC));

            List<Coin> coinsConfirmed = new List<Coin>();
            Console.WriteLine("utxoConfirmed");
            var utxoConfirmed = utxos.Confirmed.UTXOs;            
            foreach (var utx in utxoConfirmed)
            {
                coinsConfirmed.Add(utx.AsCoin());
                Console.WriteLine($"utx.Value-> {utx.Value.ToUnit(MoneyUnit.BTC)} utx.Confirmations-> {utx.Confirmations}");                
            }
            var balanceConfirmed = coinsConfirmed.Sum(x => x.Amount.ToDecimal(MoneyUnit.BTC));
            Console.WriteLine($"balanceConfirmed-> {balanceConfirmed}");

            var balanceUnConfirmed = balance - balanceConfirmed;
            Console.WriteLine($"balanceUnConfirmed-> {balanceUnConfirmed}");
bazooka70 commented 6 years ago

for now I added an extension:

    // https://github.com/dgarage/NBXplorer/blob/master/NBXplorer.Client/Models/UTXOChanges.cs
    public static Key[] GetKeys(this UTXOChanges utxos, ExtKey extKey, bool onlyConfirmed)
    {
        return utxos.GetUnspentUTXOs(onlyConfirmed).Select(u => extKey.Derive(u.KeyPath).PrivateKey).ToArray();
    }

But I'm not sure it is correct to pass the GetUnspentCoins(true) and GetKeys(userExtKey, true) to the transaction builder. will it resolve the correct Keys for the TxIn e.g.?

var coins = utxos.GetUnspentCoins(true);
var keys = utxos.GetKeys(userExtKey, true);
TransactionBuilder builder = new TransactionBuilder();
builder.AddCoins(coins);
builder.AddKeys(keys);
NicolasDorier commented 6 years ago

Recompile the server yes, I added some info inside GetStatus as well.

Good point for GetKeys. Can you make a PR ?

Yes it will resolve things just fine.

bazooka70 commented 6 years ago

Just to be sure, If I useGetUnspentCoins(onlyConfirmed: true); I need to use my extension utxos.GetKeys(..., onlyConfirmed: true), or it does not matter?

Can you make a PR ?

If you mean a pull request, I'm not sure how to do it... I can give it a try :)

NicolasDorier commented 6 years ago

You need to use your extension.

NicolasDorier commented 6 years ago

One question though: with onlyConfirmed:true do you want to remove UTXOs which has been spent on an unconfirmed transaction?

NicolasDorier commented 6 years ago

I pushed GetKeys with onlyconfirmed (1.0.1.13).

If onlyConfirmed is true, just remember that anything unconfirmed is completely ignored.

bazooka70 commented 6 years ago

One question though: with onlyConfirmed:true do you want to remove UTXOs which has been spent on an unconfirmed transaction?

Good question. I do not allow to spend any unconfirmed transactions. not even for testing. so "anything unconfirmed is completely ignored" is good for me. :) thanks!

And again, do I need to clone and recompile the server for each modification in the client (for e,g, version 1.0.1.13)?

NicolasDorier commented 6 years ago

no, this change is client only.

bazooka70 commented 6 years ago

Thanks!

NicolasDorier commented 6 years ago

Can you closed the issues you opened that has been responded and which are still open?