예제 #1
0
        //public async Task<IEnumerable<ITxPoint>> GetInputsAsync(
        //    string txId,
        //    CancellationToken cancellationToken = default(CancellationToken))
        //{
        //    var result = new List<ITxPoint>();
        //    var tx = await _explorer
        //        .GetTransactionByHashAsync(txId)
        //        .ConfigureAwait(false);

        //    foreach (var i in tx.Inputs)
        //    {
        //        var witScript = WitScript.Empty;
        //        var prevTx = await _explorer
        //            .GetTransactionByIndexAsync(i.PreviousOutput.TxIndex)
        //            .ConfigureAwait(false);

        //        if (i.Witness != null)
        //        {
        //            var wit = new List<string> {i.Witness};
        //            witScript = wit.Aggregate(witScript, (current, witness) => current + new WitScript(witness));
        //        }
        //        result.Add(new BitcoinBasedTxPoint(new IndexedTxIn
        //        {
        //            TxIn = new TxIn(new OutPoint(new uint256(prevTx.Hash), i.PreviousOutput.N), new Script()),
        //            Index = (uint)i.PreviousOutput.SpendingOutpoints[0].N,
        //            WitScript = witScript,
        //        }));
        //    }

        //    return result;
        //}

        public async Task <IEnumerable <ITxOutput> > GetUnspentOutputsAsync(
            string address,
            string afterTxId = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var unspentOutputs = await _explorer
                                 .GetUnspentOutputsAsync(new List <string>() { address })
                                 .ConfigureAwait(false);

            return(unspentOutputs.Select(u => new BitcoinBasedTxOutput(
                                             coin: new Coin(
                                                 fromTxHash: new uint256(u.TransactionHash),
                                                 fromOutputIndex: (uint)u.N,
                                                 amount: new Money(u.Value.Satoshis, MoneyUnit.Satoshi),
                                                 scriptPubKey: new Script(u.Script)),
                                             spentTxPoint: null)));
        }
