//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))); }
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)); } }