基本原理这里就不写了,只写一个简单demo的实现

首先得有一个区块用来存储区块头和区块体

type Block struct {
Version int64
PreBlockHash []byte
Hash []byte //区块体内是不存储HASH值的,这是网络中某个节点在计算时存储在息本地的,这里是为了方便实现最终的功能做的
TimeStamp int64
TargetBits int64 //难度值
Nonce int64
MerkelRoot []byte
Data []byte //区块体信息
}

还得有一个方法用于实现区块体

func NewBlock(data string, prevBlockHash []byte) *Block {
//initial block data
block := &Block{
Version:,
PreBlockHash:prevBlockHash,
//Hash:[]
TimeStamp:time.Now().Unix(),
TargetBits:,
Nonce:,
MerkelRoot:[]byte{},
Data:[]byte(data),
}
block.SetHash() //get block hash
return block
}

那区块体的hash值计算就得使用另外一个方法来实现

func (block *Block)SetHash()  {
tmp := [][]byte{
IntToByte(block.Version),
block.PreBlockHash,
IntToByte(block.TimeStamp),
block.MerkelRoot,
IntToByte(block.Nonce),
block.Data,
}
data := bytes.Join(tmp, []byte{})//join接收两个参数,第一个二维数组,第二个这里设置为空的连接符
hash := sha256.Sum256(data)
block.Hash = hash[:]
}

区块有了,那么得一个能实现把区块连接起来的文件,blockchain.go

package main

import "os"

type BlockChain struct {
blocks []*Block
} func NewBlockChain() *BlockChain {
return &BlockChain{[]*Block{NewGensisBlock()}} //添加了创世块
} func (bc *BlockChain)AddBlock(data string) {
if len(bc.blocks) <= {
os.Exit()
}
lastBlock := bc.blocks[len(bc.blocks)-] //还没取呢,如果取要取前一个块的HASH值,即取当前链最后一个块的HASH值
prevBlockHash := lastBlock.Hash
block := NewBlock(data, prevBlockHash)//取前一个块的hash值
bc.blocks = append(bc.blocks, block)
}

上面两个文件涉及到的工具写在另外一个文件

package main

import (
"bytes"
"encoding/binary"
"fmt"
"os"
) func IntToByte(num int64) []byte {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, num)//将int类型的num使用binary的方法传递到buffer里去
CheckError(err)
return buffer.Bytes()
} func CheckError(err error) {
if err != nil {
fmt.Println("err occur: ", err)
os.Exit()
}
} func NewGensisBlock() *Block { //创建创世块
return NewBlock("Gensis Block!", []byte{})
}

最后主函数的实现

package main

import "fmt"

func main()  {
bc := NewBlockChain{}
bc.AddBlock("班长转给老师一枚BTC")
bc.AddBlock("班长又转给老师一枚BTC")
for i, block := range bc.blocks {//完成区块的遍历
fmt.Println("============= block num : ", i)
fmt.Println("Version", block.Version)
fmt.Printf("PreBlockHash: %x\n", block.PreBlockHash)
fmt.Printf("Hash: %x\n", block.Hash)
fmt.Printf("TimeStamp: %x\n", block.TimeStamp)
fmt.Printf("Nonce: %x\n", block.Nonce)
fmt.Printf("MerkelRoot: %x\n", block.MerkelRoot)
fmt.Printf("Data: %s\n", block.Data)
}
}

