可可币:java 公链区块连示例,参考比特币
研究了很久的区块链,略读了比特币源码;自以为懂了使用的业务场景,懂了区块链细节。对于团队协作来说,最好的程序员是善于协作使用轮子。不过对于学习来说,最好的学习方式就是造一个轮子。因此参考比特币实现基本的区块链,彻底处理好对应的细节。
实现基础功能的比特币,支持挖矿、交易、链、p2p、
a.链:
二进制存储链,链不可更改,后面的区块包含前以区块的hash
b.挖矿:
支持pow挖矿。支持固定难度调整
c.交易:
账户使用utxo
每笔交易支持单地址支付(可以多个输入token)
解锁脚本和锁定脚本:不支持。通过固定的解锁规则
不处理点:
a.地址转换,只支持一种地址格式
b.地址校验:不校验
c.交易的默克尔hash
d.难度调整:固定难度调整
e.挖矿币:固定数量
参考比特币核心架构
在区块链中,数据不可更改。存储结构的格式需要尽量少改变,因此存储结构需要支持未来的变化。在未来变化时,历史数据能够不需要改变
存储格式:二进制,编码:高位在前,低位在后
hash长度以及算法定义
a.32位hash,采用md5计算
b.64为hash,采用sha-256计算
c.128位hash,采用sha-512计算
block:{
magic(4) //魔法字
version(4)//版本
hight(4) //当前高度
hash(128)//上一块的hash值
nonce(4)//随机数,用来执行pow算法
length(4) //块长(包含魔法字等在内的总长度)
count(4)//交易数
hash(128)://交易打包后的hash值
trans //交易内容链(变长)
}
trans:[{
tran://交易内容(变长){
length(4), 交易长度,包含自身长度
version(4)//版本
hash(64)://交易hash值,包括签名在内(不包括版本和交易长度),可作为交易的id
inputCount(4) 输入数量(长度可以为2,暂时不考虑存储,先4)
outputCount(4)输出数量,同输入数量
publicKey(162):公钥, 因为一个交易只有一个公钥,因此输入只能来自同一个地址的币做处理,(如果byte存储直接公钥为162,base64专门后为216)
signLength(4), sign长度
sign,解锁脚本--交易签名(所有输入和输出+时间戳的签名)
{
输入:
[{
inputHash(64), (输入的交易id,指上一交易对应的hash)
index(4):输入序号(对应上一交易的输出序号)
}],
输出:
[{
addr(32),输出地址,通过接收方的公钥hash计算得出
count(4), 币的数量数量
}]<br>
}<br>
validHash(32), sign通过公钥解密后内容的md5值(用来对解锁内容做校验)。
timestamp(4) 时间戳
}
}]