Rici's Coding Soup. 🍜

# Building a Blockchain in Swift (Part. 2)

Exploring the nonce and playing with the mining service.

### The nonce

Now that we have our blockchain settled and we know how the blocks and transactions work, let’s take a look at the mining mechanism.

In our payload, we can’t really change a thing. We should maintain the block integrity, so it should be added to the chain verbatim. So what can we add to block's structure that can be tweaked for this sake?

Introducing the nonce.

This value is just a random number whose only purpose here is helping us find the "perfect" hash. The way we use it is to incrementing its value.

### Mining

In a live blockchain, this algorithm isn’t part of the software. We are just putting it here for the experiment. This is the node's duty (and where all the gold relies), so it uses its own tailor-made solution.

```.css-dybovu{background-color:rgba(107,70,193,0.2);border:none;color:var(--theme-ui-colors-gray-2);cursor:pointer;font-size:14px;font-family:"IBM Plex Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";letter-spacing:0.025rem;-webkit-transition:default;transition:default;position:absolute;top:0;right:0;z-index:1;border-radius:0 0 0 0.25rem;padding:0.25rem 0.6rem;}@media screen and (min-width: 640px){.css-dybovu{font-size:14px;}}@media screen and (min-width: 768px){.css-dybovu{font-size:16px;}}.css-dybovu[disabled]{cursor:not-allowed;}.css-dybovu:not([disabled]):hover{background-color:var(--theme-ui-colors-primary);color:var(--theme-ui-colors-white);}```1final class MiningService {2  3  // 1.4  private let blockchainDifficulty: String5  6  init(difficulty: String) {7    blockchainDifficulty = difficulty8  }9  10  // 2.11  func mineBlock(previousBlock: Block, transactions: [Transaction]) -> Block {12    13    let nextHeight = previousBlock.height + 114    print("⛏ Start mining block at height \(nextHeight)...")15    16    // 3. 17    let block = Block(height: nextHeight, previousHash: previousBlock.hash)18    transactions.forEach { block.add(transaction: \$0) }19    20    // 4.21    let hash = generateHash(for: block)22    block.hash = hash23    24    return block25  }26  27  // 5.28  func generateHash(for block: Block) -> String {29    30    print("🔑 Finding the hash for block at height \(block.height)...")31    var hash = block.key.toSHA1()32    33    // 6.34    while !hash.hasPrefix(blockchainDifficulty) {35      block.incrementNonce()36      hash = block.key.toSHA1()37      print(hash)38    }39
40    print("🙌 Hash found! - \(hash)")41    return hash42  }43}``````

Wow, hold on! We have too much going on there. Let’s break it down:

1. We create the service defining the blockchain difficulty we’ll be working in. This is the amount of zeroes we’ll need to find in a hash prefix so it can be accepted by the blockchain.
2. We set a `mineBlock()` method that will take the previous block and a set of transactions we want to register and then return the recently minted block.
3. We create an instance of the next block, and then add the transactions to it.
4. Then we need to generate the hash for this block. This will require some work from the node. Once it’s done, we return the block.
5. The way we find the hash for the block is first to execute our SHA-1 function in the block key; and
6. We loop over the hash value, incrementing the nonce, until we find a value that gives us a hash which is prefixed with the number of zeroes the blockchain requires.

P.S.: In this implementation I’m using a custom SHA-1 method which you can find here

You see, you don’t have any guarantee that the `nonce` you're using next is the right one, so there's no other way apart from trial and error, to find this value.

This is a very simple way to implement a proof-of-work consensus, but not so efficient. So feel free to explore other ways to implement yours!

The beauty behind this is that it adds entropy to this problem. It’s a fair play for all nodes in the network. Whichever node finds the hash first can mine the block.

### Putting all the pieces together

Now we have enough to try to create our own blockchain. This is how we can use it:

``````1// Exercise1.swift2
3// Creates the Mining Service4let miningService = MiningService(difficulty: "00") // starting with just 2 zeroes5
6// Generates Genesis Block7let genesisBlock = Block(height: 0, previousHash: "0000000000000000000000000000000000000000") // 40 zeroes8
9// Tries to find the hash for the genesis block10genesisBlock.hash = miningService.generateHash(for: genesisBlock)11// Once it finds the hash, create the Blockchain12do {13  let blockchain = try Blockchain(genesisBlock: genesisBlock)14  print("Blockchain is ready! 🎉")15} catch let _ {16  print("🚫 Oh-oh! The block hash isn't valid.")17}``````

If you execute the code above (you can use a Swift Playground for it), you should get some output similar to this one in your console:

``````1🔑 Searching the hash for block at height 0...21CA360046CDE59C93CDAE5EC5A1A2DC7495D4A583E42D0BBF1E810538CBDCE382C040B599A2DDADEE4D4D96B51564127AE292448F75603F347C5B6894757BAC36206D7C747879F765547E7B2A2F35DC50946
7....8
95AC1DF0C735FF12CA81623D5BCA5DA56553061B610556A5A8BA5B8EC0167B35D782F10A22A1D99766111D0E0A2882B36B08196A0CC291532D8F213898B7812006809C305F6F9790890E6D7C7319817F15FCEE013🙌 Hash found! - 006809C305F6F9790890E6D7C7319817F15FCEE014Blockchain is ready! 🎉``````

My machine needed to run the function 218 times to find a hash for the genesis block! Picture how many times it would take to find a block with today’s difficulty! 😬

Now you have a blockchain you can push transactions to! Let’s try to transfer some value to people:

``````1// (Assumes the Exercise1.swift preceds)2
3// Creates a new block4let transaction = Transaction(sender: "Felipe", receiver: "Tim Cook", amount: 100)5
6let newBlock = miningService.mineBlock(previousBlock: genesisBlock, transactions: [transaction])7
8do {9  try blockchain.add(block: newBlock)10} catch let _ {11  print("🚫 Oh-oh! The block hash isn't valid.")12}``````

In your console, you should get something like this:

``````1⛏ Starting to mine the block at height 1...2🔑 Searching the hash for block at height 1...3C84DA890248ED95DF39E7AD15CACE49EA57BD6A44B75FE89D8125D91B6EA7B836F5C1765737741F8E58D12099BE01B765E0EA1F2675525EEA216448E946E2DD2E47050DFB75C1217216EBB85E1D99A359357
8...9
10C94DB820D09643D478229EA142EC0B4819503CBD1148EAA579E1E8BA192D9F2748B30989FCE7F745C81243146E96DDBBC7201A1BCC9CA4C5EF588FA0219D1300B33255769C3A5CD38E757D2C31E8CF2ACDF3C214🙌 Hash found! - 00B33255769C3A5CD38E757D2C31E8CF2ACDF3C2``````

This time the function ran for 116 times!

And that’s how your blockchain should look when printed as a JSON object:

``1{2  "blocks": [3    {4      "nonce": 218,5      "previousHash": "0000000000000000000000000000000000000000",6      "hash": "006809C305F6F9790890E6D7C7319817F15FCEE0",7      "transactions": [],8      "height": 09    },10    {11      "nonce": 116,12      "previousHash": "006809C305F6F9790890E6D7C7319817F15FCEE0",13      "hash": "00B33255769C3A5CD38E757D2C31E8CF2ACDF3C2",14      "transactions": [15        {16          "sender": "Felipe",17          "receiver": "Tim Cook",18          "amount": 10019        }20      ],21      "height": 122    }23  ]24}``

### Wrapping up

We’ve just written our first blockchain in Swift! 🍾

As I’ve mentioned earlier, we aren’t using the most efficient algorithm to find the hash, but that’s a great start. There's a long discussion about how sustainable the proof-of-work protocol is as well, as it demands too much energy.

That isn’t the only way to achieve consensus, though. Most advanced blockchains nowadays use protocols such as proof-of-stake (e.g. Ethereum 2.0 and Cardano), but there are many others, such as proof-of-authority, proof-of-capacity, etc.