持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
coinbase交易
什么是coinbase交易
coinbase交易一般是指矿工挖矿的奖励,也就是说,其没有输入项,只有输出项,且输出来自系统奖励。
如何判断Coinbase交易
首先考虑函数参数问题,由于是属于系统奖励、因此只考虑接收方就可以。但是我们作为开发人员,好歹也要“露个面”。
//创建CoinBase交易
func NewCoinbaseTX(to, data string) *Transaction {
if data == "" {
data = fmt.Sprintf("Reward to '%s'", to)
}
//创建一个输入项
txin := TXInput{[]byte{}, -1, nil, []byte(data)}
//创建输出项
txout := NewTXOutput(subsidy, to)
tx := Transaction{nil, []TXInput{txin}, []TXOutput{*txout}}
tx.SetID()
return &tx
}
coinbase的判断方法
在确定了CoinBase后,我们也可以清晰的判断出什么是coinbase交易了。该输入项的切片只有一个元素,该元素Voutx为-1,并且输出项切片只有一个元素。
//是否为CoinBase交易
func (tx Transaction) IsCoinbase() bool {
return len(tx.Vin) == 1 &&
len(tx.Vin[0].Txid) == 0 &&
tx.Vin[0].VoutIdx == -1
}
如何使用coinbase交易
- 1、修改NewBlock函数,奖原Data域替换为[]*Transaction类型。
- 2、修改ProofOfWork的prepareData和Run方法,将原Data域调整。
- 3、修改创世块创建函数,原Data域替换为Coinbase交易
- 4、修改NewBlockchain函数,创世块创建部分调整
- 5、main函数调用调整。
下面,我们对主要修改的地方做一个详细讲解:
1、修改NewBlock函数,只涉及传入参数与对象构造方面。
// 创建Block,返回Block指针
func NewBlock(txs []*Transaction, prevBlockHash []byte) *Block {
//先构造block
block := &Block{time.Now().Unix(), txs, prevBlockHash, []byte{}, 0}
//需要先挖矿
pow := NewProofOfWork(block)
nonce, hash := pow.Run()
//设置hash和nonce
block.Hash = hash
block.Nonce = nonce
return block
}
2、修改pow.go文件。pow.go的修改主要是受Block结构变化的影响。
func (pow *ProofOfWork) prepareData(nonce int64) []byte {
data := bytes.Join(
[][]byte{
pow.block.PrevBlockHash,
pow.block.HashTransactions(),
Int2Hex(pow.block.Timestamp),
Int2Hex(int64(targetBits)),
Int2Hex(nonce),
},
[]byte{},
)
return data
}
run函数主要代码:
fmt.Printf("%s\n", pow.block.Transactions[0].Vin[0].FromAddr)