Creating Simple Cryptocurrency using .NET and C# — Part 3. Wallet
In my first post, we learned about the basic blockchain, that each block has a hash, previous hash, height, timestamp, and transaction. In the second post, I added a database to the blockchain, the blockchain must have a database to store all blocks permanently.
In the two previous articles, I used the name as the identity of each account, this is just for easy understanding. Real cryptocurrencies such as bitcoin and others, use private keys, public keys, and addresses as identity or proof of ownership.
Now, in this post, I am going to integrate private keys, public keys, and addresses into our beautiful simple crypto project. To implement that I will create a Wallet.
To find out what I am working on in this post, here is an outline:
- Overview of Asymmetric Cryptography
- Creating a Service using gRPC
- Creating a Wallet
- Creating a Transaction Signature
- Verify Signature
- Create ICO Transactions
- Block Creation Schedule
- Create Block Explorer
- Video Tutorial
- Source code
Overview of Asymmetric Cryptography
Public-key cryptography, or asymmetric cryptography, is a cryptographic system which uses pairs of keys: public keys (which may be known to others), and private keys (which may never be known by any except the owner). The generation of such key pairs depends on cryptographic algorithms which are based on mathematical problems termed one-way functions. Effective security requires keeping the private key private; the public key can be openly distributed without compromising security.
You may have a question, how do you prove that blockchain transactions are yours? the answer is the signature. In the cryptocurrency world, asymmetric cryptography is used to make signatures of messages (transactions) that are sent from the wallet to the server (blockchain node) and verify that the messages were sent by the original sender.
Creating Services using gRPC
Wallet and Blockchain use client-server model, where the wallet is the client and the blockchain node is the server.
We need a way to request and send data to the blockchain node. We can use REST-API, JSON-RPC, gRPC, or other techniques. For this post I use gRPC. You can read more about gRPC on the official website grpc.io.
How to implement gRPC in .NET Project? Here are the steps:
- Adding several dependency packages.
- Creating a .proto file.
- Compiling the .proto file.
- Creating a service class.
- Adding services to Startup class.
Let’s do it one by one.
Adding several dependency packages.
To work with gRPC we need to install several packages on UbudKusCoin.csproj such as:
Project dependencies will look like this:
Creating a .proto File
The gRPC uses a .proto file to define its services. Open the project and create a folder example Grpc/protos and inside it create a file bchain. proto.
On bchain.proto, we define the services that we will provide for the wallet: SendCoin, GetBalance, GetTransactions.
Compiling the .proto file
After creating the proto file above, we must compile it, so it produces some classes that we need when working with the gRPC framework. Compiling bchain.proto is easy, just right-click the project name and build the project.
You can see the results inside folder obj/Debug/net5.0/Grpc/Protos, there are two files there: Bchain.cs and BchainGrpc.cs.
Creating a service class
To serve and respond to the request we need to make a service class. Let’s create a class BlockchainService and put it in Grpc/services folder.
Adding services to Startup.cs
We need to register the BlockchainService to Startup.cs, so that the service will be activated when the main program is run.
Until here we have done making gRPC service. We need to do some refactoring. If you remember in part 2 of my post, I created the menu class, we no longer need that, so delete it and modify the main method in Program.cs, and add this method.
Creating a Wallet
Blockchain wallets are digital wallets that allow users to store and manage their crypto. The wallet is a user interface that allows users to interact with a cryptocurrency node.
There are many kinds of cryptocurrency wallets:
In this post, I will create a desktop wallet and I will create it with the console application. The wallet user interface design is as shown below.
To implement this wallet there are several steps.
- Create Project ConsoleWallet.
- Copy .proto file and compile it
- Create Code for UI.
- Create Public Key, Private Key, and Address
- Accessing Services.
Create ConsoleWallet Project
Let’s create a new project and give it the name ConsoleWallet.The project structure will look like this:
Add several packages to the project: Grpc.Net.Client, Grpc.Net.Client.Web, Google.Protobuf, Grpc.Tools and starkbank-ecdsa. The last package is for creating public and private keys.
Copy .proto file and Compile.
When creating the gRPC service we created a bchain.proto file, now copy it to the ConsolleWallet project, and put it in the Grpc folder. For more details, see the project structure above. Compiling .proto files is easy, just recreate the project.
Create Code for UI
This is a piece of code for creating the wallet user interface. If you look at the part of the code, there are two conditions here: either an account has been created or an account has not been created.
If an account is created or restored then the Account address will be displayed and there are more menu options. If the account has not been created, an option will appear: create a new account or restore an account.
The complete source code for this user interface can be found at file ConsoleWallet.cs.
Create Private Key, Public Key, and Address
As I wrote above, that cryptocurrencies use key pairs, private keys, and public keys as identity, it is showtime, how to implement Asymmetric Cryptography in a wallet.
Let’s create an Account class. This account class has some properties and method: PubKey, PrivKey, SecretNumber, GetAddress(), CreateSignature(), GetPubKeyHex(). To create the Key pair we need starkbank-ecdsa package, please add it to the ConsoleWallet project.
Here are the code snippets for the key pairs:
// create new private key
var PrivKey = new PrivateKey();// secreet number from private key
var SecretNumber = PrivKey.secret;// get public key from private key
var PubKey = PrivKey.publicKey();// restore private key from secreet number
var PrivKey = new PrivateKey("secp256k1", BigInteger.Parse(screet));
How about the Address? Most cryptos generate addresses from Public Key in different ways, but most of them will use the hash function to generate addresses. Here I create a simple method to generate the address.
// take hash of public key
var hash = SHA256.Create().ComputeHash(PubKey.toString());// convert to string
var strBase64 = Convert.ToBase64String(hash);// add string with prefix "UKC_" (for UbudKusCoin)
var address = "UKC_" + strBase64;
Finally, here is the source code for the Account class:
Modify Main Program
The wallet will be getting and sending data from/to the blockchain server using the gRPC service. We define the server Address of the blockchain server and make a channel.
var serverAddress = "https://localhost:5002";GrpcChannel channel = GrpcChannel.ForAddress(serverAddress);BChainServiceClient bcservice = new BChainServiceClient(channel);
Before a transaction is sent from the wallet to the node, the wallet will generate the signature of the transactions. The signature together with the public key and transactions will be submitted to the server (node). You can find the code that makes the signature in the Account class inside the ConsoleWallet project.
When a blockchain node receives a transaction from the wallet, it will verify whether the transaction was sent by the original sender. To verify a transaction you need a public key, a signature, and the transaction itself.
You can find the code inside the Transaction class, inside UbudKusCoin project.
Create ICO Transactions
ICO stands for Initial Coin Offering. This is a way to raise capital for all kinds of blockchain-related projects by selling cryptocurrency. In Proof of Stake, to make their initial coins, they do ICO. Users who buy coins during the ICO are entered into the blockchain database.
In simple terms, it can be said that we are creating initial accounts that will have all the coins.
Let’s create two initial accounts that each have 4.000.000 and 2.000.000 coins. How do I generate the address? To generate address run Wallet app and create a new account and then copy its address to IcoBalance class.
In Transaction.cs class creates a method to create an initial transaction.
Block Creation Schedule
On the blockchain, a block is created by a node at certain time intervals, for example, every 30 seconds, every 1 minute. The nodes (the public key that embedded in the node) that make up the block are selected through a consensus such as PoW, PoS.
In this post, I will simplify block creation with the scheduler and set a block every 30 seconds. Of course, you can change the interval as you wish.
Please add Coravel to the UbudKusCoin project, and then create BlockJob class.
using Main;namespace UbudKusCoin.Sceduler
public class BlockJob : IInvocable
public Task Invoke()
Inside Blockchain. cs, add a method to select BuildNewBlock().
Now make the job executed every thirty seconds, to do that set it in the main method inside program.cs
Create Block Explorer
I created a block explorer here as a tool to help check the blocks created on the blockchain. Creating Block Explorer uses the same steps as when creating a wallet. I will not explain how to make it in this post. You can view the source code on GitHub, clone it and then run it.
This video will guide you on how to use UbudKusCoin Part3. First, open the project solution in a Visual Studio, and then open each project into a terminal and start each project with command: dotnet run.
Cryptocurrencies use pairs of public keys and private keys as proof of ownership which are created using Asymmetric Cryptography.
The wallet will make a signature for each transaction then together with the public key and the transaction itself will be sent to the blockchain server.
The node will verify the signature of the received transaction.
Between wallets and blockchain nodes, exchange data using services created with gRPC.
What is next
In the next post, I will write about block headers. The block header is an important part when generating block hashes, which is the fingerprint or unique identity of a block.
Thank you for reading my post. If this post is helpful please give me a bunch of claps.
Source code for this post is here: https://github.com/jhonkus/UbudKusCoin/tree/part3_wallet_and_grpc