源码参考
https://github.com/huangzhenshi/BuildBitCoinSystemGo/tree/master/blockchain_learn/chapter4
交易
- FindSpendableOutputs,找到属于该用户没有被花掉的output数组,这个output并不是这个用户的所有的output,只是该用户的足够满足这笔交易金额的未花费output
- 如果这个output数组的余额正好等于amout,那么就没有找零,如果大于转账amout,则会系统产生一笔找零
- 如果该用户所有的output的金额都小于转账金额,则抛出一个Panic,交易失败
func NewUTXOTransaction(from, to string, amount int, bc *Blockchain) *Transaction {
var inputs []TXInput
var outputs []TXOutput
// 找到足够的未花费输出
// validOutputs是一个非常巧妙的map,key为包含该用户未花费的入账条交易的交易ID,value是一个int的数组,表示该交易的Vout的下标
// value是一个该交易的Vout数组中的有效下标(归属于该用户的TXOutput)
acc, validOutputs := bc.FindSpendableOutputs(from, amount)
//这个用户拥有的全部余额都不足,交易失败
if acc < amount {
log.Panic("ERROR: Not enough funds")
}
//遍历结果集
for txid, outs := range validOutputs {
txID, err := hex.DecodeString(txid)
if err != nil {
log.Panic(err)
}
for _, out := range outs {
input := TXInput{txID, out, from}
inputs = append(inputs, input)
}
}
outputs = append(outputs, TXOutput{amount, to})
// 如果 UTXO 总数超过所需,则产生找零
if acc > amount {
outputs = append(outputs, TXOutput{acc - amount, from})
}
tx := Transaction{nil, inputs, outputs}
tx.SetID()
return &tx
}