func Test_AddressEquals(test *testing.T) { a1 := new(Address) a2 := new(Address) a1.SetBytes(address1[:]) a2.SetBytes(address1[:]) if a1.IsEqual(a2) != nil { // Out of the box, hashes should be equal primitives.PrtStk() test.Fail() } a1.SetBytes(address2[:]) if a1.IsEqual(a2) == nil { // Now they should not be equal primitives.PrtStk() test.Fail() } a2.SetBytes(address2[:]) if a1.IsEqual(a2) != nil { // Back to equality! primitives.PrtStk() test.Fail() } }
func Test_Auth2_Equals(test *testing.T) { a1 := nextAuth2_rcd() a2 := a1 if a1.IsEqual(a2) != nil { primitives.PrtStk() test.Fail() } a1 = nextAuth2_rcd() if a1.IsEqual(a2) == nil { primitives.PrtStk() test.Fail() } }
// Only validates that the transaction is well formed. This means that // the inputs cover the value of the outputs. Can't validate addresses, // as they are hashes. Can't validate the fee, because it might change // in the next period. // // If this validation returns false, the transaction can safely be // discarded. // // Note that the coinbase transaction for any block is never technically // valid. That validation must be done separately. // // Also note that we DO allow for transactions that do not have any outputs. // This provides for a provable "burn" of factoids, since all inputs would // go as "transaction fees" and those fees do not go to anyone. // // The index is the height of the transaction in a Factoid block. When // the index == 0, then it means this is the coinbase transaction. // The coinbase transaction is the "payout" transaction which cannot have // any inputs, unlike any other transaction which must have at least one // input. If the height of the transaction is known, then the index can // be used to identify the transaction. Otherwise it simply must be > 0 // to indicate it isn't a coinbase transaction. func (t Transaction) Validate(index int) error { // Inputs, outputs, and ecoutputs, must be valid, tInputs, err := t.TotalInputs() if err != nil { return err } tOutputs, err := t.TotalOutputs() if err != nil { return err } tecs, err := t.TotalECs() if err != nil { return err } // Inputs cover outputs and ecoutputs. if index != 0 && tInputs < tOutputs+tecs { return fmt.Errorf("The Inputs of the transaction do not cover the outputs") } // Cannot have zero inputs. This means you cannot use this function // to validate coinbase transactions, because they cannot have any // inputs. if len(t.Inputs) == 0 { if index > 0 { return fmt.Errorf("Transactions (other than the coinbase) must have at least one input") } } else { if index == 0 { primitives.PrtStk() fmt.Println(index, t) return fmt.Errorf("Coinbase transactions cannot have inputs.") } } // Every input must have an RCD block if len(t.Inputs) != len(t.RCDs) { return fmt.Errorf("All inputs must have a cooresponding RCD") } // Every input must match the address of an RCD (which is the hash // of the RCD for i, rcd := range t.RCDs { // Get the address specified by the RCD. address, err := rcd.GetAddress() // If there is anything wrong with the RCD, then the transaction isn't // valid. if err != nil { return fmt.Errorf("RCD %d failed to provide an address to compare with its input", i) } // If the Address (which is really a hash) isn't equal to the hash of // the RCD, this transaction is bogus. if t.Inputs[i].GetAddress().IsEqual(address) != nil { return fmt.Errorf("The %d Input does not match the %d RCD", i, i) } } return nil }