Click here to Skip to main content
15,860,859 members
Articles / Web Development / ASP.NET

Accepting Bitcoin (BTC) payments with C# ASP.NET. Primer applicable to other crypto currencies: Litecoin (LTC), Ethereum (ETH), Ripple (XRP)...

Rate me:
Please Sign up or sign in to vote.
4.94/5 (50 votes)
28 Dec 2017CPOL31 min read 149.1K   3.5K   113   30
Detailed guide on building C# ASP.NET website checkout that accepts Bitcoin (BTC), Litecoin (LTC), Ethereum (ETH) and other Crypto Currencies.

Index

Image 1

I’ve wanted to write a Bitcoin article for few years now. Ever since great reception of Introduction to PayPal for C# - ASP.NET developers and Windows Mobile, iPhone, Android - Marketplace Comparison I’ve enjoyed the process of firming my own understanding by writing here on CodeProject.

Unfortunately, last few years have been tough on my time. So even though I’ve been following Bitcoin and other crypto currencies (CCs) before the big crash of late 2013, it’s only this recent surge that has finally got me to commit to write more on technology. My opinions haven’t changed much - even back in 2013 I believed that CCs are the next big revolution that we will see in our lifetimes. Kinda like I’ve predicted that Android will be a market leader back in 2009, I can see the future in which currencies like Bitcoin are what us humans will use for storing and exchanging value.

Thus, this article will be my attempt to present the vision of future where crypto currencies become de-facto currencies. Also, I’ll strive for this article to be a complete resource - one which provides you with EVERYTHING you need to get proper start with CCs. Kinda like I did with Mobile Marketplace Comparison - I’ll provide historical background, current situation and then how you as developer can join in.

As with most of my articles, use Index above so you can easily navigate to stuff that interests you the most:

Strap yourself, we’re starting with deep dive into the past.

Past

Short history of money

Money is likely one of the most important inventions in the history of humanity. Before money value was tied to a concrete resource. Which was obviously a huge problem in various scenarios. In trading you couldn’t trade in 3.3 sheep for a cow. Also, value you could obtain was severely limited. Even if you were the best grain farmer that ever lived - sorry, you could only capture as much value as you can trade in for non perishable goods. Abstracting value and representing it by tiny pieces of gold (or other precious / rare tokens) allowed humanity to eventually preserve more value, far beyond constraints of previous system. Commodity money was paired with trade and humanity flourished.

The next big revolution came when gold and other commodity money was replaced by representative money. Instead of carrying 1 kg of gold around, you carried a paper saying that you have 1 kg of gold. Some central authority guaranteed the note, allowing you to exchange it for underlaying commodity. Start of 20th century saw most countries adopt gold standard. Practice was discouraged, but if you really wanted you could exchange any paper note of any country into certain amount of gold.

Finally, money started changing much quicker in 20th century. After World War 2 most countries started backing their currencies with US Dollar instead of gold. US dollar in turn was fixed to gold. This all changed when in 1971 when Nixon suspended conversion of Dollars into gold.

In today’s world all money is Fiat money. Fiat currencies are designated legal tender whose value is backed by government issuing it. There is nothing concrete underlaying paper notes like with representative money. If I have $100, those are worth only because other people are willing to accept them as a form of payment. Or as it is more poetically said: US Dollar has value because it is backed by “The Full Faith and Credit of U.S. Government”.

With advent of the Internet, money finally transcended paper. Sure, credit cards existed before 1960s (and you can argue that similar credit forms existed even before 20th century). But the Internet is what allowed money to truly move into new - virtual realm. Nowadays in developed countries with online banking systems it’s quite common not to interact with cash for months.

Amount of money you have is now basically the sum of digits you see on the screen when you login to your online banking.

Money and Freedom

Looking back it’s easy to see numerous flaws with various forms of money throughout the history. I love reading about counterfeiting ancient coins, for example. Or thinking how as a banker with no oversight in Middle Ages you were free to inflate number of paper notes. Yet throughout history humanity dealt with these “edge cases” in one way or the other. Someone profited, someone was ruined, life moved on.

Nowadays you can argue that with Fiat money there is only one big problem left: government control. Most people see that through inflation. If you are saving money and putting it into a bank account, realistically you are losing about 4-5% of it’s real value every year. We can argue that loss is nullified by “greater good” - government directed development of society as a whole. Basically, as long as you agree with actions of your government - you won’t care much about details of fiscal and monetary policies.

But, let’s say you live in a country where you don’t agree with the government. To use example - let’s say you are a Syrian caught in the middle of civil war. Suddenly you’re thrown in reality that all the money you’ve earned through life is not yours. Government controls it. So if government decides to purchase tanks and then inflate money supply - not much you can do. Practically at any point you can be unwillingly taxed.

You can try to obtain currency of foreign governments. But then you are at the mercy of those other governments. Plus you need to find others who are willing to trade in that currency.

Taken all that into account - it’s easy to see parallel between modern monetary system and feudal society in Middle Ages. In Middle Ages if you were born in certain village you were vassal of certain lord. So long as you stayed on the land of that lord you were obliged to serve. Not that you had much choice really - there was a lord owning the land wherever you went.

