Preface
It stems from my curiosity about blockchain mining. Recently, I am obsessed with learning GO language and used it to simply implement the principle of pow mining.
Code implementation process
Define the block information structure:
type Block struct {
//当前区块的Hash值.
HashCode string
//当前时间戳.
TimeStamp string
//当前长度.
Index int
//网络难度系数,若前导0个数符合难度系数,则挖矿成功,根据挖矿人数不断变化.
Diff int
//下一个区块的Hash值
PreHashCode string
//随机数
Nonce int
//交易信息.
Data string
}
Create a genesis block
func initFirstBlock() *Block{
var firstBlcok = new(Block)
firstBlcok.TimeStamp = string(time.Now().UnixNano())
firstBlcok.Diff = 3
firstBlcok.Nonce = 1
firstBlcok.PreHashCode = "0"
firstBlcok.Data = "创世块"
firstBlcok.Index = 1
for ; ; {
hashCode := generateHashCode(*firstBlcok)
fmt.Println(hashCode)
if strings.HasPrefix(hashCode, strings.Repeat("0", firstBlcok.Diff)) {
firstBlcok.HashCode = hashCode
break
}else {
firstBlcok.Nonce++
}
}
fmt.Println("创世模块初始化完毕")
return firstBlcok
}
Tools for generating hash values
Used to generate HashCode in Block
//计算hash值.
func generateHashCode(block Block) string {
//生成规则.
record := strconv.Itoa(block.Index) + block.TimeStamp +
strconv.Itoa(block.Nonce) + strconv.Itoa(block.Diff) + block.PreHashCode
hash := sha256.New()
hash.Write([]byte(record))
sum := hash.Sum(nil)
hashCode := hex.EncodeToString(sum)
return hashCode
}
After having the block, start to create the chain
type Node struct {
block Block
nextBlock Block
index int
}
func initFirstChain(block *Block) *Node {
node := new(Node)
node.index = 1
return node
}
func createNextNode(block Block,node *Node) *Node {
nextNode := new(Node)
nextNode.index = node.index + 1
node.nextBlock = block
return nextNode
}
POW mining
func calNextBlock(diff int, block *Block) Block {
nextBlock := new(Block)
nextBlock.Index = block.Index + 1
nextBlock.TimeStamp = string(time.Now().UnixNano())
marshal, _ := json.Marshal(block)
nextBlock.Data = string(marshal)
nextBlock.Diff = diff
nextBlock.PreHashCode = block.HashCode
for ; ; {
hashCode := generateHashCode(*nextBlock)
fmt.Println(hashCode)
if strings.HasPrefix(hashCode, strings.Repeat("0", nextBlock.Diff)) {
nextBlock.HashCode = hashCode
break
}else {
nextBlock.Nonce++
}
}
fmt.Println("挖矿成功!!!")
return *nextBlock
}
Main function
func main() {
now := time.Now()
//初始化创世模块
firstBlock := initFirstBlock()
//初始化链表
chain := initFirstChain(firstBlock)
//开始挖坑
block := calNextBlock(6, firstBlock)
node := createNextNode(block, chain)
fmt.Println(node)
elapsed := time.Since(now)
fmt.Println("用时:", elapsed)
}
Test Results
to sum up
The value of diff determines the difficulty coefficient of mining. The system will continuously perform hash collisions according to the value of diff, until a qualified hash value is collided to indicate that the mining is successful, and then this block is uploaded and updated to the chain.