持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
GO语言实现UTXO模型
对于比特币而言,一个人拥有的比特币余额就是看他所掌管的账户地址里包含多少个比特币,而计算这个比特币数量的方式或者说它的数据结构就叫做UTXO(Unspent Transaction Output),它体现里交易的原子性,即某个UTXO被引用就失效,更利于保证比特币不被双花攻击。
如何定义交易
交易存在三要素:转出方、接收方、金额。比特币的交易数据大致包含三部分内容:元数据、输入项、输出项。 真实的比特币交易是相当复杂的,我们需要简化一下。
1、先定义一些结构体:
```go // 交易输入结构 type TXInput struct { Txid []byte //引用交易ID VoutIdx int //使用的交易输出编号 FromAddr string //输入方验签 }
// 交易输出结构 type TXOutput struct { Value int //输出金额 ToAddr string //收方验签 }
// 交易结构 type Transaction struct { ID []byte //交易ID Vin []TXInput //交易输入项 Vout []TXOutput //交易输出项 }
```
2、将交易结构序列化后计算hash值
```go // 交易结构 type Transaction struct { ID []byte //交易ID Vin []TXInput //交易输入项 Vout []TXOutput //交易输出项 }
// 将交易信息转换为hash,并设为ID func (tx *Transaction) SetID() { var encoded bytes.Buffer var hash [32]byte
enc := gob.NewEncoder(&encoded)
enc.Encode(tx)
hash = sha256.Sum256(encoded.Bytes())
tx.ID = hash[:]
} ```
3、需要在Block结构体中增加交易信息数据,为[]*Transaction类型
go // 定义区块结构 type Block struct { Timestamp int64 //时间戳 Transactions []*Transaction //交易信息 PrevBlockHash []byte //前块hash值 Hash []byte //当前块hash值 Nonce int64 //随机值 }
4、实现一种交易转[]byte的方法.
```go
//构建区块交易hash值 func (b *Block) HashTransactions() []byte { var txHashes [][]byte var txHash [32]byte
for _, tx := range b.Transactions {
//字符串拼接ID
txHashes = append(txHashes, tx.ID)
}
//Join将txHashes的元素连接起来以创建一个新的字节片。分隔符[]byte{}放置在所得切片中的元素之间
txHash = sha256.Sum256(bytes.Join(txHashes, []byte{}))
return txHash[:]
} ```