Skip to content

Instantly share code, notes, and snippets.

@jv-amorim
Last active April 26, 2020 20:35
Show Gist options
  • Save jv-amorim/9869a9ff89e0f5b69def6fd80adb2f09 to your computer and use it in GitHub Desktop.
Save jv-amorim/9869a9ff89e0f5b69def6fd80adb2f09 to your computer and use it in GitHub Desktop.
These notes are about my that is on Github.

📌️ Blockchain in C# - Basic Concepts

Content:

  • Private Key;
  • Public Key;
  • Networks;
  • PubKey hash;
  • ScriptPubKey;
  • Transactions.

Notes:

  • These notes are about my Blockchain project that is on Github.
  • In this file, the codes samples are written in C#, using the NBitcoin and QBitNinja.Client libraries.
  • These notes were taken from the book "Programming the Blockchain in C#", available for free at this link.

🔑️ Private Key:

Your wallet software uses a private key to spend the money you received on this address. The keys are not stored on the network and they can be generated without access to the Internet.

Key privateKey = new Key(); // Generate a random private key.


🗝️ Public Key:

From the private key, we use a one-way cryptographic function, to generate a public key.

PubKey publicKey = privateKey.PubKey;


🔌️ Networks:

TestNet is a Bitcoin network for development purposes. Bitcoins on this network worth nothing. MainNet is the Bitcoin network everybody uses. You can acquire testnet coins quickly by using faucets, just google "get testnet bitcoins".


🏷️ Bitcoin Address:

Bitcoin Address is what you share to the world to get paid. You can easily get your bitcoin address from your public key and the network on which this address should be used.

Console.WriteLine(publicKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main));
Console.WriteLine(publicKey.GetAddress(ScriptPubKeyType.Legacy, Network.TestNet));

🛅️ PubKey hash:

To be precise, a bitcoin address is made up of a version byte (which is different on both networks) and your public key’s hash bytes. Both of these bytes are concatenated and then encoded into a Base58Check.

The Base58Check encoding has some neat features, such as checksums to prevent typos and a lack of ambiguous characters such as '0' and 'O'. The Base58Check encoding also provides a consistent way to determine the network of a given address; preventing a wallet from sending MainNet coins to a TestNet address.

var publicKeyHash = publicKey.Hash;
var mainNetAddress = publicKeyHash.GetAddress(ScriptPubKeyType.Legacy, Network.Main);
var testNetAddress = publicKeyHash.GetAddress(ScriptPubKeyType.Legacy, Network.TestNet);

📄️ ScriptPubKey:

Internally, the Bitcoin protocol identifies the recipient of Bitcoin by a ScriptPubKey (a Bitcoin Address is only a user interface concept). The ScriptPubKey is a short script that explains what conditions must be met to claim ownership of bitcoins. I may look like this:

OP_DUP OP_HASH160 14836dbe7f38c5ac3d49e8d790af808a4ee9edcf OP_EQUALVERIFY OP_CHECKSIG

We are able to generate the ScriptPubKey from the Bitcoin Address. This is a step that all bitcoin clients do to translate the “human friendly” Bitcoin Address to the Blockchain readable address.

Public Key -> PubKey hash

Pubkey hash + Network -> Bitcoin Address

Bitcoin Address -> ScriptPubKey
var publicKeyHash = new KeyId("14836dbe7f38c5ac3d49e8d790af808a4ee9edcf");
var testNetAddress = publicKeyHash.GetAddress(ScriptPubKeyType.Legacy, Network.TestNet);
var mainNetAddress = publicKeyHash.GetAddress(ScriptPubKeyType.Legacy, Network.Main);
Console.WriteLine(mainNetAddress.ScriptPubKey);
Console.WriteLine(testNetAddress.ScriptPubKey);

We can generate a bitcoin address from the ScriptPubKey and the network identifier. It is also possible to retrieve the hash from the ScriptPubKey and generate a Bitcoin Address from it.

var paymentScript = publicKeyHash.ScriptPubKey;
var sameMainNetAddress = paymentScript.GetDestinationAddress(Network.Main);
var samePublicKeyHash = (KeyId) paymentScript.GetDestination();
var sameMainNetAddress2 = new BitcoinPubKeyAddress(samePublicKeyHash, Network.Main);

🔑️ More about Private Key:

Private keys are often represented in Base58Check called a Bitcoin Secret (also known as Wallet Import Format or simply WIF), like Bitcoin Addresses.

Key privateKey = new Key();
BitcoinSecret mainNetPrivateKey = privateKey.GetBitcoinSecret(ScriptPubKeyType.Legacy, Network.Main);
BitcoinSecret testNetPrivateKey = privateKey.GetBitcoinSecret(ScriptPubKeyType.Legacy, Network.TestNet);

Note that it is easy to go from BitcoinSecret to private Key. On the other hand, it is impossible to go from a Bitcoin Address to Public Key because the Bitcoin Address contains a hash of the Public Key, not the Public Key itself.


💱️ Transactions:

Transactions are the most important part of the bitcoin system. Everything else in bitcoin is designed to ensure that transactions can be created, propagated on the network, validated, and finally added to the global ledger of transactions (the blockchain). Transactions are data structures that encode the transfer of value between participants in the bitcoin system. Each transaction is a public entry in bitcoin’s blockchain, the global double-entry bookkeeping ledger.

A transaction may have no recipient, or it may have several. The same can be said for senders! On the Blockchain, the sender and recipient are always abstracted with a ScriptPubKey. We can get transaction data from Blockchain.info. The data can be parsed with NBitcoin using:

Transaction tx = Transaction.Parse(<transaction raw bytes>, Network.Main);

But for development, this data can be parsed with QBitNinja.Client. For more content about transactions, read the book and the code in my Github project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment