MetacoSA / QBitNinja

An Open Source and powerful blockchain API
MIT License
68 stars 42 forks source link

Get incomes & spendings from a transaction #62

Closed ArtjomP closed 6 years ago

ArtjomP commented 6 years ago

Hello! I have a transaction & I know my wallet public address:

...
var bitcoinAccountAddress = BitcoinAddress.Create(accountAddress, network);
var client = new QBitNinjaClient(network);
var clientTransaction = await client.GetTransaction(transactionId);

I tried something like this to get spent money:

 var spentCoinsAddresses = clientTransaction.SpentCoins.
                Select(o => o.TxOut.ScriptPubKey.GetDestinationAddress(network)).
                Where(o => o == bitcoinAccountAddress);
var spentCoinsSum = clientTransaction.ReceivedCoins.Where(
                 o =>
                 {
                     var txOutAddress = o.TxOut.ScriptPubKey.GetDestinationAddress(network);
                     return !spentCoinsAddresses.Contains(txOutAddress) && txOutAddress != bitcoinAccountAddress;
                 }).
                Sum(o => (o.Amount as Money).ToDecimal(MoneyUnit.BTC));

I don't like it.

May be there is a way to do it with QBitNinja?

Is there a way to get what I spent from my wallet or what I got to my wallet?

Thx!

NicolasDorier commented 6 years ago

there is the summary like https://api.qbit.ninja/balances/15sYbVpRh6dyWycZMwPdxJWD4xbfxReeHe/summary is this what you need?

ArtjomP commented 6 years ago

It seems this is summary for a wallet (public key). I need summary for a transaction https://live.blockcypher.com/btc-testnet/tx/142821551159e9de77627b875c10068de904131fef4585eea72b850489c0a62c/

I want to estimate value sent or incame.

ArtjomP commented 6 years ago

Something like the BalanceOperation from NBitCoin

NicolasDorier commented 6 years ago

@ArtjomP you mean a line like http://api.qbit.ninja/balances/akEBcY5k1dn2yeEdFnTMwdhVbHxtgHb6GGi but that you can fetch with txid & address?

ArtjomP commented 6 years ago

I wrote such code to do the task. May be someone will need it.

var accountAddress = await GeneratePublicAddressAsync();
var bitcoinAccountAddress = BitcoinAddress.Create(accountAddress, network);

var receivedCoinsSum = clientTransaction.ReceivedCoins.Sum(
                o => (o.Amount as Money).ToDecimal(MoneyUnit.BTC));
var spentCoinsAddresses = clientTransaction.SpentCoins.
                Select(o => o.TxOut.ScriptPubKey.GetDestinationAddress(network)).
                Where(o => o == bitcoinAccountAddress);
Decimal spentCoinsSum = 0m;
if (spentCoinsAddresses.Any())
{
     spentCoinsSum = clientTransaction.ReceivedCoins.Where(
                    o =>
                    {
                        var txOutAddress = o.TxOut.ScriptPubKey.GetDestinationAddress(network);
                        return !spentCoinsAddresses.Contains(txOutAddress) && txOutAddress != bitcoinAccountAddress;
                    }).
                   Sum(o => (o.Amount as Money).ToDecimal(MoneyUnit.BTC));
                spentCoinsSum += clientTransaction.Fees.ToDecimal(MoneyUnit.BTC);
}
spentCoinsAddresses = clientTransaction.SpentCoins.
               Select(o => o.TxOut.ScriptPubKey.GetDestinationAddress(network));
            var incomeMoney = clientTransaction.ReceivedCoins.Where(
                o =>
                {
                    var txOutAddress = o.TxOut.ScriptPubKey.GetDestinationAddress(network);
                    return !spentCoinsAddresses.Contains(txOutAddress) && txOutAddress == bitcoinAccountAddress;
                }
                ).
                Sum(o => (o.Amount as Money).ToDecimal(MoneyUnit.BTC));
var totalMoney = incomeMoney - spentCoinsSum;