“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.