// Creates a Transaction spending coins and hours from our coins func CreateSpendingTransaction(wlt wallet.Wallet, unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool, headTime uint64, amt wallet.Balance, fee, burnFactor uint64, dest cipher.Address) (coin.Transaction, error) { txn := coin.Transaction{} auxs := unspent.AllForAddresses(wlt.GetAddresses()) // Subtract pending spends from available puxs := unconfirmed.SpendsForAddresses(unspent, wlt.GetAddressSet()) auxs = auxs.Sub(puxs) // Determine which unspents to spend spends, err := createSpends(headTime, auxs.Flatten(), amt, fee, burnFactor) if err != nil { return txn, err } // Add these unspents as tx inputs toSign := make([]cipher.SecKey, len(spends)) spending := wallet.Balance{0, 0} for i, au := range spends { entry, exists := wlt.GetEntry(au.Body.Address) if !exists { log.Panic("On second thought, the wallet entry does not exist") } txn.PushInput(au.Hash()) toSign[i] = entry.Secret spending.Coins += au.Body.Coins spending.Hours += au.CoinHours(headTime) } // Determine how much change we get back, if any _, changeHours, err := calculateBurnAndChange(spending.Hours, amt.Hours, fee, burnFactor) if err != nil { // This should not occur, else createSpends is broken return txn, err } change := wallet.NewBalance(spending.Coins-amt.Coins, changeHours) // TODO -- send change to a new address changeAddr := spends[0].Body.Address if change.Coins == 0 { if change.Hours > 0 { msg := ("Have enough coins, but not enough to send coin hours " + "change back. Would spend %d more hours than requested.") return txn, fmt.Errorf(msg, change.Hours) } } else { txn.PushOutput(changeAddr, change.Coins, change.Hours) } // Finalize the the transaction txn.PushOutput(dest, amt.Coins, amt.Hours) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil }
//DEPRECATE //deprecate dependency on wallet // Creates a Transaction spending coins and hours from our coins //MOVE SOMEWHERE ELSE //Move to wallet or move to ??? func CreateSpendingTransaction(wlt wallet.Wallet, unconfirmed *UnconfirmedTxnPool, unspent *coin.UnspentPool, headTime uint64, amt wallet.Balance, dest cipher.Address) (coin.Transaction, error) { txn := coin.Transaction{} auxs := unspent.AllForAddresses(wlt.GetAddresses()) // Subtract pending spends from available puxs := unconfirmed.SpendsForAddresses(unspent, wlt.GetAddressSet()) auxs = auxs.Sub(puxs) // Determine which unspents to spend spends, err := createSpends(headTime, auxs.Flatten(), amt) if err != nil { return txn, err } // Add these unspents as tx inputs toSign := make([]cipher.SecKey, len(spends)) spending := wallet.Balance{0, 0} for i, au := range spends { entry, exists := wlt.GetEntry(au.Body.Address) if !exists { log.Panic("On second thought, the wallet entry does not exist") } txn.PushInput(au.Hash()) toSign[i] = entry.Secret spending.Coins += au.Body.Coins spending.Hours += au.CoinHours(headTime) } //keep 1/4th of hours as change //send half to each address var changeHours uint64 = spending.Hours / 4 if amt.Coins == spending.Coins { txn.PushOutput(dest, amt.Coins, changeHours/2) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil } change := wallet.NewBalance(spending.Coins-amt.Coins, changeHours/2) // TODO -- send change to a new address changeAddr := spends[0].Body.Address //create transaction txn.PushOutput(changeAddr, change.Coins, change.Hours) txn.PushOutput(dest, amt.Coins, changeHours/2) txn.SignInputs(toSign) txn.UpdateHeader() return txn, nil }