热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:区块链实战实现简单的区块与区块链交易

篇首语:本文由编程笔记#小编为大家整理,主要介绍了区块链实战实现简单的区块与区块链交易相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了区块链实战实现简单的区块与区块链交易相关的知识,希望对你有一定的参考价值。






区块链实战
字节字段说明
4版本区块版本号,表示本区块遵守的验证规则
32父区块头哈希值前一区块的Merkle树根的哈希值,同样采取SHA256计算
32Merkle根该区块中交易的Merkle树根的哈希值,同样采用SHA256计算
4时间戳该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11各区块的时间的中值,同时全节点也会拒接那些超过自己两个小时的时间戳的区块
4难度目标该区块工作量证明算法的难度目标,已经使用特定算法编码
4Nonce未来找到满足难度目标所设定的随机数,为了解决32为随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均改变,以此扩展nonce的位数

**注意:**区块不存储hash值,节点接受区块后独立计算并存储在本地。


Version 1


区块相关:

​ 1.定义一个区块的结构Block

​ a.区块头:6个字段

​ b.区块体:字符串表示data


  1. 提供一个创建区块的方法

    ​ NewBlock(参数)


区块链相关


  1. 定义一个区块链结构BlockChain

    ​ Block数组


    1. 提供一个创建BlockChain()的方法

    ​ NewBlockChain()


    1. 提供一个添加区块的方法

    ​ AddBlock(参数)

block.go文件

package main
import (
"bytes"
"crypto/sha256"
"time"
)
/*
1.定义一个区块的结构Block
​a.区块头:6个字段
​b.区块体:字符串表示data
*/

//区块
type Block struct {
Version int64 //版本
PerBlockHash []byte //前一个区块的hash值
Hash []byte //当前区块的hash值,是为了简化代码
MerKelRoot []byte //梅克尔根
TimeStamp int64 //时间抽
Bits int64 //难度值
Nonce int64 //随机值
//区块体
Data []byte //交易信息
}
/*
提供一个创建区块的方法
NewBlock(参数)
*/

func NewBlock(data string ,prevBlockHash []byte) *Block {
var block Block
block = Block{
Version: 1,
PerBlockHash: prevBlockHash,
//Hash: []byte{}, //区块不存储hash值,节点接受区块后独立计算并存储在本地。
MerKelRoot: []byte{},
TimeStamp: time.Now().Unix(),
Bits: 1,
Nonce: 1,
Data: []byte(data),
}
block.SetHash() //填充Hash
return &block
}
func (block *Block) SetHash() {
// 源码里面是要传二维切片 func Join(s [][]byte, sep []byte) []byte
tmp :=[][]byte{
IntToByte(block.Version),
block.PerBlockHash,
block.MerKelRoot,
IntToByte(block.TimeStamp),
IntToByte(block.Bits),
IntToByte(block.Nonce),
}
data:=bytes.Join(tmp,[]byte{}) //之后再计算hash
hash := sha256.Sum256(data)
block.Hash = hash[:] //变切片
}
//创始块
func NewGensisBlock() *Block{
return NewBlock("Genesis Block!",[]byte{})
}

blockChain.go文件

package main
/*
1. 定义一个区块链结构BlockChain
Block数组
*/

type BlockChain struct {
blocks []*Block
}
/*
2. 提供一个创建BlockChain()的方法
NewBlockChain()
*/

func NewBlockChain() *BlockChain {
block := NewGensisBlock()
return &BlockChain{blocks:[]*Block{block}} //创建只有一个元素的区块链,初始化
}
/*
3. 提供一个添加区块的方法
AddBlock(参数)
*/

func (bc *BlockChain)AddBlock(data string) {
PerBlockHash := bc.blocks[len(bc.blocks)-1].Hash //这一个区块的哈希是前一块的哈希值
block := NewBlock(data,PerBlockHash)
bc.blocks = append(bc.blocks,block)
}

utils.go文件

package main
import (
"bytes"
"encoding/binary"
"fmt"
"os"
)
func IntToByte(num int64) []byte {
//func Write(w io.Writer, order ByteOrder, data interface{}) error {
var buffer bytes.Buffer
err := binary.Write(&buffer, binary.BigEndian, num)
CheckErr("IntToByte",err)
return buffer.Bytes()
}
func CheckErr(position string,err error) {
if err != nil {
fmt.Println("error ,pos:",position,err)
os.Exit(1)
}
}

main.go文件

package main
import "fmt"
func main() {
bc := NewBlockChain()
bc.AddBlock("A send B 1BTC")
bc.AddBlock("B send C 1BTC")
for _,block := range bc.blocks {
fmt.Printf("Version : %d\\n",block.Version)
fmt.Printf("PerBlockHash : %x\\n",block.PerBlockHash)
fmt.Printf("Hash : %x\\n",block.Hash)
fmt.Printf("MerKelRoot : %x\\n",block.MerKelRoot)
fmt.Printf("TimeStamp : %d\\n",block.TimeStamp)
fmt.Printf("Bits : %d\\n",block.Bits)
fmt.Printf("Nonce : %d\\n",block.Nonce)
fmt.Printf("Data : %s\\n",block.Data)
}
}

执行结果






推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文详细解析了JavaScript中相称性推断的知识点,包括严厉相称和宽松相称的区别,以及范例转换的规则。针对不同类型的范例值,如差别范例值、统一类的原始范例值和统一类的复合范例值,都给出了具体的比较方法。对于宽松相称的情况,也解释了原始范例值和对象之间的比较规则。通过本文的学习,读者可以更好地理解JavaScript中相称性推断的概念和应用。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
互联网控军
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有