func (tx *Transaction) Deserialize(data []byte) error {
	var err error
	buffer := xbase.NewBufferReader(data)
	if tx.version, err = buffer.ReadU32(); err != nil {
		return err
	}
	var marker byte
	if marker, err = buffer.ReadU8(); err != nil {
		return err
	}
	if marker != witnessMarker {
		return fmt.Errorf("witness.marker.error.want:%x.got:%x", witnessMarker, marker)
	}
	var flag byte
	if flag, err = buffer.ReadU8(); err != nil {
		return err
	}
	if flag != witnessFlag {
		return fmt.Errorf("witness.flag.error.want:%x.got:%x", witnessFlag, flag)
	}
	var ins uint64
	if ins, err = buffer.ReadVarInt(); err != nil {
		return err
	}
	if ins > 0 {
		tx.inputs = make([]*TxIn, ins)
		for i := 0; i < int(ins); i++ {
			txIn := &TxIn{}
			if txIn.Hash, err = buffer.ReadBytes(hashSize); err != nil {
				return err
			}
			if txIn.Index, err = buffer.ReadU32(); err != nil {
				return err
			}
			if txIn.RawUnlockingScript, err = buffer.ReadVarBytes(); err != nil {
				return err
			}
			if txIn.Sequence, err = buffer.ReadU32(); err != nil {
				return err
			}
			tx.inputs[i] = txIn
		}
	}
	var outs uint64
	if outs, err = buffer.ReadVarInt(); err != nil {
		return err
	}
	if outs > 0 {
		tx.outputs = make([]*TxOut, outs)
		for i := 0; i < int(outs); i++ {
			txOut := &TxOut{}
			if txOut.Value, err = buffer.ReadU64(); err != nil {
				return err
			}
			if txOut.Script, err = buffer.ReadVarBytes(); err != nil {
				return err
			}
			tx.outputs[i] = txOut
		}
	}
	if flag != 0x00 {
		for _, in := range tx.inputs {
			witCount, err := buffer.ReadVarInt()
			if err != nil {
				return err
			}
			in.Witness = make([][]byte, witCount)
			for j := uint64(0); j < witCount; j++ {
				if in.Witness[j], err = buffer.ReadVarBytes(); err != nil {
					return err
				}
			}
		}
	}
	if tx.lockTime, err = buffer.ReadU32(); err != nil {
		return err
	}
	return nil
}
Deserialize -- decode bytes to witness transaction struct.
package xcore
import (
	"fmt"
	"strings"
	"github.com/keyfuse/tokucore/xbase"
	"github.com/keyfuse/tokucore/xcrypto"
	"github.com/keyfuse/tokucore/xerror"
	"github.com/keyfuse/tokucore/xvm"
)
const (
	hashSize        = 32          
	witnessMarker   = byte(0x00)  
	witnessFlag     = byte(0x01)  
	defaultSequence = 0xffffffff  
	witnessScaleFactor = 4
)
type SigHashType uint32
const (
	SigHashOld          SigHashType = 0x0
	SigHashAll          SigHashType = 0x1
	SigHashNone         SigHashType = 0x2
	SigHashSingle       SigHashType = 0x3
	SigTypeMask         SigHashType = 0x1f
	SigHashAnyOneCanPay SigHashType = 0x80
	sigHashMask = 0x1f
)
type TxIn struct {
	Hash               []byte  
	Index              uint32  
	Value              uint64  
	Sequence           uint32
	SignatureHash      []byte    
	RedeemScript       []byte    
	Witness            [][]byte  
	WitnessScriptCode  []byte    
	RawLockingScript   []byte    
	FinalLockingScript []byte    
	RawUnlockingScript []byte    
}
func NewTxIn(txHash []byte, n uint32, value uint64, script []byte, redeemScript []byte) (*TxIn, error) {
	scriptInstance, err := ParseLockingScript(script)
	if err != nil {
		return nil, err
	}
	witnessScriptCode, err := scriptInstance.GetWitnessScriptCode(redeemScript)
	if err != nil {
		return nil, err
	}
	rawLocking, err := scriptInstance.GetRawLockingScriptBytes()
	if err != nil {
		return nil, err
	}
	finalLocking, err := scriptInstance.GetFinalLockingScriptBytes(redeemScript)
	if err != nil {
		return nil, err
	}
	return &TxIn{
		Hash:               txHash,
		Index:              n,
		Value:              value,
		Sequence:           defaultSequence,
		RedeemScript:       redeemScript,
		WitnessScriptCode:  witnessScriptCode,
		RawLockingScript:   rawLocking,
		FinalLockingScript: finalLocking,
	}, nil
}
func (txin *TxIn) HasWitness() bool {
	return txin.WitnessScriptCode != nil
}
type TxOut struct {
	Value  uint64
	Script []byte
}
func NewTxOut(value uint64, script []byte) *TxOut {
	return &TxOut{
		Value:  value,
		Script: script,
	}
}
type Transaction struct {
	version      uint32
	lockTime     uint32
	inputs       []*TxIn
	outputs      []*TxOut
	hashPrevouts []byte
	hashSequence []byte
	hashOutputs  []byte
}
func NewTransaction() *Transaction {
	return &Transaction{
		version: 1,
	}
}
func (tx *Transaction) SetVersion(ver uint32) {
	tx.version = ver
}
func (tx *Transaction) SetLockTime(time uint32) {
	tx.lockTime = time
}
func (tx *Transaction) SetTxIn(idx int, amount uint64, script []byte, redeemScript []byte) error {
	txIn := tx.inputs[idx]
	scriptInstance, err := ParseLockingScript(script)
	if err != nil {
		return err
	}
	witnessScriptCode, err := scriptInstance.GetWitnessScriptCode(redeemScript)
	if err != nil {
		return err
	}
	rawLocking, err := scriptInstance.GetRawLockingScriptBytes()
	if err != nil {
		return err
	}
	finalLocking, err := scriptInstance.GetFinalLockingScriptBytes(redeemScript)
	if err != nil {
		return err
	}
	rawUnlocking, err := scriptInstance.WitnessToUnlockingScriptBytes(txIn.Witness)
	if err != nil {
		return err
	}
	if rawUnlocking != nil {
		txIn.RawUnlockingScript = rawUnlocking
	}
	txIn.Value = amount
	txIn.RedeemScript = redeemScript
	txIn.WitnessScriptCode = witnessScriptCode
	txIn.RawLockingScript = rawLocking
	txIn.FinalLockingScript = finalLocking
	return nil
}
func (tx *Transaction) AddInput(in *TxIn) {
	tx.inputs = append(tx.inputs, in)
}
func (tx *Transaction) AddOutput(out *TxOut) {
	tx.outputs = append(tx.outputs, out)
}
func (tx *Transaction) Hash() []byte {
	return xcrypto.DoubleSha256(tx.SerializeNoWitness())
}
func (tx *Transaction) ID() string {
	return xbase.NewIDToString(tx.Hash())
}
func (tx *Transaction) WitnessHash() []byte {
	return xcrypto.DoubleSha256(tx.Serialize())
}
func (tx *Transaction) WitnessID() string {
	return xbase.NewIDToString(tx.WitnessHash())
}
func (tx *Transaction) SignIndex(idx int, compressed bool, hashType SigHashType, keys ...*xcrypto.PrvKey) error {
	txIn := tx.inputs[idx]
	signs := make([]PubKeySign, 0)
	if len(keys) > 1 && txIn.RedeemScript == nil {
		return xerror.NewError(Errors, ER_TRANSACTION_SIGN_REDEEM_EMPTY, idx, len(keys))
	}
	for _, key := range keys {
		var err error
		var pubkey []byte
		var signature []byte
		if compressed {
			pubkey = key.PubKey().SerializeCompressed()
		} else {
			pubkey = key.PubKey().SerializeUncompressed()
		}
		if txIn.HasWitness() {
			if signature, err = tx.WitnessSignature(idx, hashType, key); err != nil {
				return err
			}
		} else {
			if signature, err = tx.RawSignature(idx, hashType, key); err != nil {
				return err
			}
		}
		signs = append(signs, PubKeySign{
			PubKey:    pubkey,
			Signature: signature,
		})
	}
	return tx.EmbedIdxSignature(idx, signs)
}
func (tx *Transaction) EmbedIdxSignature(idx int, signs []PubKeySign) error {
	txIn := tx.inputs[idx]
	if len(signs) > 1 && txIn.RedeemScript == nil {
		return xerror.NewError(Errors, ER_TRANSACTION_SIGN_REDEEM_EMPTY, idx, len(signs))
	}
	scriptInstance, err := ParseLockingScript(txIn.RawLockingScript)
	if err != nil {
		return err
	}
	if txIn.RawUnlockingScript, err = scriptInstance.GetRawUnlockingScriptBytes(signs, txIn.RedeemScript); err != nil {
		return nil
	}
	if txIn.Witness, err = scriptInstance.GetWitnessUnlockingScriptBytes(signs, txIn.RedeemScript); err != nil {
		return err
	}
	return nil
}
func (tx *Transaction) EmbedIdxEcdsaSignature(idx int, pubkey *xcrypto.PubKey, ecdsaSig []byte, hashType SigHashType) error {
	var signs []PubKeySign
	finalsig := append(ecdsaSig, byte(hashType))
	signs = append(signs, PubKeySign{PubKey: pubkey.SerializeCompressed(), Signature: finalsig})
	return tx.EmbedIdxSignature(idx, signs)
}
func (tx *Transaction) RawSignatureHash(idx int, hashType SigHashType) []byte {
	buffer := xbase.NewBuffer()
	buffer.WriteU32(tx.version)
	switch hashType {
	case SigHashAll:
		buffer.WriteVarInt(uint64(len(tx.inputs)))
		for i, in := range tx.inputs {
			buffer.WriteBytes(in.Hash)
			buffer.WriteU32(in.Index)
			if i == idx {
				if in.RedeemScript != nil {
					buffer.WriteVarBytes(in.RedeemScript)
				} else {
					script := xvm.RemoveOpcode(in.FinalLockingScript, byte(xvm.OP_CODESEPARATOR))
					buffer.WriteVarBytes(script)
				}
			} else {
				buffer.WriteVarBytes(nil)
			}
			buffer.WriteU32(in.Sequence)
		}
		buffer.WriteVarInt(uint64(len(tx.outputs)))
		for _, out := range tx.outputs {
			buffer.WriteU64(out.Value)
			buffer.WriteVarBytes(out.Script)
		}
	}
	buffer.WriteU32(tx.lockTime)
	buffer.WriteU32(uint32(hashType))
	return xcrypto.DoubleSha256(buffer.Bytes())
}
func (tx *Transaction) WitnessV0SignatureHash(idx int, hashType SigHashType) []byte {
	var zeroHash [32]byte
	txIn := tx.inputs[idx]
	if (hashType & SigHashAnyOneCanPay) == 0 {
		if tx.hashPrevouts == nil {
			hashBuffer := xbase.NewBuffer()
			for _, in := range tx.inputs {
				hashBuffer.WriteBytes(in.Hash[:])
				hashBuffer.WriteU32(in.Index)
			}
			tx.hashPrevouts = xcrypto.DoubleSha256(hashBuffer.Bytes())
		}
	} else {
		tx.hashPrevouts = zeroHash[:]
	}
	if (hashType&SigHashAnyOneCanPay) == 0 && (hashType&sigHashMask) != SigHashSingle && (hashType&sigHashMask) != SigHashNone {
		if tx.hashSequence == nil {
			hashBuffer := xbase.NewBuffer()
			for _, in := range tx.inputs {
				hashBuffer.WriteU32(in.Sequence)
			}
			tx.hashSequence = xcrypto.DoubleSha256(hashBuffer.Bytes())
		}
	} else {
		tx.hashSequence = zeroHash[:]
	}
	if hashType&SigHashSingle != SigHashSingle && hashType&SigHashNone != SigHashNone {
		if tx.hashOutputs == nil {
			hashBuffer := xbase.NewBuffer()
			for _, out := range tx.outputs {
				hashBuffer.WriteU64(out.Value)
				hashBuffer.WriteVarBytes(out.Script)
			}
			tx.hashOutputs = xcrypto.DoubleSha256(hashBuffer.Bytes())
		}
	} else {
		tx.hashOutputs = zeroHash[:]
	}
	buffer := xbase.NewBuffer()
	buffer.WriteU32(tx.version)
	buffer.WriteBytes(tx.hashPrevouts)
	buffer.WriteBytes(tx.hashSequence)
	buffer.WriteBytes(txIn.Hash)
	buffer.WriteU32(txIn.Index)
	buffer.WriteVarBytes(txIn.WitnessScriptCode)
	buffer.WriteU64(txIn.Value)
	buffer.WriteU32(txIn.Sequence)
	buffer.WriteBytes(tx.hashOutputs)
	buffer.WriteU32(tx.lockTime)
	buffer.WriteU32(uint32(hashType))
	return xcrypto.DoubleSha256(buffer.Bytes())
}
func (tx *Transaction) RawSignature(idx int, hashType SigHashType, prv *xcrypto.PrvKey) ([]byte, error) {
	inputs := len(tx.inputs)
	if idx >= inputs {
		return nil, xerror.NewError(Errors, ER_TRANSACTION_SIGN_OUT_INDEX, idx, inputs)
	}
	txIn := tx.inputs[idx]
	txIn.SignatureHash = tx.RawSignatureHash(idx, hashType)
	signature, err := xcrypto.EcdsaSign(prv, txIn.SignatureHash)
	if err != nil {
		return nil, err
	}
	return append(signature, byte(hashType)), nil
}
func (tx *Transaction) WitnessSignature(idx int, hashType SigHashType, prv *xcrypto.PrvKey) ([]byte, error) {
	var sighash []byte
	var signature []byte
	inputs := len(tx.inputs)
	if idx >= inputs {
		return nil, xerror.NewError(Errors, ER_TRANSACTION_SIGN_OUT_INDEX, idx, inputs)
	}
	in := tx.inputs[idx]
	script, err := ParseLockingScript(in.RawLockingScript)
	if err != nil {
		return nil, err
	}
	scriptVersion := script.GetScriptVersion()
	switch scriptVersion {
	case WITNESS_V0:
		sighash = tx.WitnessV0SignatureHash(idx, hashType)
		signature, err = xcrypto.EcdsaSign(prv, sighash)
		if err != nil {
			return nil, err
		}
	default:
		return nil, xerror.NewError(Errors, ER_SCRIPT_SIGNATURE_TYPE_UNKNOW, scriptVersion)
	}
	in.SignatureHash = sighash
	return append(signature, byte(hashType)), nil
}
func (tx *Transaction) HasWitness() bool {
	for _, in := range tx.inputs {
		if in.HasWitness() {
			return true
		}
	}
	return false
}
func (tx *Transaction) Serialize() []byte {
	buffer := xbase.NewBuffer()
	hasWitness := tx.HasWitness()
	buffer.WriteU32(tx.version)
	if hasWitness {
		buffer.WriteU8(witnessMarker)
		buffer.WriteU8(witnessFlag)
	}
	buffer.WriteVarInt(uint64(len(tx.inputs)))
	for _, in := range tx.inputs {
		buffer.WriteBytes(in.Hash)
		buffer.WriteU32(in.Index)
		if in.HasWitness() {
			buffer.WriteVarBytes(nil)
		} else {
			buffer.WriteVarBytes(in.RawUnlockingScript)
		}
		buffer.WriteU32(in.Sequence)
	}
	buffer.WriteVarInt(uint64(len(tx.outputs)))
	for _, out := range tx.outputs {
		buffer.WriteU64(out.Value)
		buffer.WriteVarBytes(out.Script)
	}
	if hasWitness {
		for _, in := range tx.inputs {
			wits := in.Witness
			buffer.WriteVarInt(uint64(len(wits)))
			for _, wit := range wits {
				buffer.WriteVarBytes(wit)
			}
		}
	}
	buffer.WriteU32(tx.lockTime)
	return buffer.Bytes()
}