Esempio n. 1
0
// Bitcoin specific type checking
func isClassA(tx *btcutil.Tx) bool {
	mtx := tx.MsgTx()
	for _, txOut := range mtx.TxOut {
		_, scriptType := mscutil.GetAddrs(txOut.PkScript)
		if scriptType == btcscript.MultiSigTy {
			return false
		}
	}

	// If it wasn't multi sig it's class a
	return true
}
Esempio n. 2
0
// Parse transaction takes care of testing the tx for certain rules; class A/B checking
// Fundraiser checks and Dex messages as well as properly delegating the raw messages to
// the proper object which. After a full Msg has been assembled it will return the Msg
// or an error with a description. Whoever called this function should delegate the msg
// to the proper object handler.
func (mp *MsgParser) ParseTx(tx *btcutil.Tx, height, time int64) (msgs []*Msg, err error) {
	sender, _ := mscutil.FindSender(tx.MsgTx().TxIn, mp.btcdb)

	// Check if this is a Class A transaction
	if isClassA(tx) {
		mscutil.Logger.Println("Got 'Class A' transaction with hash", tx.Sha())

		// Create a simple send transaction
		simpleSend, e := mscutil.MakeClassASimpleSend(sender, mscutil.GetAddrsClassA(tx))
		err = e

		if simpleSend != nil {
			mscutil.Logger.Println("Decoded Simple Send transaction:", simpleSend, simpleSend.Data)
			msgs = append(msgs, &Msg{msg: simpleSend})
		}
	} else {
		mscutil.Logger.Println("Got 'Class B' tx with hash", tx.Sha())

		// Parse addresses from the tx using class B rules
		plainTextKeys, receiver, e := mscutil.GetAddrsClassB(tx, sender)
		err = e
		if err == nil {
			// Receiver is first, data is second in the slice

			// Let's change 00000014h to 22d
			data := plainTextKeys[0][2:10]
			f, _ := hex.DecodeString(data)
			messageType := int(f[3])

			switch messageType {
			case mscutil.TxMsgTy:
				simpleSend, e := mscutil.MakeClassBSimpleSend(plainTextKeys, receiver, sender)
				err = e

				if simpleSend != nil {
					// TODO: Do we want to add the sender and receiver to the simple send message?
					mscutil.Logger.Println("Got Simple Send Class B from", sender, "to", receiver)
					msgs = append(msgs, &Msg{msg: simpleSend})
				}
			default:
				err = fmt.Errorf("Unknown message type %d. Support for transaction type not implemented yet.\n", messageType)
				return nil, err
			}
		}
	}

	if height <= mscutil.FundraiserEndBlock {
		// Collect the addresses and values for every input used for this transaction
		highestAddress, _ := mscutil.FindSender(tx.MsgTx().TxIn, mp.btcdb)

		var totalSpend int64
		for _, txOut := range tx.MsgTx().TxOut {
			addr, _ := mscutil.GetAddrs(txOut.PkScript)
			if addr[0].Addr == mscutil.ExodusAddress {
				totalSpend += txOut.Value
			}
		}

		fundraiserTx, e := mscutil.NewFundraiserTransaction(highestAddress, totalSpend, time)
		err = e

		msgs = append(msgs, &Msg{msg: fundraiserTx})
	}

	// If nothing has been found it check for Payment for accept DEx message.
	if len(msgs) == 0 {
		// TODO:
	}

	return
}
Esempio n. 3
0
// Parse transaction takes care of testing the tx for certain rules; class A/B checking
// Fundraiser checks and Dex messages as well as properly delegating the raw messages to
// the proper object which. After a full Msg has been assembled it will return the Msg
// or an error with a description. Whoever called this function should delegate the msg
// to the proper object handler.
func (mp *MsgParser) ParseTx(tx *btcutil.Tx, height, time int64) (msg *Msg, err error) {
	sender, _ := mscutil.FindSender(tx.MsgTx().TxIn, mp.server.btcdb)

	// Check if this is a Class A transaction
	if isClassA(tx) {
		mscutil.Logger.Println("Got 'Class A' transaction with hash", tx.Sha())

		highestAddress, _ := mscutil.FindSender(tx.MsgTx().TxIn, mp.server.btcdb)

		// Create a simple send transaction
		simpleSend, e := mscutil.MakeClassASimpleSend(highestAddress, mscutil.GetAddrsClassA(tx))
		err = e

		if simpleSend != nil {
			mscutil.Logger.Println("Decoded Simple Send transaction:", simpleSend, simpleSend.Data)
			msg = &Msg{msg: simpleSend}
			mscutil.Logger.Fatal("SHUTDOWN")
		}
	} else {
		mscutil.Logger.Println("Got 'Class B' tx")

		// Parse addresses from the tx using class B rules
		plainTextKeys, receiver, err := mscutil.GetAddrsClassB(tx, sender)
		if err == nil {
			// Receiver is first, data is second in the slice
			data := plainTextKeys[0][1]
			// Figure out the message type
			msgType := mscutil.GetTypeFromAddress(string(data))
			switch msgType {
			case mscutil.TxMsgTy:
				simpleSend, e := mscutil.MakeClassBSimpleSend(plainTextKeys, receiver)
				err = e

				if simpleSend != nil {
					mscutil.Logger.Println("Got simple send class b transaction")
					msg = &Msg{msg: simpleSend}
				}
			case mscutil.DexMsgTy:
			default:
				mscutil.Logger.Println("Unknown message type %d. FIXME or erroneus.\n", int(msgType))
			}
		}
	}

	// If nothing has been found it is either a Exodus Kickstarter / Payment for accept DEx message.
	if msg == nil && err != nil {

		if height <= mscutil.FundraiserEndBlock {
			// Collect the addresses and values for every input used for this transaction
			highestAddress, _ := mscutil.FindSender(tx.MsgTx().TxIn, mp.server.btcdb)

			var totalSpend int64
			for _, txOut := range tx.MsgTx().TxOut {
				addr, _ := mscutil.GetAddrs(txOut.PkScript)
				if addr[0].Addr == mscutil.ExodusAddress {
					totalSpend += txOut.Value
				}
			}

			fundraiserTx, e := mscutil.NewFundraiserTransaction(highestAddress, totalSpend, time)
			err = e

			msg = &Msg{msg: fundraiserTx}
		} else {
			//MakeDexMessage(outputs)
		}
	}

	return
}