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) } } }
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 }