Introduction

Blockchain is one of the most revolutionary technologies of the 21st century and is still evolving, with much of its potential yet to be fully realized. At its core, a blockchain is just a distributed database. But what makes it unique is that it is not a private database, but a public one, meaning that everyone who uses it has a full or partial copy of their data. New records can only be added with the consent of other administrators of the database. Moreover, it is blockchain that makes cryptocurrencies and smart contracts possible.

In this series of articles, we will build a simplified cryptocurrency based on a simple blockchain implementation.

Block

Let’s start with the “block” part of the “blockchain”. In a blockchain, blocks are used to store valuable information. In fact, transaction information is the value of all cryptocurrencies. In addition, the block contains some technical information, such as the version, the current timestamp, and the hash value of the previous block. In this article, we are not going to implement a block like the one described in the Bitcoin specification, but rather use a simplified version of it that contains only important information. This is what it looks like:

type Block struct {
	Timestamp     int64
	Data          []byte
	PrevBlockHash []byte
	Hash          []byte
}
Copy the code

The Timestamp field is the current Timestamp (when the block was created), the Data field is the actual valuable information contained in the block, the PrevBlockHash field stores the Hash of the previous block, and the Hash field is the Hash of the current block. In the Bitcoin specification Timestamp, PrevBlockHash, and Hash are the bulk, which forms a separate Data structure, and Data is another Data structure. We’ve mixed them up for simplicity.

So how do we compute the hash? Hashing is a very important feature of blockchain, and it is this feature that makes blockchain secure. The problem is that calculating a hash is a computationally difficult operation that takes some time even on fast computers (which is why people buy powerful Gpus to mine bitcoin). This is a deliberate architectural design that makes it difficult to add new blocks, preventing them from being modified after they are added. We will discuss and implement this mechanism in a future article.

Currently, we just take the partial fields of the Block structure (Timestamp, Data, and PrevBlockHash) and concatenate them with each other, then compute a SHA-256 on the concatenated result, and we get the hash.

Do this in the SetHash method:

func (b *Block) SetHash() {
	timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
	headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
	hash := sha256.Sum256(headers)

	b.Hash = hash[:]}Copy the code

Next, following the Golang convention, we will implement a function that simplifies the creation of blocks:

func NewBlock(data string, prevBlockHash []byte) *Block {
	block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
	block.SetHash()
	return block
}
Copy the code

This is the block!

Blockchain

Now let’s implement a blockchain. At its core, a blockchain is just a database with a specific structure: it’s an ordered list of backlinks. This means that blocks are stored in insertion order, and each block is linked to the previous block. This structure allows for quick access to the latest block in the chain and (effectively) access to the block through its hash.

In Golang, this structure can be implemented with an array and a map: Array stores ordered hashes (in Golang, arrays are ordered), and map stores hash -> block pairs (in Golang, maps are unordered). But in the basic prototype phase, we only used array, because we don’t need to hash blocks yet.

type Blockchain struct {
	blocks []*Block
}
Copy the code

This is our first blockchain! I never thought it would be so easy 😉

Now let’s add blocks:

func (bc *Blockchain) AddBlock(data string) {
	prevBlock := bc.blocks[len(bc.blocks)-1]
	newBlock := NewBlock(data, prevBlock.Hash)
	bc.blocks = append(bc.blocks, newBlock)
}
Copy the code

The end! But is that it?

To add a new block, we need an existing block, but we don’t have a block in our blockchain! Therefore, in any blockchain, there must be at least one block, and this block, the first block in the chain, is often called the Genesis block. Let’s implement a method to create a genesis block:

func NewGenesisBlock() *Block {
	return NewBlock("Genesis Block", []byte{})
}
Copy the code

Now, we can implement a function to create a blockchain with genesis blocks:

func NewBlockchain() *Blockchain {
	return &Blockchain{[]*Block{NewGenesisBlock()}}
}
Copy the code

Let’s check if the blockchain works:

func main() {
	bc := NewBlockchain()

	bc.AddBlock("Send 1 BTC to Ivan")
	bc.AddBlock("Send 2 more BTC to Ivan")

	for _, block := range bc.blocks {
		fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
		fmt.Printf("Data: %s\n", block.Data)
		fmt.Printf("Hash: %x\n", block.Hash)
		fmt.Println()
	}
}
Copy the code

Output:

Prev. hash:
Data: Genesis Block
Hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168

Prev. hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168
Data: Send 1 BTC to Ivan
Hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1

Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1
Data: Send 2 more BTC to Ivan
Hash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1
Copy the code

Conclusion

We built a very simple blockchain prototype: it’s just an array of blocks, each connected to the previous block. The actual blockchain is clearly much more complex. Adding new blocks to our blockchain is easy and quick, but adding new blocks to the actual blockchain requires some work: some heavy calculations must be performed (a mechanism called proof-of-work) before permission is granted to add blocks. Moreover, blockchain is a distributed database with no single decision maker. Therefore, new blocks must be confirmed and approved by other participants in the network (this mechanism is called consensus). There are no transactions in our blockchain yet!

In future articles, we’ll cover these features.

Cc /posts/build…


For more articles, visit http://www.apexyun.com/

Contact email: [email protected]

(Please do not reprint without permission)