My Blockchain in Go

My Blockchain in GoMauricio M.

RibeiroBlockedUnblockFollowFollowingMay 16TL;DR;This post is a personal note to explain how I implemented the same blockchain of previous post in Golang.

Nevertheless, it can be used by other people who wants to get more knowledge about developing a blockchain in Go.

My blockchain in PythonTL;DR;medium.

comThe structure of this story follows exactly the one I posted just above.

The difference is in the details of each language and on the app structure (which does not differ so much by the way).

The source codes from both the server and the client sides can be found at the Conclusion section.

It is available for all those who wants to fork/improve it.

SummaryThis post is organized in the following sections:Installing dependenciesThe application to be developed hereApp structureStructure of the blockchainInitialization of the applicationRoutingGet BlockchainRegister a bet in the blockchainMining a blockRegister nodes of the network and the consensus logicCheck the bets of a player or a matchClient Test applicationConclusionInstalling dependenciesIn order to make this work, we need to install:GoGorilla Mux libraryAnd we have to set the GOPATH variable.

I also suggest to place all the app structure inside the %GOPATH%/src folder (or $GOPATH/src if you are not on Windows).

The application to be developed hereLike in the previous post of my blockchain in Python; a group of people decide to organize a competition of football match betting.

Each player will make their bets on the matches Portugal vs.

Switzerland; and Netherlands vs.

England, valid for the semi-finals of Europe Nations League.

As they do not know themselves very much, they prefer to go for a Blockchain application to register their bets, and like this there will no be no doubts whatsoever about cheating or somebody changing their results randomly.

All bets are treated like a transaction and are properly registered in a chain that is shared among all players.

Each person has their own copy of all the bets.

So, let’s start the implementation of this Blockchain!App structureThe structure of our application is a bit more complex than the Python version.

This is the directory structure that must be under the $GOPATH folder.

src|–BlockchainBetSportGolang|–|– bet|–| |– controller.

go (where we are going to place the handlers)|–| |– model.

go (the representation of the objects)|–| |– blockchain.

go (the blockchain business logic)|–| |– router.

go (the routes definition)|–|– logger|–| |– logger.

go|–|– main.

goMost of the structure and the logic of this application is based on the API that I developed here:A fullstack epic part I — a REST API in Go accessing Mongo DBDeveloping the the backend side of a dummy appmedium.

comStructure of the blockchainEach block of our chain will have the following information:the index of the block: an incremental integera timestamp corresponding to the creation date/time of the blocka collection of bets (more details below in this same section)the nonce used to mine the block (more details in the “Mining a block” section)the hash of the blockthe hash of the previous blockStructure of a blockWhen creating our Go struct, we put the name and the type of the variable, and on the right we give the name that is going to be sent by the API whenever bet information is sent to any application that calls it.

Each bet in the block contains:the name of the player (the person who is betting)the id of the matchthe score given by the player to both teamsStructure of a betInitialization of the applicationIn main.

go:App initialization in main.

goWhen a user launches the application, typinggo run main.

go 9000the main() method is executed; and this is what happens there:the address variable is set to the value input by the user (9000)the routers are initialized (more details in the following sections)the headers are initialized (accepting calls from any origin and working with GET and POST requests)the app starts listening to the port defined in the address variable (9000)RoutingAs we have seen previously, one of the steps during the initialization of the application is the creation of the routes to be called by the client.

In our logic, the router.

go file contains the definitions of the routes, and the corresponding functions of controller.

go that are called by them.

This is the code of router.

go:router.

go: definition of the routes and their creationThe function called by main.

go — NewRouter — gets the address of the node (the address variable read in main), sets it to the current URL.

In this case, when the user typedgo run main.

go 9000The server application will run in this URL: http://localhost:9000And finally, we have a loop in the routes array, setting the routes of our server application.

This is done via the Gorilla Mux package.

Last but not least, it calls the CreateNewBlock function from the blockchain in order to create the Genesis block (line 108 on the code above).

More details about blocks creation later.

controller.

blockchain.

CreateNewBlock(100, "0", "0")Get the blockchainThe basic function to test all our functionalities is to get the blockchain.

Basically, we need to set:a route to be called by client in router.

goa function to respond to this route in controller.

go.