Now, since this is supposed to be a programming article I won’t go into deeper socio-economical analysis. All of the previous talk boils down to a simple question:

Do you believe that individual should have freedom to truly own it’s money?

In this era of promoting individual freedoms, I almost always hear “yes, of course” as the first answer. But, naturally, things are not as simple as that. I will expand on this topic in closing section of the article.

The Dawn of Bitcoin

It is important to note that Bitcoin was released during the height of 2008 financial crisis. Reading about the crisis doesn’t do it justice, a video much better captures the widespread panic that was present:

Satoshi Nakamoto, creator of Bitcoin, had his own view on the whole situation. So he included following text in the genesis block when starting Blockchain:

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

Not much is known about Satoshi Nakamoto. Over years many people have tried figuring out who is the person behind obvious pseudonym. Hunt goes far beyond curiosity, as it’s estimated that Satoshi owns about 1 million Bitcoins. At current BTC prices that translates to around $4 billion, making him one of the richest people in the world.

Regardless of who Satoshi really was, the results of work done between October 2008 and late 2010 have spawned $100+ billion market. So what is Bitcoin and what are ideas behind it that ended up creating such huge industry in less than a decade?

You can actually get pretty good overview of Bitcoin from Satoshi’s first post on The Cryptography Mailing List. To quote intro of the post:

I've been working on a new electronic cash system that's fully
peer-to-peer, with no trusted third party.

The paper is available at:
http://www.bitcoin.org/bitcoin.pdf

The main properties:
 Double-spending is prevented with a peer-to-peer network.
 No mint or other trusted parties.
 Participants can be anonymous.
 New coins are made from Hashcash style proof-of-work.
 The proof-of-work for new coin generation also powers the
    network to prevent double-spending.

https://www.mail-archive.com/cryptography@metzdowd.com/msg09959.html

Key concept is - of course - no trusted third party. As we witnessed during Short history of money; we humans always had some kind of central authority in charge. No matter how long the chain, there was always someone at the end of it, pulling the strings and making decisions, ensuring everything runs according to rules.

With Bitcoin, for the first time, we are able to establish a trust network without central authority. All participants are able to interact and exchange, easily verifying that transactions are processed within well defined rules.

I think that trust network is the part that escapes most people. Forget money for a moment - think about any kind of agreement between two parties. In current system we live in, agreements are likely to be recorded by contracts. Depending on jurisdiction, there is some central authority (court) which enforces terms of contract. In a sense - it doesn’t matter what contract says. What matters is how court interprets what contract says… and how much power court has to make you respect what it sees as your contractual obligations.

Bitcoin is revolution because it takes out central authority as a prerequisite for trust network. As long as you are able to implement/code contract - once it’s part of blockchain you may rest assured it will execute under specified conditions. There is no need for intervention from some kind of central authority.

One coin to rule them all. Or is it?

While lots of people were busy calling Bitcoin 21st century version of Tulip crisis those knowledgeable enough took time creating new systems that exploit this new-found freedom of trust systems without central authority.

Ethereum (ETH)

Probably the most ambitious project on this front is Ethereum (ETH), which aims to provide ability to code almost any type of smart contract and have it executed as part of it’s peer-to-peer network. I am somewhat of skeptic when it comes to feasibility of ETH… but long term it’s interesting to see how this idea will unfold. Vitalik and team sure have set extremely ambitions goals ahead of themselves; as seen by roadblocks they’ve ran into. But no-one made it big by playing safe, right? So far they seem to be doing good considering ETH currently has $26 billion market cap (second only to Bitcoin).

Monero (XMR)

Monero is another very interesting implementation of decentralized trust system. One that’s downright scary to most people because it takes anonymity one step further. Unlike Bitcoin, in Monero transactions are untraceable by default. With ring signatures on the input side and stealth addresses on the output side, anonymity of participants is cryptographically guaranteed. In Bitcoin if you can assign identity to certain public address it is possible to follow the trace of transactions. In Monero even if you can somehow establish identity of certain public address (which is very unlikely) the next transaction is a jump to nowhere. Simply there is no way for you to determine with 100% certainty where exactly money went.

While I am huge fan of Monero, I understand why it is scary for majority of people. Simply, it’s impossible to distinguish actors within the system. Let’s say we figure out there are few individuals in Bitcoin eco-system that 99.99% of us agree are doing something despicable. THEORETICALLY we can identify public addresses tied to that 0.01% group, isolate them and prevent their interaction with the rest of the system. It wouldn’t be easy endeavor… but still, it is possible. With Monero there isn’t even theoretical chance of doing this. As long as Monero system exists and there are participants within it, complete anonymity of everyone involved is cryptographically guaranteed. Here is a nice video overview of concepts that make this possible:

Litecoin (LTC)

Litecoin is pretty much Bitcoin with few important distinctions: faster blocks (2.5 instead of 10 minutes) and public leader. Charlie Lee is quite vocal on Twitter. Considering his status as founder, he is able to steer future of Litecoin the way he sees fit. Over past few years that turned out to be quite asset - while Bitcoin civil war unfolded there was zero drama in Litecoin space. Paradoxically, Litecoin today is pretty much currency that both sides in Bitcoin scaling debate wanted - one that effectively uses 4x1MB blocks over 10 minute period and has SegWit support.

