“This is the 15th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.

A blockchain case based on PoS consensus algorithm

This article appears in my column: Blockchain in Detail

This column will describe the blockchain consensus algorithm, ethereum smart contract, super ledger smart contract, EOS smart contract related knowledge, and also introduce several practical projects in detail. If possible, we can also read the source code of Ethereum together. If you are interested, let’s learn block chain technology together

Zero, preface,

We wrote a case using PoW consensus algorithm before, but we found that using PoW consensus algorithm to generate a block requires a lot of SHA256 encryption operations, which costs a lot of resources. Our PoS can better solve this problem.

1. Define block and block chain

type Block struct { Index int TimeStamp string BPM int HashCode string PrevHash string Validator string } var Blockchain  []BlockCopy the code

Similar to the block in the previous example, we added a Validator to keep track of who created the block. A blockchain is simply putting blocks into an array of blocks, and because there is a record of the hash value and the hash value of the previous block, they are connected.

Second, generate new blocks

func GenerateNextBlock(oldBlock Block, BPM int, address string) Block {
    var newBlock Block
    newBlock.Index = oldBlock.Index + 1
    newBlock.TimeStamp = time.Now().String()
    newBlock.PrevHash = oldBlock.HashCode
    newBlock.BPM = BPM
    newBlock.Validator = address
    newBlock.HashCode = GenerateHashValue(newBlock)
    return newBlock
}
Copy the code

The height of the new block is set to Index of the previous block plus one, the TimeStamp is set to the string of the current time, the previous block hash PrevHash is set to the hash of the previous block, the block data BPM is set to the incoming data, and the Validator is the address of the node that generated the current block. HashCode is the hash of the current block.

Third, compute the hash

func GenerateHashValue(block Block) string {
    var hashcode = block.PrevHash +
        block.TimeStamp + block.Validator +
        strconv.Itoa(block.BPM) + strconv.Itoa(block.Index)
    var sha = sha256.New()
    sha.Write([]byte(hashcode))
    hashed := sha.Sum(nil)
    return hex.EncodeToString(hashed)
}
Copy the code

This also has this step in the previous PoW case, the steps are the same, if not clear, please refer to my previous article on PoW case.

4. Several data structures of the project

Struct {tokens int address string} var n [2] Node var addr [6000] stringCopy the code

Structure Node is used to describe the Node, including the number of coins of the Node, Node address. N is an array of nodes, which is used to store nodes. The string array addr is used to store mining addresses. The more tokens a node has, the more space it takes up in the array.

5. Master logic

func main() {
    n[0] = Node{tokens: 1000, address: "abc123"}
    n[1] = Node{tokens: 5000, address: "bcd321"}
​
    var count = 0
    for i := 0; i < len(n); i++ {
        for j := 0; j < n[i].tokens; j++ {
            addr[count] = n[i].address
            count++
        }
    }
​
    rand.Seed(time.Now().Unix())
    var rd = rand.Intn(6000)
    var adds = addr[rd]
​
    var firstBlock Block
    firstBlock.BPM = 100
    firstBlock.PrevHash = "0"
    firstBlock.TimeStamp = time.Now().String()
    firstBlock.Validator = "abc123"
    firstBlock.Index = 1
    firstBlock.HashCode = GenerateHashValue(firstBlock)
​
    Blockchain = append(Blockchain, firstBlock)
    
    var secondBlock = GenerateNextBlock(firstBlock, 200, adds)
    Blockchain = append(Blockchain, secondBlock)
    fmt.Println(Blockchain)
}
Copy the code

Create two blockchain participants, that is, two nodes, and pass in the coins they hold and the addresses of the nodes.

The following double for loop is used to allocate positions in the ADDR array based on the number of tokens on each node

The addr array has the address “abc123” of 1000 node 0s. Similarly, if node 1 has 5000 tokens, then 5000 elements from addr[1000] are used to store node 1’s address “bCD321”.

And then I’m going to randomly pick one of the 6,000 addresses, which could be node 0 or node 1, but the probability of node 0 is 1/6, and the probability of node 1 is 5/6.

rand.Seed(time.Now().Unix())
var rd = rand.Intn(6000)
var adds = addr[rd]
Copy the code

The next step is to generate the Genesis block and put it into the blockchain, similar to the EXAMPLE of the PoW consensus algorithm, which I won’t describe.

A second block is then generated and placed in the blockchain, where the addr is the random address of the node.