Пример #1
0
func FactoidAddInput(trans fct.ITransaction, key string, address fct.IAddress, amount uint64) error {
	ok := Utility.IsValidKey(key)
	if !ok {
		return fmt.Errorf("Invalid name for transaction")
	}

	// First look if this is really an update
	for _, input := range trans.GetInputs() {
		if input.GetAddress().IsSameAs(address) {
			input.SetAmount(amount)
			return nil
		}
	}

	// Add our new input
	err := factoidState.GetWallet().AddInput(trans, address, amount)
	if err != nil {
		return fmt.Errorf("Failed to add input")
	}

	// Update our map with our new transaction to the same key. Otherwise, all
	// of our work will go away!
	factoidState.GetDB().PutRaw([]byte(fct.DB_BUILD_TRANS), []byte(key), trans)

	return nil
}
Пример #2
0
func (w *SCWallet) SignInputs(trans fct.ITransaction) (bool, error) {

	data, err := trans.MarshalBinarySig() // Get the part of the transaction we sign
	if err != nil {
		return false, err
	}

	var numSigs int = 0

	inputs := trans.GetInputs()
	rcds := trans.GetRCDs()
	for i, rcd := range rcds {
		rcd1, ok := rcd.(*fct.RCD_1)
		if ok {
			pub := rcd1.GetPublicKey()
			we := w.db.GetRaw([]byte(fct.W_ADDRESS_PUB_KEY), pub).(*WalletEntry)
			if we != nil {
				var pri [fct.SIGNATURE_LENGTH]byte
				copy(pri[:], we.private[0])
				bsig := ed25519.Sign(&pri, data)
				sig := new(fct.Signature)
				sig.SetSignature(bsig[:])
				sigblk := new(fct.SignatureBlock)
				sigblk.AddSignature(sig)
				trans.SetSignatureBlock(i, sigblk)
				numSigs += 1
			}
		}
	}

	return numSigs == len(inputs), nil
}
Пример #3
0
func filtertransaction(trans fct.ITransaction, addresses [][]byte) bool {
	if addresses == nil || len(addresses) == 0 {
		return true
	}
	if len(trans.GetInputs()) == 0 &&
		len(trans.GetOutputs()) == 0 {
		return false
	}

	if len(addresses) == 1 && bytes.Equal(addresses[0], trans.GetSigHash().Bytes()) {
		return true
	}

Search:
	for _, adr := range addresses {

		for _, in := range trans.GetInputs() {
			if bytes.Equal(adr, in.GetAddress().Bytes()) {
				continue Search
			}
		}
		for _, out := range trans.GetOutputs() {
			if bytes.Equal(adr, out.GetAddress().Bytes()) {
				continue Search
			}
		}
		for _, ec := range trans.GetECOutputs() {
			if bytes.Equal(adr, ec.GetAddress().Bytes()) {
				continue Search
			}
		}
		return false
	}
	return true
}
Пример #4
0
// Assumes validation has already been done.
func (fs *FactoidState) UpdateTransaction(trans fct.ITransaction) error {
	for _, input := range trans.GetInputs() {
		err := fs.UpdateBalance(input.GetAddress(), -int64(input.GetAmount()))
		if err != nil {
			return err
		}
	}
	for _, output := range trans.GetOutputs() {
		err := fs.UpdateBalance(output.GetAddress(), int64(output.GetAmount()))
		if err != nil {
			return err
		}
	}
	for _, ecoutput := range trans.GetECOutputs() {
		err := fs.UpdateECBalance(ecoutput.GetAddress(), int64(ecoutput.GetAmount()))
		if err != nil {
			return err
		}
	}

	fs.numTransactions++
	cp.CP.AddUpdate(
		"transprocessed", // tag
		"status",         // Category
		fmt.Sprintf("Factoid Transactions Processed: %d", fs.numTransactions), // Title
		"", // Message
		0)  // When to expire the message; 0 is never

	return nil
}
Пример #5
0
func PrtTrans(t fct.ITransaction) {
	fmt.Println("Transaction")
	for _, input := range t.GetInputs() {
		fmt.Println("in ", input.GetAddress(), input.GetAmount(), fs.GetBalance(input.GetAddress()))
	}
	for _, output := range t.GetOutputs() {
		fmt.Println("out", output.GetAddress(), output.GetAmount(), fs.GetBalance(output.GetAddress()))
	}
	for _, ecoutput := range t.GetECOutputs() {
		fmt.Println("ec ", ecoutput.GetAddress(), ecoutput.GetAmount(), fs.GetECBalance(ecoutput.GetAddress()))
	}
}
Пример #6
0
func FactoidAddFee(trans fct.ITransaction, key string, address fct.IAddress, name string) (uint64, error) {
	{
		ins, err := trans.TotalInputs()
		if err != nil {
			return 0, err
		}
		outs, err := trans.TotalOutputs()
		if err != nil {
			return 0, err
		}
		ecs, err := trans.TotalECs()
		if err != nil {
			return 0, err
		}

		if ins != outs+ecs {
			return 0, fmt.Errorf("Inputs and outputs don't add up")
		}
	}

	ok := Utility.IsValidKey(key)
	if !ok {
		return 0, fmt.Errorf("Invalid name for transaction")
	}

	fee, err := GetFee()
	if err != nil {
		return 0, err
	}

	transfee, err := trans.CalculateFee(uint64(fee))
	if err != nil {
		return 0, err
	}

	adr, err := factoidState.GetWallet().GetAddressHash(address)
	if err != nil {
		return 0, err
	}

	for _, input := range trans.GetInputs() {
		if input.GetAddress().IsSameAs(adr) {
			amt, err := fct.ValidateAmounts(input.GetAmount(), transfee)
			if err != nil {
				return 0, err
			}
			input.SetAmount(amt)
			return transfee, nil
		}
	}
	return 0, fmt.Errorf("%s is not an input to the transaction.", key)
}
Пример #7
0
// Returns an error message about what is wrong with the transaction if it is
// invalid, otherwise you are good to go.
func (fs *FactoidState) Validate(index int, trans fct.ITransaction) error {
	err := fs.currentBlock.ValidateTransaction(index, trans)
	if err != nil {
		return err
	}

	var sums = make(map[[32]byte]uint64, 10)  // Look at the sum of an address's inputs
	for _, input := range trans.GetInputs() { //    to a transaction.
		bal, err := fct.ValidateAmounts(sums[input.GetAddress().Fixed()], input.GetAmount())
		if err != nil {
			return err
		}
		if bal > fs.GetBalance(input.GetAddress()) {
			return fmt.Errorf("Not enough funds in input addresses for the transaction")
		}
		sums[input.GetAddress().Fixed()] = bal
	}
	return nil
}
Пример #8
0
// Returns an error message about what is wrong with the transaction if it is
// invalid, otherwise you are good to go.
func (fs *AssetState) Validate(trans fct.ITransaction) error {

	if err := trans.ValidateSignatures(); err != nil {
		return err
	}

	var sums = make(map[fct.IAddress]uint64, 10)
	for _, input := range trans.GetInputs() {
		bal, err := fct.ValidateAmounts(
			sums[input.GetAddress()], // Will be zero the first time around
			input.GetAmount())        // Get this amount, check against bounds
		if err != nil {
			return err
		}
		if bal > fs.GetBalance(input.GetAddress()) {
			return fmt.Errorf("Not enough funds in input addresses for the transaction")
		}
		sums[input.GetAddress()] = bal
	}
	return nil
}
Пример #9
0
// Add the first transaction of a block.  This transaction makes the
// payout to the servers, so it has no inputs.   This transaction must
// be deterministic so that all servers will know and expect its output.
func (b *FBlock) AddCoinbase(trans fct.ITransaction) error {
	b.BodyMR = nil
	if len(b.Transactions) != 0 {
		return fmt.Errorf("The coinbase transaction must be the first transaction")
	}
	if len(trans.GetInputs()) != 0 {
		return fmt.Errorf("The coinbase transaction cannot have any inputs")
	}
	if len(trans.GetECOutputs()) != 0 {
		return fmt.Errorf("The coinbase transaction cannot buy Entry Credits")
	}
	if len(trans.GetRCDs()) != 0 {
		return fmt.Errorf("The coinbase transaction cannot have anyRCD blocks")
	}
	if len(trans.GetSignatureBlocks()) != 0 {
		return fmt.Errorf("The coinbase transaction is not signed")
	}

	// TODO Add check here for the proper payouts.

	b.Transactions = append(b.Transactions, trans)
	return nil
}