一、PoW工作量证明


返回

1.1 产生区块

  • 定义区块结构体

    type Block struct {
    	PreHash   string // 上一个区块的哈希值
    	TimeStamp string // 时间戳
    	Diff      int    // 当前网络难度系数:控制哈希值有几个前导0
    	Data      string // 数据:交易信息
    	Index     int    // 区块高度
    	Nonce     int    // 随机值:决定了当前区块的哈希值,大量随机尝试,直到哈希值前导0有Diff个,即所谓的挖矿
    	HashCode  string // 当前区块的哈希值
    }
    
    
  • 产生首个区块

    func GenerateFirstBlock(data string) Block {
    	var firstBlock Block
    	firstBlock.PreHash = "0"
    	firstBlock.TimeStamp = time.Now().String()
    	firstBlock.Diff = 4
    	firstBlock.Data = data
    	firstBlock.Index = 1
    	firstBlock.Nonce = 0
    	firstBlock.HashCode = GenerationHashValue(firstBlock)
    	return firstBlock
    }
    
    
  • 产生新区块

    func GenerateNewBlock(data string, oldBlock Block) Block {
    	var newBlock Block
    	newBlock.PreHash = oldBlock.HashCode
    	newBlock.TimeStamp = time.Now().String()
    	newBlock.Diff = 4
    	newBlock.Data = data
    	newBlock.Index = oldBlock.Index + 1
    	newBlock.Nonce = 0
    	newBlock.HashCode = pow(newBlock.Diff, &newBlock)
    	return newBlock
    }
    
    // 计算区块的哈希值
    func GenerationHashValue(block Block) string {
    	// 准备区块内的数据
    	var hashData = strconv.Itoa(block.Index) + strconv.Itoa(block.Nonce) + strconv.Itoa(block.Diff) + block.TimeStamp
    	// 对数据进行哈希算法
    	var sha = sha256.New()
    	sha.Write([]byte(hashData))
    	hashed := sha.Sum(nil)
    	// 将字节转为字符串
    	return hex.EncodeToString(hashed)
    }
    
    // PoW工作量证明算法进行哈希碰撞
    func pow(diff int, block *Block) string {
    	// 不停的挖矿
    	for {
    		// 计算哈希值
    		hash := GenerationHashValue(*block)
    		// 哈希值前导0满足要求,挖矿成功
    		if strings.HasPrefix(hash, strings.Repeat("0", diff)) {
    			fmt.Println("挖矿次数:",block.Nonce)
    			fmt.Println("挖矿成功:",hash)
    			return hash
    		} else {
    			block.Nonce++
    		}
    	}
    }
    
    

1.2 产生区块链

  • 通过链表的形式,维护区块链业务

  • 定义链表

    type Node struct {
    	NextNode *Node        // 指针域
    	Data     *Block.Block // 数据域:Block包中的Block
    }
    
    
  • 创建头节点

    func CreateHeaderNode(data *Block.Block) *Node {
      // 生成一个头节点,存放首个区块
    	headerNode := new(Node)
    	headerNode.NextNode = nil
    	headerNode.Data = data
    	return headerNode
    }
    
    
  • 添加新节点

    func AddNode(data *Block.Block, node *Node) *Node {
      // 生成一个新节点,存放新的区块
    	var newNode *Node = new(Node)
    	newNode.NextNode = nil
    	newNode.Data = data
      // 上一个节点的指针域指向当前的新节点
    	node.NextNode = newNode
    	return newNode
    }
    
    
  • 遍历区块链

    func ShowNodes(node *Node) {
    	n := node
    	for{
    		//尾节点,结束循环
    		if n.NextNode==nil{
    			fmt.Println(n.Data)
    			break
    		}else {
    			fmt.Println(n.Data)
    			n = n.NextNode
    		}
    	}
    }
    
    

1.3 数据持久化

  • 使用LevelDB实现区块链数据持久化存储

  • 手动实现一个LevelDB

    package test_leveldb
    
    import "fmt"
    
    //定义LevelDB结构体
    type DB struct {
    	path string
    	data map[string][]byte
    }
    
    //模拟开启连接
    func New(path string) (*DB, error) {
    	self := DB{
    		path: path,
    		data: make(map[string][]byte),
    	}
    	return &self, nil
    }
    
    //模拟关闭连接
    func (self *DB) Close() error {
    	return nil
    }
    
    //模拟 PUT
    func (self *DB) PUT(key []byte, value []byte) error {
    	self.data[string(key)] = value
    	return nil
    }
    
    //模拟 GET
    func (self *DB) GET(key []byte) ([]byte, error) {
    	if v, ok := self.data[string(key)]; ok {
    		return v, nil
    	} else {
    		return nil, fmt.Errorf("没有此值")
    	}
    }
    
    //模拟 DELETE
    func (self *DB) DELETE(key []byte) error {
    	if _, ok := self.data[string(key)]; ok {
    		delete(self.data, string(key))
    		return nil
    	} else {
    		return fmt.Errorf("没有此值")
    	}
    }
    
    //模拟 遍历取值
    func (self *DB) Ietrator() Iterator {
    	return NewDefaultIterator(self.data)
    }
    
    
  • 迭代器实现

    package test_leveldb
    
    import "fmt"
    
    type Iterator interface {
    	Next() bool    // 判断是否有下一个值
    	Key() []byte   // 键
    	Value() []byte // 值
    }
    
    // 键值的结构体
    type Pair struct {
    	Key   []byte
    	Value []byte
    }
    
    // 迭代器的结构体
    type DefaultIterator struct {
    	data   []Pair
    	index  int
    	length int
    }
    
    // 创建默认的迭代器
    func NewDefaultIterator(data map[string][]byte) *DefaultIterator {
    	self := new(DefaultIterator)
    	self.index = -1
    	self.length = len(data)
    	for k, v := range data {
    		p := Pair{
    			Key:   []byte(k),
    			Value: v,
    		}
    		self.data = append(self.data, p)
    	}
    	return self
    }
    
    //Next方法
    func (self *DefaultIterator) Next() bool {
    	// 迭代器还有值
    	if self.index < self.length-1 {
    		self.index++
    		return true
    	} else {
    		return false
    	}
    }
    
    //Key方法
    func (self *DefaultIterator) Key() []byte {
    	if self.index == -1 || self.index >= self.length {
    		panic(fmt.Errorf("越界异常"))
    	}
    	return self.data[self.index].Key
    }
    
    //Value方法
    func (self *DefaultIterator) Value() []byte {
    	if self.index == -1 || self.index >= self.length {
    		panic(fmt.Errorf("越界异常"))
    	}
    	return self.data[self.index].Value
    }
    
    

1.4 在广域网中做广播

返回