Ejemplo n.º 1
0
// AddOutput adds a standard pay to public key hash output to a payment transaction.
func (p *Payment) AddOutput(addrHash []byte, value uint64) error {
	s, err := script.PayToPubKeyHash(addrHash)
	if err != nil {
		return err
	}
	p.tx.AddOutput(&messages.TxOutput{
		Value:  value,
		Script: s,
	})
	return nil
}
Ejemplo n.º 2
0
// AddInputsAndFee to payment adds spendable inputs from the account until
// the value of the inputs matches or surpases the outputs. If the inputs
// become larger than the outputs, a change output from the account is added.
// No more outputs should be added after calling this.
func (p *Payment) AddInputsAndFee(fee uint64) error {
	a := p.account
	required := fee
	for _, outs := range p.tx.Outputs {
		required += outs.Value
	}
	// Get a list of unspent outputs that this account can spend.
	spendables := a.SpendableOutputs()

	count := duplicateCountNeeded(spendables, required)
	if count <= 0 {
		return fmt.Errorf("No enough funds to send: %d", required)
	}
	for i := 0; i < count; i++ {
		// Make a new copy of the transaction we've set up so far,
		// including all outputs.
		tx := *p.tx

		// Add inputs to transaction until it has enough.
		var total uint64
		for _, spend := range spendables {
			// For payments from multiple unconfirmed duplicates
			// we're assuming we only need splits from a single
			// duplicated transactions. If we end up using splits
			// from more than one, we'll be in a situation where we
			// rely on the splits with the same "index" gets
			// confirmed for all duplicated transactions.
			index := 0
			if len(spend.outputs) > 1 {
				index = i
			}
			output := spend.outputs[index]
			total += output.Value
			tx.AddInput(&messages.TxInput{
				PreviousOutput: &messages.OutPoint{
					Hash:  []byte(output.TxHash()),
					Index: output.Index(),
				},
				Sequence: 0xffffffff,
				// Temporarily store the subscript needed to
				// sign tx in signature.
				Signature: output.Script,
			})

			// Add keys in same order as inputs are added. This is
			// a bit hacky, but works since we control the order
			// the transactions are signed.
			p.keys = append(p.keys, spend.key)
			if total >= required {
				break
			}
		}
		if total > required {
			// Add change output for the excess satoshis.
			s, err := script.PayToPubKeyHash(a.NextChangeAddress())
			if err != nil {
				return fmt.Errorf("Failed to add change output: %v", err)
			}
			tx.AddOutput(&messages.TxOutput{
				Value:  total - required,
				Script: s,
			})
		}
		// Append completed transaction to list.
		p.transactions = append(p.transactions, &tx)
	}
	return nil
}