BCash (BCH)

OK, OK… Bitcoin Cash. I just had to do it ;). Without going too much into several years worth drama that preceded August 1st fork (I would need separate article for that) let’s get to the main thing - scaling debate. As Bitcoin started exploding in popularity over last few years, and there were more and more transactions in the system, BTC started hitting transaction count wall. When initially designing system Satoshi limited blocks to 1MB. This comes out to about 2000 transactions per 10 minutes. So if you want to support 4000 transactions per 10 minutes, all you need to do is increase block limit to 2MB, right?

Well, that’s exactly how the whole stressful Bitcoin scaling debate started years ago. See, that 1MB block limit is there also as a spam prevention measure. For your transaction to be included in the next block you need to offer attractive fee for miner to include your transaction. If there is no transaction fee, malicious actor could just create huge number of transactions, spam and paralyze Bitcoin network. Then there was also the miner argument - the bigger the blocks, the higher incentive for mining centralization. Bigger blocks take more time to propagate across the network, and Blockchain grows more quickly. Plus of course, we can go on and on about economic theory behind limited Blockchain space and transaction fees.

Eventually, two camps formed:

  1. Group that wanted block size increase as a way to increase transaction count
  2. Group that wanted block size to remain the same for various reasons, and find alternative methods of scaling (namely through SegWit - Segregated Witness)

After several years of ferocious online geek fighting, Group 2 finally prevailed and scheduled SegWit activation for late August 2017. As Group 1 didn’t want SegWit included in Bitcoin they decided to fork the source code. So they’ve built client that excluded SegWit, allowed 8 MB blocks, and introduced few fixes (some of which are pretty sweet). This all culminated on August 1st 14:14 ET, when first BCH block was mined. It contained 6,985 transactions with block size of 1.92 MB. Thus Bitcoin Cash was born.

Now, as someone who has spent most of his life in startups - I very well understand dynamics behind situations like this. Simply, every big project requires people with different mindsets. If you are investor on certain project, even though you and developers working on the project are namely on the same team - you have different mindsets and goals. Great developers want to build great systems. Great investors want to reap great profits. It’s in situations like that that leaders like Steve Jobs make their lasting impressions.

Bitcoin, by design, doesn’t have this. With Satoshi disappearing there is absolutely no central power. Reaching consensus on anything new is extremely hard.

Looking back, I think that BCH fork is probably the best thing that could’ve happened. Those that think bigger blocks are answer for scaling now have their own Coin. Those that reject bigger blocks for whatever reason have their own Coin. And people like me who are OK with both solutions are now free to transact between two Blockchains with previously obtained value, as they see fit.

Other Crypto Currencies

Even though previous paragraphs would make you think otherwise, we’ve only scratched the surface of crypto currencies available today. On any given day there is now over $2+ billion trading volume on various exchanges around the world. Just visit Coinmarketcap.com and see for yourself. If you want my personal recommendation of currencies to look into, I would recommend:

I want to close out this section with a simple message - I invite you to think beyond money. Decentralized trust networks will revolutionize many aspects of our societies. For better or worse, money is just the first of those aspects.

Present

High level technical overview of Bitcoin

Two components are crucial for understanding Bitcoin from technical perspective: Public key cryptography and Blockchain. Let’s look at each of them.

Asymmetric / Public-key cryptography

Public key cryptography is at foundation of Bitcoin technology. For those with absolutely no knowledge of asymmetric cryptography - it’s a scheme where you have set of two related keys: private and public. After you generate set of two keys and release Public key into the wild, you are able to do two great things:

  1. Public key encryption - anyone who wants to communicate with you securely encrypts messages using Public key. These messages can only be decrypted by Private key. Encryption also preserves integrity of encrypted message - it can’t be modified in transport.

  2. Digital signatures - you can prove ownership of Private key without sharing it. Using Private key you encrypt predefined message generating Signature. Now anyone can use your Public key to decrypt Signature and verify it matches predefined message. This proves you do own Private key behind Public key.

Math that enables this magic is quite mind numbing. I recommend this video that presents ECC (which is used in Bitcoin for generating Private and Public key):

In Bitcoin the flow of generation goes: private key -> public key -> wallet address. Math behind process allows us to only go from left to right. Namely, if you have private key you can easily produce public key and wallet address. But you can’t go back - you can’t deduce private key from public key. Same for wallet address, which is generated by Base58Checksum encoding following concatination:

[version byte][Hash160(public key)][Base58 Checksum]

When you have private key (and thus public key and wallet address), you are essentially able to receive and send Bitcoin transactions. Simply, anyone that wants to send you BTC simply needs to know your wallet address. Then, using your private key you are controlling BTC sent to your wallet address and can pass it further to new addresses.

Blockchain

Now, the big problem - double spend. Say you have 1 BTC tied to your wallet address. You decide to be a bad actor and generate two transactions that send the same 1 BTC to two different addresses. Which transaction will be valid?

This is a trivial problem to solve when there is central authority. Transactions are ordered by time, so the first one to arrive will succeed in deducing balance and then second one will be rejected. In decentralized system you can’t rely on time - you somehow need to ensure “correct” state is propagated along all nodes. But how do you decide which state is “correct” when you have two conflicting transactions?

