Example #1
0
func TestPayments(t *testing.T) {
	seed := "xprv9z29aRLQo4Gkn2z7XczXBDup2Nig8EvDCXV7wub6FnSe36UkakkEfTN4TZH9obaPj" +
		"7yn4Zh5P1JSRvnfXAi6riG9g8WqrZjzenkU9MHxy6g"
	account, err := NewAccount(seed)
	if err != nil {
		t.Fatalf("Failed to set up account", err)
	}

	mock := NewMockInventory()
	account.SetTxInventory(mock)

	pay := account.NewPayment()
	decoded, _, _ := base58.BitcoinCheckDecode("1QAsw4fsfq3MJdgiEGod3MxY9BY2EnTWEU")
	pay.AddOutput(decoded, 50000)
	err = pay.AddInputsAndFee(10000)
	if err != nil {
		t.Fatalf("Failed to add inputs to payment: %v", err)
	}
	err = pay.Sign()
	if err != nil {
		t.Fatalf("Failed to sign payment: %v", err)
	}
	transactions := pay.Transactions()
	if len(transactions) != 1 {
		t.Errorf("Bad number of transactions, got %d expected 1.",
			len(transactions))
	}
	tx := transactions[0]

	for index, input := range tx.Inputs {
		stack := script.Stack{}
		err = stack.Execute(input.Signature, nil)
		if err != nil {
			t.Fatalf("Failed to push signature: %v", err)
		}
		prev := input.PreviousOutput
		inputTx, found := mock.inv[string(prev.Hash)]
		if !found {
			t.Fatalf("Input tx %x not found in map.", prev.Hash)
		}
		subscript := inputTx.Outputs[prev.Index].Script

		data := &script.Data{
			Hasher: func(c uint32) []byte {
				return utils.DoubleHash(tx.SignSerialize(
					index, subscript, c))
			}}
		err = stack.Execute(inputTx.Outputs[prev.Index].Script, data)
		if err != nil {
			t.Fatalf("Failed to execute script: %v", err)
		}
		if !stack.CheckSuccess() {
			t.Errorf("Signature on input %d not valid.", index)
		}
	}
}
Example #2
0
func (inv *Inventory) VerifyTransaction(tx *messages.Transaction) (bool, error) {
	var inputValue, outputValue uint64
	for index, input := range tx.Inputs {
		stack := script.Stack{}
		err := stack.Execute(input.Signature, nil)
		if err != nil {
			return false, fmt.Errorf("Failed to push signature: %v", err)
		}
		prev := input.PreviousOutput
		d, found := inv.txHashes[string(prev.Hash)]
		if !found {
			return false, fmt.Errorf("Input tx %x not found in map.", prev.Hash)
		}
		inputTx := d.tx
		output := inputTx.Outputs[prev.Index]
		inputValue += output.Value

		data := &script.Data{
			Hasher: func(c uint32) []byte {
				return utils.DoubleHash(tx.SignSerialize(
					index, output.Script, c))
			}}
		err = stack.Execute(output.Script, data)
		if err != nil {
			return false, fmt.Errorf("Failed to execute script: %v", err)
		}
		if !stack.CheckSuccess() {
			return false, fmt.Errorf("Signature on input %d not valid.", index)
		}
	}
	for _, output := range tx.Outputs {
		outputValue += output.Value
	}
	if outputValue > inputValue {
		return false, fmt.Errorf("Outputs have higher value (%d) than inputs (%d).",
			outputValue, inputValue)
	}
	return true, nil
}