[GO]用go语言实现区块链工作原理的更多相关文章

  1. [GO]go语言实现区块链工作证明(pow)原理

    package main import ( "math/big" "bytes" "math" "crypto/sha256&qu ...

  2. Go语言开发区块链只需180行代码

    区块链开发用什么语言?通过本文你将使用Go语言开发自己的区块链(或者说用go语言搭建区块链).理解哈希函数是如何保持区块链的完整性.掌握如何用Go语言编程创造并添加新的块.实现多个节点通过竞争生成块. ...

  3. 比原链CTO James | Go语言成为区块链主流开发语言的四点理由

    11月24日,比原链CTO James参加了Go中国举办的Gopher Meetup杭州站活动,与来自阿里.网易的技术专家带来Kubernetes.区块链.日志采集.云原生等话题的分享.James向大 ...

  4. 用Hyperledger Fabric(超级账本)来构建Java语言开发区块链的环境

    面向 Java 开发人员的链代码简介 您或许听说过区块链,但可能不确定它对 Java™ 开发人员有何用.本教程将帮助大家解惑.我将分步展示如何使用 Hyperledger Fabric v0.6 来构 ...

  5. 使用Go语言编写区块链P2P网络(译)(转)

    转自:https://mp.weixin.qq.com/s/2daFH9Ej5fVlWmpsN5HZzw 外文链接: https://medium.com/coinmonks/code-a-simpl ...

  6. HyperLedger Fabric 1.4 区块链工作过程(2.3)

    区块链的工作过程分交易产生.交易广播.节点计算.获取记账权.记账权广播.接收区块.验证区块和完成记账七个过程. 1) 交易产生:用户向区块链发了一笔交易信息,将产生交易:2) 交易广播:当一笔新交易产 ...

  7. 001/Go语言构建区块链(mooc)

    1.区块链发展与现状 视频地址:https://www.imooc.com/video/17452 注意: 比特币与以太坊最大的区别在于: 以太坊引入了对图灵完美智能合约的支持,人们可以将任何业务逻辑 ...

  8. spring-cloud-Zuul学习(三)【中级篇】--Filter链 工作原理与Zuul原生Filter【重新定义spring cloud实践】

    这里开始记录zuul中级进阶内容.前面说过了,zuul主要是一层一层的Filter过滤器组成,并且Zuul的逻辑引擎与Filter可用其他基于JVM的语言编写,比如:Groovy. 工作原理 Zuul ...

  9. 通过blockchain_go分析区块链交易原理

    原文链接-石匠的Blog 1.背景 在去中心化的区块链中进行交易(转账)是怎么实现的呢?本篇通过blockchain_go来分析一下.需要进行交易,首先就需要有交易的双方以及他们的认证机制,其次是各自 ...

随机推荐

  1. Hadoop MapReduce任务的启动分析

      正常情况下,我们都是启动Hadoop任务的方式大概就是通过hadoop jar命令(或者写在shell中),事实上运行的hadoop就是一个包装的.sh,下面就是其中的最后一行,表示在其中执行一个 ...

  2. 透过一个实例理解C++语言的explicit关键字

    我们先看一段代码:    建立people.cpp 文件,然后输入下列内容:class People{    public:      int age;     explicit People (in ...

  3. BP神经网络的数学原理及其算法实现

    什么是BP网络 BP网络的数学原理 BP网络算法实现 转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/44514073  上一篇 ...

  4. USB驱动程序之USB总线驱动程序学习笔记

    USB总线驱动程序的作用 1. 识别USB设备 1.1 分配地址 1.2 并告诉USB设备(set address) 1.3 发出命令获取描述符 描述符的信息可以在include\linux\usb\ ...

  5. 03——微信小程序官方demo讲解——page部分

    一个page由一个文件夹以及文件夹下四个文件组成. 比如一个页面叫index.则需要在pages目录下新建一个index目录,且包含由index+类型(js\wxml\wxss\json)为名组成的若 ...

  6. 原生JS模拟jQuery $

    模拟jQuery的$选择器 在获取元素的时候使用ID选择器,返回的是一个对象:使用类选择器或者标签选择器返回可能是一组元素:将获取到的一个或一组元素进行一个简易的封装封装成一个TQObject 什么是 ...

  7. python写个Hack Scan

    前言: 之前逛SAFEING极客社区的时候 发现一款黑市卖2000多的软件,后面下载了 打不开.发现config文件里面有些不错的东西.总结了一下 有了以下的脚本. 脚本用处: [1]探测CMS(不敢 ...

  8. SqlServer 获得存储过程的返回值(参数返回),别玩了output

    declare @dingdanid int declare @fanhuizhi int set @dingdanid = 1 exec 检测订单出库资格 @dingdanid ,@fanhuizh ...

  9. A标签的href设置为#代表什么意思?

    空锚点<a href="#abc">a link <#>表示跳到锚点abc,<a href="#">a link <# ...

  10. Spring 学习记录6 BeanFactory(2)

    主题 除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类. 结构 DefaultListabl ...