예제 #2
0
        public static void Serialize(walletManagement wallet, int minUnusedKeys = 4)
        {
            if (MainWindow.CheckForInternetConnection())
            {
                var walletData = JsonConvert.DeserializeObject <Data>(
                    File.ReadAllText(walletFileSerializer.Deserialize(wallet.WalletFilePath).walletTransactionsPath));

                var addresses = walletData.addresses.change.ToList();
                addresses.AddRange(walletData.addresses.receiving);

                explorer = new BlockExplorer();

                var addressesData = explorer.GetMultiAddressAsync(addresses).Result;

                foreach (var tx in addressesData.Transactions)
                {
                    if (walletData.txData.Keys.Contains(tx.Hash))
                    {
                        continue;
                    }

                    var InputsPerAddress  = new List <Inputs>();
                    var OutputsPerAddress = new List <Outputs>();

                    tx.Inputs.ToList().ForEach(inp =>
                    {
                        InputsPerAddress.Add(new Inputs
                        {
                            address = inp.PreviousOutput.Address,
                            index   = inp.PreviousOutput.N,
                            value   = inp.PreviousOutput.Value.GetBtc()
                        });
                        if (walletData.addresses.receiving.Contains(inp.PreviousOutput.Address))
                        {
                            walletData.usedAddresses.Add(inp.PreviousOutput.Address);
                        }
                        if (walletData.addresses.change.Contains(inp.PreviousOutput.Address))
                        {
                            walletData.usedAddresses.Add(inp.PreviousOutput.Address);
                        }
                    });
                    tx.Outputs.ToList().ForEach(outp =>
                    {
                        OutputsPerAddress.Add(new Outputs
                        {
                            address = outp.Address,
                            index   = outp.N,
                            value   = outp.Value.GetBtc()
                        });
                        if (walletData.addresses.receiving.Contains(outp.Address))
                        {
                            walletData.usedAddresses.Add(outp.Address);
                        }
                        if (walletData.addresses.change.Contains(outp.Address))
                        {
                            walletData.usedAddresses.Add(outp.Address);
                        }
                    });
                    walletData.txData.Add(tx.Hash,
                                          new TxData
                    {
                        hash     = tx.Hash,
                        date     = tx.Time,
                        lockTime = tx.BlockHeight,
                        size     = tx.Size,
                        fee      = NB.Money.Satoshis(tx.Fee).ToDecimal(NB.MoneyUnit.BTC),
                        value    = NB.Money.Satoshis(tx.Result).ToDecimal(NB.MoneyUnit.BTC),
                        inputs   = InputsPerAddress,
                        outputs  = OutputsPerAddress
                    });
                }

                var unusedreceivingKeysCount = walletData.addresses.receiving.Count;
                walletData.addresses.receiving.ForEach(key =>
                {
                    if (walletData.usedAddresses.Contains(key))
                    {
                        unusedreceivingKeysCount--;
                    }
                });
                if (unusedreceivingKeysCount < minUnusedKeys)
                {
                    var receivingKeysStartIndex = walletData.addresses.receiving.Count;
                    for (var i = 0; i < minUnusedKeys; i++)
                    {
                        walletData.addresses.receiving.Add(wallet
                                                           .GetAddress(receivingKeysStartIndex++, HdPathType.Receive).ToString());
                    }
                }

                var unusedchangeKeysCount = walletData.addresses.change.Count;
                walletData.addresses.change.ForEach(key =>
                {
                    if (walletData.usedAddresses.Contains(key))
                    {
                        unusedreceivingKeysCount--;
                    }
                });
                if (unusedchangeKeysCount < minUnusedKeys)
                {
                    var changeKeysStartIndex = walletData.addresses.change.Count;
                    for (var i = 0; i < minUnusedKeys; i++)
                    {
                        walletData.addresses.receiving.Add(wallet.GetAddress(changeKeysStartIndex++, HdPathType.Change)
                                                           .ToString());
                    }
                }

                walletData.unspent_Outputs = new List <Unspent_Outputs>();

                var unspentChange = explorer.GetUnspentOutputsAsync(walletData.addresses.change).Result;

                foreach (var outp in unspentChange)
                {
                    var existsOuts = walletData.unspent_Outputs.FirstOrDefault(x =>
                                                                               x.hash == outp.tx_hash_big_endian && x.confirmations == outp.Confirmations &&
                                                                               x.index == outp.N);
                    if (existsOuts == null)
                    {
                        var tx = walletData.txData.FirstOrDefault(x => x.Key == outp.tx_hash_big_endian);
                        tx.Value.outputs.ForEach(output =>
                        {
                            if (output.index == outp.N)
                            {
                                walletData.unspent_Outputs.Add(new Unspent_Outputs
                                {
                                    hash          = outp.tx_hash_big_endian,
                                    address       = output.address,
                                    confirmations = outp.Confirmations,
                                    index         = outp.N,
                                    value         = outp.Value.GetBtc()
                                });
                            }
                        });
                    }
                }

                var unspentReceiving = explorer.GetUnspentOutputsAsync(walletData.addresses.receiving).Result;

                foreach (var outp in unspentReceiving)
                {
                    var existsOuts = walletData.unspent_Outputs.FirstOrDefault(x =>
                                                                               x.hash == outp.tx_hash_big_endian && x.confirmations == outp.Confirmations &&
                                                                               x.index == outp.N);
                    if (existsOuts == null)
                    {
                        var tx = walletData.txData.FirstOrDefault(x => x.Key == outp.tx_hash_big_endian);
                        tx.Value.outputs.ForEach(output =>
                        {
                            if (output.index == outp.N)
                            {
                                walletData.unspent_Outputs.Add(new Unspent_Outputs
                                {
                                    hash          = outp.tx_hash_big_endian,
                                    address       = output.address,
                                    confirmations = outp.Confirmations,
                                    index         = outp.N,
                                    value         = outp.Value.GetBtc()
                                });
                            }
                        });
                    }
                }

                foreach (var tx in walletData.txData.Values)
                {
                    if (tx.value > 0)
                    {
                        foreach (var outp in tx.outputs)
                        {
                            if (walletData.usedAddresses.Contains(outp.address))
                            {
                                tx.address = outp.address;
                                break;
                            }
                        }
                    }
                    else
                    {
                        foreach (var inp in tx.inputs)
                        {
                            if (walletData.usedAddresses.Contains(inp.address))
                            {
                                tx.address = inp.address;
                                break;
                            }
                        }
                    }
                }

                File.WriteAllText(walletFileSerializer.Deserialize(wallet.WalletFilePath).walletTransactionsPath,
                                  JsonConvert.SerializeObject(walletData));
            }
        }