交易四(发起一笔正常的交易)

源码参考

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
}

你可能感兴趣的:(交易四(发起一笔正常的交易))