This function will return the pointer to the blockchain variable marshalled in JSON format to the client:Test itWe can quickly test it via Postman.

This is how the request and response will look like:Register a bet in the blockchainNow we are going to start registering the bets in the blockchain.

We are going to implement it in three steps:add the routes to the routes configuration, in router.

go:RegisterAndBroadcastBet: the route to be called by the client, which will register the bet in current blockchain; and send it to all nodes in the networkRegisterBet: the route to be called by the server after registering the bet in its blockchain to register the bet in the other nodes of the networkfor each one of these routes, we create a function to respond to them in controller.

go.

These functions will call the register bet function in blockchain:Notes:the function MakeCall is a general function to make calls to other nodes.

It is going to be used every time we need to synchronize information among all nodes in the networkthe function MakePostCall just invokes MakeCall to make POST requests to other nodesFinally, the implementation of the bet registering inside blockchain.

goTest itIn order to test it, we can try to register a bet and then call the get blockchain logic to check the registered bet in the pending_bets array.

Registering the bet of player “john” on the match “NlEn” (Netherlands vs.

England).

He bets England is going to win 2–1; so the score of team one (Netherlands) will be set to 1; and the score of team two (England) will be set to 2Posting to http://localhost:9000/bet/broadcast to test the bet registrationChecking the pending betNext, we are going to see how to mine and create a block containing all the pending bets.

Mining a blockIn blockchain, in order to create a block to be registered in the chain, a node needs to pass a proof of work test.

It consists of finding a nonce (an integer in our case) that, combined with all the other data in the block, will return a hash code which begins with “0000”.

The first step to accomplish this is to develop the proof of work calculation, in blockchain.

go:The idea is simple: increment the nonce until the SHA256 hash of the block data returns a string starting with “0000”With this in place, we can move to the mining logic.

As usual, we are going to:add the /mine router to the list of routes in router.

go, linking to Mine function in controller.

go:/mine route added to routes configurationimplement the Mine function in controller.

go.

This function is going to:get the last block from the blockchain (calling the GetLastBlock method)marshal the current block dataencode it to stringcall the ProofOfWork function (showed above) to find the nonce of the blockwith this nonce, retrieve the block hash to attach to the block to be created (calling the HashBlock method)with this nonce, create a new block to be added to the chain (calling the CreateNewBlock method)convert this new block into JSON and send it to the other nodes (via making a POST call to /receive-new-block on each node of the network), so that they can also add this block to their chainMining logic in controller.

goThe last step is to develop the response to /receive-new-block in the nodes that will receive the mined blockadd the /receive-new-block to the routes array in router.

gocreate the ReceiveNewBlock in controller.

go, which will respond to this route:This function will:unmarshall the block that is in JSON formatcheck the block hash (calling the CheckNewBlockHash of blockchain.

go)if the block is accepted, add it to the chainLast but not least, we have to implement the CheckNewBlockHash function in blockchain.

go:Logically, here we compare the new block’s previous block hash with the hash of the last block contained in the node’s chain, as well as the indexes.

Test itWe can test the mining logic by:Registering a bet (like in the previous section)Calling the /mine endpoint (it may take a little time)Test of mining logicThen, we call the get blockchain logic so that we can see that the “pending” bet now is an “official” bet present in a block.

Besides this, we can see that the pending_bets array is now empty.

You can see also that the hash of the block starts with “0000”:The blockchain now has a new block with the registered betBut … how do we do to synchronize all nodes and find a consensus if two or more of them have different versions of the chain?Register nodes of the network and the consensus logicLet us suppose we have two nodes, node_1 running in http://localhost:9000go run main.

go 9000and node_2 running in http://localhost:9001go run main.

go 9001And each one of them has a different chain registered.

How to synchronize their chains into only one?The first part is that we need to register node_2 into the network of node_1.

node_2 will have to call the /register-and-broadcast-node endpoint of node_1.

To do this, we do a POST call toPOST http://localhost:9000/register-and-broadcast-nodepassing in its body the node to be registered, in JSON format, like this:{ "newnodeurl": "http://localhost:9001" }Please note: newnodeurl must be between quotes, differently from the Python versionAgain, we follow the same steps:in router.

