예제 #1
0
// FactoidEncode encodes the receiver to w using the protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding transactions to be stored to disk, such as in a
// database, as opposed to encoding transactions for the wire.
func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error {

	var buf [1]byte

	buf[0] = msg.Version

	_, err := w.Write(buf[:])
	if err != nil {
		return err
	}

	var buf8 [8]byte

	if !factoid.FactoidTx_LocktimeCheck(msg.LockTime) {
		return errors.New("fTx encode locktime check")
	}

	binary.BigEndian.PutUint64(buf8[:], uint64(msg.LockTime))
	_, err = w.Write(buf8[3:8]) // LockTime is 5 bytes
	if err != nil {
		return err
	}

	txoutcount := uint64(len(msg.TxOut))
	err = writeVarInt(w, pver, txoutcount)
	if err != nil {
		return err
	}

	for _, to := range msg.TxOut {
		err = writeTxOut(w, pver, to)
		if err != nil {
			return err
		}
	}

	ecoutcount := uint64(len(msg.ECOut))
	err = writeVarInt(w, pver, ecoutcount)
	if err != nil {
		return err
	}

	for _, eco := range msg.ECOut {
		err = writeECOut(w, pver, eco)
		if err != nil {
			return err
		}
	}

	incount := uint64(len(msg.TxIn))
	err = writeVarInt(w, pver, incount)
	if err != nil {
		return err
	}

	for _, ti := range msg.TxIn {
		err = writeTxIn(w, pver, ti)
		if err != nil {
			return err
		}
	}

	/* TODO: RE-ENABLE
	rcdcount := uint64(len(msg.RCDreveal))
	err = writeVarInt(w, pver, rcdcount)
	if err != nil {
		return err
	}

	for _, rcd := range msg.RCDreveal {
		err = writeRCD(w, pver, rcd)
		if err != nil {
			return err
		}
	}
	*/

	/* TODO: RE-ENABLE
	for _, sig := range msg.TxSig {
		err = writeSig(w, pver, sig)
		if err != nil {
			return err
		}
	}
	*/

	return nil
}
예제 #2
0
// BtcDecode decodes r using the protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding transactions stored to disk, such as in a
// database, as opposed to decoding transactions from the wire.
func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
	//	util.Trace()

	/*
		if s, ok := r.(io.Seeker); ok {
		}
		nowseek, _ := s.Seek(0, os.SEEK_CUR)

		fmt.Println("nowseek= ", nowseek)

		{
			me := bufio.NewReader(r)
			peekbuf, _ := me.Peek(1000)

			fmt.Println("bufio peek= ", spew.Sdump(peekbuf))
		}
	*/

	//	s.Seek(nowseek, os.SEEK_SET)

	var buf [1]byte

	_, err := io.ReadFull(r, buf[:])
	if err != nil {
		return err
	}

	msg.Version = uint8(buf[0])
	//	util.Trace(fmt.Sprintf("version=%d\n", msg.Version))

	//	fmt.Printf("buf= %v (%d)\n", buf, msg.Version)

	if !factoid.FactoidTx_VersionCheck(msg.Version) {
		return errors.New("fTx version check")
	}

	var buf5 [5]byte
	_, err = io.ReadFull(r, buf5[:])
	if err != nil {
		return err
	}

	fmt.Printf("buf5= %v\n", buf5)

	full8slice := []byte{0, 0, 0}
	full8slice = append(full8slice, buf5[:]...)

	fmt.Printf("full8slice= %v\n", full8slice)

	msg.LockTime = int64(binary.BigEndian.Uint64(full8slice))

	if !factoid.FactoidTx_LocktimeCheck(msg.LockTime) {
		//util.Trace("LOCKTIME error: MsgTx= " + spew.Sdump(*msg))
		return errors.New("fTx decode locktime check")
	}

	outcount, err := readVarInt(r, pver)
	if err != nil {
		return err
	}
	//util.Trace(fmt.Sprintf("outcount=%d\n", outcount))

	// Prevent more input transactions than could possibly fit into a
	// message.  It would be possible to cause memory exhaustion and panics
	// without a sane upper bound on this count.
	if outcount > uint64(inNout_cap) {
		str := fmt.Sprintf("too many input transactions to fit into "+
			"max message size [count %d, max %d]", outcount,
			inNout_cap)
		return messageError("MsgTx.BtcDecode maxtxout", str)
	}

	msg.TxOut = make([]*TxOut, outcount)
	for i := uint64(0); i < outcount; i++ {
		to := TxOut{}
		err = readTxOut(r, pver, &to)
		if err != nil {
			return err
		}
		msg.TxOut[i] = &to
	}
	//	util.Trace()

	eccount, err := readVarInt(r, pver)
	if err != nil {
		return err
	}
	//	util.Trace(fmt.Sprintf("eccount=%d\n", eccount))

	// Prevent more input transactions than could possibly fit into a
	// message.  It would be possible to cause memory exhaustion and panics
	// without a sane upper bound on this count.
	if eccount > uint64(inNout_cap) {
		str := fmt.Sprintf("too many input transactions to fit into "+
			"max message size [count %d, max %d]", eccount,
			inNout_cap)
		return messageError("MsgTx.BtcDecode maxecout", str)
	}

	//	util.Trace()

	msg.ECOut = make([]*TxEntryCreditOut, eccount)
	for i := uint64(0); i < eccount; i++ {
		eco := TxEntryCreditOut{}
		err = readECOut(r, pver, &eco)
		if err != nil {
			return err
		}
		msg.ECOut[i] = &eco
	}
	//	util.Trace()

	incount, err := readVarInt(r, pver)
	//util.Trace(fmt.Sprintf("incount=%d\n", incount))

	msg.TxIn = make([]*TxIn, incount)
	for i := uint64(0); i < incount; i++ {
		ti := TxIn{}
		err = readTxIn(r, pver, &ti)
		if err != nil {
			return err
		}
		msg.TxIn[i] = &ti
	}
	//	util.Trace()

	/* LOOKS LIKE ERROR HERE
	_, err = io.ReadFull(r, buf[:])
	if err != nil {
		return err
	}
	//	util.Trace()
	*/

	/* TODO: RE-ENABLE
	rcdcount, err := readVarInt(r, pver)

	if rcdcount > uint64(inNout_cap) {
		str := fmt.Sprintf("too many RCDs to fit into "+
			"max message size [count %d, max %d]", rcdcount,
			inNout_cap)
		return messageError("MsgTx.BtcDecode max rcd", str)
	}
	//	util.Trace()

	msg.RCDreveal = make([]*RCDreveal, rcdcount)
	for i := uint64(0); i < rcdcount; i++ {
		rcd := RCDreveal{}
		err = readRCD(r, pver, &rcd)
		if err != nil {
			return err
		}
		msg.RCDreveal[i] = &rcd
	}
	*/

	/* TODO:
	RE - ENABLE
	msg.TxSig = make([]*TxSig, incount)
	for i := uint64(0); i < incount; i++ {
		sig := TxSig{}
		err = readSig(r, pver, &sig)
		if err != nil {
			return err
		}
		msg.TxSig[i] = &sig
	}
	//util.Trace()

	// ----------------------------------------------
	if !factoid_CountCheck(msg) {
		errors.New("Factoid check 1")
	}
	*/

	if !disableSpew {
		fmt.Println("MsgTx= ", spew.Sdump(*msg))
	}

	return nil
}