This is the problem that Blockchain solves. In a nutshell, Blockchain is a ledger of Bitcoin transactions that are confirmed as valid. Every 10 minutes (on average) new block is crafted by a miner who is the global winner of hashing lottery. That miner formats the block by:

  1. Picking out as many pending transactions as he can fit in block (1 MB limit, remember?)
    • Miners most will likely choose transactions with biggest transaction fees; they get to keep those for themselves
    • Conflicting transactions are dealt with - in case of double spend only one can be picked to be included in block
    • Invalid transactions are rejected - if there is transaction that tries to spend input already spent for example
  2. Appending special (coinbase) transaction that sends mining reward (currently 12.5 BTC) and transaction fees to a wallet address miner controls
  3. Generating valid header for the block that ensures integrity of block contents and links to previous block

Image 2
Example of block header

After candidate block is formed hashing lottery starts. Proof-of-work algorithm in Bitcoin is double SHA256 hash of block header. Most miners simply change nonce field and perform double SHA256 on header until they produce hash that’s below target difficulty.

Difficulty is determined as number of leading zeros in hash. As an example, here is one of the recent block hashes: 00000000000000000085e7274fe5c9dbeee67128c3e081d12c5f5a151a7769ce. Even with Bitcoin network nearing power of 10,000 trillion hashes / second - it took around 10 minutes for valid block with this hash to be found.

After new block is found, and one of the transactions we mentioned at start of this section is included, race for new block on top of this one begins. Theoretically it possible for double spend attack to go through even if transaction is included in new, top block (1 confirmation). All that needs to happen is that alternative chain, the one that doesn’t include previously confirmed transaction, becomes longest. But this scenario is EXTREMELY unlikely and VERY costly for attacker.

For great video illustration of what I presented here, take a look at YouTube video by CuriousInvetor:

Sending your first BTC transaction with C#

Let’s finally turn all this previous talk into code. Prerequisites for running next few examples are:

  1. Visual Studio (any edition or version)
  2. NBitcoin - great C# Bitcoin library. Author seems to be Legend here on CodeProject, so be sure to check out his article on the NBitcoin library
    -If you want to browse source code you’ll need to download Visual Studio 2017 or Visual Studio Code. Old versions of VS will have trouble opening .csproj files
    -If you don’t care about source code you can simply execute: Install-Package NBitcoin in Package Manager Console

Bitcoin has support for separate TestNet which we will use in our examples. Basically you are free to build and test your Bitcoin related applications on TestNet and then when they are ready you can move them to production by switching few parameters.

For our first example let’s generate Private+Public key pair and appropriate address on TestNet.

C#
public class Example1
{
    public static void Run(string[] args)
    {
        var key = new Key();
        var address = key.PubKey.GetAddress(Network.TestNet);
        Console.WriteLine("Your BTC address: {0}\n\n", address);

        Console.ReadLine(); // wait for user input to proceed
    }
}

As you can see - NBitcoin makes it EXTREMELY easy to get started with Bitcoin coding. Now, let’s build primitive wallet app. On first start we will generate private key. That private key will be encrypted with password and stored on disk to be preserved across restarts. That will enable us one persistent public address we can use to receive funds in future examples.

C#
public class Example2
{
    private const string PRIVATE_KEY_PATH = "secret.key";
    private static readonly Network _network = Network.TestNet;
    public static void Run(string[] args)
    {
        // recover private key if it was saved and encrypted with password
        Key _privateKey = null;
        if (File.Exists(PRIVATE_KEY_PATH))
        {
            var sec = new BitcoinEncryptedSecretNoEC(File.ReadAllBytes(PRIVATE_KEY_PATH), _network);

            do
            {
                var password = ask("Private key password?");
                try
                {
                    _privateKey = sec.GetKey(password);
                    break; // stop while
                }
                catch (SecurityException)
                {
                    Console.WriteLine("Invalid password");
                }
            }
            while (true);
        }
        else
        {
            _privateKey = new Key();
        }

        // Display wallet address for receiving money
        var address = _privateKey.PubKey.GetAddress(_network);
        Console.WriteLine("Your BTC address: {0}\n\n", address);

        Console.ReadLine(); // wait for user input to proceed

        // Save private key to local file that's encrypted with password
        var persPass = ask("If you want to save this private key, enter password");
        if (!String.IsNullOrWhiteSpace(persPass))
        {
            var encKey = _privateKey.GetEncryptedBitcoinSecret(persPass, _network);
            File.WriteAllBytes(PRIVATE_KEY_PATH, encKey.ToBytes());
        }
    }

    private static string ask(string message)
    {
        Console.WriteLine(message);
        return Console.ReadLine();
    }
}

So, now we have our own persistent private, public key pair that’s securely stored on disk (well, depending on password and if somebody is looking at your screen during Console.ReadLine()). Now, let’s receive some funds into that wallet. On TestNet there are faucets that can send you some funds for testing. You can Google for “Bitcoin TestNet faucet”… right now I’m using: https://testnet.manu.backend.hamburg/faucet

