主页 > imtoken钱包怎么下载 > Go语言简单实现比特币挖矿原理
Go语言简单实现比特币挖矿原理
区块链的基本概念
区块链本质上是一个点对点的分布式账本数据库。
比特币底层采用区块链的技术架构。 区块链本身实际上是一系列相互关联的数据块,每一个相邻的块都是相互连接的,它的链接指针是通过密码学哈希算法对块头进行处理后生成的块头的哈希值。 每个区块数据块记录了一组由哈希算法组成的树状交易状态信息,保证了每个区块中的交易数据不可篡改,区块链中链接的区块不可篡改。
比特币交易记录将存储在数据块中。 在比特币系统中,大约每 10 分钟就会产生一个区块。 每个数据块一般包括两部分:头部(Header)和块体(Body)比特币挖矿原理,如图所示。
1-1.jpg
区块头封装了当前版本号(Version)、上一个区块的地址(Prev-Block)、时间戳(Timestamp)、随机数(Nonce)、当前区块的目标哈希值(Bits),以及默克尔数。 根值(Merkle-root)等信息。
区块头分析
前 80 个字节是区块头
{
"hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
"ver": 1,
"prev_block": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",
"mrkl_root": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",
"time": 1293623863,
"bits": 453281356,
"nonce": 274148111
}
字节字段说明
4个
版本
区块版本号,表示区块符合的验证规则
32
父区块头哈希
前一个区块的哈希值,使用SHA计算(SHA256(父区块头))
32
默克尔根
本区块交易的默克尔树根的哈希值也是通过SHA计算的(SHA256(父区块头))
4个
时间戳
出块的大概时间,精确到秒的UNIX时间戳,必须严格大于前11个出块时间的中位数,全节点也会拒绝那些超过自身2小时时间戳的块
4个
难度目标
块工作负载算法的难度目标,使用特定算法编码
4个
随机数
为了找到满足难度目标的随机数,解决32位随机数在算力飙升的情况下不够用的问题,规定可以更改timestamp和coinbase交易信息来扩容随机数位数
矿业
区块是在挖矿过程中产生的。 所谓挖矿,其实就是一种穷举随机数的算法,将上一个区块的哈希值加上十分钟内所有的交易订单,加上一个计数,计算出一个256位的字符串哈希值比特币挖矿原理,输入的随机数Nonce使哈希值满足一定条件,获得该区块的交易记账权。 新生成的块需要快速广播,以便其他节点可以验证它们以防止伪造。 记账成功,获得区块奖励,即挖出比特币。
得到比特币
随着随机数(Nonce)的不断变化,会产生不同的哈希值。 当生成的哈希值左边连续数字中0值的个数大于等于当前区块的难度值时,碰撞成功。 找到随机数,正确记账,得到比特币。 如下所示:
1-2.png
难度为4,碰撞产生的随机数为87471,随着难度的不断增加,碰撞产生随机数的概率越来越低。 目前比特币矿机算力最大的是蚂蚁的S9矿机(14TH/s)。 我有两个,现在日产量只有0.0009个BTC,少得可怜。 . 。代码
定义块结构
type block struct {
ver int //版本号
prev_block string //父区块的哈希值
mekl_root string //该区块merkle树的哈希值
time string //时间戳
bits int // 难度
}
获取哈希值
func getHashValueStr(nonce int,blc block) string {
//拼接区块版本号,时间戳,父区块,merkle树,随机数为hv字符串
hv := strconv.Itoa(blc.ver) + blc.time + blc.prev_block+
blc.mekl_root + strconv.Itoa(nonce)
first := sha256.New()
first.Write([]byte(hv))
// first.Sum(nil)返回值为[]byte 类型的数组,
而哈希值由每位字符16进制字符组成,所以应用fmt.Springtf
函数将数组转化为单个字节为16进制拼接而成的哈希字符串
return fmt.Sprintf("%x",first.Sum(nil))
}
检查生成随机数的哈希函数是否满足条件
func mining(hashStr string, diff int) bool {
var I int
for i = 0; i < len(hashStr); i++ {
//如果i位数 的值不为0,不满足条件,跳出循环
if hashStr[i] != '0' {
break
}
}
//判断i的值是否大于当前的难度,大于碰撞成功,否则失败
return i >= diff
}
得到随机数
func getNonce(blc block)int {
nonce := 0
//改变nonce的值,如果返回false,nonce++
for !mining(getHashValueStr(nonce,blc), blc.bits) {
fmt.Println(getHashValueStr(nonce,blc))
nonce ++
}
fmt.Println(getHashValueStr(nonce,blc))
fmt.Println("出块成功!")
return nonce
}
主功能
func main() {
prev_block := "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"
mrkl_root := "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250"
time := "1293623863"
bits := 4
block := block{1, prev_block, mrkl_root, time, bits}
nc := getNonce(block)
fmt.Println(nc)
}
运算结果
1-3
总结
代码只是简单的实现了比特币的挖矿原理,其实可能比这个更详细,考虑的更全面。
至于采矿,兵法上有“兵贵而速”之说。 2017年,比特币大幅上涨。 那时候难度不是很高。 在云南和四川投资矿厂的人赚了很多钱。 2017年初认识一个矿工,他在挖矿,巅峰时期拥有2万个S9,年收入近10亿。 投资成本据说要几十万。 当然,这些也需要一定的远见和勇气。 我现在只是回顾过去。 当时,没有人知道比特币能涨得这么快。 包括我现在会继续买矿机的原因,也是因为我认为比特币还远没有达到应有的价值。 虽然产量少,但我不会把挖出来的币卖掉。 5年后,10年后看,现在看过去可能也是一样的。 当然,这些都不是重点,也不构成投资建议。 专注于代码,看代码!
源代码
据说github的star对找工作很重要,哈哈哈。 喜欢就给个star吧!