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.
Monitor Your Wallet
1. Setup your Safe
As you have learned in the previous lesson, create a safe, that will be monitored.
Network network = Network.TestNet;
Safe safe = Safe.Create(out mnemonic, "password", "Hidden.wallet", network);
Or load it if it's already created:
Safe safe = Safe.Load("password", walletFilePath);
2. Create a SafeMonitor
var safeMonitor = new HttpSafeMonitor(safe, addressCount: 1000);
This would register the first 1000 addresses on QBitNinja.
With HTTP, there are privacy concerns, since the HTTP API knows which addresses are in a Safe.
These concerns can be solved with using an SPV or a full-node. Implementation of them are expected in the future.
3. Make Some Transactions
Retrieve some addresses and send some testnet coins to them, so there will be things to monitor. You can get testnet coins easily, just Google it.
Console.WriteLine(safeMonitor.Safe.GetAddress(0));
Console.WriteLine(safeMonitor.Safe.GetAddress(10));
Console.WriteLine(safeMonitor.Safe.GetAddress(999));
4. Follow the Initialization Progress
I provide some events that help you check if everything is properly synced between QBitNinja and your Monitor.
safeMonitor.InitializationStateChanged += delegate(object sender, EventArgs args)
{
var monitor = (HttpSafeMonitor) sender;
Console.WriteLine($"Initialization state: {monitor.InitializationState}");
};
safeMonitor.InitializationProgressPercentChanged += delegate(object sender, EventArgs args)
{
var monitor = (HttpSafeMonitor) sender;
Console.WriteLine($"Initializing: {monitor.InitializationProgressPercent}%");
};
while (safeMonitor.InitializationState != State.Ready)
Thread.Sleep(100);
5. Get the Balances
In the background, the HttpSafeMonitor
constantly keeps itself synced. The latency is about 5 seconds.
SafeBalanceInfo safeBalanceInfo = safeMonitor.SafeBalanceInfo;
Console.WriteLine($"Number of monitored addresses: {safeBalanceInfo.MonitoredAddressCount}");
Console.WriteLine($"Balance: {safeBalanceInfo.Balance}");
Console.WriteLine($"Confirmed: {safeBalanceInfo.Confirmed}");
Console.WriteLine($"Unconfirmed: {safeBalanceInfo.Unconfirmed}");
foreach (AddressBalanceInfo balanceInfo in safeBalanceInfo.AddressBalances)
{
if (balanceInfo.Balance != 0)
Console.WriteLine($"{balanceInfo.Address}: {balanceInfo.Balance}");
}
6. Get Safe History
You can get the history in a very similar way.
SafeHistory history = safeMonitor.SafeHistory;
Console.WriteLine("totalreceived: " + history.TotalReceived);
Console.WriteLine("totalspent: " + history.TotalSpent);
foreach (AddressHistoryRecord record in history.Records)
{
Console.WriteLine(record.Address + " " + record.Amount);
}
7. Listen to Changes
I provide you an event whenever changes happen.
safeMonitor.BalanceChanged += delegate(object sender, EventArgs args)
{
var monitor = (HttpSafeMonitor) sender;
Console.WriteLine($"Confirmed balance of safe: {monitor.SafeBalanceInfo.Confirmed}");
Console.WriteLine($"Unconfirmed balance of safe: {monitor.SafeBalanceInfo.Unconfirmed}");
Console.WriteLine(
$"TransacitonId: {monitor.SafeHistory.Records.OrderBy
(x => x.DateTime).Last().TransactionId}");
};
Run the software and send some testnet coins to one of the addresses, see how the event fires when the transaction is propagated and when it is confirmed.
What's Next?
During the next part, I will armor you with the ability to spend your funds.
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.
History
- 19th June, 2016: Initial version