After Faucet processes your request and displays notice that funds are sent most likely you will get Bitcoin Test Net Transaction ID. Now, we can use online Blockchain Explorer that supports TestNet to see transaction to our wallet. I recommend BlockCypher’s TestNet Blockchain Explorer. Either Wallet Address or Transaction ID will allow you to get info, like this:

Image 3

So, I have received 1 BTC into my wallet. Now, let’s be a good citizen and send those 1 BTC (minus transaction fees) back to the address we have received them from. In code we need to build transaction that will reference input(s) we have received and then send everything as output back to originating wallet.

C#
public class Example3
{
    private const string PRIVATE_KEY_PATH = "secret.key";
    private const double BTC_AMOUNT_RECEIVED = 1.1;
    private static readonly Network _network = Network.TestNet;
    public static void Run(string[] args)
    {
        // recover private key if it was saved and encrypted with password
        Key _privateKey = null;
        if (File.Exists(PRIVATE_KEY_PATH))
        {
            var sec = new BitcoinEncryptedSecretNoEC(File.ReadAllBytes(PRIVATE_KEY_PATH), _network);

            do
            {
                var password = ask("Private key password?");
                try
                {
                    _privateKey = sec.GetKey(password);
                    break; // stop while
                }
                catch (SecurityException)
                {
                    Console.WriteLine("Invalid password");
                }
            }
            while (true);
        }
        else
        {
            throw new Exception("Run this example after Example2.cs");
        }

        var destAddress = ask("Enter address to which all funds should be sent");
        if (!String.IsNullOrWhiteSpace(destAddress))
        {
            var funding = new Transaction()
            {
                Outputs = { new TxOut(BTC_AMOUNT_RECEIVED.ToString(), _privateKey.GetBitcoinSecret(_network).GetAddress()) }
            };
            Coin[] sendingCoins = funding.Outputs
                .Select((o, i) => new Coin(new OutPoint(funding.GetHash(), i), o))
                .ToArray();

            var dest = _network.CreateBitcoinAddress(destAddress);
            var txBuilder = new TransactionBuilder();
            var tx = txBuilder
                .AddCoins(sendingCoins)
                .AddKeys(_privateKey)
                .Send(dest, (BTC_AMOUNT_RECEIVED - 0.01).ToString())
                .SendFees(0.01.ToString())
                .SetChange(_privateKey.ScriptPubKey)
                .BuildTransaction(true);

            var resTransaction = txBuilder.Verify(tx); //check fully signed
            if (resTransaction)
            {
                Console.WriteLine(tx.ToString());
                Console.ReadLine();
            }
        }
    }

    private static string ask(string message)
    {
        Console.WriteLine(message);
        return Console.ReadLine();
    }
}

This will produce transaction that in JSON format looks similar to:

<code>{
  "hash": "0fc964cdedd26f1598503e9a0677cdad304d68de1f64b0e147bd25c7d99fc55e",
  "ver": 1,
  "vin_sz": 1,
  "vout_sz": 1,
  "lock_time": 0,
  "size": 192,
  "in": [
    {
      "prev_out": {
        "hash": "4644a8ac4531aa82c8de5a555d6ba83671b7f696aea01fd91c283e0829a28b1e",
        "n": 0
      },
      "scriptSig": "30450221008214a424a0488f1c9ac32855f6fa40ea3e88e929a774bff064fdffd221cc3b7b02204a8f2330c9ec5f6562bd132bc06bbf0d563343bae5cd1715d8c296ea29c0775e01 031f7fc0b8de7be2c82164b1f9eafa3cd3af78f284ecadabbdf1bc3959d3259c48"
    }
  ],
  "out": [
    {
      "value": "1.09000000",
      "scriptPubKey": "OP_DUP OP_HASH160 b34fad2260a6fb3e8e6390752de4761a98bdcc6f OP_EQUALVERIFY OP_CHECKSIG"
    }
  ]
}
</code>

In order for this transaction to be propagated, we need to be part of Bitcoin network. Which can be done in two ways:

  1. Participate as full node on Bitcoin peer-to-peer network. This requires that you download full Blockchain in order to verify incoming transactions and fully generate outgoing transactions. Then, when you have full Blockchain (150GB+ at the moment) on your computer, you’ll be able to start establishing network connections with other nodes and participate
  2. Become participant through some of the publicly available APIs. Blockchain.info was my first choice few years ago, but I’ve switched to BlockCypher since.

In this article we’ll proceed with #2 - using BlockCypher to continue. Notice that this introduces Internet connectivity as result. But, considering that you are reading this article on CodeProject I’m sure you’ll prefer transferring MB or two over downloading 150 GB to continue ;). Don’t worry - another library that takes care of most things is ready & waiting.

Bitcoin through BlockCypher API with C#

Boris Scheiman wrote great C# library that works as wrapper for BlockCypher API. Last year I’ve forked it and added few improvements. Unfortunately these changes are still not available in NuGet package. Code examples I’ll use here are based on latest code in repository, so in case you do Install-Package BlockCypher you may be missing some functionality. I’ll contact Boris and see if he can update NuGet, in the meantime know that DLL that comes in examples is built from latest code in repository.

