public async Task <BalanceModel> GetAddressBalance(string walletAddress) { var client = _clientFactory(); client.Colored = true; if (_settings.Bcc.UseBccNinja) { return(await client.GetBalance(BitcoinAddress.Create(walletAddress, _connectionParams.Network), true)); } return(await client.GetBalanceBetween(new BalanceSelector(BitcoinAddress.Create(walletAddress, _connectionParams.Network)), from : BlockFeature.Parse(Constants.BccBlock.ToString()), unspentOnly : true)); }
public Task <GetBlockResponse> GetBlock(BlockFeature blockFeature, bool headerOnly = false) { return(Get <GetBlockResponse>("blocks/" + EscapeUrlPart(blockFeature.ToString()) + "?headerOnly=" + headerOnly)); }
private ConfirmedBalanceLocator ToBalanceLocator(BlockFeature feature) { return(ToBalanceLocator(AtBlock(feature))); }
BalanceModel Balance(BalanceId balanceId, BalanceLocator continuation, BlockFeature until, BlockFeature from, bool includeImmature, bool unspentOnly, bool colored) { CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(30000); BalanceQuery query = new BalanceQuery(); query.RawOrdering = true; query.From = null; if (from != null) { query.From = ToBalanceLocator(from); query.FromIncluded = true; } if (continuation != null) { query = new BalanceQuery { From = continuation, FromIncluded = false }; query.RawOrdering = true; } if (query.From == null) { query.From = new UnconfirmedBalanceLocator(DateTimeOffset.UtcNow - Expiration); } if (until != null) { query.To = ToBalanceLocator(until); query.FromIncluded = true; } if (query.To.IsGreaterThan(query.From)) { throw InvalidParameters("Invalid argument : from < until"); } var client = Configuration.Indexer.CreateIndexerClient(); client.ColoredBalance = colored; var balance = client .GetOrderedBalance(balanceId, query) .TakeWhile(_ => !cancel.IsCancellationRequested) .WhereNotExpired(Expiration) .Where(o => includeImmature || IsMature(o, Chain.Tip)) .AsBalanceSheet(Chain); var balanceChanges = balance.All; if (until != null && balance.Confirmed.Count != 0) //Strip unconfirmed that can appear after the last until { List <OrderedBalanceChange> oldUnconfirmed = new List <OrderedBalanceChange>(); var older = balanceChanges.Last(); for (int i = 0; i < balanceChanges.Count; i++) { var last = balanceChanges[i]; if (last.BlockId == null) { if (last.SeenUtc < older.SeenUtc) { oldUnconfirmed.Add(last); } } else { break; } } foreach (var unconf in oldUnconfirmed) { balanceChanges.Remove(unconf); } } var conflicts = RemoveConflicts(balance); if (unspentOnly) { HashSet <OutPoint> spents = new HashSet <OutPoint>(); foreach (var change in balanceChanges.SelectMany(b => b.SpentCoins)) { spents.Add(change.Outpoint); } foreach (var change in balanceChanges) { change.SpentCoins.Clear(); change.ReceivedCoins.RemoveAll(c => spents.Contains(c.Outpoint)); } } var result = new BalanceModel(balanceChanges, Chain); result.ConflictedOperations = result.GetBalanceOperations(conflicts, Chain); if (cancel.IsCancellationRequested) { if (balanceChanges.Count > 0) { var lastop = balanceChanges[balanceChanges.Count - 1]; result.Continuation = lastop.CreateBalanceLocator(); } } return(result); }
public BalanceSummary BalanceSummary( BalanceId balanceId, BlockFeature at, bool debug, bool colored ) { var repo = Configuration.CreateWalletRepository(); CancellationTokenSource cancel = new CancellationTokenSource(); cancel.CancelAfter(30000); var checkpoint = Configuration.Indexer.CreateIndexer() .GetCheckpoint(balanceId.Type == BalanceType.Address ? IndexerCheckpoints.Balances : IndexerCheckpoints.Wallets); var atBlock = AtBlock(at); var query = new BalanceQuery(); query.RawOrdering = true; query.From = null; if (at != null) { query.From = ToBalanceLocator(atBlock); } if (query.From == null) { query.From = new UnconfirmedBalanceLocator(DateTimeOffset.UtcNow - Expiration); } query.PageSizes = new[] { 1, 10, 100 }; var cacheTable = repo.GetBalanceSummaryCacheTable(balanceId, colored); var cachedSummary = cacheTable.Query(Chain, query).FirstOrDefault(c => (((ConfirmedBalanceLocator)c.Locator).BlockHash == atBlock.HashBlock && at != null) || c.Immature.TransactionCount == 0 || ((c.Immature.TransactionCount != 0) && !IsMature(c.OlderImmature, atBlock))); var cachedLocator = cachedSummary == null ? null : (ConfirmedBalanceLocator)cachedSummary.Locator; if (cachedSummary != null && at != null && cachedLocator.Height == atBlock.Height) { cachedSummary.CacheHit = CacheHit.FullCache; cachedSummary.PrepareForSend(at, debug); return(cachedSummary); } cachedSummary = cachedSummary ?? new BalanceSummary() { Confirmed = new BalanceSummaryDetails(), UnConfirmed = new BalanceSummaryDetails(), OlderImmature = int.MaxValue }; int stopAtHeight = cachedSummary.Locator == null ? -1 : cachedLocator.Height; int lookback = (int)(Expiration.Ticks / this.Network.Consensus.PowTargetSpacing.Ticks); if (at == null) { stopAtHeight = stopAtHeight - lookback; } var client = Configuration.Indexer.CreateIndexerClient(); client.ColoredBalance = colored; var diff = client .GetOrderedBalance(balanceId, query) .WhereNotExpired(Expiration) .TakeWhile(_ => !cancel.IsCancellationRequested) //Some confirmation of the fetched unconfirmed may hide behind stopAtHeigh .TakeWhile(_ => _.BlockId == null || _.Height > stopAtHeight - lookback) .AsBalanceSheet(Chain); if (cancel.Token.IsCancellationRequested) { throw new HttpResponseException(new HttpResponseMessage() { StatusCode = HttpStatusCode.InternalServerError, ReasonPhrase = "The server can't fetch the balance summary because the balance is too big. Please, load it in several step with ?at={blockFeature} parameter. Once fully loaded after all the step, the summary will return in constant time." }); } RemoveBehind(diff, stopAtHeight); RemoveConflicts(diff); var unconfs = diff.Unconfirmed; var confs = cachedLocator == null ? diff.Confirmed : diff.Confirmed.Where(c => c.Height > cachedLocator.Height).ToList(); var immature = confs.Where(c => !IsMature(c, atBlock)).ToList(); var summary = new BalanceSummary() { Confirmed = BalanceSummaryDetails.CreateFrom(confs, Network, colored), Immature = BalanceSummaryDetails.CreateFrom(immature, Network, colored), UnConfirmed = BalanceSummaryDetails.CreateFrom(unconfs, Network, colored), }; summary.Confirmed += cachedSummary.Confirmed; summary.Immature += cachedSummary.Immature; summary.Locator = new ConfirmedBalanceLocator(atBlock.Height, atBlock.HashBlock); summary.CacheHit = cachedSummary.Locator == null ? CacheHit.NoCache : CacheHit.PartialCache; var newCachedLocator = (ConfirmedBalanceLocator)summary.Locator; if ( cachedSummary.Locator == null || newCachedLocator.BlockHash != cachedLocator.BlockHash) { var olderImmature = immature.Select(_ => _.Height).Concat(new[] { int.MaxValue }).Min(); var newCachedSummary = new Models.BalanceSummary() { Confirmed = summary.Confirmed, Immature = summary.Immature, Locator = summary.Locator, OlderImmature = Math.Min(cachedSummary.OlderImmature, olderImmature) }; var checkpointBlock = Chain.GetBlock(checkpoint.BlockLocator.Blocks[0]); if (checkpointBlock != null && checkpointBlock.Height >= atBlock.Height) { cacheTable.Create(newCachedLocator, newCachedSummary); } } summary.PrepareForSend(at, debug); return(summary); }
public async Task <ActionResult> Index(string search = null, int count = 5) { count = Math.Max(0, count); count = Math.Min(50, count); if (!string.IsNullOrWhiteSpace(search)) { search = search.Trim(); if (search.StartsWith("0x") || search.Contains("OP_")) { return(RedirectToAction("Address", new { address = search })); } try { BitcoinAddress.Create(search, QBit.Network); return(RedirectToAction("Address", new { address = search })); } catch { } if (search.Length == 32 * 2) { if (search.StartsWith("0000000000")) { return(RedirectToAction("Block", new { blockFeature = search })); } else { return(RedirectToAction("Transaction", new { txId = search })); } } try { BlockFeature.Parse(search); return(RedirectToAction("Block", new { blockFeature = search })); } catch { } return(View()); } var responses = await Task.WhenAll(Enumerable .Range(0, count) .Select(i => QBit.GetBlock(new BlockFeature(SpecialFeature.Last) { Offset = -i }, true, true)) .ToArray()); var model = new MainModel(); model.NextCount = count + 5; foreach (var response in responses.Where(r => r.ExtendedInformation != null && r.AdditionalInformation != null)) { var blockModel = new MainBlockModel(); blockModel.Hash = response.AdditionalInformation.BlockId; blockModel.Height = response.AdditionalInformation.Height; blockModel.Size = ToKB(response.ExtendedInformation.Size); blockModel.Time = ToRelative(response.AdditionalInformation.BlockTime); blockModel.TransactionsCount = response.ExtendedInformation.TransactionCount; blockModel.Fees = ToString(response.ExtendedInformation.BlockReward - response.ExtendedInformation.BlockSubsidy); model.Blocks.Add(blockModel); } return(View(model)); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Please enter a valid question number as commande line argument"); } else if (args.First() == "Question-1") { Key privateKey = new Key(); // generate a random private key PubKey publicKey = privateKey.PubKey; // Get the public key //Console.WriteLine(publicKey); Console.WriteLine(privateKey.ToString(Network.TestNet)); var mainnetAddress = publicKey.GetAddress(Network.Main); //Mainnet address var testnetAddress = publicKey.GetAddress(Network.TestNet); // Testnet address string walletInfo = privateKey.ToString(Network.TestNet) + "@" + mainnetAddress.ToString() + "@" + testnetAddress.ToString(); walletInfo = walletInfo.Replace("@", System.Environment.NewLine); System.IO.File.WriteAllText("C:\\Users\\Mathieu\\Documents\\Blockchain\\wallet2.txt", walletInfo); // Generate QR-code QRCodeGenerator qrGenerator = new QRCodeGenerator(); QRCodeData qrCodeData = qrGenerator.CreateQrCode(testnetAddress.ToString(), QRCodeGenerator.ECCLevel.Q); QRCode qrCode = new QRCode(qrCodeData); Bitmap qrCodeImage = qrCode.GetGraphic(11); // Print the bitmap PrintDocument pd = new PrintDocument(); pd.PrintPage += (thesender, ev) => { float x = 230.0F; float y = 320.0F; RectangleF srcRect = new RectangleF(40.0F, 40.0F, 600.0F, 600.0F); GraphicsUnit units = GraphicsUnit.Pixel; ev.Graphics.DrawImage(qrCodeImage, x, y, srcRect, units); }; pd.Print(); } else if (args.First() == "Question-2") { Key privateKey = new Key(); // generate a random private key PubKey publicKey = privateKey.PubKey; // Get the public key var vanityAddress = publicKey.GetAddress(Network.TestNet); //TestNet address string Text = vanityAddress.ToString(); while (Text.Substring(1, 4).Equals("math", StringComparison.CurrentCultureIgnoreCase) == false) { privateKey = new Key(); // generate a random private key publicKey = privateKey.PubKey; // Get the public key vanityAddress = publicKey.GetAddress(Network.TestNet); //TestNet address Text = vanityAddress.ToString(); } Console.WriteLine(vanityAddress.ToString()); string walletInfo = privateKey.ToString(Network.TestNet) + "@" + vanityAddress.ToString(); walletInfo = walletInfo.Replace("@", System.Environment.NewLine); System.IO.File.WriteAllText("C:\\Users\\Mathieu\\Documents\\Blockchain\\vanity2.txt", walletInfo); } else if (args.First() == "Question-3") { // Create a client QBitNinjaClient client = new QBitNinjaClient(Network.Main); string TXID = "12bec2fe21387b60c33f2e766557dfeb8b9f1b75d505745f11100d6b2425cf9f"; // Parse transaction id to NBitcoin.uint256 so the client can eat it var transactionId = uint256.Parse(TXID); // Query the transaction GetTransactionResponse transactionResponse = client.GetTransaction(transactionId).Result; Console.WriteLine(); Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); // Outputs of the transaction = Received Coins Console.WriteLine("Output associated to TX = " + TXID); Console.WriteLine(); List <ICoin> receivedCoins = transactionResponse.ReceivedCoins; Money receivedAmount = Money.Zero; foreach (var coinR in receivedCoins) { Money amount = (Money)coinR.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinR.TxOut.ScriptPubKey; Console.WriteLine("ScriptPubKey = \"" + paymentScript + "\""); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine("Going to address : " + address); receivedAmount = (Money)coinR.Amount.Add(receivedAmount); Console.WriteLine(); } Console.WriteLine("Total output amount = " + receivedAmount.ToDecimal(MoneyUnit.BTC) + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); // Inputs of the transaction Console.WriteLine("Inputs associated to TX = " + TXID); Console.WriteLine(); List <ICoin> spentCoins = transactionResponse.SpentCoins; Money spentAmount = Money.Zero; foreach (var coinS in spentCoins) { Money amount = (Money)coinS.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinS.TxOut.ScriptPubKey; Console.WriteLine("ScriptPubKey = \"" + paymentScript + "\""); // It's the ScriptPubKey var address = paymentScript.GetDestinationAddress(Network.Main); Console.WriteLine("Coming from address : " + address); spentAmount = (Money)coinS.Amount.Add(spentAmount); Console.WriteLine(); } Console.WriteLine("Total input amount = " + spentAmount.ToDecimal(MoneyUnit.BTC) + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); // Now looking at the fees NBitcoin.Transaction transaction = transactionResponse.Transaction; var fee = transaction.GetFee(spentCoins.ToArray()); Console.WriteLine("Transaction fees = " + fee.ToString() + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); var inputs = transaction.Inputs; foreach (TxIn input in inputs) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine("Previous TX hash : " + previousOutpoint.Hash); // hash of prev tx Console.WriteLine("Previous TX index : " + previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); // Getting the balance from the address string copayAddress = "mz2oHHuMqnJg2grqCrKRDGs2vwG5dwNDRu"; BitcoinAddress WalletAddress = new BitcoinPubKeyAddress(copayAddress, Network.TestNet); QBitNinjaClient testnetClient = new QBitNinjaClient(Network.TestNet); var balanceModel = testnetClient.GetBalance(WalletAddress).Result; var unspentCoins = new List <Coin>(); foreach (var operation in balanceModel.Operations) { unspentCoins.AddRange(operation.ReceivedCoins.Select(coin => coin as Coin)); } var balance = unspentCoins.Sum(x => x.Amount.ToDecimal(MoneyUnit.BTC)); Console.WriteLine(); Console.WriteLine("Copay Address = " + copayAddress); Console.WriteLine("Total balance = " + balance.ToString()); // Get all operations for that address if (balanceModel.Operations.Count > 0) { foreach (var operation in balanceModel.Operations) { // We take the transaction ID var TXIDb = operation.TransactionId; GetTransactionResponse transactionResponseb = testnetClient.GetTransaction(TXIDb).Result; NBitcoin.Transaction transactionb = transactionResponse.Transaction; Console.WriteLine(); Console.WriteLine("Transaction list for the address : "); Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); // Outputs of the transaction = Received Coins Console.WriteLine("Transaction ID : " + TXIDb); Console.WriteLine(); Console.WriteLine("OUTPUTS"); Console.WriteLine(); List <ICoin> receivedCoinsb = transactionResponseb.ReceivedCoins; foreach (var coinR in receivedCoinsb) { Money amount = (Money)coinR.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinR.TxOut.ScriptPubKey; var address = paymentScript.GetDestinationAddress(Network.TestNet); Console.WriteLine("Going to address : " + address); Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); // Inputs of the transaction Console.WriteLine("INPUTS"); Console.WriteLine(); List <ICoin> spentCoinsb = transactionResponseb.SpentCoins; foreach (var coinS in spentCoinsb) { Money amount = (Money)coinS.Amount; Console.WriteLine("Amount = " + amount.ToDecimal(MoneyUnit.BTC) + " BTC"); var paymentScript = coinS.TxOut.ScriptPubKey; var address = paymentScript.GetDestinationAddress(Network.TestNet); Console.WriteLine("Coming from address : " + address); Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); // Now looking at the fees var feeb = transactionb.GetFee(spentCoinsb.ToArray()); Console.WriteLine("Transaction fees = " + feeb.ToString() + " BTC"); Console.WriteLine("--------------------------------------------------------------------------"); var inputsb = transactionb.Inputs; foreach (TxIn input in inputsb) { OutPoint previousOutpoint = input.PrevOut; Console.WriteLine("Previous TX hash : " + previousOutpoint.Hash); // hash of prev tx Console.WriteLine("Previous TX index : " + previousOutpoint.N); // idx of out from prev tx, that has been spent in the current tx Console.WriteLine(); } Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); } } // List of UTXO Console.WriteLine(); Console.WriteLine("List of UTXO"); foreach (var c in unspentCoins) { Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(c.Outpoint.ToString()); Console.WriteLine(); } } else if (args.First() == "Question-4") { // Sending a transaction var bitcoinPrivateKey = new BitcoinSecret("cP8UmUrZgiRfQZF9C7VYvJQuPK2Ao9ZTnR1BcZ79hADqn9yNTFXg"); var network = bitcoinPrivateKey.Network; var address = bitcoinPrivateKey.GetAddress(); var client = new QBitNinjaClient(Network.TestNet); var transactionId = uint256.Parse("9e698153d261be07b939ee3e4638b0c09eb466b485f2e09eded5a5eb6fff0519"); var transactionResponse = client.GetTransaction(transactionId).Result; // From where ? var receivedCoins = transactionResponse.ReceivedCoins; OutPoint outPointToSpend = null; foreach (var coin in receivedCoins) { if (coin.TxOut.ScriptPubKey == bitcoinPrivateKey.ScriptPubKey) { outPointToSpend = coin.Outpoint; } } if (outPointToSpend == null) { throw new Exception("TxOut doesn't contain our ScriptPubKey"); } Console.WriteLine("We want to spend {0}. outpoint:", outPointToSpend.N + 1); var transaction = Transaction.Create(network); transaction.Inputs.Add(new TxIn() { PrevOut = outPointToSpend }); // To where ? var CopayAddress = new BitcoinPubKeyAddress("mokLh8W4J4DzZpj2XyEhE1ReZf5BnsSZcs"); // How much we want to spend var CopayAmount = new Money(0.08m, MoneyUnit.BTC); // How much miner fee we want to pay var minerFee = new Money(0.0001m, MoneyUnit.BTC); // How much we want to get back as change var txInAmount = (Money)receivedCoins[(int)outPointToSpend.N].Amount; var changeAmount = txInAmount - CopayAmount - minerFee; TxOut CopayTxOut = new TxOut() { Value = CopayAmount, ScriptPubKey = CopayAddress.ScriptPubKey }; TxOut changeTxOut = new TxOut() { Value = changeAmount, ScriptPubKey = bitcoinPrivateKey.ScriptPubKey }; transaction.Outputs.Add(CopayTxOut); transaction.Outputs.Add(changeTxOut); // We can use the private key to sign transaction.Inputs[0].ScriptSig = bitcoinPrivateKey.ScriptPubKey; transaction.Sign(bitcoinPrivateKey, receivedCoins.ToArray()); BroadcastResponse broadcastResponse = client.Broadcast(transaction).Result; if (!broadcastResponse.Success) { Console.Error.WriteLine("ErrorCode: " + broadcastResponse.Error.ErrorCode); Console.Error.WriteLine("Error message: " + broadcastResponse.Error.Reason); } else { Console.WriteLine("Success! Hash of the transaction :"); Console.WriteLine(transaction.GetHash()); } // Confirmations of the transaction var newTXID = uint256.Parse("4777e829eabd4dd5821153d016e5f3256998e962d0e10af1935bfd7ee95e45d0"); int n = 0; while (n < 10) { GetTransactionResponse newTXResponse = client.GetTransaction(newTXID).Result; Console.WriteLine(); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine("Current number of confirmations : " + newTXResponse.Block.Confirmations); Console.WriteLine("--------------------------------------------------------------------------"); Console.WriteLine(); System.Threading.Thread.Sleep(10000); n++; } } else if (args.First() == "Question-5") { // We identify the blocks in question // And we create a list of address that have received these coinbase transactions var client = new QBitNinjaClient(Network.Main); var blockHeight = new BlockFeature(2); var blockResponse = client.GetBlock(blockHeight).Result; var TX = blockResponse.Block.Transactions.First(); var reward = TX.Outputs.First(); var nextAddr = reward.ScriptPubKey.GetDestinationAddress(Network.Main); Console.WriteLine(nextAddr); } }
public object Find(string data) { data = data.Trim(); var b58 = NoException(() => WhatIsBase58.GetFromBase58Data(data)); if (b58 != null) { if (b58 is WhatIsAddress) { var address = (WhatIsAddress)b58; TryFetchRedeemOrPubKey(address); } return(b58); } if (data.Length == 0x40) { var tx = NoException(() => Controller.JsonTransaction(new uint256(data))); if (tx != null) { return(tx); } } var b = NoException(() => Controller.JsonBlock(BlockFeature.Parse(data), true)); if (b != null) { return(b); } if (data.Length == 0x28) //Hash of pubkey or script { TxDestination dest = new KeyId(data); var address = new WhatIsAddress(dest.GetAddress(Network)); if (TryFetchRedeemOrPubKey(address)) { return(address); } dest = new ScriptId(data); address = new WhatIsAddress(dest.GetAddress(Network)); if (TryFetchRedeemOrPubKey(address)) { return(address); } } var script = NoException(() => GetScriptFromBytes(data)); if (script != null) { return(new WhatIsScript(script, Network)); } script = NoException(() => GetScriptFromText(data)); if (script != null) { return(new WhatIsScript(script, Network)); } var sig = NoException(() => new TransactionSignature(Encoders.Hex.DecodeData(data))); if (sig != null) { return(new WhatIsTransactionSignature(sig)); } var pubkeyBytes = NoException(() => Encoders.Hex.DecodeData(data)); if (pubkeyBytes != null && PubKey.Check(pubkeyBytes, true)) { var pubKey = NoException(() => new PubKey(data)); if (pubKey != null) { return(new WhatIsPublicKey(pubKey, Network)); } } if (data.Length == 80 * 2) { var blockHeader = NoException(() => { var h = new BlockHeader(); h.ReadWrite(Encoders.Hex.DecodeData(data)); return(h); }); if (blockHeader != null) { return(new WhatIsBlockHeader(blockHeader)); } } return(null); }
/// <summary> /// Try to interpret the given string in a few ways in order to detect what object it's supposed to represent. /// </summary> /// <returns>The object represented by the input string. This may be a Bitcoin address, a script, a signature, a public key, etc.</returns> public async Task <object> Find(string data) { data = data.Trim(); // Is it a Bitcoin address? var b58 = NoException(() => WhatIsBase58.GetFromBitcoinString(data)); if (b58 != null) { if (b58 is WhatIsAddress address) { await TryFetchRedeemOrPubKey(address); // Shouldn't the return value here be checked? } return(b58); } // Is it a transaction ID? if (data.Length == 0x40) { try { return(await Controller.JsonTransaction(uint256.Parse(data), false)); } catch { // Well, apparently it's not a transaction ID. } } // Is it a block feature? var b = NoException(() => Controller.JsonBlock(BlockFeature.Parse(data), true, false)); if (b != null) { return(b); } // Is it the hash of a public key (modeled as KeyId in NBitcoin), or is it the hash of a script ID? if (data.Length == 0x28) // Hash of pubkey or script { TxDestination dest = new KeyId(data); var address = new WhatIsAddress(dest.GetAddress(Network)); if (await TryFetchRedeemOrPubKey(address)) { return(address); } dest = new ScriptId(data); address = new WhatIsAddress(dest.GetAddress(Network)); if (await TryFetchRedeemOrPubKey(address)) { return(address); } } // Is it a script? var script = NoException(() => GetScriptFromBytes(data)); if (script != null) { return(new WhatIsScript(script, Network)); } script = NoException(() => GetScriptFromText(data)); if (script != null) { return(new WhatIsScript(script, Network)); } // Is it a transaction signature? var sig = NoException(() => new TransactionSignature(Encoders.Hex.DecodeData(data))); if (sig != null) { return(new WhatIsTransactionSignature(sig)); } // Is it a hexstring representing the bytes of a public key? var pubkeyBytes = NoException(() => Encoders.Hex.DecodeData(data)); if (pubkeyBytes != null && PubKey.Check(pubkeyBytes, true)) { var pubKey = NoException(() => new PubKey(data)); if (pubKey != null) { return(new WhatIsPublicKey(pubKey, Network)); } } // Is it a blockheader? if (data.Length == 80 * 2) { var blockHeader = NoException(() => { var h = ConsensusFactory.CreateBlockHeader(); h.ReadWrite(Encoders.Hex.DecodeData(data), ConsensusFactory); return(h); }); if (blockHeader != null) { return(new WhatIsBlockHeader(blockHeader)); } } // No idea what this is. return(null); }