#### 前言:闲暇时期,参考了一些资料,用go简单的实现了比特币中的一些相关功能,实现完全大概2000行代码左右,现在刚利用闲暇时间写了一点小功能,大概500多行代码左右,只实现了基本的区块链接,存储是选择了github上面的一个开源库,bolt轻量级数据库,还有很多需要迭代完善,这个月内打算完善好,可供参考
- 区块的结构,和区块链的结构定义,一些相关功能没有加入,后期会加入,比如交易,UTXO等
- pow工作量证明,现在不够完善,后期会完善
- 钱包结点的相关功能,后期会完善
- 加密的相关功能,后期会完善
```
type Block struct { //区块的一个结构
Version uint64 //版本号
PrevBlockHash []byte //前区块哈希值
MerkelRoot []byte //这是一个哈希值,后面完善
TimeStamp uint64 //时间戳,从1970.1.1到现在的秒数
Difficulty uint64 //通过这个数字,算出一个哈希值:0x00010000000xxx,暂时写死难度,代码里面大概5个前导0以上本地普通电脑就跑不动了
Nonce uint64 // 这是我们要找的随机数,挖矿就找证书
Hash []byte //当前区块哈希值, 正常的区块不存在,我们为了方便放进来
Data []byte //数据本身,区块体,先用字符串表示,v4版本的时候会引用真正的交易结构
}
```
```
//定义一个区块链结构,使用bolt数据库进行保存
type BlockChain struct { //存储在数据库中,会生成一个文件
//数据库的句柄
Db *bolt.DB
//最后一个区块的哈希值
lastHash []byte //在内存中的临时值,只保存最后一个区块哈希
}
```
```
const difficulty = 16 //难度值写死暂时,后期完善
//1. 定义工作量证明, block, 难度值
type ProofOfWork struct {
//数据来源
block Block
//难度值
target *big.Int //一个能够处理大数的内置的类型,有比较方法
}
```
上面是一些基本的结构,
这里比较主要的就是工作量证明函数
我们来看一下实现方式
```
func (pow *ProofOfWork) Run() ([]byte, uint64) {
//1. 拿到区块数据
//block := pow.block
//区块的哈希值
var currentHash [32]byte
//挖矿的随机值
var nonce uint64
for {
info := pow.prepareData(nonce)
//2. 对数据做哈希运算
currentHash = sha256.Sum256(info)
//3. 比较
//引用big.int,将获取的[]byte类型的哈希值转成big.int
var currentHashInt big.Int
currentHashInt.SetBytes(currentHash[:])
// -1 if x < y
// 0 if x == y
// +1 if x > y
//
//func (x *Int) Cmp(y *Int) (r int) {
if currentHashInt.Cmp(pow.target) == -1 {
//a. 比目标小,成功,返回哈希和nonce
break
} else {
//b. 比目标大,继续nonce++
nonce++
}
}
return currentHash[:], nonce
}
```
这里的哈希运算就是,加上随机数来运算哈希,一直找找到一个随机数使得哈希符合难度值
比目标哈希是00001xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,那么就需要找比这个哈希小的哈希,就是前面一定要有5个0的哈希才符合要求,这样打包区块才是有效的,
我们这里就简单实现了,后期迭代会加入UTXO,交易机制,还有钱包结点相关功能,欢迎提意见,
### 如果想详细参考的见github地址:https://github.com/wumansgy/btcmodel