To start you’ll need to go to https://www.blockcypher.com/ and open developer account. Processing HTTP calls costs and the only way you can battle spam is by assigning accounts to requests. When you have token ready you can start issuing API calls and get live stats from Bitcoin network. Let’s open up by something that’s obviously missing in previous examples: checking balance.

C#
class Example4
{
    public static async Task RunAsync(string[] args)
    {
        var privateKey = getPrivateKeyFromDisk();

        var api = new Blockcypher(MySettings.Default.BlockcypherToken, Endpoint.BtcTest3);
        var address = privateKey.PubKey.GetAddress(Network.TestNet).ToString();
        var balance = await api.GetBalanceForAddress(address);

        Console.WriteLine("Balance of {0} is {1} BTC", address, balance.FinalBalance.Btc);
    }
}

Notice the way both libraries work with TestNet. And even though before this moment we had absolutely no connection to Bitcoin network, we were still able to create valid wallet address that received funds. This is how cold storage and paper wallets work - you generate keys completely offline and then just provide wallet address to live Bitcoin network. This concept is used for some really sweet projects like Bitcoin physical coins.

Now, let’s finally generate sending transaction that will return funds to faucet wallet. Blockcypher API and library streamlines transaction sending as much as possible. All you need is:

  1. Private key you’ll use to sign transaction locally
  2. Wallet address tied to your private key from which you are sending
  3. Destination wallet address
  4. Amount (in Satoshis) you want to send. -1 will allow you to send all funds from wallet
C#
class Example5
{
    public static async Task RunAsync(string[] args)
    {
        var privateKey = getPrivateKeyFromDisk();

        var api = new Blockcypher(MySettings.Default.BlockcypherToken, Endpoint.BtcTest3);
        var address = privateKey.PubKey.GetAddress(Network.TestNet).ToString();

        // -1 for satoshi "sweeps" input wallet transfering all BTC into new wallet
        // http://dev.blockcypher.com/#creating-transactions
        var sendingAmt = -1;

        var privateKeyBytes = privateKey.GetBitcoinSecret(Network.TestNet).ToBytes();
        var hexPrivate = Encoders.Hex.EncodeData(privateKeyBytes);

        var taskRes = await api.Send(address, "mws4hQ4dMkvdoXDzHyDTrsXf9ohPwj6J2b", hexPrivate, sendingAmt);
        if (taskRes.IsError)
        {
            foreach (var error in taskRes.Errors)
                Console.WriteLine(error);
        }
        else
        {
            Console.WriteLine("Transaction sent. Hash: {0}", taskRes.Transactions.Hash);
        }
    }
}

And that’s it! BlockCypher library makes creating and sending transactions very easy since it automatically references unspent outputs. Not to mention properly generating transaction and propagating it across the network.

Of course, sending is just one side of equation. Receiving money through some kind of checkout system is what most developers are interested in. So, how would you build a Bitcoin checkout system? Theoretically, it’s quite easy:

  1. You take order details and generate wallet address that’s supposed to receive payment (say 1 BTC). Deterministic wallets are quite useful in this scenario - they allow you to create only 1 private key and derive unlimited number of public keys (and thus wallet addresses).
  2. Display wallet address to customer allowing him to send funds to complete transaction.
  3. Monitor payment wallet address for incoming transaction. As soon as transaction arrives (and is confirmed certain number of times) you can release product customer is purchasing.

In past almost all API providers like BlockCypher and Blockchain.info had this service free of charge. But as you can imagine - as Bitcoin exploded in popularity and Blockchain size grew - it became unprofitable to host and run free checkouts. At the moment I don’t know any API provider that will generate and monitor forwarding addresses for free.

Luckily, another company now provides an easy solution for accepting payments in almost any Crypto Currency.

Coinpayments - accepting Bitcoin (BTC), Litecoin (LTC), Ethereum (ETH) with C#

Disclosure - I did have occasional problems with Coinpayments. After talking with their development team issues were eventually resolved. I do wish they could commit more resources to providing support to developers who wish to integrate with their system. I believe what they offer is valuable service for negligible fee of 0.50% per transaction. Obviously, if I didn’t like their platform I wouldn’t be presenting it here.

I have coded and open sourced library to abstract their API in C#. Which means you’ll pretty much be able to accept payments in few lines of code. Majority of time spent will be on setting up your Coinpayments account and configuring it - currencies you want to accept, location of IPN processor, etc. Let’s follow the steps:

  1. Create account and login to Dashboard
  2. Go to Coin Settings and select crypto currencies you are willing to accept. You can see lots of currencies including Bitcoin (BTC), Litecoin (LTC), Ethereum (ETH) and others. For our example we will use Litecoin TestNet (LTCT).
  3. Go to Account Settings and select tab named “Merchant Settings”. Here you need to:
    -IPN Secret: set it to 20+ length alphanumeric string
    -IPN Verification Method: HMAC
    -IPN URL: this will be URL where Instant Payment Notification (IPN) will be sent when user pays. Make sure your webserver is configured to accept incoming HTTP connections (plus allow port through firewall if needed)
  4. Go to API Keys and generate new key. Then, click on Edit Permissions button. For testing purposes you can allow all permissions. At minimum you will need create_transaction permission to generate wallet address for payment. Read more about all methods in API documentation

