type Block struct {
//1.区块高度
Height int64
//2.上个区块HASH
PrevBlockHash []byte
//3.交易数据
Txs []*transaction.Transaction
//4.时间戳
Timestamp int64
//5.当前区块的hash
Hash []byte
//6.Nonce
Nonce int64
}
二、创建创世区块
/*
生成创世区块
*/
func CreateGenesisBlock(address string) (block *Block,err error) {
//生成transaction
tx,err := transaction.NewCoinbaseTransaction(address)
if err != nil {
log.Println(err)
return nil,err
}
return NewBlock([]*transaction.Transaction{tx},1,[]byte{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}),nil
}
1.生成交易的方法
/*
创世块创建的Transaction
*/
func NewCoinbaseTransaction(address string) (tx *Transaction,err error) {
//代表消费
txInput := &TXInput{[]byte{},-1,"Genesis"}
txOutput := &TXOutput{10,address}
tx = &Transaction{[]byte{},[]*TXInput{txInput},[]*TXOutput{txOutput}}
//设置交易hash
err = tx.hashTransaction()
return
}
2.生成区块的方法
/*
创建新的区块
*/
func NewBlock(txs []*transaction.Transaction,height int64,preBlockHash []byte) *Block {
//创建区块
b := &Block{height,preBlockHash,txs,time.Now().Unix(),nil,0}
//调用工作量证明的方法并且返回有效的Hash和Nonce
pow := NewProofOfWork(b)
hash,nonce := pow.Run()
//设置计算成功返回的hash和nonce
b.Hash = hash
b.Nonce = nonce
return b
}
3.工作量证明算法(proof of work定义成一个struct)
//256位Hash里面前面至少要有20个零
const targetBit = 20 //难度系数
type ProofOfWork struct {
Block *Block
target *big.Int
}
/*
创建新的工作量证明对象
*/
func NewProofOfWork(b *Block) *ProofOfWork {
//1.创建一个初始值为1的target
target := big.NewInt(1)
//2.左移256 - targetBit
target = target.Lsh(target,256 -targetBit)
return &ProofOfWork{b,target}
}
/*
开始计算
*/
func (pow *ProofOfWork) Run() ([]byte, int64) {
var nonce = 0
var hashInt big.Int
var hash [32]byte
for {
//1.拼接数据
dataBytes := pow.prepareData(nonce)
//2.生成hash
hash = sha256.Sum256(dataBytes)
//将hash存储到hashInt
hashInt.SetBytes(hash[:])
fmt.Printf("\r正在挖矿hash:%x",hash)
//3.判断hash是否小于pow的target,如果满足条件,跳出循环
if pow.target.Cmp(&hashInt) == 1 {
break
}
nonce = nonce + 1
}
return hash[:],int64(nonce)
}
/*
数据拼接,返回字节数组
*/
func (pow *ProofOfWork) prepareData(nonce int) []byte {
data := bytes.Join(
[][]byte{
pow.Block.PrevBlockHash,
pow.Block.HashTransactions(),
utils.IntToHex(pow.Block.Timestamp),
utils.IntToHex(targetBit),
utils.IntToHex(int64(nonce)),
utils.IntToHex(int64(pow.Block.Height)),
},
[]byte{})
return data
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)