go, add the following routes to the list:/register-and-broadcast-node to be called every time a new node has to be added to the network/register-node to be called on each node already present in the network to also add the newly added node/register-nodes-bulk that will pass all the current nodes of the network to the new node, so they it will also have them in its internal list of nodesRegister nodes routingin controller.

go, we develop the function that will answer to each route:First: RegisterAndBroadcastNode, which answers to /register-and-broadcast-nodeFunction that responds to /register-and-broadcast-nodeSecond: RegisterNode, which answers to /register-nodeFunction that responds to /register-nodeThird: RegisterNodesBulk, which answers to /register-nodes-bulkFunction that responds to /register-nodes-bulkBut… what if node_2 had already a chain that is slightly different from the one of the network of node_1?.We need to find a consensus so that both nodes — and then all the network — have the same chains, with the same bets.

Here, we are going to use a very simple solution to find a consensus: the network which contains the longest chain keeps it, forcing the other to drop its chain and get the new one.

This is how we are going to develop the /consensus endpointadding the route in router.

go:adding the function Consensus in controller.

go:when a consensus is found, we need to see if the new chain (if the chain is changed) is valid.

We do this with the ChainIsValid function in blockchain.

go:For each in the block in the chain, we check if the hashes generated with their nonces correspond, and if the previous block hash is indeed equal to the hash of the previous block.

Test itSupposing we have our node_1 running in port 9000 with the block of player “john” created in the previous sections in its chain.

We start node_2 in port 9001 with an empty chain.

Get blockchain of node 1Get blockchain of node 2Register node 2 into the network of node 1Calling consensus logic in node 2 (chain is replaced)Check that blockchain of node 2 is really changed, and network_nodes array contains node 1:Check that blockchain of node 1 remains the same, and network_nodes array contains node 2Great!.Blockchains in both nodes are equal, and network is synchronized.

Check the bets of a player or a matchIn the last part of the server code, we are going to see how to retrieve all bets linked to a player or to a match in special.

We go to the same steps as before:adding the routes in router.

go:adding the corresponding functions to controller.

go:Like this, any calls to the endpoint /match/NlEn will call the function GetBetsForMatch passing “NlEn” in the variable “matchId”.

Likewise, any calls to endpoint /player/john will call the function GetBetsForPlayer passing “john” in the variable “playerName”.

adding the business logic functions in blockchain.

go, in charge of searching for the bets in the chain:Test itAfter registering the bet of player John, and mining the block (remember: we are looking for official, and not pending, bets), we can call http://localhost:9000/player/john to retrieve the bet that John did for the match Netherlands vs.

England:Also, we can call http://localhost:9000/match/NlEn to retrieve all bets done for the match Netherlands vs.

England:Client test applicationBesides the steps that I described in the previous sections, another way for you to test this application is by using a very simple client app that registers and sends bets to the Blockchain.

It is downloadable from the link below:morris-ribs/sportprogsExtremely simple UI for sport prognostics .

Contribute to morris-ribs/sportprogs development by creating an account on…github.

comTo run it, open a terminal, browse to the path of the downloaded solution, and run the following instruction.

$ npm i && npm startThis will automatically open the test page.

Once the page is open, type the name of the player and the scores of the two matches and hit the “Send Bets” button.

Once the bets are sent, you can use Postman to check that the bet is well registered in the pending_bets array.

Then, we call the mine function:And finally, we can see that the block with the two bets of player Jane are registered:In the client app, just call http://localhost:3000/player/jane:Display of page http://localhost/player/janeConclusionThis is the Golang version of the bets blockchain that I implemented firstly in Python.

The complete solution is on the link below:morris-ribs/BlockchainBetSportGolangA blockchain implementation in Golang.

Contribute to morris-ribs/BlockchainBetSportGolang development by creating an…github.

comDo not hesitate in forking and improving the solution if you want to.

 ;)Some sources (don’t hesitate in sending me more!)A fullstack epic part I — a REST API in Go accessing Mongo DBDeveloping the the backend side of a dummy appmedium.

comWTF is The Blockchain?The ultimate 3500-word guide in plain English to understand Blockchain.

hackernoon.

comBlockchain And Entertprises — A Match Made In HeavenAs the world becomes increasingly digital, do not be surprised when you see more and more businesses upgrade their…hackernoon.

com.

. More details

Leave a Reply