Now that you have finished setup process you will need to update variables in CoinpaymentsApi library, namely:

  1. Public Key (from API Keys page)
  2. Private Key (from API Keys page)
  3. Ipn Secret (from Account Settings, Merchant Settings)
  4. Merchant Id (from Account Settings)

Since these variables are in .settings file you can change them across projects so you have support for various environments (development, staging, production). Also, you can copy them into your web.config if you are building ASP.NET website and during automatic build/deployment change them on the fly.

Now, let’s see code that would allow us to generate checkout page for user to send us $10 in LTCT.

C#
protected async void btnBuy_Click(object sender, EventArgs e)
{
    var purchase = await CoinpaymentsApi.CreateTransaction(10, "USD", "LTCT", "peusa@outlook.com");
    Response.Redirect(purchase.Result.StatusUrl);
}

Yeah, believe it or not - two lines. First line initializes transaction for user, passing his email so Coinpayments can also email the payment URL to customer. In second line we redirect customer to payment URL so that he can easily scan QR code and track payment status.

To send payment you can use Litecoin Test Tools. This webpage enables you to send up to 10 LTCT to any wallet you desire, either in one or multiple transactions. Once payment comes in it will be processed by our Instant Payment Notification (IPN) handler:

C#
public class IpnHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        var req = IpnBase.Parse<IpnApi>(context.Request.Form);

        var hmac = context.Request.Headers["HMAC"];
        if (hmac == null || !req.SigIsValid(hmac))
        {
            response(context, HttpStatusCode.BadRequest, "Invalid HMAC / MerchantId");
            return;
        }
        
        if (checkForDuplicate(req))
        {
            response(context, HttpStatusCode.OK, "Duplicate transactions");
            return;
        }

        if (req.SuccessStatusLax() && req.IpnType == "api")
        {
            // TODO: Process payment as needed, release product
        }

        response(context, HttpStatusCode.OK, "1");
    }

    private bool checkForDuplicate(IpnApi req)
    {
        // TODO: Implement check against database if needed
        return false;
    }

    private void response(HttpContext context, HttpStatusCode statusCode, string text)
    {
        context.Response.StatusCode = (int)statusCode;
        context.Response.ContentType = "text/plain";
        context.Response.Write(text);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Note that you may need to setup your IIS / IIS Express to allow outside connections for your website hosting IPN handler. Same for firewall; especially on custom ports if you are using them. Example ASP.NET website that you can run and setup using your own Coinpayments credentials is in code that accompanies this article.

And that’s it! You now have payment gateway that can accept any kind of crypto currency easily.

Future

It is important to note that almost all crypto currencies we have discussed here are open source. So, theoretically, nothing stops you from visiting their respective GitHub repository and joining the development. Practically - we are talking about financial systems that are currently worth more than some of the hottest tech companies. Thus, before spending any time and effort of coding, be sure to reach out to current development team and look through issue tracker.

In my mind, there is no doubt that in future current financial systems will be replaced by something similar to what crypto currencies are doing right now. This change will not be easy, of course. Economic freedom is basis for all other freedoms. I agree, it’s highly unlikely that big governments will just say - sure, we give up control over currencies. But, as with all other advanced technologies, decentralized trust systems will provide immense benefits for countries that focus on them. Japan already overtook United States as #1 Bitcoin exchange market. Russia is looking into modernizing it’s financial systems with Ethereum after being crippled by US led financial sanctions in 2014.

To me, development and adoption of Crypto Currencies will be similar to what happened with the Internet. Some countries have tried to regulate and control Internet. Some outright banned it. As a result they only stifled their own development. In the end innovation and individual freedoms will always prevail.

End of 2017 update

First version of this article went up back in September 2017. Bitcoin price was just bouncing back after retreating from $4500 to $3500. It’s end of December now, and BTC is sitting at $14,500 after healthy pullback from $20,000 levels.

Surprisingly, situation in crypto currency space is the same as it always was. I remember the days when Bitcoin crossed $100 and people were yelling how it’s the biggest scam in history of mankind. Then there were those predicting that after $100 next target is $10,000. To be honest, I’ve always found both camps somewhat “crazy”. I did believe in technology behind Bitcoin (and still do), but as someone well involved in space I also knew too well about numerous problems that are not so public.

Thus this perpetual deja-vu that I seem to be stuck in is very weird. Now that price exploded there are even more people yelling “Monopoly money”! Bulls are countering with predictions of $1,000,000 for 1 BTC. Me personally… I don’t know. I can see both scenarios playing out. Satoshi said it perfectly himself when asked if Bitcoin will be valuable and used:

I’m sure that in 20 years there will either be very large transaction volume or no volume.

Unfortunately, it seems that middle ground will only be reached through extremes. The important thing however is that BTC/USD rate doesn’t matter at this point. Trustless peer to peer networks in which you can reach distributed consensus will be implemented and revolutionize various parts of our society. Before widespread Internet adoption in 1990s, it was ludacris to even think that I could write an article and then share it with thousands around the world without going through vetting process of well established publisher. And even then, my article could only be read by select few who purchased magazine. Then websites like CodeProject happened.

For better or worse, that’s what will now happen with money. Instead of dealing with gatekeepers, you will be free to send “money” to anyone and receive “money” from anyone. No bank accounts, no payment processors… even countries won’t be able to freezing your funds. All with simple private & public key pair. Of course, it’s a question how this newfound freedom will be used. It is understandable that lot of people are scared. My hope is that humanity will handle it in the same manner we’ve handled majority of newfound freedoms.

To illustrate how last year went, here is first screenshot of Coinmarketcap.com on 2016-12-25:

Image 4

Year later, on 2017-12-25, this is what we had:

Image 5

I wish that 2018 for cryptos ends up being like 1998 was to the Internet. Hopefully we still have a year or two before the big crash ;). Nobody likes being part of long recoveries that follow. But regardless of what happens, technology will survive. We will see Blockchain implemented in charities so that donors can transparently see where their money went. We will massive proof of work systems that consume even more electricity than Bitcoin consumes today. Cryptography renaissance will continue and we’ll benefit from it for decades to come.

