示例#1
0
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()
	}
}
示例#2
0
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()
	}
}
示例#3
0
// 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
}