Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

HiddenBitcoin: High level C# Bitcoin Wallet Library - Monitor The Blockchain (Part 2 - Lesson 1)

0.00/5 (No votes)
18 Jun 2016 2  
Quickstart to Bitcoin wallet development in C#

Table of Contents

Important Note

If you would like to use it in production, get in touch with me. As long as nobody is using it in production, I will keep changing it according to my needs.

Introduction

Developer time is money. This guide is an ideal quick start to Bitcoin for C# developers.

I am developing a Bitcoin wallet, called HiddenWallet. The HiddenBitcoin library is the introduction of another abstraction layer between NBitcoin and my user interface.

By the end of this three part tutorial, you will be able to build a Bitcoin wallet.

Quote:

While programming to an API can assist in getting an application up quickly, the developer is limited to innovations that can take place against the API.

Nicolas Dorier, Bitcoin core developer, creator of NBitcoin, the C# Bitcoin library. Keep this quote in mind while using my high-level API.
He is also the main author of the C# Bitcoin book, what I am co-authoring.

How high level is it? In my opinion, a GUI developer, designer should not be able to make too many mistakes. They should not know about inputs and outputs and scriptpubkeys. They should stick at the addresses, privatekeys and wallets level. Also NBitcoin should be fully abstracted away.

If you are familiar with NBitcoin, you can find a deeper level version of this tutorial as a case study in the C# Bitcoin book.

How to Monitor Addresses?

The Blockchain

The Bitcoin Blockchain is a public ledger, so everyone can see every transaction that ever happened there. One can submit a transaction anytime. However at this point, the transaction is not confirmed, it is possible if the added transaction fee is too low the confirmation does not happen. A set of transaction confirms every 10 minutes.

Address Balances

It is very straightforward how you can get a balance of an address:

var network = Network.MainNet;

// HttpMonitor can monitor The Blockchain through HTTP (QBitNinja)
var httpMonitor = new HttpMonitor(network);

// Checking address balances
AddressBalanceInfo balanceInfo = httpMonitor.GetAddressBalanceInfo("1ENCTCkqoJqy2XZ2m2Dy1bRax7hsSnC5Fc");
Console.WriteLine($"Address balance: {balanceInfo.Balance}"); // 0,05474889
Console.WriteLine($"Confirmed balance: {balanceInfo.Confirmed}"); // 0
Console.WriteLine($"Unconfirmed balance: {balanceInfo.Unconfirmed}"); // 0,05474889

There are multiple ways to access The Blockchain, through HTTP API, SPV of full node.
Currently HiddenBitcoin is capable of HTTP, so let's not care about the rest for now.

Note:

I have done an SPV implementation too, but there were too many problems, so I decided not go down on that road for now.

A full-node is very cumbersome to run and it is not getting better. Although I think the code should be straightforward to implement, my audience for HiddenWallet are normal users, not companies, not developers and they will never be running a full-node.
That being said, I will implement it to HiddenBitcoin, but it is not a priority right now.

An other important note: Balance = Confirmed + Unconfirmed. It means, the unconfirmed balance can be positive or negative, for example if you send some money from the address.

Address History

// Get history of an address
AddressHistory history = httpMonitor.GetAddressHistory("1ENCTCkqoJqy2XZ2m2Dy1bRax7hsSnC5Fc");

Console.WriteLine("Number of transactions: " + history.Records.Count);

// Exercise: are all transaction confirmed?
var allTransactionsConfirmed = true;
foreach (AddressHistoryRecord record in history.Records)
{
    Console.WriteLine(record.TransactionId + " : " + record.Amount);
    allTransactionsConfirmed = allTransactionsConfirmed && record.Confirmed;
}
Console.WriteLine("All transactions are confirmed: " + allTransactionsConfirmed);

// Exercise: get the balance of the address
Console.WriteLine("Total received - Total spent = Balance");
Console.WriteLine(history.TotalReceived + " - " + history.TotalSpent + " = " +
                    (history.TotalReceived - history.TotalSpent));

How to Monitor Transactions?

A transaction can have multiple inputs and multiple outputs.

// Get some data from the transaction
TransactionInfo transactionInfo1 = httpMonitor.GetTransactionInfo(history.Records.First().TransactionId);
            
Console.WriteLine("txid: " + transactionInfo1.Id);
Console.WriteLine("Network: " + transactionInfo1.Network);
Console.WriteLine("Confirmed: " + transactionInfo1.Confirmed);
Console.WriteLine("Total amount of all inputs: " + transactionInfo1.TotalInputAmount);
Console.WriteLine("Total amount of all outputs: " + transactionInfo1.TotalOutputAmount);
Console.WriteLine("Fee : " + transactionInfo1.Fee);

Console.WriteLine(Environment.NewLine + "Input addresses and amounts: ");
foreach (var input in transactionInfo1.Inputs)
{
    Console.WriteLine(input.Amount + " " + input.Address);
}
Console.WriteLine(Environment.NewLine + "Output addresses and amounts: ");
foreach (var output in transactionInfo1.Outputs)
{
    Console.WriteLine(output.Amount + " " + output.Address);
}

There are some transctions my API does not care about, let's call them exotic ones, here is how you can handle them:

// Sometimes my API can't fully process a transaction, because it has OP_RETURN for example
// It should not be a concern for a Bitcoin wallet that purely handles money, 
// if a transaction output or input has not been added
// that means it has some other purpose, a wallet API can dismiss it
// This tx is exotic (has OP_RETURN)
TransactionInfo transactionInfo2 =
    httpMonitor.GetTransactionInfo("8bae12b5f4c088d940733dcd1455efc6a3a69cf9340e17a981286d3778615684");
Console.WriteLine(transactionInfo2.Id);
Console.WriteLine("There are exotic inputs or outputs, so not all of them have been added successfully: "
                    + Environment.NewLine + !transactionInfo2.AllInOutsAdded);

What's Next?

During the next lesson, I am going to show you how you can monitor the Safe, I have introduced you in the first part.  

License agreement

If you do not like my tutorial or code you are obligated to do a Cersei Lannister walk of shame.  
Moreover after your death I will be entitled to take away your soul.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here