So if you are a programmer, forget BTC/USD rate and ignore the buzz. Fire up your IDE like those before us fired it up in 1998, 1988, 1978… We still have some coding left to do…

Image 6

Cat tax

Notice of future updates

I plan on updating this article in coming months. It is already pretty big read, so I needed to glance over few parts and exclude some topics.

In the meantime, feel free to comment and ask questions - if I can help with anything, I’ll be glad to do so. And if you can’t reach me here, try LinkedIn… especially if you are doing something interesting in Crypto Currency space.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
If you liked this article, consider reading other articles by me. For republishing article on other websites, please contact me by leaving a comment.

Comments and Discussions

 
QuestionIPN not Working from Coinpayments Side Pin
ravinbhl8-Jun-20 14:49
ravinbhl8-Jun-20 14:49 
Questionhow use that code? Pin
Member 147623189-Apr-20 2:23
Member 147623189-Apr-20 2:23 
QuestionHow to set success_url using this API?? Pin
Member 1075605011-May-18 23:57
Member 1075605011-May-18 23:57 
QuestionHow to return or redirect our custom Thankyou page after payment will be complete?? Pin
Member 1075605011-May-18 19:02
Member 1075605011-May-18 19:02 
QuestionReceiver does not accept that coin Pin
Member 132047986-May-18 11:44
Member 132047986-May-18 11:44 
AnswerRe: Receiver does not accept that coin Pin
Member 107560509-May-18 2:15
Member 107560509-May-18 2:15 
QuestionExcellent Work. You Article is *not* too long Pin
Member 832697029-Apr-18 4:57
Member 832697029-Apr-18 4:57 
GeneralMy vote of 5 Pin
Anton Damhuis3-Jan-18 23:50
Anton Damhuis3-Jan-18 23:50 
GeneralRe: My vote of 5 Pin
lepipele29-Jan-18 18:25
lepipele29-Jan-18 18:25 
QuestionThe born of trusted third parties is inevitable... ? Pin
JH6430-Dec-17 5:31
JH6430-Dec-17 5:31 
AnswerRe: The born of trusted third parties is inevitable... ? Pin
zokocx1-Jan-18 16:48
zokocx1-Jan-18 16:48 
Questionthanks for this project Pin
Member 1359516828-Dec-17 10:36
Member 1359516828-Dec-17 10:36 
PraiseGreat article Pin
Member 1344501625-Dec-17 2:53
Member 1344501625-Dec-17 2:53 
QuestionVote of 5. Please fix all dead links (CTRL + F --> "Video...:" ... yet no link shared) Pin
Member 271004224-Dec-17 5:12
professionalMember 271004224-Dec-17 5:12 
AnswerRe: Vote of 5. Please fix all dead links (CTRL + F --> "Video...:" ... yet no link shared) Pin
lepipele24-Dec-17 8:19
lepipele24-Dec-17 8:19 
GeneralRe: Vote of 5. Please fix all dead links (CTRL + F --> "Video...:" ... yet no link shared) Pin
Curt Huff30-Dec-17 3:12
Curt Huff30-Dec-17 3:12 
GeneralMy vote of 5 Pin
JoshYates198022-Dec-17 10:36
professionalJoshYates198022-Dec-17 10:36 
QuestionNow that's an article! Pin
Chris Maunder22-Dec-17 5:33
cofounderChris Maunder22-Dec-17 5:33 
AnswerRe: Now that's an article! Pin
lepipele24-Dec-17 8:09
lepipele24-Dec-17 8:09 
QuestionAwesome post Pin
Controller Guru21-Dec-17 23:22
Controller Guru21-Dec-17 23:22 
AnswerRe: Awesome post Pin
lepipele24-Dec-17 8:21
lepipele24-Dec-17 8:21 
AnswerRe: Awesome post Pin
Controller Guru7-Jan-18 19:15
Controller Guru7-Jan-18 19:15 
GeneralMy vote of 5 Pin
Robert_Dyball21-Dec-17 10:44
professionalRobert_Dyball21-Dec-17 10:44 
GeneralRe: My vote of 5 Pin
lepipele24-Dec-17 8:21
lepipele24-Dec-17 8:21 
QuestionWebhook And WebSocket Pin
HitJariwala11-Nov-17 18:22
HitJariwala11-Nov-17 18:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.