diff --git a/api/service/transactionApiService.go b/api/service/transactionApiService.go
index 79a921548..fc189514d 100644
--- a/api/service/transactionApiService.go
+++ b/api/service/transactionApiService.go
@@ -193,6 +193,7 @@ func (ts *TransactionService) GetTransactions(
 			&tx.Signature,
 			&tx.Version,
 			&tx.TransactionIndex,
+			&tx.MultisigChild,
 		)
 		if err != nil {
 			if err != sql.ErrNoRows {
diff --git a/api/service/transactionApiService_test.go b/api/service/transactionApiService_test.go
index 7d1553980..7b770aa3a 100644
--- a/api/service/transactionApiService_test.go
+++ b/api/service/transactionApiService_test.go
@@ -591,6 +591,7 @@ func (*mockQueryGetTransactionsSuccess) ExecuteSelect(qStr string, tx bool, args
 					[]byte{0, 0, 0, 0, 0, 0, 0},
 					1,
 					1,
+					false,
 				),
 			)
 	}
@@ -684,6 +685,7 @@ func TestTransactionService_GetTransactions(t *testing.T) {
 						Signature:               []byte{0, 0, 0, 0, 0, 0, 0},
 						Version:                 1,
 						TransactionIndex:        1,
+						MultisigChild:           false,
 					},
 				},
 			},
@@ -737,6 +739,7 @@ func (*mockQueryGetTransactionSuccess) ExecuteSelect(
 			8,
 			[]byte{1, 2, 3, 4, 5, 6, 7, 8},
 			[]byte{0, 0, 0, 0, 0, 0, 0}, 1, 1,
+			false,
 		),
 	)
 	return db.Query("")
@@ -759,6 +762,7 @@ func (*mockQueryGetTransactionSuccess) ExecuteSelectRow(qstr string, tx bool, ar
 				8,
 				[]byte{1, 2, 3, 4, 5, 6, 7, 8},
 				[]byte{0, 0, 0, 0, 0, 0, 0}, 1, 1,
+				false,
 			),
 	)
 	return db.QueryRow(""), nil
@@ -837,6 +841,7 @@ func TestTransactionService_GetTransaction(t *testing.T) {
 				Signature:               []byte{0, 0, 0, 0, 0, 0, 0},
 				Version:                 1,
 				TransactionIndex:        1,
+				MultisigChild:           false,
 			},
 		},
 	}
diff --git a/cmd/main.go b/cmd/main.go
index 518e95363..9fca5ec9b 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -7,6 +7,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/zoobc/zoobc-core/cmd/signature"
+
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
 	"github.com/zoobc/zoobc-core/cmd/account"
@@ -73,6 +75,7 @@ func main() {
 	rootCmd.AddCommand(genesisblock.Commands())
 	rootCmd.AddCommand(rollback.Commands(sqliteDB))
 	rootCmd.AddCommand(parserCmd)
+	rootCmd.AddCommand(signature.Commands())
 	generateCmd.AddCommand(account.Commands())
 	generateCmd.AddCommand(transaction.Commands(sqliteDB))
 	generateCmd.AddCommand(block.Commands())
diff --git a/cmd/readme.md b/cmd/readme.md
index 2fed2bf37..fb24880f8 100644
--- a/cmd/readme.md
+++ b/cmd/readme.md
@@ -103,7 +103,7 @@ ofiness deviation starved"
 
 ### Account Generating multisig
 ```bash
-go run main.go generate account multisig --addresses BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN --addresses BCZD_VxfO2S9aziIL3cn_cXW7uPDVPOrnXuP98GEAUC7 --addresses BCZKLvgUYZ1KKx-jtF9KoJskjVPvB9jpIjfzzI6zDW0J —min-sigs 2 —nonce 3
+go run main.go generate account multisig --addresses BCZnSfqpP5tqFQlMTYkDeBVFWnbyVK7vLr5ORFpTjgtN --addresses BCZD_VxfO2S9aziIL3cn_cXW7uPDVPOrnXuP98GEAUC7 --addresses BCZKLvgUYZ1KKx-jtF9KoJskjVPvB9jpIjfzzI6zDW0J —-min-sigs=2 --nonce=3
 ```
 
 ### Account Generate with spesific signature type
diff --git a/cmd/signature/cmd.go b/cmd/signature/cmd.go
new file mode 100644
index 000000000..a4f06d133
--- /dev/null
+++ b/cmd/signature/cmd.go
@@ -0,0 +1,71 @@
+package signature
+
+import (
+	"encoding/hex"
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/zoobc/zoobc-core/common/model"
+
+	"github.com/zoobc/zoobc-core/common/crypto"
+	"golang.org/x/crypto/sha3"
+
+	"github.com/spf13/cobra"
+)
+
+var (
+	/*
+		Signer command line tools
+	*/
+	signerCmd = &cobra.Command{
+		Use:   "sign",
+		Short: "sign provided data",
+		Long:  "sign any provided data by using the --seed parameter",
+	}
+)
+
+func init() {
+	signerCmd.Flags().StringVar(&dataHex, "data-hex", "", "hex string of the data to sign")
+	signerCmd.Flags().StringVar(&dataBytes, "data-bytes", "", "data bytes separated by `, `. eg:"+
+		"--data-bytes='1, 222, 54, 12, 32'")
+	signerCmd.Flags().StringVar(&seed, "seed", "", "your secret phrase")
+	signerCmd.Flags().BoolVar(&hash, "hash", false, "turn this flag on to hash the data before signing")
+}
+
+func Commands() *cobra.Command {
+	signerCmd.Run = SignData
+	return signerCmd
+}
+
+func SignData(*cobra.Command, []string) {
+	var (
+		unsignedBytes       []byte
+		hashedUnsignedBytes [32]byte
+		signature           []byte
+	)
+	if dataHex != "" {
+		unsignedBytes, _ = hex.DecodeString(dataHex)
+	} else {
+		txByteCharSlice := strings.Split(dataBytes, ", ")
+		for _, v := range txByteCharSlice {
+			byteValue, err := strconv.Atoi(v)
+			if err != nil {
+				panic("failed to parse transaction bytes")
+			}
+			unsignedBytes = append(unsignedBytes, byte(byteValue))
+		}
+	}
+	if hash {
+		hashedUnsignedBytes = sha3.Sum256(unsignedBytes)
+		signature, _ = (&crypto.Signature{}).Sign(hashedUnsignedBytes[:], model.SignatureType_DefaultSignature, seed)
+	} else {
+		signature, _ = (&crypto.Signature{}).Sign(unsignedBytes, model.SignatureType_DefaultSignature, seed)
+	}
+	edUtil := crypto.NewEd25519Signature()
+	fmt.Printf("account-address:\t%v\n", edUtil.GetAddressFromSeed(seed))
+	fmt.Printf("transaction-bytes:\t%v\n", unsignedBytes)
+	fmt.Printf("transaction-hash:\t%v\n", hex.EncodeToString(hashedUnsignedBytes[:]))
+	fmt.Printf("signature-bytes:\t%v\n", signature)
+	fmt.Printf("signature-hex:\t%v\n", hex.EncodeToString(signature))
+}
diff --git a/cmd/signature/const.go b/cmd/signature/const.go
new file mode 100644
index 000000000..a92680bab
--- /dev/null
+++ b/cmd/signature/const.go
@@ -0,0 +1,8 @@
+package signature
+
+var (
+	seed      string
+	dataHex   string
+	dataBytes string
+	hash      bool
+)
diff --git a/cmd/transaction/cmd.go b/cmd/transaction/cmd.go
index 05b9a7f57..26bfbc0f5 100644
--- a/cmd/transaction/cmd.go
+++ b/cmd/transaction/cmd.go
@@ -78,6 +78,7 @@ func init() {
 	txCmd.PersistentFlags().Int64Var(&fee, "fee", 1, "defines the fee of the transaction")
 	txCmd.PersistentFlags().BoolVar(&post, "post", false, "post generated bytes to [127.0.0.1:7000](default)")
 	txCmd.PersistentFlags().StringVar(&postHost, "post-host", "127.0.0.1:7000", "destination of post action")
+	txCmd.PersistentFlags().StringVar(&senderAddress, "sender-address", "", "transaction's sender address")
 	txCmd.PersistentFlags().Int32Var(
 		&senderSignatureType,
 		"sender-signature-type",
@@ -150,8 +151,8 @@ func init() {
 		"to be valid")
 	multiSigCmd.Flags().StringVar(&unsignedTxHex, "unsigned-transaction", "", "hex string of the unsigned transaction bytes")
 	multiSigCmd.Flags().StringVar(&txHash, "transaction-hash", "", "hash of transaction being signed by address-signature list (hex)")
-	multiSigCmd.Flags().StringSliceVar(&addressSignatures, "address-signatures", []string{}, "address-signature list "+
-		"--address-signatures='address1-signature1,address2-signature2'")
+	multiSigCmd.Flags().StringToStringVar(&addressSignatures, "address-signatures", make(map[string]string), "address:signature list "+
+		"--address1='signature1' --address2='signature2'")
 }
 
 // Commands set TXGeneratorCommandsInstance that will used by whole commands
diff --git a/cmd/transaction/const.go b/cmd/transaction/const.go
index cfd6163c2..dff3003ca 100644
--- a/cmd/transaction/const.go
+++ b/cmd/transaction/const.go
@@ -27,6 +27,7 @@ var (
 	fee                     int64
 	post                    bool
 	postHost                string
+	senderAddress           string
 	senderSignatureType     int32
 
 	// Send money transaction
@@ -55,7 +56,7 @@ var (
 
 	// multiSignature
 	unsignedTxHex     string
-	addressSignatures []string
+	addressSignatures map[string]string
 	txHash            string
 	addresses         []string
 	nonce             int64
diff --git a/cmd/transaction/generator.go b/cmd/transaction/generator.go
index 7beb66e44..c6b9ec8b6 100644
--- a/cmd/transaction/generator.go
+++ b/cmd/transaction/generator.go
@@ -239,22 +239,28 @@ func GenerateBasicTransaction(
 	timestamp, fee int64,
 	recipientAccountAddress string,
 ) *model.Transaction {
-	var senderAccountAddress string
-	switch model.SignatureType(senderSignatureType) {
-	case model.SignatureType_DefaultSignature:
-		senderAccountAddress = crypto.NewEd25519Signature().GetAddressFromSeed(senderSeed)
-	case model.SignatureType_BitcoinSignature:
-		var (
-			bitcoinSig = crypto.NewBitcoinSignature(crypto.DefaultBitcoinNetworkParams(), crypto.DefaultBitcoinCurve())
-			pubKey     = bitcoinSig.GetPublicKeyFromSeed(senderSeed, crypto.DefaultBitcoinPublicKeyFormat())
-			err        error
-		)
-		senderAccountAddress, err = bitcoinSig.GetAddressPublicKey(pubKey)
-		if err != nil {
-			fmt.Println("GenerateBasicTransaction-BitcoinSignature-Failed GetPublicKey")
+	var (
+		senderAccountAddress string
+	)
+	if senderSeed == "" {
+		senderAccountAddress = senderAddress
+	} else {
+		switch model.SignatureType(senderSignatureType) {
+		case model.SignatureType_DefaultSignature:
+			senderAccountAddress = crypto.NewEd25519Signature().GetAddressFromSeed(senderSeed)
+		case model.SignatureType_BitcoinSignature:
+			var (
+				bitcoinSig = crypto.NewBitcoinSignature(crypto.DefaultBitcoinNetworkParams(), crypto.DefaultBitcoinCurve())
+				pubKey     = bitcoinSig.GetPublicKeyFromSeed(senderSeed, crypto.DefaultBitcoinPublicKeyFormat())
+				err        error
+			)
+			senderAccountAddress, err = bitcoinSig.GetAddressPublicKey(pubKey)
+			if err != nil {
+				fmt.Println("GenerateBasicTransaction-BitcoinSignature-Failed GetPublicKey")
+			}
+		default:
+			panic("GenerateBasicTransaction-Invalid Signature Type")
 		}
-	default:
-		panic("GenerateBasicTransaction-Invalid Signature Type")
 	}
 
 	if timestamp <= 0 {
@@ -318,6 +324,9 @@ func GenerateSignedTxBytes(tx *model.Transaction, senderSeed string, signatureTy
 	tx.Fee += minimumFee
 
 	unsignedTxBytes, _ := transactionUtil.GetTransactionBytes(tx, false)
+	if senderSeed == "" {
+		return unsignedTxBytes
+	}
 	tx.Signature, _ = signature.Sign(
 		unsignedTxBytes,
 		model.SignatureType(signatureType),
@@ -388,7 +397,7 @@ func GeneratedMultiSignatureTransaction(
 	minSignature uint32,
 	nonce int64,
 	unsignedTxHex, txHash string,
-	addressSignatures, addresses []string,
+	addressSignatures map[string]string, addresses []string,
 ) *model.Transaction {
 	var (
 		signatures    = make(map[string][]byte)
@@ -410,29 +419,28 @@ func GeneratedMultiSignatureTransaction(
 			return nil
 		}
 	}
-
 	if txHash != "" {
 		transactionHash, err := hex.DecodeString(txHash)
 		if err != nil {
 			return nil
 		}
-		for _, v := range addressSignatures {
-			asig := strings.Split(v, "-")
-			if len(asig) < 2 {
-				return nil
+		for k, v := range addressSignatures {
+			if k == "" {
+				sigType := util.ConvertUint32ToBytes(2)
+				signatures[k] = sigType
+			} else {
+				signature, err := hex.DecodeString(v)
+				if err != nil {
+					return nil
+				}
+				signatures[k] = signature
 			}
-			signature, err := hex.DecodeString(asig[1])
-			if err != nil {
-				return nil
-			}
-			signatures[asig[0]] = signature
 		}
 		signatureInfo = &model.SignatureInfo{
 			TransactionHash: transactionHash,
 			Signatures:      signatures,
 		}
 	}
-
 	tx.TransactionType = util.ConvertBytesToUint32(txTypeMap["multiSignature"])
 	txBody := &model.MultiSignatureTransactionBody{
 		MultiSignatureInfo:       multiSigInfo,
diff --git a/cmd/zoomd b/cmd/zoomd
new file mode 100755
index 000000000..7fecc46bc
Binary files /dev/null and b/cmd/zoomd differ
diff --git a/common/crypto/signature.go b/common/crypto/signature.go
index aaecf05b8..0a8fd5a0f 100644
--- a/common/crypto/signature.go
+++ b/common/crypto/signature.go
@@ -129,6 +129,8 @@ func (*Signature) VerifySignature(payload, signature []byte, accountAddress stri
 			)
 		}
 		return nil
+	case model.SignatureType_MultisigSignature: // multisig validation-only
+		return nil
 	default:
 		return blocker.NewBlocker(
 			blocker.ValidationErr,
diff --git a/common/database/migration.go b/common/database/migration.go
index 671dc436f..cabf6af21 100644
--- a/common/database/migration.go
+++ b/common/database/migration.go
@@ -278,20 +278,23 @@ func (m *Migration) Init() error {
 			`,
 			`
 			CREATE TABLE IF NOT EXISTS "pending_transaction" (
+				"sender_address" TEXT,			-- sender of transaction 
 				"transaction_hash" BLOB,		-- transaction hash of pending transaction
 				"transaction_bytes" BLOB,		-- full transaction bytes of the pending transaction
 				"status" INTEGER,			-- execution status of the pending transaction
 				"block_height" INTEGER,			-- height when pending transaction inserted/updated
+				"latest" INTEGER,			-- latest flag for pending transaction
 				PRIMARY KEY("transaction_hash", "block_height")
 			)
 			`,
 			`
 			CREATE TABLE IF NOT EXISTS "pending_signature" (
-				"transaction_hash" INTEGER,		-- transaction hash of pending transaction being signed
+				"transaction_hash" BLOB,		-- transaction hash of pending transaction being signed
 				"account_address" TEXT,			-- account address of the respective signature
 				"signature" BLOB,			-- full transaction bytes of the pending transaction
 				"block_height" INTEGER,			-- height when pending signature inserted/updated
-				PRIMARY KEY("account_address", "transaction_hash")
+				"latest" INTEGER,			-- latest flag for pending signature 
+				PRIMARY KEY("account_address", "transaction_hash", "block_height")
 			)
 			`,
 			`
@@ -301,10 +304,15 @@ func (m *Migration) Init() error {
 				"nonce" INTEGER,			-- full transaction bytes of the pending transaction
 				"addresses" TEXT,			-- list of addresses / participants of the multisig account
 				"block_height" INTEGER,			-- height when multisignature_info inserted / updated
+				"latest" INTEGER,			-- latest flag for pending signature
 				PRIMARY KEY("multisig_address", "block_height")
 			)
 			`,
 			`
+			ALTER TABLE "transaction"
+				ADD COLUMN "multisig_child" INTEGER DEFAULT 0
+			`,
+			`
 			CREATE INDEX "node_registry_height_idx" ON "node_registry" ("height")
 			`,
 			`
diff --git a/common/model/multiSignature.pb.go b/common/model/multiSignature.pb.go
index fe07f8b22..c9e88dec1 100644
--- a/common/model/multiSignature.pb.go
+++ b/common/model/multiSignature.pb.go
@@ -57,6 +57,7 @@ type MultiSignatureInfo struct {
 	Addresses            []string `protobuf:"bytes,3,rep,name=Addresses,proto3" json:"Addresses,omitempty"`
 	MultisigAddress      string   `protobuf:"bytes,4,opt,name=MultisigAddress,proto3" json:"MultisigAddress,omitempty"`
 	BlockHeight          uint32   `protobuf:"varint,5,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
+	Latest               bool     `protobuf:"varint,6,opt,name=Latest,proto3" json:"Latest,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -122,6 +123,13 @@ func (m *MultiSignatureInfo) GetBlockHeight() uint32 {
 	return 0
 }
 
+func (m *MultiSignatureInfo) GetLatest() bool {
+	if m != nil {
+		return m.Latest
+	}
+	return false
+}
+
 // represent the signature posted by account
 type SignatureInfo struct {
 	TransactionHash      []byte            `protobuf:"bytes,1,opt,name=TransactionHash,proto3" json:"TransactionHash,omitempty"`
@@ -176,6 +184,7 @@ type PendingSignature struct {
 	AccountAddress       string   `protobuf:"bytes,2,opt,name=AccountAddress,proto3" json:"AccountAddress,omitempty"`
 	Signature            []byte   `protobuf:"bytes,3,opt,name=Signature,proto3" json:"Signature,omitempty"`
 	BlockHeight          uint32   `protobuf:"varint,4,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
+	Latest               bool     `protobuf:"varint,5,opt,name=Latest,proto3" json:"Latest,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -234,12 +243,21 @@ func (m *PendingSignature) GetBlockHeight() uint32 {
 	return 0
 }
 
+func (m *PendingSignature) GetLatest() bool {
+	if m != nil {
+		return m.Latest
+	}
+	return false
+}
+
 // represent transaction inside multisig body
 type PendingTransaction struct {
-	TransactionHash      []byte                   `protobuf:"bytes,1,opt,name=TransactionHash,proto3" json:"TransactionHash,omitempty"`
-	TransactionBytes     []byte                   `protobuf:"bytes,2,opt,name=TransactionBytes,proto3" json:"TransactionBytes,omitempty"`
-	Status               PendingTransactionStatus `protobuf:"varint,3,opt,name=Status,proto3,enum=model.PendingTransactionStatus" json:"Status,omitempty"`
-	BlockHeight          uint32                   `protobuf:"varint,4,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
+	SenderAddress        string                   `protobuf:"bytes,1,opt,name=SenderAddress,proto3" json:"SenderAddress,omitempty"`
+	TransactionHash      []byte                   `protobuf:"bytes,2,opt,name=TransactionHash,proto3" json:"TransactionHash,omitempty"`
+	TransactionBytes     []byte                   `protobuf:"bytes,3,opt,name=TransactionBytes,proto3" json:"TransactionBytes,omitempty"`
+	Status               PendingTransactionStatus `protobuf:"varint,4,opt,name=Status,proto3,enum=model.PendingTransactionStatus" json:"Status,omitempty"`
+	BlockHeight          uint32                   `protobuf:"varint,5,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"`
+	Latest               bool                     `protobuf:"varint,6,opt,name=Latest,proto3" json:"Latest,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
 	XXX_unrecognized     []byte                   `json:"-"`
 	XXX_sizecache        int32                    `json:"-"`
@@ -270,6 +288,13 @@ func (m *PendingTransaction) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_PendingTransaction proto.InternalMessageInfo
 
+func (m *PendingTransaction) GetSenderAddress() string {
+	if m != nil {
+		return m.SenderAddress
+	}
+	return ""
+}
+
 func (m *PendingTransaction) GetTransactionHash() []byte {
 	if m != nil {
 		return m.TransactionHash
@@ -298,6 +323,13 @@ func (m *PendingTransaction) GetBlockHeight() uint32 {
 	return 0
 }
 
+func (m *PendingTransaction) GetLatest() bool {
+	if m != nil {
+		return m.Latest
+	}
+	return false
+}
+
 func init() {
 	proto.RegisterEnum("model.PendingTransactionStatus", PendingTransactionStatus_name, PendingTransactionStatus_value)
 	proto.RegisterType((*MultiSignatureInfo)(nil), "model.MultiSignatureInfo")
@@ -310,34 +342,36 @@ func init() {
 func init() { proto.RegisterFile("model/multiSignature.proto", fileDescriptor_136af44c597c17ae) }
 
 var fileDescriptor_136af44c597c17ae = []byte{
-	// 454 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xdd, 0x6e, 0xd3, 0x30,
-	0x1c, 0xc5, 0x71, 0xb2, 0x4e, 0xea, 0x7f, 0x1f, 0x0d, 0x16, 0x42, 0xa6, 0xe2, 0x23, 0xaa, 0x10,
-	0xb2, 0x2a, 0x68, 0xd1, 0xb8, 0x00, 0x21, 0x71, 0xb1, 0x8a, 0x4a, 0xe3, 0x62, 0x03, 0x79, 0x5c,
-	0x71, 0x97, 0x3a, 0x26, 0xb5, 0xd6, 0xd8, 0x55, 0x6c, 0xa3, 0x95, 0xe7, 0xe0, 0x11, 0x78, 0x0e,
-	0xee, 0xe0, 0xb9, 0xd0, 0x9c, 0xd0, 0xa6, 0x09, 0x08, 0xf5, 0x26, 0x8a, 0x7f, 0xc7, 0x39, 0x3e,
-	0xff, 0x63, 0x05, 0xfa, 0xb9, 0x4e, 0xc5, 0x62, 0x9c, 0xbb, 0x85, 0x95, 0x97, 0x32, 0x53, 0x89,
-	0x75, 0x85, 0x18, 0x2d, 0x0b, 0x6d, 0x35, 0xee, 0x78, 0x6d, 0xf0, 0x0b, 0x01, 0x3e, 0xdf, 0xd2,
-	0xdf, 0xa9, 0xcf, 0x1a, 0x3f, 0x85, 0xdb, 0xe7, 0x52, 0xc9, 0xdc, 0xe5, 0x6b, 0x6e, 0x08, 0x8a,
-	0x11, 0x3d, 0x62, 0x6d, 0x01, 0x13, 0xe8, 0x5c, 0x68, 0xc5, 0x05, 0x09, 0x62, 0x44, 0xc3, 0x49,
-	0xf0, 0x1c, 0xb1, 0x12, 0xe0, 0xfb, 0xd0, 0x3d, 0x4d, 0xd3, 0x42, 0x18, 0x23, 0x0c, 0x09, 0xe3,
-	0x90, 0x76, 0xd9, 0x06, 0x60, 0x0a, 0x3d, 0x7f, 0xb6, 0x91, 0x59, 0x05, 0xc9, 0x5e, 0x8c, 0x68,
-	0x97, 0x35, 0x31, 0x8e, 0xe1, 0x60, 0xb2, 0xd0, 0xfc, 0xea, 0x4c, 0xc8, 0x6c, 0x6e, 0x49, 0xc7,
-	0x27, 0xa9, 0xa3, 0xc1, 0x0f, 0x04, 0x47, 0xdb, 0x33, 0x50, 0xe8, 0x7d, 0x2c, 0x12, 0x65, 0x12,
-	0x6e, 0xa5, 0x56, 0x67, 0x89, 0x99, 0xfb, 0x09, 0x0e, 0x59, 0x13, 0xe3, 0xb7, 0x00, 0xb5, 0x31,
-	0x83, 0x38, 0xa4, 0x07, 0x27, 0x8f, 0x47, 0xbe, 0xa0, 0xd1, 0x96, 0xe7, 0x66, 0x65, 0xa6, 0xca,
-	0x16, 0x2b, 0x56, 0xfb, 0xae, 0xff, 0x06, 0x7a, 0x0d, 0x19, 0x47, 0x10, 0x5e, 0x89, 0x95, 0x3f,
-	0xb6, 0xcb, 0x6e, 0x5e, 0xf1, 0x1d, 0xe8, 0x7c, 0x49, 0x16, 0xae, 0xac, 0xea, 0x90, 0x95, 0x8b,
-	0xd7, 0xc1, 0x2b, 0x34, 0xf8, 0x8e, 0x20, 0xfa, 0x20, 0x54, 0x2a, 0x55, 0xb6, 0xb6, 0xd9, 0x61,
-	0x86, 0x27, 0x70, 0x7c, 0xca, 0xb9, 0x76, 0xca, 0xfe, 0xa9, 0x32, 0xf0, 0xa7, 0x36, 0xe8, 0xcd,
-	0x8d, 0xac, 0xed, 0x49, 0xe8, 0xbd, 0x36, 0xa0, 0xd9, 0xf3, 0x5e, 0xbb, 0xe7, 0x9f, 0x08, 0x70,
-	0x15, 0xb3, 0x16, 0x61, 0x87, 0xa0, 0x43, 0x88, 0x6a, 0x68, 0xb2, 0xb2, 0xc2, 0x54, 0x65, 0xb4,
-	0x38, 0x7e, 0x09, 0xfb, 0x97, 0x36, 0xb1, 0xce, 0xf8, 0xa4, 0xc7, 0x27, 0x8f, 0xaa, 0x4b, 0x69,
-	0x07, 0x28, 0xb7, 0xb1, 0x6a, 0xfb, 0xff, 0xe7, 0x18, 0x7e, 0x43, 0x40, 0xfe, 0x65, 0x83, 0x1f,
-	0xc0, 0xbd, 0xb6, 0x56, 0x91, 0xe8, 0x16, 0x7e, 0x08, 0xfd, 0xb6, 0x3c, 0xbd, 0x16, 0xdc, 0x59,
-	0x91, 0x46, 0x08, 0xf7, 0xe1, 0x6e, 0x5b, 0xbf, 0xd0, 0xef, 0x97, 0x51, 0xf0, 0x77, 0xeb, 0xe9,
-	0xf5, 0x52, 0x16, 0x22, 0x8d, 0xc2, 0xc9, 0xf0, 0x13, 0xcd, 0xa4, 0x9d, 0xbb, 0xd9, 0x88, 0xeb,
-	0x7c, 0xfc, 0x55, 0xeb, 0x19, 0x2f, 0x9f, 0xcf, 0xb8, 0x2e, 0xc4, 0x98, 0xeb, 0x3c, 0xd7, 0x6a,
-	0xec, 0x5b, 0x98, 0xed, 0xfb, 0x3f, 0xf9, 0xc5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x15,
-	0x8a, 0xed, 0xe7, 0x03, 0x00, 0x00,
+	// 491 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xdf, 0x8a, 0xd3, 0x40,
+	0x14, 0xc6, 0x9d, 0x64, 0x53, 0xec, 0xd9, 0xed, 0x36, 0x0e, 0xb2, 0xc4, 0xe2, 0x9f, 0x50, 0x16,
+	0x09, 0x45, 0x5b, 0x59, 0x2f, 0x14, 0xc1, 0x8b, 0x2d, 0x16, 0x56, 0x70, 0x57, 0x99, 0x7a, 0xe5,
+	0x5d, 0x3a, 0x19, 0xd3, 0x61, 0x9b, 0x99, 0x92, 0x99, 0xc8, 0xd6, 0x5b, 0x5f, 0xc1, 0xc7, 0x11,
+	0x1f, 0xc5, 0x67, 0x91, 0x4e, 0xd2, 0x36, 0x7f, 0xaa, 0xa0, 0x37, 0x21, 0xf3, 0xfb, 0x26, 0x67,
+	0xce, 0xf7, 0xcd, 0x21, 0xd0, 0x4b, 0x64, 0xc4, 0x16, 0xa3, 0x24, 0x5b, 0x68, 0x3e, 0xe5, 0xb1,
+	0x08, 0x75, 0x96, 0xb2, 0xe1, 0x32, 0x95, 0x5a, 0x62, 0xc7, 0x68, 0xfd, 0x5f, 0x08, 0xf0, 0x65,
+	0x45, 0x7f, 0x2b, 0x3e, 0x4b, 0xfc, 0x04, 0xee, 0x5c, 0x72, 0xc1, 0x93, 0x2c, 0xd9, 0x72, 0xe5,
+	0x21, 0x1f, 0x05, 0x1d, 0xd2, 0x14, 0xb0, 0x07, 0xce, 0x95, 0x14, 0x94, 0x79, 0x96, 0x8f, 0x02,
+	0x7b, 0x6c, 0x3d, 0x43, 0x24, 0x07, 0xf8, 0x3e, 0xb4, 0xcf, 0xa3, 0x28, 0x65, 0x4a, 0x31, 0xe5,
+	0xd9, 0xbe, 0x1d, 0xb4, 0xc9, 0x0e, 0xe0, 0x00, 0xba, 0xe6, 0x6c, 0xc5, 0xe3, 0x02, 0x7a, 0x07,
+	0x3e, 0x0a, 0xda, 0xa4, 0x8e, 0xb1, 0x0f, 0x87, 0xe3, 0x85, 0xa4, 0xd7, 0x17, 0x8c, 0xc7, 0x73,
+	0xed, 0x39, 0xa6, 0x93, 0x32, 0xc2, 0x27, 0xd0, 0x7a, 0x17, 0x6a, 0xa6, 0xb4, 0xd7, 0xf2, 0x51,
+	0x70, 0x9b, 0x14, 0xab, 0xfe, 0x4f, 0x04, 0x9d, 0xaa, 0xb7, 0x00, 0xba, 0x1f, 0xd3, 0x50, 0xa8,
+	0x90, 0x6a, 0x2e, 0xc5, 0x45, 0xa8, 0xe6, 0xc6, 0xd9, 0x11, 0xa9, 0x63, 0xfc, 0x06, 0xa0, 0x64,
+	0xdf, 0xf2, 0xed, 0xe0, 0xf0, 0xec, 0x74, 0x68, 0x82, 0x1b, 0x56, 0x6a, 0xee, 0x56, 0x6a, 0x22,
+	0x74, 0xba, 0x22, 0xa5, 0xef, 0x7a, 0xaf, 0xa1, 0x5b, 0x93, 0xb1, 0x0b, 0xf6, 0x35, 0x5b, 0x99,
+	0x63, 0xdb, 0x64, 0xfd, 0x8a, 0xef, 0x82, 0xf3, 0x25, 0x5c, 0x64, 0x79, 0x84, 0x47, 0x24, 0x5f,
+	0xbc, 0xb2, 0x5e, 0xa2, 0xfe, 0x0f, 0x04, 0xee, 0x07, 0x26, 0x22, 0x2e, 0xe2, 0x6d, 0x99, 0x7f,
+	0xf0, 0xf0, 0x18, 0x8e, 0xcf, 0x29, 0x95, 0x99, 0xd0, 0x9b, 0x88, 0x2d, 0x73, 0x6a, 0x8d, 0xae,
+	0x6f, 0x6a, 0x5b, 0xde, 0xb3, 0x4d, 0xad, 0x1d, 0xa8, 0xe7, 0x7f, 0xf0, 0xb7, 0xfc, 0x9d, 0x4a,
+	0xfe, 0xdf, 0x2c, 0xc0, 0x45, 0xfb, 0xa5, 0xd6, 0xf0, 0x29, 0x74, 0xa6, 0x4c, 0x44, 0x2c, 0xdd,
+	0x74, 0x95, 0x67, 0x51, 0x85, 0xfb, 0x6c, 0x5a, 0xfb, 0x6d, 0x0e, 0xc0, 0x2d, 0xa1, 0xf1, 0x4a,
+	0x9b, 0x79, 0x5b, 0x6f, 0x6d, 0x70, 0xfc, 0x02, 0x5a, 0x53, 0x1d, 0xea, 0x2c, 0x9f, 0xb6, 0xe3,
+	0xb3, 0x47, 0xc5, 0x95, 0x36, 0xdb, 0xcc, 0xb7, 0x91, 0x62, 0xfb, 0xff, 0x4f, 0xe1, 0xe0, 0x3b,
+	0x02, 0xef, 0x4f, 0xe5, 0xf1, 0x03, 0xb8, 0xd7, 0xd4, 0x0a, 0xe2, 0xde, 0xc2, 0x0f, 0xa1, 0xd7,
+	0x94, 0x27, 0x37, 0x8c, 0x66, 0x9a, 0x45, 0x2e, 0xc2, 0x3d, 0x38, 0x69, 0xea, 0x57, 0xf2, 0xfd,
+	0xd2, 0xb5, 0xf6, 0x97, 0x9e, 0xdc, 0x2c, 0x79, 0xca, 0x22, 0xd7, 0x1e, 0x0f, 0x3e, 0x05, 0x31,
+	0xd7, 0xf3, 0x6c, 0x36, 0xa4, 0x32, 0x19, 0x7d, 0x95, 0x72, 0x46, 0xf3, 0xe7, 0x53, 0x2a, 0x53,
+	0x36, 0xa2, 0x32, 0x49, 0xa4, 0x18, 0x99, 0x74, 0x66, 0x2d, 0xf3, 0xdf, 0x78, 0xfe, 0x3b, 0x00,
+	0x00, 0xff, 0xff, 0x25, 0x40, 0xb8, 0x4b, 0x55, 0x04, 0x00, 0x00,
 }
diff --git a/common/model/signature.pb.go b/common/model/signature.pb.go
index 10aad9c0a..b9b488b19 100644
--- a/common/model/signature.pb.go
+++ b/common/model/signature.pb.go
@@ -28,16 +28,20 @@ const (
 	// in bytes: []byte{1,0,0,0}, bitcoin uses a specific Koblitz curve secp256k1
 	// Koblitz curves are a type of Elliptic Curve Digital Signature Algorithm
 	SignatureType_BitcoinSignature SignatureType = 1
+	// in bytes: []byte{2,0,0,0} for multisig validation purpose only
+	SignatureType_MultisigSignature SignatureType = 2
 )
 
 var SignatureType_name = map[int32]string{
 	0: "DefaultSignature",
 	1: "BitcoinSignature",
+	2: "MultisigSignature",
 }
 
 var SignatureType_value = map[string]int32{
-	"DefaultSignature": 0,
-	"BitcoinSignature": 1,
+	"DefaultSignature":  0,
+	"BitcoinSignature":  1,
+	"MultisigSignature": 2,
 }
 
 func (x SignatureType) String() string {
@@ -55,14 +59,15 @@ func init() {
 func init() { proto.RegisterFile("model/signature.proto", fileDescriptor_a69ee5fbbdd37ed5) }
 
 var fileDescriptor_a69ee5fbbdd37ed5 = []byte{
-	// 130 bytes of a gzipped FileDescriptorProto
+	// 145 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0xcd, 0x4f, 0x49,
 	0xcd, 0xd1, 0x2f, 0xce, 0x4c, 0xcf, 0x4b, 0x2c, 0x29, 0x2d, 0x4a, 0xd5, 0x2b, 0x28, 0xca, 0x2f,
-	0xc9, 0x17, 0x62, 0x05, 0x0b, 0x6b, 0x59, 0x73, 0xf1, 0x06, 0xc3, 0x64, 0x42, 0x2a, 0x0b, 0x52,
+	0xc9, 0x17, 0x62, 0x05, 0x0b, 0x6b, 0x05, 0x71, 0xf1, 0x06, 0xc3, 0x64, 0x42, 0x2a, 0x0b, 0x52,
 	0x85, 0x44, 0xb8, 0x04, 0x5c, 0x52, 0xd3, 0x12, 0x4b, 0x73, 0x4a, 0xe0, 0xe2, 0x02, 0x0c, 0x20,
-	0x51, 0xa7, 0xcc, 0x92, 0xe4, 0xfc, 0xcc, 0x3c, 0x84, 0x28, 0xa3, 0x93, 0x56, 0x94, 0x46, 0x7a,
-	0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x55, 0x7e, 0x7e, 0x52, 0x32, 0x84,
-	0xd4, 0x4d, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcd, 0xcd, 0xcf, 0xd3, 0x07, 0x5b, 0x94,
-	0xc4, 0x06, 0xb6, 0xd6, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x8c, 0x04, 0xb0, 0x8f, 0x00,
-	0x00, 0x00,
+	0x51, 0xa7, 0xcc, 0x92, 0xe4, 0xfc, 0xcc, 0x3c, 0x84, 0x28, 0xa3, 0x90, 0x28, 0x97, 0xa0, 0x6f,
+	0x69, 0x4e, 0x49, 0x66, 0x71, 0x66, 0x3a, 0x42, 0x98, 0xc9, 0x49, 0x2b, 0x4a, 0x23, 0x3d, 0xb3,
+	0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0xbf, 0x2a, 0x3f, 0x3f, 0x29, 0x19, 0x42, 0xea,
+	0x26, 0xe7, 0x17, 0xa5, 0xea, 0x27, 0xe7, 0xe7, 0xe6, 0xe6, 0xe7, 0xe9, 0x83, 0xed, 0x4f, 0x62,
+	0x03, 0xbb, 0xc6, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x53, 0x54, 0x61, 0xa6, 0x00, 0x00,
+	0x00,
 }
diff --git a/common/model/transaction.pb.go b/common/model/transaction.pb.go
index 80519d09a..5233955b1 100644
--- a/common/model/transaction.pb.go
+++ b/common/model/transaction.pb.go
@@ -94,7 +94,8 @@ type Transaction struct {
 	TransactionBodyLength   uint32 `protobuf:"varint,11,opt,name=TransactionBodyLength,proto3" json:"TransactionBodyLength,omitempty"`
 	TransactionBodyBytes    []byte `protobuf:"bytes,12,opt,name=TransactionBodyBytes,proto3" json:"TransactionBodyBytes,omitempty"`
 	TransactionIndex        uint32 `protobuf:"varint,13,opt,name=TransactionIndex,proto3" json:"TransactionIndex,omitempty"`
-	// TransactionBody
+	MultisigChild           bool   `protobuf:"varint,14,opt,name=MultisigChild,proto3" json:"MultisigChild,omitempty"`
+	// transactionbody
 	//
 	// Types that are valid to be assigned to TransactionBody:
 	//	*Transaction_EmptyTransactionBody
@@ -108,9 +109,9 @@ type Transaction struct {
 	//	*Transaction_ApprovalEscrowTransactionBody
 	//	*Transaction_MultiSignatureTransactionBody
 	TransactionBody isTransaction_TransactionBody `protobuf_oneof:"TransactionBody"`
-	Signature       []byte                        `protobuf:"bytes,24,opt,name=Signature,proto3" json:"Signature,omitempty"`
+	Signature       []byte                        `protobuf:"bytes,25,opt,name=Signature,proto3" json:"Signature,omitempty"`
 	// nullable
-	Escrow               *Escrow  `protobuf:"bytes,25,opt,name=Escrow,proto3" json:"Escrow,omitempty"`
+	Escrow               *Escrow  `protobuf:"bytes,26,opt,name=Escrow,proto3" json:"Escrow,omitempty"`
 	XXX_NoUnkeyedLiteral struct{} `json:"-"`
 	XXX_unrecognized     []byte   `json:"-"`
 	XXX_sizecache        int32    `json:"-"`
@@ -232,48 +233,55 @@ func (m *Transaction) GetTransactionIndex() uint32 {
 	return 0
 }
 
+func (m *Transaction) GetMultisigChild() bool {
+	if m != nil {
+		return m.MultisigChild
+	}
+	return false
+}
+
 type isTransaction_TransactionBody interface {
 	isTransaction_TransactionBody()
 }
 
 type Transaction_EmptyTransactionBody struct {
-	EmptyTransactionBody *EmptyTransactionBody `protobuf:"bytes,14,opt,name=emptyTransactionBody,proto3,oneof"`
+	EmptyTransactionBody *EmptyTransactionBody `protobuf:"bytes,15,opt,name=emptyTransactionBody,proto3,oneof"`
 }
 
 type Transaction_SendMoneyTransactionBody struct {
-	SendMoneyTransactionBody *SendMoneyTransactionBody `protobuf:"bytes,15,opt,name=sendMoneyTransactionBody,proto3,oneof"`
+	SendMoneyTransactionBody *SendMoneyTransactionBody `protobuf:"bytes,16,opt,name=sendMoneyTransactionBody,proto3,oneof"`
 }
 
 type Transaction_NodeRegistrationTransactionBody struct {
-	NodeRegistrationTransactionBody *NodeRegistrationTransactionBody `protobuf:"bytes,16,opt,name=nodeRegistrationTransactionBody,proto3,oneof"`
+	NodeRegistrationTransactionBody *NodeRegistrationTransactionBody `protobuf:"bytes,17,opt,name=nodeRegistrationTransactionBody,proto3,oneof"`
 }
 
 type Transaction_UpdateNodeRegistrationTransactionBody struct {
-	UpdateNodeRegistrationTransactionBody *UpdateNodeRegistrationTransactionBody `protobuf:"bytes,17,opt,name=updateNodeRegistrationTransactionBody,proto3,oneof"`
+	UpdateNodeRegistrationTransactionBody *UpdateNodeRegistrationTransactionBody `protobuf:"bytes,18,opt,name=updateNodeRegistrationTransactionBody,proto3,oneof"`
 }
 
 type Transaction_RemoveNodeRegistrationTransactionBody struct {
-	RemoveNodeRegistrationTransactionBody *RemoveNodeRegistrationTransactionBody `protobuf:"bytes,18,opt,name=removeNodeRegistrationTransactionBody,proto3,oneof"`
+	RemoveNodeRegistrationTransactionBody *RemoveNodeRegistrationTransactionBody `protobuf:"bytes,19,opt,name=removeNodeRegistrationTransactionBody,proto3,oneof"`
 }
 
 type Transaction_ClaimNodeRegistrationTransactionBody struct {
-	ClaimNodeRegistrationTransactionBody *ClaimNodeRegistrationTransactionBody `protobuf:"bytes,19,opt,name=claimNodeRegistrationTransactionBody,proto3,oneof"`
+	ClaimNodeRegistrationTransactionBody *ClaimNodeRegistrationTransactionBody `protobuf:"bytes,20,opt,name=claimNodeRegistrationTransactionBody,proto3,oneof"`
 }
 
 type Transaction_SetupAccountDatasetTransactionBody struct {
-	SetupAccountDatasetTransactionBody *SetupAccountDatasetTransactionBody `protobuf:"bytes,20,opt,name=setupAccountDatasetTransactionBody,proto3,oneof"`
+	SetupAccountDatasetTransactionBody *SetupAccountDatasetTransactionBody `protobuf:"bytes,21,opt,name=setupAccountDatasetTransactionBody,proto3,oneof"`
 }
 
 type Transaction_RemoveAccountDatasetTransactionBody struct {
-	RemoveAccountDatasetTransactionBody *RemoveAccountDatasetTransactionBody `protobuf:"bytes,21,opt,name=removeAccountDatasetTransactionBody,proto3,oneof"`
+	RemoveAccountDatasetTransactionBody *RemoveAccountDatasetTransactionBody `protobuf:"bytes,22,opt,name=removeAccountDatasetTransactionBody,proto3,oneof"`
 }
 
 type Transaction_ApprovalEscrowTransactionBody struct {
-	ApprovalEscrowTransactionBody *ApprovalEscrowTransactionBody `protobuf:"bytes,22,opt,name=approvalEscrowTransactionBody,proto3,oneof"`
+	ApprovalEscrowTransactionBody *ApprovalEscrowTransactionBody `protobuf:"bytes,23,opt,name=approvalEscrowTransactionBody,proto3,oneof"`
 }
 
 type Transaction_MultiSignatureTransactionBody struct {
-	MultiSignatureTransactionBody *MultiSignatureTransactionBody `protobuf:"bytes,23,opt,name=multiSignatureTransactionBody,proto3,oneof"`
+	MultiSignatureTransactionBody *MultiSignatureTransactionBody `protobuf:"bytes,24,opt,name=multiSignatureTransactionBody,proto3,oneof"`
 }
 
 func (*Transaction_EmptyTransactionBody) isTransaction_TransactionBody() {}
@@ -1554,96 +1562,97 @@ func init() {
 func init() { proto.RegisterFile("model/transaction.proto", fileDescriptor_8333001f09b34082) }
 
 var fileDescriptor_8333001f09b34082 = []byte{
-	// 1449 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4f, 0x6f, 0xdb, 0xc6,
-	0x12, 0x17, 0x29, 0xcb, 0xb1, 0x47, 0x92, 0x23, 0x6f, 0x64, 0x89, 0x71, 0xec, 0x58, 0x8f, 0xb1,
-	0x0d, 0x3d, 0x27, 0xb1, 0x5f, 0xfc, 0x82, 0x34, 0xcd, 0xcd, 0x8a, 0x93, 0xca, 0x68, 0xdc, 0xb8,
-	0x6b, 0x27, 0x87, 0x00, 0x3d, 0xd0, 0xd4, 0x46, 0x22, 0x22, 0x71, 0x59, 0x72, 0x95, 0xd4, 0x4d,
-	0x51, 0xa0, 0x69, 0x7b, 0x28, 0xd0, 0x63, 0xbf, 0x52, 0xbf, 0x45, 0x2f, 0x2d, 0x7a, 0xea, 0x87,
-	0x28, 0x0a, 0x2e, 0x57, 0x12, 0x97, 0xa2, 0x48, 0x36, 0xbd, 0xf4, 0x22, 0x40, 0xf3, 0x9b, 0x9d,
-	0x3f, 0xbb, 0xc3, 0xdf, 0xce, 0x2c, 0xd4, 0x07, 0xb4, 0x43, 0xfa, 0x7b, 0xcc, 0x35, 0x6c, 0xcf,
-	0x30, 0x99, 0x45, 0xed, 0x5d, 0xc7, 0xa5, 0x8c, 0xa2, 0x02, 0x07, 0x56, 0xd7, 0x02, 0xdc, 0x71,
-	0x29, 0x7d, 0xf9, 0xf4, 0xe5, 0xd3, 0x37, 0x36, 0x71, 0xbd, 0x9e, 0xe5, 0x04, 0x4a, 0xab, 0x35,
-	0x81, 0x1a, 0x5d, 0xcb, 0x36, 0x26, 0x8b, 0x57, 0xb5, 0x40, 0x7e, 0x6e, 0x30, 0xb3, 0x87, 0x89,
-	0x49, 0x2c, 0x87, 0x09, 0x44, 0xd8, 0xb3, 0x69, 0x87, 0x60, 0xd2, 0xb5, 0x3c, 0xe6, 0x86, 0xd7,
-	0xa1, 0x00, 0x25, 0x9e, 0xe9, 0xd2, 0x37, 0x42, 0xb6, 0x1a, 0xc8, 0x06, 0xc3, 0x3e, 0xb3, 0x4e,
-	0xad, 0xae, 0x6d, 0xb0, 0xa1, 0x4b, 0x02, 0x4c, 0xff, 0xa3, 0x0c, 0xc5, 0xb3, 0x49, 0xe8, 0x48,
-	0x83, 0x4b, 0xcf, 0x89, 0xeb, 0x59, 0xd4, 0xd6, 0x94, 0x86, 0xd2, 0x2c, 0xe3, 0xd1, 0x5f, 0x84,
-	0x40, 0x3d, 0x3a, 0xd4, 0xd4, 0x86, 0xd2, 0xcc, 0xb7, 0xd4, 0xff, 0x29, 0x58, 0x3d, 0x3a, 0x44,
-	0x6b, 0x70, 0xa9, 0xd5, 0xa7, 0xe6, 0xab, 0xa3, 0x43, 0x2d, 0x3f, 0x06, 0x46, 0x22, 0x54, 0x83,
-	0xf9, 0x36, 0xb1, 0xba, 0x3d, 0xa6, 0xcd, 0x71, 0x53, 0xe2, 0x1f, 0xda, 0x87, 0xea, 0x29, 0xb1,
-	0x3b, 0xc4, 0x3d, 0x30, 0x4d, 0x3a, 0xb4, 0xd9, 0x41, 0xa7, 0xe3, 0x12, 0xcf, 0xd3, 0x0a, 0x0d,
-	0xa5, 0xb9, 0x88, 0x63, 0x31, 0x74, 0x1f, 0xea, 0x98, 0x98, 0x96, 0x63, 0x11, 0x9b, 0x45, 0x96,
-	0xcd, 0xf3, 0x65, 0xb3, 0x60, 0xd4, 0x84, 0xcb, 0xa1, 0x04, 0xcf, 0x2e, 0x1c, 0xa2, 0x5d, 0xe2,
-	0xe1, 0x44, 0xc5, 0xa8, 0x0a, 0xf9, 0xc7, 0x84, 0x68, 0x0b, 0xe3, 0x4c, 0xfc, 0xbf, 0xa8, 0x01,
-	0x8b, 0x67, 0xd6, 0x80, 0x78, 0xcc, 0x18, 0x38, 0xda, 0xe2, 0x18, 0x9b, 0x08, 0x23, 0x1e, 0xda,
-	0x86, 0xd7, 0xd3, 0xa0, 0xa1, 0x34, 0x4b, 0x38, 0x2a, 0x46, 0x77, 0x61, 0x25, 0x24, 0x6a, 0xd1,
-	0xce, 0xc5, 0x13, 0x62, 0x77, 0x59, 0x4f, 0x2b, 0xf2, 0x88, 0xe2, 0x41, 0x7f, 0xbf, 0x22, 0x40,
-	0xeb, 0x82, 0x11, 0x4f, 0x2b, 0x71, 0x27, 0xb1, 0x18, 0xda, 0x81, 0x4a, 0x48, 0x7e, 0x64, 0x77,
-	0xc8, 0x17, 0x5a, 0x99, 0x3b, 0x99, 0x92, 0xa3, 0x4f, 0xa1, 0x4a, 0x06, 0x0e, 0xbb, 0x88, 0x18,
-	0xd2, 0x96, 0x1a, 0x4a, 0xb3, 0xb8, 0x7f, 0x6d, 0x97, 0x97, 0xcf, 0xee, 0xa3, 0x18, 0x95, 0x76,
-	0x0e, 0xc7, 0x2e, 0x45, 0x9f, 0x81, 0xe6, 0x11, 0xbb, 0x73, 0x4c, 0x6d, 0x32, 0x65, 0xf6, 0x32,
-	0x37, 0xbb, 0x21, 0xcc, 0x9e, 0xce, 0x50, 0x6b, 0xe7, 0xf0, 0x4c, 0x13, 0xc8, 0x85, 0x8d, 0x68,
-	0xfd, 0x47, 0xbd, 0x54, 0xb8, 0x97, 0x6d, 0xe1, 0xe5, 0x93, 0x64, 0xed, 0x76, 0x0e, 0xa7, 0x19,
-	0x44, 0xdf, 0x29, 0xb0, 0x35, 0x74, 0x3a, 0x06, 0x23, 0x29, 0xc6, 0xb4, 0x65, 0xee, 0xfa, 0x96,
-	0x70, 0xfd, 0x2c, 0xcb, 0x9a, 0x76, 0x0e, 0x67, 0x33, 0xce, 0xc3, 0x70, 0xc9, 0x80, 0xbe, 0x4e,
-	0x0d, 0x03, 0x49, 0x61, 0xe0, 0x2c, 0x6b, 0xfc, 0x30, 0x32, 0x19, 0x47, 0xdf, 0x28, 0xb0, 0x69,
-	0xf6, 0x0d, 0x6b, 0x90, 0x16, 0xc5, 0x15, 0x1e, 0xc5, 0x4d, 0x11, 0xc5, 0xc3, 0x0c, 0x4b, 0xda,
-	0x39, 0x9c, 0xc9, 0x34, 0x7a, 0x0b, 0xba, 0x47, 0xd8, 0xd0, 0x11, 0x1f, 0xfc, 0xa1, 0xc1, 0x0c,
-	0x8f, 0xb0, 0x68, 0x00, 0x55, 0x1e, 0xc0, 0x7f, 0xc7, 0xe5, 0x96, 0xb6, 0xa0, 0x9d, 0xc3, 0x19,
-	0xcc, 0xa2, 0xaf, 0xe1, 0x46, 0xb0, 0x53, 0xc9, 0xde, 0x57, 0xb8, 0xf7, 0x1d, 0xe9, 0x10, 0xd2,
-	0xdc, 0x67, 0x31, 0x8c, 0xfa, 0xb0, 0x6e, 0x38, 0x8e, 0x4b, 0x5f, 0x1b, 0xfd, 0x47, 0x9c, 0xec,
-	0xa3, 0x9e, 0x6b, 0xdc, 0xf3, 0xa6, 0xf0, 0x7c, 0x90, 0xa4, 0xdb, 0xce, 0xe1, 0x64, 0x63, 0xbe,
-	0x37, 0xf9, 0xfa, 0x88, 0x7a, 0xab, 0x4b, 0xde, 0x8e, 0x93, 0x74, 0x7d, 0x6f, 0x89, 0xc6, 0xd0,
-	0x1a, 0x2c, 0x8e, 0x31, 0x4d, 0xe3, 0x2c, 0x37, 0x11, 0xa0, 0x2d, 0x98, 0x0f, 0x82, 0xd4, 0xae,
-	0x72, 0xa7, 0xe5, 0x11, 0x41, 0x71, 0x21, 0x16, 0x60, 0x6b, 0x59, 0x62, 0x65, 0xdf, 0xae, 0x5e,
-	0x83, 0x6a, 0x1c, 0x8b, 0xe9, 0xf7, 0x40, 0x9b, 0x45, 0x43, 0x68, 0x15, 0xe6, 0x0f, 0x06, 0xfe,
-	0x39, 0xf0, 0xfb, 0x30, 0xe0, 0x7e, 0x21, 0xd1, 0xff, 0x54, 0x60, 0x23, 0xad, 0x48, 0x37, 0xa1,
-	0xec, 0xab, 0x9c, 0x0c, 0xcf, 0xfb, 0x96, 0xf9, 0x31, 0xb9, 0xe0, 0x66, 0x4a, 0x58, 0x16, 0xa2,
-	0x6d, 0x58, 0x8a, 0xdc, 0x6a, 0x2a, 0xbf, 0xd5, 0x22, 0x52, 0x74, 0x17, 0x8a, 0xfe, 0xc2, 0x91,
-	0x52, 0x9e, 0x6f, 0x00, 0x0a, 0x91, 0x9c, 0x40, 0x70, 0x58, 0x0d, 0x35, 0xa1, 0xfc, 0x84, 0x9a,
-	0xaf, 0x48, 0xa7, 0x65, 0xf4, 0x0d, 0xdb, 0x24, 0xfc, 0x3e, 0x0e, 0x52, 0x91, 0x01, 0x74, 0x1b,
-	0x0a, 0x27, 0x94, 0xbe, 0xb1, 0xf9, 0x5d, 0x5c, 0xdc, 0xaf, 0x0b, 0xcb, 0x27, 0x91, 0xe6, 0x05,
-	0x07, 0x5a, 0xfa, 0x2f, 0x0a, 0x6c, 0x65, 0xe2, 0xb7, 0x8c, 0xdb, 0x10, 0x49, 0x4f, 0x7d, 0xcf,
-	0xf4, 0xf2, 0xa9, 0xe9, 0xcd, 0x65, 0x4a, 0xef, 0x18, 0xb6, 0x32, 0xd1, 0x66, 0xb6, 0xec, 0xf4,
-	0xb7, 0xb0, 0x99, 0x85, 0xff, 0x32, 0xee, 0xd5, 0x38, 0x17, 0x35, 0x53, 0x2e, 0xbf, 0x2b, 0xa0,
-	0xa7, 0x93, 0x5f, 0xd0, 0x9b, 0x31, 0x36, 0xd5, 0x9b, 0x29, 0xa3, 0xde, 0x6c, 0x1a, 0x4b, 0xea,
-	0xcd, 0xd4, 0xe4, 0xde, 0x6c, 0x15, 0x16, 0x4e, 0x5c, 0xea, 0x10, 0x97, 0x5d, 0xf0, 0x43, 0x5b,
-	0xc4, 0xe3, 0xff, 0xa8, 0x0a, 0x85, 0xe7, 0x46, 0x7f, 0x18, 0x14, 0xeb, 0x22, 0x0e, 0xfe, 0xa0,
-	0xeb, 0xb0, 0x70, 0x3c, 0x34, 0x7b, 0x7e, 0xf3, 0xc5, 0x6b, 0x74, 0x8e, 0x1f, 0xf3, 0x58, 0xa6,
-	0xff, 0xac, 0xc0, 0x8d, 0x0c, 0x2c, 0xfb, 0x6f, 0xcf, 0x53, 0xff, 0x0a, 0xd6, 0x13, 0x29, 0x1b,
-	0xdd, 0x81, 0x85, 0x91, 0x02, 0x0f, 0x7a, 0x69, 0x7f, 0x45, 0xe2, 0xc1, 0x11, 0x88, 0xc7, 0x6a,
-	0xfe, 0x77, 0x12, 0xee, 0xfd, 0xc2, 0xcd, 0xbc, 0x0c, 0xe8, 0xbf, 0x29, 0xb0, 0x9e, 0xc8, 0xe1,
-	0xe8, 0x08, 0x90, 0xac, 0x70, 0x64, 0xbf, 0xa4, 0x3c, 0x90, 0xe2, 0xfe, 0xd5, 0xd8, 0x5b, 0xc0,
-	0x57, 0xc0, 0x31, 0x8b, 0xd0, 0x03, 0xd0, 0x9e, 0xd9, 0x9e, 0xd5, 0xb5, 0x49, 0x27, 0xec, 0x85,
-	0xb7, 0xb8, 0x2a, 0xaf, 0xfc, 0x99, 0x38, 0x7a, 0x00, 0x65, 0x39, 0x82, 0x80, 0x11, 0xab, 0xa3,
-	0xdb, 0x5e, 0x72, 0x2e, 0xab, 0xea, 0x37, 0x61, 0xe5, 0x23, 0xa9, 0x30, 0x30, 0xf9, 0x7c, 0x48,
-	0x3c, 0x26, 0x26, 0x1d, 0x25, 0x3c, 0xe9, 0xe8, 0x3f, 0xa8, 0x50, 0x93, 0xb5, 0xbd, 0x91, 0xfa,
-	0x34, 0x77, 0x2b, 0xb1, 0xdc, 0x3d, 0x19, 0x87, 0x54, 0x69, 0x1c, 0xda, 0x81, 0xa5, 0xf1, 0x2c,
-	0x71, 0xca, 0x0c, 0x97, 0x85, 0xf8, 0x2b, 0x82, 0xa0, 0x6d, 0x28, 0x8d, 0x25, 0x8f, 0xec, 0x4e,
-	0x88, 0xc8, 0x25, 0x79, 0xdc, 0xd0, 0x53, 0x88, 0x1f, 0x7a, 0xee, 0x00, 0x9c, 0x8c, 0x87, 0x4f,
-	0x3e, 0x4b, 0x15, 0xf7, 0x97, 0x47, 0x5c, 0x32, 0x06, 0x70, 0x48, 0x49, 0x7f, 0x05, 0xf5, 0xa9,
-	0xad, 0xf0, 0x1c, 0x6a, 0x7b, 0x04, 0x69, 0x50, 0x38, 0xa3, 0x4c, 0x94, 0x64, 0xf0, 0x6d, 0x06,
-	0x02, 0x74, 0x0f, 0x4a, 0xe1, 0x15, 0x9a, 0xda, 0xc8, 0x87, 0xb8, 0x3d, 0x7c, 0x0a, 0x92, 0x9e,
-	0x7e, 0x08, 0xb5, 0x13, 0xea, 0xc5, 0x1d, 0x93, 0x3c, 0xe2, 0x04, 0xf5, 0x12, 0x30, 0xe5, 0x94,
-	0x5c, 0x7f, 0x0a, 0xf5, 0x29, 0x2b, 0x22, 0xe4, 0xbb, 0xd2, 0x00, 0x2c, 0x4a, 0x38, 0x2e, 0xae,
-	0xb0, 0x9a, 0xfe, 0xa3, 0x02, 0x35, 0xbf, 0x67, 0xf8, 0x67, 0x71, 0xf9, 0x9d, 0xce, 0xc3, 0x9e,
-	0x61, 0x05, 0x27, 0xe4, 0x97, 0x45, 0x01, 0x4f, 0x04, 0xfe, 0x29, 0x06, 0xc3, 0xf0, 0xe4, 0x2a,
-	0xc8, 0x07, 0x83, 0x65, 0x44, 0xac, 0x63, 0xa8, 0x4f, 0x45, 0x23, 0xf2, 0xfb, 0x00, 0x4a, 0xad,
-	0xd0, 0x2b, 0x82, 0x48, 0xf0, 0x8a, 0x48, 0x30, 0x0c, 0x61, 0x49, 0x51, 0xff, 0x5e, 0x81, 0x0d,
-	0x91, 0x13, 0x9f, 0xe8, 0x67, 0xd4, 0xbe, 0xc4, 0x1c, 0x7e, 0xa6, 0xf9, 0x66, 0x1e, 0x47, 0xa4,
-	0x29, 0x79, 0x26, 0x3e, 0x23, 0xe8, 0x3f, 0x29, 0xb0, 0xe6, 0x27, 0x37, 0x33, 0x08, 0xc9, 0xb8,
-	0x12, 0x35, 0x7e, 0x0b, 0x96, 0xc3, 0x8b, 0x46, 0xbc, 0x92, 0x6f, 0x96, 0xf0, 0x34, 0xf0, 0x37,
-	0xb6, 0xfc, 0x05, 0xac, 0xcf, 0x88, 0x4a, 0x6c, 0xfc, 0x87, 0x50, 0x0e, 0xef, 0x67, 0xb0, 0x35,
-	0x33, 0x76, 0x5e, 0xd6, 0xd4, 0x8f, 0x61, 0x43, 0xfe, 0xc2, 0x8e, 0x2d, 0xdb, 0x1a, 0x0c, 0x07,
-	0x8f, 0x09, 0x79, 0x9f, 0xea, 0xbf, 0x0f, 0x8d, 0xd9, 0xe6, 0x44, 0xb4, 0xe2, 0xf1, 0x43, 0x91,
-	0x1e, 0x3f, 0x76, 0x7e, 0x55, 0x21, 0xe6, 0x99, 0xa4, 0x12, 0xed, 0xa2, 0x2b, 0x39, 0xa4, 0x05,
-	0x8f, 0x3a, 0xd1, 0x1e, 0xba, 0xa2, 0xa0, 0x0d, 0xb8, 0x96, 0xd0, 0xf1, 0x54, 0x54, 0xb4, 0x0d,
-	0xff, 0x49, 0x6d, 0x22, 0x2b, 0xef, 0xb8, 0x5e, 0x6a, 0x3b, 0x56, 0x79, 0x37, 0x87, 0xb6, 0xa0,
-	0x91, 0xd6, 0x67, 0x55, 0xde, 0xcd, 0x23, 0x1d, 0xae, 0x27, 0x37, 0x44, 0x95, 0x3c, 0xda, 0xf4,
-	0x3f, 0x81, 0xc4, 0x6e, 0xa2, 0xf2, 0xad, 0x8a, 0xd6, 0xe1, 0xea, 0xcc, 0xcb, 0xba, 0x32, 0xe7,
-	0xc3, 0x33, 0x2f, 0xd3, 0x4a, 0xa1, 0xb5, 0xf3, 0xa2, 0xd9, 0xb5, 0x58, 0x6f, 0x78, 0xbe, 0x6b,
-	0xd2, 0xc1, 0xde, 0x97, 0x94, 0x9e, 0x9b, 0xc1, 0xef, 0x6d, 0x93, 0xba, 0x64, 0xcf, 0xa4, 0x83,
-	0x01, 0xb5, 0xf7, 0x78, 0xd1, 0x9c, 0xcf, 0xf3, 0x57, 0xbb, 0xff, 0xff, 0x15, 0x00, 0x00, 0xff,
-	0xff, 0x5e, 0x24, 0x3a, 0xdd, 0x75, 0x14, 0x00, 0x00,
+	// 1468 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6e, 0xdb, 0xc6,
+	0x16, 0x16, 0x29, 0xcb, 0xb1, 0x8f, 0x24, 0x47, 0x9e, 0xc8, 0x12, 0xa3, 0xd8, 0xb1, 0x2e, 0x63,
+	0x1b, 0xba, 0x4e, 0x62, 0xdf, 0xf8, 0x06, 0x69, 0x9a, 0x9d, 0x15, 0x27, 0x95, 0xd1, 0xa8, 0x71,
+	0xc7, 0x4e, 0x16, 0x01, 0xba, 0xa0, 0xa9, 0x89, 0x44, 0x44, 0xe2, 0xb0, 0xe4, 0x28, 0xa9, 0x9b,
+	0xa2, 0x40, 0xd3, 0x76, 0x51, 0xa0, 0x8b, 0x2e, 0xfa, 0x4a, 0x7d, 0x8b, 0x6e, 0x5a, 0xf4, 0x39,
+	0x8a, 0x82, 0xc3, 0x91, 0xc4, 0xa1, 0x28, 0x8a, 0x4d, 0x37, 0xdd, 0x08, 0xd0, 0xf9, 0xce, 0xef,
+	0xcc, 0xe1, 0xf9, 0x19, 0xa8, 0x0e, 0x68, 0x87, 0xf4, 0xf7, 0x99, 0x6b, 0xd8, 0x9e, 0x61, 0x32,
+	0x8b, 0xda, 0x7b, 0x8e, 0x4b, 0x19, 0x45, 0x39, 0x0e, 0xd4, 0xd6, 0x03, 0xdc, 0x71, 0x29, 0x7d,
+	0xf9, 0xf4, 0xe5, 0xd3, 0x37, 0x36, 0x71, 0xbd, 0x9e, 0xe5, 0x04, 0x4c, 0xb5, 0x8a, 0x40, 0x8d,
+	0xae, 0x65, 0x1b, 0x13, 0xe1, 0x9a, 0x16, 0xd0, 0xcf, 0x0d, 0x66, 0xf6, 0x30, 0x31, 0x89, 0xe5,
+	0x30, 0x81, 0x08, 0x7d, 0x36, 0xed, 0x10, 0x4c, 0xba, 0x96, 0xc7, 0xdc, 0xb0, 0x1c, 0x0a, 0x50,
+	0xe2, 0x99, 0x2e, 0x7d, 0x23, 0x68, 0xb5, 0x80, 0x36, 0x18, 0xf6, 0x99, 0x75, 0x6a, 0x75, 0x6d,
+	0x83, 0x0d, 0x5d, 0x12, 0x60, 0xfa, 0x4f, 0x2b, 0x90, 0x3f, 0x9b, 0xb8, 0x8e, 0x34, 0xb8, 0xf4,
+	0x9c, 0xb8, 0x9e, 0x45, 0x6d, 0x4d, 0xa9, 0x2b, 0x8d, 0x22, 0x1e, 0xfd, 0x45, 0x08, 0xd4, 0xe3,
+	0x23, 0x4d, 0xad, 0x2b, 0x8d, 0x6c, 0x53, 0xfd, 0x9f, 0x82, 0xd5, 0xe3, 0x23, 0xb4, 0x0e, 0x97,
+	0x9a, 0x7d, 0x6a, 0xbe, 0x3a, 0x3e, 0xd2, 0xb2, 0x63, 0x60, 0x44, 0x42, 0x15, 0x58, 0x6c, 0x11,
+	0xab, 0xdb, 0x63, 0xda, 0x02, 0x57, 0x25, 0xfe, 0xa1, 0x03, 0x28, 0x9f, 0x12, 0xbb, 0x43, 0xdc,
+	0x43, 0xd3, 0xa4, 0x43, 0x9b, 0x1d, 0x76, 0x3a, 0x2e, 0xf1, 0x3c, 0x2d, 0x57, 0x57, 0x1a, 0xcb,
+	0x38, 0x16, 0x43, 0xf7, 0xa1, 0x8a, 0x89, 0x69, 0x39, 0x16, 0xb1, 0x59, 0x44, 0x6c, 0x91, 0x8b,
+	0xcd, 0x82, 0x51, 0x03, 0x2e, 0x87, 0x02, 0x3c, 0xbb, 0x70, 0x88, 0x76, 0x89, 0xbb, 0x13, 0x25,
+	0xa3, 0x32, 0x64, 0x1f, 0x13, 0xa2, 0x2d, 0x8d, 0x23, 0xf1, 0xff, 0xa2, 0x3a, 0x2c, 0x9f, 0x59,
+	0x03, 0xe2, 0x31, 0x63, 0xe0, 0x68, 0xcb, 0x63, 0x6c, 0x42, 0x8c, 0x58, 0x68, 0x19, 0x5e, 0x4f,
+	0x83, 0xba, 0xd2, 0x28, 0xe0, 0x28, 0x19, 0xdd, 0x85, 0xb5, 0x10, 0xa9, 0x49, 0x3b, 0x17, 0x4f,
+	0x88, 0xdd, 0x65, 0x3d, 0x2d, 0xcf, 0x3d, 0x8a, 0x07, 0xfd, 0xf3, 0x8a, 0x00, 0xcd, 0x0b, 0x46,
+	0x3c, 0xad, 0xc0, 0x8d, 0xc4, 0x62, 0x68, 0x17, 0x4a, 0x21, 0xfa, 0xb1, 0xdd, 0x21, 0x5f, 0x68,
+	0x45, 0x6e, 0x64, 0x8a, 0x8e, 0xb6, 0xa0, 0xd8, 0xf6, 0x73, 0xc3, 0xb3, 0xba, 0x0f, 0x7b, 0x56,
+	0xbf, 0xa3, 0xad, 0xd4, 0x95, 0xc6, 0x12, 0x96, 0x89, 0xe8, 0x53, 0x28, 0x93, 0x81, 0xc3, 0x2e,
+	0x22, 0xe6, 0xb4, 0xcb, 0x75, 0xa5, 0x91, 0x3f, 0xb8, 0xb6, 0xc7, 0x93, 0x6c, 0xef, 0x51, 0x0c,
+	0x4b, 0x2b, 0x83, 0x63, 0x45, 0xd1, 0x67, 0xa0, 0x79, 0xc4, 0xee, 0xb4, 0xa9, 0x4d, 0xa6, 0xd4,
+	0x96, 0xb8, 0xda, 0x4d, 0xa1, 0xf6, 0x74, 0x06, 0x5b, 0x2b, 0x83, 0x67, 0xaa, 0x40, 0x2e, 0x6c,
+	0x46, 0xbf, 0x92, 0xa8, 0x95, 0x55, 0x6e, 0x65, 0x47, 0x58, 0xf9, 0x24, 0x99, 0xbb, 0x95, 0xc1,
+	0xf3, 0x14, 0xa2, 0xef, 0x14, 0xd8, 0x1e, 0x3a, 0x1d, 0x83, 0x91, 0x39, 0xca, 0x34, 0xc4, 0x4d,
+	0xdf, 0x12, 0xa6, 0x9f, 0xa5, 0x91, 0x69, 0x65, 0x70, 0x3a, 0xe5, 0xdc, 0x0d, 0x97, 0x0c, 0xe8,
+	0xeb, 0xb9, 0x6e, 0x5c, 0x91, 0xdc, 0xc0, 0x69, 0x64, 0x7c, 0x37, 0x52, 0x29, 0x47, 0xdf, 0x28,
+	0xb0, 0x65, 0xf6, 0x0d, 0x6b, 0x30, 0xcf, 0x8b, 0x32, 0xf7, 0xe2, 0xa6, 0xf0, 0xe2, 0x61, 0x0a,
+	0x91, 0x56, 0x06, 0xa7, 0x52, 0x8d, 0xde, 0x82, 0xee, 0x11, 0x36, 0x74, 0x44, 0x59, 0x38, 0x32,
+	0x98, 0xe1, 0x11, 0x16, 0x75, 0x60, 0x8d, 0x3b, 0xf0, 0xdf, 0x71, 0xba, 0xcd, 0x13, 0x68, 0x65,
+	0x70, 0x0a, 0xb5, 0xe8, 0x6b, 0xb8, 0x11, 0x9c, 0x54, 0xb2, 0xf5, 0x0a, 0xb7, 0xbe, 0x2b, 0x5d,
+	0xc2, 0x3c, 0xf3, 0x69, 0x14, 0xa3, 0x3e, 0x6c, 0x18, 0x8e, 0xe3, 0xd2, 0xd7, 0x46, 0xff, 0x11,
+	0x6f, 0x09, 0x51, 0xcb, 0x55, 0x6e, 0x79, 0x4b, 0x58, 0x3e, 0x4c, 0xe2, 0x6d, 0x65, 0x70, 0xb2,
+	0x32, 0xdf, 0x9a, 0xdc, 0x64, 0xa2, 0xd6, 0x34, 0xc9, 0x5a, 0x3b, 0x89, 0xd7, 0xb7, 0x96, 0xa8,
+	0x0c, 0xad, 0xc3, 0xf2, 0x18, 0xd3, 0xae, 0xf2, 0x5a, 0x38, 0x21, 0xa0, 0x6d, 0x58, 0x0c, 0x9c,
+	0xd4, 0x6a, 0xdc, 0x68, 0x71, 0x54, 0xa0, 0x38, 0x11, 0x0b, 0xb0, 0xb9, 0x2a, 0xd5, 0x6e, 0x5f,
+	0xaf, 0x5e, 0x81, 0x72, 0x5c, 0x15, 0xd3, 0xef, 0x81, 0x36, 0xab, 0x0c, 0xa1, 0x1a, 0x2c, 0x1e,
+	0x0e, 0xfc, 0x7b, 0xe0, 0x5d, 0x33, 0xe8, 0x10, 0x82, 0xa2, 0xff, 0xa9, 0xc0, 0xe6, 0xbc, 0x24,
+	0xdd, 0x82, 0xa2, 0xcf, 0x72, 0x32, 0x3c, 0xef, 0x5b, 0xe6, 0xc7, 0xe4, 0x82, 0xab, 0x29, 0x60,
+	0x99, 0x88, 0x76, 0x60, 0x25, 0xd2, 0xfb, 0x54, 0xde, 0xfb, 0x22, 0x54, 0x74, 0x17, 0xf2, 0xbe,
+	0xe0, 0x88, 0x29, 0xcb, 0x0f, 0x00, 0x85, 0x8a, 0x9c, 0x40, 0x70, 0x98, 0x0d, 0x35, 0xa0, 0xf8,
+	0x84, 0x9a, 0xaf, 0x48, 0xa7, 0x69, 0xf4, 0x0d, 0xdb, 0x24, 0xbc, 0x6b, 0x07, 0xa1, 0xc8, 0x00,
+	0xba, 0x0d, 0xb9, 0x13, 0x4a, 0xdf, 0xd8, 0xbc, 0x63, 0xe7, 0x0f, 0xaa, 0x42, 0xf3, 0x49, 0x64,
+	0xc4, 0xc1, 0x01, 0x97, 0xfe, 0xab, 0x02, 0xdb, 0xa9, 0xea, 0x5b, 0xca, 0x63, 0x88, 0x84, 0xa7,
+	0xbe, 0x67, 0x78, 0xd9, 0xb9, 0xe1, 0x2d, 0xa4, 0x0a, 0xaf, 0x0d, 0xdb, 0xa9, 0xca, 0x66, 0xba,
+	0xe8, 0xf4, 0xb7, 0xb0, 0x95, 0xa6, 0xfe, 0xa5, 0x3c, 0xab, 0x71, 0x2c, 0x6a, 0xaa, 0x58, 0xfe,
+	0x50, 0x40, 0x9f, 0x5f, 0xfc, 0x82, 0x09, 0x8e, 0xb1, 0xa9, 0x09, 0x4e, 0x19, 0x4d, 0x70, 0xd3,
+	0x58, 0xd2, 0x04, 0xa7, 0x26, 0x4f, 0x70, 0x35, 0x58, 0x3a, 0x71, 0xa9, 0x43, 0x5c, 0x76, 0xc1,
+	0x2f, 0x6d, 0x19, 0x8f, 0xff, 0xa3, 0x32, 0xe4, 0x9e, 0x1b, 0xfd, 0x61, 0x90, 0xac, 0xcb, 0x38,
+	0xf8, 0x83, 0xae, 0xc3, 0x52, 0x7b, 0x68, 0xf6, 0xfc, 0x11, 0x8d, 0xe7, 0xe8, 0x02, 0xbf, 0xe6,
+	0x31, 0x4d, 0xff, 0x45, 0x81, 0x1b, 0x29, 0xaa, 0xec, 0xbf, 0x3d, 0x4e, 0xfd, 0x2b, 0xd8, 0x48,
+	0x2c, 0xd9, 0xe8, 0x0e, 0x2c, 0x8d, 0x18, 0xb8, 0xd3, 0x2b, 0x07, 0x6b, 0x52, 0x1d, 0x1c, 0x81,
+	0x78, 0xcc, 0xe6, 0x7f, 0x27, 0xe1, 0x09, 0x31, 0x3c, 0xf2, 0xcb, 0x80, 0xfe, 0xbb, 0x02, 0x1b,
+	0x89, 0x35, 0x1c, 0x1d, 0x03, 0x92, 0x19, 0x8e, 0xed, 0x97, 0x94, 0x3b, 0x92, 0x3f, 0xb8, 0x1a,
+	0xdb, 0x05, 0x7c, 0x06, 0x1c, 0x23, 0x84, 0x1e, 0x80, 0xf6, 0xcc, 0xf6, 0xac, 0xae, 0x4d, 0x3a,
+	0x61, 0x2b, 0x7c, 0x10, 0x56, 0x79, 0xe6, 0xcf, 0xc4, 0xd1, 0x03, 0x28, 0xca, 0x1e, 0x04, 0x15,
+	0xb1, 0x3c, 0xea, 0xf6, 0x92, 0x71, 0x99, 0x55, 0xbf, 0x09, 0x6b, 0x1f, 0x49, 0x89, 0x81, 0xc9,
+	0xe7, 0x43, 0xe2, 0x31, 0xb1, 0x0f, 0x29, 0xe1, 0x7d, 0x48, 0xff, 0x41, 0x85, 0x8a, 0xcc, 0xed,
+	0x8d, 0xd8, 0xa7, 0x6b, 0xb7, 0x12, 0x5b, 0xbb, 0x27, 0x4b, 0x93, 0x2a, 0x2d, 0x4d, 0xbb, 0xb0,
+	0x32, 0xde, 0x38, 0x4e, 0x99, 0xe1, 0xb2, 0x50, 0xfd, 0x8a, 0x20, 0x68, 0x07, 0x0a, 0x63, 0xca,
+	0x23, 0xbb, 0x13, 0x2a, 0xe4, 0x12, 0x3d, 0x6e, 0x35, 0xca, 0xc5, 0xaf, 0x46, 0x77, 0x00, 0x4e,
+	0xc6, 0x2b, 0x2a, 0xdf, 0xb8, 0xf2, 0x07, 0xab, 0xa3, 0x5a, 0x32, 0x06, 0x70, 0x88, 0x49, 0x7f,
+	0x05, 0xd5, 0xa9, 0xa3, 0xf0, 0x1c, 0x6a, 0x7b, 0x04, 0x69, 0x90, 0x3b, 0xa3, 0x4c, 0xa4, 0x64,
+	0xf0, 0x6d, 0x06, 0x04, 0x74, 0x0f, 0x0a, 0x61, 0x09, 0x4d, 0xad, 0x67, 0x43, 0xb5, 0x3d, 0x7c,
+	0x0b, 0x12, 0x9f, 0x7e, 0x04, 0x95, 0x13, 0xea, 0xc5, 0x5d, 0x93, 0xbc, 0x08, 0x05, 0xf9, 0x12,
+	0x54, 0xca, 0x29, 0xba, 0xfe, 0x14, 0xaa, 0x53, 0x5a, 0x84, 0xcb, 0x77, 0xa5, 0x35, 0x59, 0xa4,
+	0x70, 0x9c, 0x5f, 0x61, 0x36, 0xfd, 0x47, 0x05, 0x2a, 0xfe, 0xcc, 0xf0, 0xcf, 0xfc, 0xf2, 0x27,
+	0x9d, 0x87, 0x3d, 0xc3, 0x0a, 0x6e, 0xc8, 0x4f, 0x8b, 0x1c, 0x9e, 0x10, 0xfc, 0x5b, 0x0c, 0x56,
+	0xe6, 0x49, 0x2b, 0xc8, 0x06, 0xeb, 0x67, 0x84, 0xac, 0x63, 0xa8, 0x4e, 0x79, 0x23, 0xe2, 0xfb,
+	0x00, 0x0a, 0xcd, 0xd0, 0x5b, 0x83, 0x08, 0xf0, 0x8a, 0x08, 0x30, 0x0c, 0x61, 0x89, 0x51, 0xff,
+	0x5e, 0x81, 0x4d, 0x11, 0x13, 0xdf, 0xfb, 0x67, 0xe4, 0xbe, 0x54, 0x39, 0xfc, 0x48, 0xb3, 0x8d,
+	0x2c, 0x8e, 0x50, 0xe7, 0xc4, 0x99, 0xf8, 0xd8, 0xa0, 0xff, 0xac, 0xc0, 0xba, 0x1f, 0xdc, 0x4c,
+	0x27, 0x24, 0xe5, 0x4a, 0x54, 0xf9, 0x2d, 0x58, 0x0d, 0x0b, 0x8d, 0xea, 0x4a, 0xb6, 0x51, 0xc0,
+	0xd3, 0xc0, 0xdf, 0x38, 0xf2, 0x17, 0xb0, 0x31, 0xc3, 0x2b, 0x71, 0xf0, 0x1f, 0x42, 0x31, 0x7c,
+	0x9e, 0xc1, 0xd1, 0xcc, 0x38, 0x79, 0x99, 0x53, 0x6f, 0xc3, 0xa6, 0xfc, 0x85, 0xb5, 0x2d, 0xdb,
+	0x1a, 0x0c, 0x07, 0x8f, 0x09, 0x79, 0x9f, 0xec, 0xbf, 0x0f, 0xf5, 0xd9, 0xea, 0x84, 0xb7, 0xe2,
+	0x89, 0x44, 0x91, 0x9e, 0x48, 0x76, 0x7f, 0x53, 0x21, 0xe6, 0x31, 0xa5, 0x14, 0x9d, 0xa2, 0x4b,
+	0x19, 0xa4, 0x05, 0x4f, 0x3f, 0xd1, 0x19, 0xba, 0xa4, 0xa0, 0x4d, 0xb8, 0x96, 0x30, 0xf1, 0x94,
+	0x54, 0xb4, 0x03, 0xff, 0x99, 0x3b, 0x44, 0x96, 0xde, 0x71, 0xbe, 0xb9, 0xe3, 0x58, 0xe9, 0xdd,
+	0x02, 0xda, 0x86, 0xfa, 0xbc, 0x39, 0xab, 0xf4, 0x6e, 0x11, 0xe9, 0x70, 0x3d, 0x79, 0x20, 0x2a,
+	0x65, 0xd1, 0x96, 0xff, 0x09, 0x24, 0x4e, 0x13, 0xa5, 0x6f, 0x55, 0xb4, 0x01, 0x57, 0x67, 0x36,
+	0xeb, 0xd2, 0x82, 0x0f, 0xcf, 0x6c, 0xa6, 0xa5, 0x5c, 0x73, 0xf7, 0x45, 0xa3, 0x6b, 0xb1, 0xde,
+	0xf0, 0x7c, 0xcf, 0xa4, 0x83, 0xfd, 0x2f, 0x29, 0x3d, 0x37, 0x83, 0xdf, 0xdb, 0x26, 0x75, 0xc9,
+	0xbe, 0x49, 0x07, 0x03, 0x6a, 0xef, 0xf3, 0xa4, 0x39, 0x5f, 0xe4, 0x6f, 0x7b, 0xff, 0xff, 0x2b,
+	0x00, 0x00, 0xff, 0xff, 0x7b, 0xa6, 0x4b, 0xbd, 0x9b, 0x14, 0x00, 0x00,
 }
diff --git a/common/query/multisignatureInfoQuery.go b/common/query/multisignatureInfoQuery.go
index 0ae6664fa..84605cb47 100644
--- a/common/query/multisignatureInfoQuery.go
+++ b/common/query/multisignatureInfoQuery.go
@@ -10,8 +10,11 @@ import (
 
 type (
 	MultisignatureInfoQueryInterface interface {
-		GetMultisignatureInfoByAddress(multisigAddress string) (str string, args []interface{})
-		InsertMultisignatureInfo(multisigInfo *model.MultiSignatureInfo) (str string, args []interface{})
+		GetMultisignatureInfoByAddress(
+			multisigAddress string,
+			currentHeight, limit uint32,
+		) (str string, args []interface{})
+		InsertMultisignatureInfo(multisigInfo *model.MultiSignatureInfo) [][]interface{}
 		Scan(multisigInfo *model.MultiSignatureInfo, row *sql.Row) error
 		ExtractModel(multisigInfo *model.MultiSignatureInfo) []interface{}
 		BuildModel(multisigInfos []*model.MultiSignatureInfo, rows *sql.Rows) ([]*model.MultiSignatureInfo, error)
@@ -32,6 +35,7 @@ func NewMultisignatureInfoQuery() *MultisignatureInfoQuery {
 			"nonce",
 			"addresses",
 			"block_height",
+			"latest",
 		},
 		TableName: "multisignature_info",
 	}
@@ -41,21 +45,44 @@ func (msi *MultisignatureInfoQuery) getTableName() string {
 	return msi.TableName
 }
 
-func (msi *MultisignatureInfoQuery) GetMultisignatureInfoByAddress(multisigAddress string) (str string, args []interface{}) {
-	query := fmt.Sprintf("SELECT %s FROM %s WHERE multisig_address = ?", strings.Join(msi.Fields, ", "), msi.getTableName())
+func (msi *MultisignatureInfoQuery) GetMultisignatureInfoByAddress(
+	multisigAddress string,
+	currentHeight, limit uint32,
+) (str string, args []interface{}) {
+	var (
+		blockHeight uint32
+	)
+	if currentHeight > limit {
+		blockHeight = currentHeight - limit
+	}
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE multisig_address = ? AND block_height >= ? AND latest = true",
+		strings.Join(msi.Fields, ", "), msi.getTableName())
 	return query, []interface{}{
 		multisigAddress,
+		blockHeight,
 	}
 }
 
 // InsertPendingSignature inserts a new pending transaction into DB
-func (msi *MultisignatureInfoQuery) InsertMultisignatureInfo(multisigInfo *model.MultiSignatureInfo) (str string, args []interface{}) {
-	return fmt.Sprintf(
-		"INSERT INTO %s (%s) VALUES(%s)",
+func (msi *MultisignatureInfoQuery) InsertMultisignatureInfo(multisigInfo *model.MultiSignatureInfo) [][]interface{} {
+	var queries [][]interface{}
+	insertQuery := fmt.Sprintf("INSERT OR REPLACE INTO %s (%s) VALUES(%s)",
 		msi.getTableName(),
 		strings.Join(msi.Fields, ", "),
 		fmt.Sprintf("? %s", strings.Repeat(", ? ", len(msi.Fields)-1)),
-	), msi.ExtractModel(multisigInfo)
+	)
+	updateQuery := fmt.Sprintf("UPDATE %s SET latest = false WHERE multisig_address = ? "+
+		"AND block_height != %d AND latest = true",
+		msi.getTableName(),
+		multisigInfo.BlockHeight,
+	)
+	queries = append(queries,
+		append([]interface{}{insertQuery}, msi.ExtractModel(multisigInfo)...),
+		[]interface{}{
+			updateQuery, multisigInfo.MultisigAddress,
+		},
+	)
+	return queries
 }
 
 func (*MultisignatureInfoQuery) Scan(multisigInfo *model.MultiSignatureInfo, row *sql.Row) error {
@@ -66,6 +93,7 @@ func (*MultisignatureInfoQuery) Scan(multisigInfo *model.MultiSignatureInfo, row
 		&multisigInfo.Nonce,
 		&addresses,
 		&multisigInfo.BlockHeight,
+		&multisigInfo.Latest,
 	)
 	multisigInfo.Addresses = strings.Split(addresses, ", ")
 	return err
@@ -79,6 +107,7 @@ func (*MultisignatureInfoQuery) ExtractModel(multisigInfo *model.MultiSignatureI
 		&multisigInfo.Nonce,
 		addresses,
 		&multisigInfo.BlockHeight,
+		&multisigInfo.Latest,
 	}
 }
 
@@ -96,6 +125,7 @@ func (msi *MultisignatureInfoQuery) BuildModel(
 			&multisigInfo.Nonce,
 			&addresses,
 			&multisigInfo.BlockHeight,
+			&multisigInfo.Latest,
 		)
 		multisigInfo.Addresses = strings.Split(addresses, ", ")
 		if err != nil {
@@ -113,5 +143,14 @@ func (msi *MultisignatureInfoQuery) Rollback(height uint32) (multiQueries [][]in
 			fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", msi.getTableName()),
 			height,
 		},
+		{
+			fmt.Sprintf("UPDATE %s SET latest = ? WHERE latest = ? AND (block_height || '_' || "+
+				"multisig_address) IN (SELECT (MAX(block_height) || '_' || multisig_address) as con "+
+				"FROM %s GROUP BY multisig_address)",
+				msi.getTableName(),
+				msi.getTableName(),
+			),
+			1, 0,
+		},
 	}
 }
diff --git a/common/query/multisignatureInfoQuery_test.go b/common/query/multisignatureInfoQuery_test.go
index 4ced18a9e..88870a0fe 100644
--- a/common/query/multisignatureInfoQuery_test.go
+++ b/common/query/multisignatureInfoQuery_test.go
@@ -2,11 +2,12 @@ package query
 
 import (
 	"database/sql"
-	"fmt"
 	"reflect"
 	"strings"
 	"testing"
 
+	"github.com/zoobc/zoobc-core/common/constant"
+
 	"github.com/DATA-DOG/go-sqlmock"
 
 	"github.com/zoobc/zoobc-core/common/model"
@@ -37,6 +38,7 @@ func getBuildModelSuccessMockRows() *sql.Rows {
 		int64(10),
 		"addresses",
 		uint32(12),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	rows, _ := db.Query("")
@@ -89,6 +91,7 @@ func TestMultisignatureInfoQuery_BuildModel(t *testing.T) {
 					Nonce:             10,
 					Addresses:         []string{"addresses"},
 					BlockHeight:       12,
+					Latest:            true,
 				},
 			},
 			wantErr: false,
@@ -120,6 +123,7 @@ var (
 		Addresses:         []string{"A", "B"},
 		MultisigAddress:   "",
 		BlockHeight:       0,
+		Latest:            true,
 	}
 	// Extract mocks
 )
@@ -153,6 +157,7 @@ func TestMultisignatureInfoQuery_ExtractModel(t *testing.T) {
 				&mockExtractMultisignatureInfoMultisig.Nonce,
 				strings.Join(mockExtractMultisignatureInfoMultisig.Addresses, ", "),
 				&mockExtractMultisignatureInfoMultisig.BlockHeight,
+				&mockExtractMultisignatureInfoMultisig.Latest,
 			},
 		},
 	}
@@ -175,7 +180,8 @@ func TestMultisignatureInfoQuery_GetMultisignatureInfoByAddress(t *testing.T) {
 		TableName string
 	}
 	type args struct {
-		multisigAddress string
+		multisigAddress      string
+		currentHeight, limit uint32
 	}
 	tests := []struct {
 		name     string
@@ -192,10 +198,12 @@ func TestMultisignatureInfoQuery_GetMultisignatureInfoByAddress(t *testing.T) {
 			},
 			args: args{
 				multisigAddress: "A",
+				currentHeight:   0,
+				limit:           constant.MinRollbackBlocks,
 			},
-			wantStr: "SELECT multisig_address, minimum_signatures, nonce, addresses, block_height FROM " +
-				"multisignature_info WHERE multisig_address = ?",
-			wantArgs: []interface{}{"A"},
+			wantStr: "SELECT multisig_address, minimum_signatures, nonce, addresses, block_height, latest FROM " +
+				"multisignature_info WHERE multisig_address = ? AND block_height >= ? AND latest = true",
+			wantArgs: []interface{}{"A", uint32(0)},
 		},
 	}
 	for _, tt := range tests {
@@ -204,7 +212,11 @@ func TestMultisignatureInfoQuery_GetMultisignatureInfoByAddress(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := msi.GetMultisignatureInfoByAddress(tt.args.multisigAddress)
+			gotStr, gotArgs := msi.GetMultisignatureInfoByAddress(
+				tt.args.multisigAddress,
+				tt.args.currentHeight,
+				tt.args.limit,
+			)
 			if gotStr != tt.wantStr {
 				t.Errorf("GetMultisignatureInfoByAddress() gotStr = %v, want %v", gotStr, tt.wantStr)
 			}
@@ -223,6 +235,7 @@ var (
 		Addresses:         nil,
 		MultisigAddress:   "",
 		BlockHeight:       0,
+		Latest:            true,
 	}
 	// InsertMultisignatureInfo mocks
 )
@@ -236,11 +249,10 @@ func TestMultisignatureInfoQuery_InsertMultisignatureInfo(t *testing.T) {
 		multisigInfo *model.MultiSignatureInfo
 	}
 	tests := []struct {
-		name     string
-		fields   fields
-		args     args
-		wantStr  string
-		wantArgs []interface{}
+		name   string
+		fields fields
+		args   args
+		want   [][]interface{}
 	}{
 		{
 			name: "InsertMultisigInfo-Success",
@@ -251,9 +263,16 @@ func TestMultisignatureInfoQuery_InsertMultisignatureInfo(t *testing.T) {
 			args: args{
 				multisigInfo: mockInsertMultisignatureInfoMultisig,
 			},
-			wantStr: "INSERT INTO multisignature_info (multisig_address, minimum_signatures, " +
-				"nonce, addresses, block_height) VALUES(? , ? , ? , ? , ? )",
-			wantArgs: mockMultisigInfoQueryInstance.ExtractModel(mockInsertMultisignatureInfoMultisig),
+			want: [][]interface{}{
+				append([]interface{}{
+					"INSERT OR REPLACE INTO multisignature_info (multisig_address, minimum_signatures, " +
+						"nonce, addresses, block_height, latest) VALUES(? , ? , ? , ? , ? , ? )",
+				}, mockMultisigInfoQueryInstance.ExtractModel(
+					mockInsertMultisignatureInfoMultisig)...),
+				{
+					"UPDATE multisignature_info SET latest = false WHERE multisig_address = ? AND " +
+						"block_height != 0 AND latest = true", mockInsertMultisignatureInfoMultisig.MultisigAddress,
+				}},
 		},
 	}
 	for _, tt := range tests {
@@ -262,12 +281,9 @@ func TestMultisignatureInfoQuery_InsertMultisignatureInfo(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := msi.InsertMultisignatureInfo(tt.args.multisigInfo)
-			if gotStr != tt.wantStr {
-				t.Errorf("InsertMultisignatureInfo() gotStr = %v, want %v", gotStr, tt.wantStr)
-			}
-			if !reflect.DeepEqual(gotArgs, tt.wantArgs) {
-				t.Errorf("InsertMultisignatureInfo() gotArgs = %v, want %v", gotArgs, tt.wantArgs)
+			got := msi.InsertMultisignatureInfo(tt.args.multisigInfo)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("InsertMultisignatureInfo() got = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -298,9 +314,15 @@ func TestMultisignatureInfoQuery_Rollback(t *testing.T) {
 			},
 			wantMultiQueries: [][]interface{}{
 				{
-					fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", mockMultisigInfoQueryInstance.TableName),
+					"DELETE FROM multisignature_info WHERE block_height > ?",
 					uint32(10),
 				},
+				{
+					"UPDATE multisignature_info SET latest = ? WHERE latest = ? AND (block_height || '_' || " +
+						"multisig_address) IN (SELECT (MAX(block_height) || '_' || multisig_address) as con " +
+						"FROM multisignature_info GROUP BY multisig_address)",
+					1, 0,
+				},
 			},
 		},
 	}
@@ -337,6 +359,7 @@ func getNumberScanSuccessMockRow() *sql.Row {
 		int64(10),
 		"addresses",
 		uint32(12),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	return db.QueryRow("")
@@ -438,6 +461,7 @@ var (
 			"nonce",
 			"addresses",
 			"block_height",
+			"latest",
 		},
 		TableName: "multisignature_info",
 	}
diff --git a/common/query/pendingSignatureQuery.go b/common/query/pendingSignatureQuery.go
index 8aeb90807..4a0a590d1 100644
--- a/common/query/pendingSignatureQuery.go
+++ b/common/query/pendingSignatureQuery.go
@@ -10,8 +10,11 @@ import (
 
 type (
 	PendingSignatureQueryInterface interface {
-		GetPendingSignatureByHash(txHash []byte) (str string, args []interface{})
-		InsertPendingSignature(pendingSig *model.PendingSignature) (str string, args []interface{})
+		GetPendingSignatureByHash(
+			txHash []byte,
+			currentHeight, limit uint32,
+		) (str string, args []interface{})
+		InsertPendingSignature(pendingSig *model.PendingSignature) [][]interface{}
 		Scan(pendingSig *model.PendingSignature, row *sql.Row) error
 		ExtractModel(pendingSig *model.PendingSignature) []interface{}
 		BuildModel(pendingSigs []*model.PendingSignature, rows *sql.Rows) ([]*model.PendingSignature, error)
@@ -31,6 +34,7 @@ func NewPendingSignatureQuery() *PendingSignatureQuery {
 			"account_address",
 			"signature",
 			"block_height",
+			"latest",
 		},
 		TableName: "pending_signature",
 	}
@@ -40,21 +44,44 @@ func (psq *PendingSignatureQuery) getTableName() string {
 	return psq.TableName
 }
 
-func (psq *PendingSignatureQuery) GetPendingSignatureByHash(txHash []byte) (str string, args []interface{}) {
-	query := fmt.Sprintf("SELECT %s FROM %s WHERE transaction_hash = ?", strings.Join(psq.Fields, ", "), psq.getTableName())
+func (psq *PendingSignatureQuery) GetPendingSignatureByHash(
+	txHash []byte,
+	currentHeight, limit uint32,
+) (str string, args []interface{}) {
+	var (
+		blockHeight uint32
+	)
+	if currentHeight > limit {
+		blockHeight = currentHeight - limit
+	}
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE transaction_hash = ? AND block_height >= ? AND latest = true",
+		strings.Join(psq.Fields, ", "), psq.getTableName())
 	return query, []interface{}{
 		txHash,
+		blockHeight,
 	}
 }
 
 // InsertPendingSignature inserts a new pending transaction into DB
-func (psq *PendingSignatureQuery) InsertPendingSignature(pendingSig *model.PendingSignature) (str string, args []interface{}) {
-	return fmt.Sprintf(
-		"INSERT INTO %s (%s) VALUES(%s)",
+func (psq *PendingSignatureQuery) InsertPendingSignature(pendingSig *model.PendingSignature) [][]interface{} {
+	var queries [][]interface{}
+	insertQuery := fmt.Sprintf("INSERT OR REPLACE INTO %s (%s) VALUES(%s)",
 		psq.getTableName(),
 		strings.Join(psq.Fields, ", "),
 		fmt.Sprintf("? %s", strings.Repeat(", ? ", len(psq.Fields)-1)),
-	), psq.ExtractModel(pendingSig)
+	)
+	updateQuery := fmt.Sprintf("UPDATE %s SET latest = false WHERE account_address = ? AND transaction_hash = ? "+
+		"AND block_height != %d AND latest = true",
+		psq.getTableName(),
+		pendingSig.BlockHeight,
+	)
+	queries = append(queries,
+		append([]interface{}{insertQuery}, psq.ExtractModel(pendingSig)...),
+		[]interface{}{
+			updateQuery, pendingSig.AccountAddress, pendingSig.TransactionHash,
+		},
+	)
+	return queries
 }
 
 func (*PendingSignatureQuery) Scan(pendingSig *model.PendingSignature, row *sql.Row) error {
@@ -63,6 +90,7 @@ func (*PendingSignatureQuery) Scan(pendingSig *model.PendingSignature, row *sql.
 		&pendingSig.AccountAddress,
 		&pendingSig.Signature,
 		&pendingSig.BlockHeight,
+		&pendingSig.Latest,
 	)
 	return err
 }
@@ -73,6 +101,7 @@ func (*PendingSignatureQuery) ExtractModel(pendingSig *model.PendingSignature) [
 		&pendingSig.AccountAddress,
 		&pendingSig.Signature,
 		&pendingSig.BlockHeight,
+		&pendingSig.Latest,
 	}
 }
 
@@ -86,6 +115,7 @@ func (psq *PendingSignatureQuery) BuildModel(
 			&pendingSig.AccountAddress,
 			&pendingSig.Signature,
 			&pendingSig.BlockHeight,
+			&pendingSig.Latest,
 		)
 		if err != nil {
 			return nil, err
@@ -99,8 +129,18 @@ func (psq *PendingSignatureQuery) BuildModel(
 func (psq *PendingSignatureQuery) Rollback(height uint32) (multiQueries [][]interface{}) {
 	return [][]interface{}{
 		{
-			fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", psq.getTableName()),
+			fmt.Sprintf("DELETE FROM %s WHERE height > ?", psq.TableName),
 			height,
 		},
+		{
+			fmt.Sprintf("UPDATE %s SET latest = ? WHERE latest = ? AND (block_height || '_' || "+
+				"account_address || '_' || transaction_hash) IN (SELECT (MAX(block_height) || '_' || "+
+				"account_address || '_' || transaction_hash) as con FROM %s GROUP BY account_address "+
+				"|| '_' || transaction_hash)",
+				psq.TableName,
+				psq.TableName,
+			),
+			1, 0,
+		},
 	}
 }
diff --git a/common/query/pendingSignatureQuery_test.go b/common/query/pendingSignatureQuery_test.go
index 625acfbdd..d36e729f7 100644
--- a/common/query/pendingSignatureQuery_test.go
+++ b/common/query/pendingSignatureQuery_test.go
@@ -2,10 +2,11 @@ package query
 
 import (
 	"database/sql"
-	"fmt"
 	"reflect"
 	"testing"
 
+	"github.com/zoobc/zoobc-core/common/constant"
+
 	"github.com/DATA-DOG/go-sqlmock"
 
 	"github.com/zoobc/zoobc-core/common/model"
@@ -28,6 +29,7 @@ func TestNewPendingSignatureQuery(t *testing.T) {
 					"account_address",
 					"signature",
 					"block_height",
+					"latest",
 				},
 				TableName: "pending_signature",
 			},
@@ -61,6 +63,7 @@ func getPendingSignatureQueryBuildModelRowsSuccess() *sql.Rows {
 		"account_address",
 		make([]byte, 64),
 		uint32(10),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	rows, _ := db.Query("")
@@ -114,6 +117,7 @@ func TestPendingSignatureQuery_BuildModel(t *testing.T) {
 					AccountAddress:  "account_address",
 					Signature:       make([]byte, 64),
 					BlockHeight:     10,
+					Latest:          true,
 				},
 			},
 			wantErr: false,
@@ -174,6 +178,7 @@ func TestPendingSignatureQuery_ExtractModel(t *testing.T) {
 				&mockExtractModelPendingSig.AccountAddress,
 				&mockExtractModelPendingSig.Signature,
 				&mockExtractModelPendingSig.BlockHeight,
+				&mockExtractModelPendingSig.Latest,
 			},
 		},
 	}
@@ -196,7 +201,8 @@ func TestPendingSignatureQuery_GetPendingSignatureByHash(t *testing.T) {
 		TableName string
 	}
 	type args struct {
-		txHash []byte
+		txHash               []byte
+		currentHeight, limit uint32
 	}
 	tests := []struct {
 		name     string
@@ -212,12 +218,15 @@ func TestPendingSignatureQuery_GetPendingSignatureByHash(t *testing.T) {
 				TableName: mockPendingSignatureQueryIntance.TableName,
 			},
 			args: args{
-				txHash: make([]byte, 32),
+				txHash:        make([]byte, 32),
+				currentHeight: 0,
+				limit:         constant.MinRollbackBlocks,
 			},
-			wantStr: "SELECT transaction_hash, account_address, signature, block_height FROM pending_signature " +
-				"WHERE transaction_hash = ?",
+			wantStr: "SELECT transaction_hash, account_address, signature, block_height, latest FROM " +
+				"pending_signature WHERE transaction_hash = ? AND block_height >= ? AND latest = true",
 			wantArgs: []interface{}{
 				make([]byte, 32),
+				uint32(0),
 			},
 		},
 	}
@@ -227,7 +236,11 @@ func TestPendingSignatureQuery_GetPendingSignatureByHash(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := psq.GetPendingSignatureByHash(tt.args.txHash)
+			gotStr, gotArgs := psq.GetPendingSignatureByHash(
+				tt.args.txHash,
+				tt.args.currentHeight,
+				tt.args.limit,
+			)
 			if gotStr != tt.wantStr {
 				t.Errorf("GetPendingSignatureByHash() gotStr = %v, want %v", gotStr, tt.wantStr)
 			}
@@ -256,11 +269,10 @@ func TestPendingSignatureQuery_InsertPendingSignature(t *testing.T) {
 		pendingSig *model.PendingSignature
 	}
 	tests := []struct {
-		name     string
-		fields   fields
-		args     args
-		wantStr  string
-		wantArgs []interface{}
+		name   string
+		fields fields
+		args   args
+		want   [][]interface{}
 	}{
 		{
 			name: "InsertPendingSignature-Success",
@@ -271,9 +283,16 @@ func TestPendingSignatureQuery_InsertPendingSignature(t *testing.T) {
 			args: args{
 				pendingSig: mockInsertPendingSignaturePendingSig,
 			},
-			wantStr: "INSERT INTO pending_signature (transaction_hash, account_address, signature, " +
-				"block_height) VALUES(? , ? , ? , ? )",
-			wantArgs: mockPendingSignatureQueryIntance.ExtractModel(mockInsertPendingSignaturePendingSig),
+			want: [][]interface{}{
+				append([]interface{}{"INSERT OR REPLACE INTO pending_signature (transaction_hash, account_address, " +
+					"signature, block_height, latest) VALUES(? , ? , ? , ? , ? )"},
+					mockPendingSignatureQueryIntance.ExtractModel(mockInsertPendingSignaturePendingSig)...),
+				{
+					"UPDATE pending_signature SET latest = false WHERE account_address = ? AND transaction_hash = " +
+						"? AND block_height != 0 AND latest = true",
+					mockInsertPendingSignaturePendingSig.AccountAddress, mockInsertPendingSignaturePendingSig.TransactionHash,
+				},
+			},
 		},
 	}
 	for _, tt := range tests {
@@ -282,12 +301,9 @@ func TestPendingSignatureQuery_InsertPendingSignature(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := psq.InsertPendingSignature(tt.args.pendingSig)
-			if gotStr != tt.wantStr {
-				t.Errorf("InsertPendingSignature() gotStr = %v, want %v", gotStr, tt.wantStr)
-			}
-			if !reflect.DeepEqual(gotArgs, tt.wantArgs) {
-				t.Errorf("InsertPendingSignature() gotArgs = %v, want %v", gotArgs, tt.wantArgs)
+			got := psq.InsertPendingSignature(tt.args.pendingSig)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("InsertPendingSignature() gotArgs = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -318,9 +334,16 @@ func TestPendingSignatureQuery_Rollback(t *testing.T) {
 			},
 			wantMultiQueries: [][]interface{}{
 				{
-					fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", mockPendingSignatureQueryIntance.TableName),
+					"DELETE FROM pending_signature WHERE height > ?",
 					uint32(10),
 				},
+				{
+					"UPDATE pending_signature SET latest = ? WHERE latest = ? AND (block_height || '_' || " +
+						"account_address || '_' || transaction_hash) IN (SELECT (MAX(block_height) || '_' || " +
+						"account_address || '_' || transaction_hash) as con FROM pending_signature GROUP BY " +
+						"account_address || '_' || transaction_hash)",
+					1, 0,
+				},
 			},
 		},
 	}
@@ -356,6 +379,7 @@ func getMockScanRowSuccess() *sql.Row {
 		"account_address",
 		make([]byte, 64),
 		uint32(10),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	return db.QueryRow("")
diff --git a/common/query/pendingTransactionQuery.go b/common/query/pendingTransactionQuery.go
index bebc406b5..e7f084dbc 100644
--- a/common/query/pendingTransactionQuery.go
+++ b/common/query/pendingTransactionQuery.go
@@ -10,8 +10,19 @@ import (
 
 type (
 	PendingTransactionQueryInterface interface {
-		GetPendingTransactionByHash(txHash []byte) (str string, args []interface{})
-		InsertPendingTransaction(pendingTx *model.PendingTransaction) (str string, args []interface{})
+		GetPendingTransactionByHash(
+			txHash []byte,
+			status model.PendingTransactionStatus,
+			currentHeight, limit uint32,
+		) (str string, args []interface{})
+		GetPendingTransactionsBySenderAddress(
+			multisigAddress string,
+			status model.PendingTransactionStatus,
+			currentHeight, limit uint32,
+		) (
+			str string, args []interface{},
+		)
+		InsertPendingTransaction(pendingTx *model.PendingTransaction) [][]interface{}
 		Scan(pendingTx *model.PendingTransaction, row *sql.Row) error
 		ExtractModel(pendingTx *model.PendingTransaction) []interface{}
 		BuildModel(pendingTxs []*model.PendingTransaction, rows *sql.Rows) ([]*model.PendingTransaction, error)
@@ -27,10 +38,12 @@ type (
 func NewPendingTransactionQuery() *PendingTransactionQuery {
 	return &PendingTransactionQuery{
 		Fields: []string{
+			"sender_address",
 			"transaction_hash",
 			"transaction_bytes",
 			"status",
 			"block_height",
+			"latest",
 		},
 		TableName: "pending_transaction",
 	}
@@ -40,39 +53,88 @@ func (ptq *PendingTransactionQuery) getTableName() string {
 	return ptq.TableName
 }
 
-func (ptq *PendingTransactionQuery) GetPendingTransactionByHash(txHash []byte) (str string, args []interface{}) {
-	query := fmt.Sprintf("SELECT %s FROM %s WHERE transaction_hash = ?", strings.Join(ptq.Fields, ", "), ptq.getTableName())
+func (ptq *PendingTransactionQuery) GetPendingTransactionByHash(
+	txHash []byte,
+	status model.PendingTransactionStatus,
+	currentHeight, limit uint32,
+) (str string, args []interface{}) {
+	var (
+		blockHeight uint32
+	)
+	if currentHeight > limit {
+		blockHeight = currentHeight - limit
+	}
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE transaction_hash = ? AND status = ? AND block_height >= ? "+
+		"AND latest = true", strings.Join(ptq.Fields, ", "), ptq.getTableName())
 	return query, []interface{}{
 		txHash,
+		status,
+		blockHeight,
+	}
+}
+
+func (ptq *PendingTransactionQuery) GetPendingTransactionsBySenderAddress(
+	multisigAddress string,
+	status model.PendingTransactionStatus,
+	currentHeight, limit uint32,
+) (str string, args []interface{}) {
+	var (
+		blockHeight uint32
+	)
+	if currentHeight > limit {
+		blockHeight = currentHeight - limit
+	}
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE sender_address = ? AND status = ? AND block_height >= ? "+
+		"AND latest = true ORDER BY block_height ASC",
+		strings.Join(ptq.Fields, ", "), ptq.getTableName())
+	return query, []interface{}{
+		multisigAddress,
+		status,
+		blockHeight,
 	}
 }
 
 // InsertPendingTransaction inserts a new pending transaction into DB
-func (ptq *PendingTransactionQuery) InsertPendingTransaction(pendingTx *model.PendingTransaction) (str string, args []interface{}) {
-	return fmt.Sprintf(
-		"INSERT INTO %s (%s) VALUES(%s)",
+func (ptq *PendingTransactionQuery) InsertPendingTransaction(pendingTx *model.PendingTransaction) [][]interface{} {
+	var queries [][]interface{}
+	insertQuery := fmt.Sprintf("INSERT OR REPLACE INTO %s (%s) VALUES(%s)",
 		ptq.getTableName(),
 		strings.Join(ptq.Fields, ", "),
 		fmt.Sprintf("? %s", strings.Repeat(", ? ", len(ptq.Fields)-1)),
-	), ptq.ExtractModel(pendingTx)
+	)
+	updateQuery := fmt.Sprintf("UPDATE %s SET latest = false WHERE transaction_hash = ? AND block_height != %d AND latest = true",
+		ptq.getTableName(),
+		pendingTx.BlockHeight,
+	)
+	queries = append(queries,
+		append([]interface{}{insertQuery}, ptq.ExtractModel(pendingTx)...),
+		[]interface{}{
+			updateQuery, pendingTx.TransactionHash,
+		},
+	)
+	return queries
 }
 
 func (*PendingTransactionQuery) Scan(pendingTx *model.PendingTransaction, row *sql.Row) error {
 	err := row.Scan(
+		&pendingTx.SenderAddress,
 		&pendingTx.TransactionHash,
 		&pendingTx.TransactionBytes,
 		&pendingTx.Status,
 		&pendingTx.BlockHeight,
+		&pendingTx.Latest,
 	)
 	return err
 }
 
 func (*PendingTransactionQuery) ExtractModel(pendingTx *model.PendingTransaction) []interface{} {
 	return []interface{}{
+		&pendingTx.SenderAddress,
 		&pendingTx.TransactionHash,
 		&pendingTx.TransactionBytes,
 		&pendingTx.Status,
 		&pendingTx.BlockHeight,
+		&pendingTx.Latest,
 	}
 }
 
@@ -82,10 +144,12 @@ func (ptq *PendingTransactionQuery) BuildModel(
 	for rows.Next() {
 		var pendingTx model.PendingTransaction
 		err := rows.Scan(
+			&pendingTx.SenderAddress,
 			&pendingTx.TransactionHash,
 			&pendingTx.TransactionBytes,
 			&pendingTx.Status,
 			&pendingTx.BlockHeight,
+			&pendingTx.Latest,
 		)
 		if err != nil {
 			return nil, err
@@ -99,8 +163,17 @@ func (ptq *PendingTransactionQuery) BuildModel(
 func (ptq *PendingTransactionQuery) Rollback(height uint32) (multiQueries [][]interface{}) {
 	return [][]interface{}{
 		{
-			fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", ptq.getTableName()),
+			fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", ptq.TableName),
 			height,
 		},
+		{
+			fmt.Sprintf("UPDATE %s SET latest = ? WHERE latest = ? AND (block_height || '_' || "+
+				"transaction_hash) IN (SELECT (MAX(block_height) || '_' || transaction_hash) as con "+
+				"FROM %s GROUP BY transaction_hash)",
+				ptq.getTableName(),
+				ptq.getTableName(),
+			),
+			1, 0,
+		},
 	}
 }
diff --git a/common/query/pendingTransactionQuery_test.go b/common/query/pendingTransactionQuery_test.go
index f50e34b80..081a1345c 100644
--- a/common/query/pendingTransactionQuery_test.go
+++ b/common/query/pendingTransactionQuery_test.go
@@ -2,10 +2,11 @@ package query
 
 import (
 	"database/sql"
-	"fmt"
 	"reflect"
 	"testing"
 
+	"github.com/zoobc/zoobc-core/common/constant"
+
 	"github.com/DATA-DOG/go-sqlmock"
 
 	"github.com/zoobc/zoobc-core/common/model"
@@ -24,10 +25,12 @@ func TestNewPendingTransactionQuery(t *testing.T) {
 			name: "NewPendingTransactionQuery-Success",
 			want: &PendingTransactionQuery{
 				Fields: []string{
+					"sender_address",
 					"transaction_hash",
 					"transaction_bytes",
 					"status",
 					"block_height",
+					"latest",
 				},
 				TableName: "pending_transaction",
 			},
@@ -57,10 +60,12 @@ func getPendingTransactionQueryBuildModelSuccessRow() *sql.Rows {
 	db, mock, _ := sqlmock.New()
 	mockRow := sqlmock.NewRows(mockPendingTransactionQueryInstance.Fields)
 	mockRow.AddRow(
+		"",
 		make([]byte, 32),
 		make([]byte, 100),
 		model.PendingTransactionStatus_PendingTransactionExecuted,
 		uint32(10),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	rows, _ := db.Query("")
@@ -110,10 +115,12 @@ func TestPendingTransactionQuery_BuildModel(t *testing.T) {
 			},
 			want: []*model.PendingTransaction{
 				{
+					SenderAddress:    "",
 					TransactionHash:  make([]byte, 32),
 					TransactionBytes: make([]byte, 100),
 					Status:           model.PendingTransactionStatus_PendingTransactionExecuted,
 					BlockHeight:      10,
+					Latest:           true,
 				},
 			},
 			wantErr: false,
@@ -170,10 +177,12 @@ func TestPendingTransactionQuery_ExtractModel(t *testing.T) {
 				pendingTx: mockPendingTransactionExtractModel,
 			},
 			want: []interface{}{
+				&mockPendingTransactionExtractModel.SenderAddress,
 				&mockPendingTransactionExtractModel.TransactionHash,
 				&mockPendingTransactionExtractModel.TransactionBytes,
 				&mockPendingTransactionExtractModel.Status,
 				&mockPendingTransactionExtractModel.BlockHeight,
+				&mockPendingTransactionExtractModel.Latest,
 			},
 		},
 	}
@@ -196,7 +205,9 @@ func TestPendingTransactionQuery_GetPendingTransactionByHash(t *testing.T) {
 		TableName string
 	}
 	type args struct {
-		txHash []byte
+		txHash               []byte
+		status               model.PendingTransactionStatus
+		currentHeight, limit uint32
 	}
 	tests := []struct {
 		name     string
@@ -212,12 +223,17 @@ func TestPendingTransactionQuery_GetPendingTransactionByHash(t *testing.T) {
 				TableName: mockPendingTransactionQueryInstance.TableName,
 			},
 			args: args{
-				txHash: make([]byte, 32),
+				txHash:        make([]byte, 32),
+				status:        model.PendingTransactionStatus_PendingTransactionPending,
+				currentHeight: 0,
+				limit:         constant.MinRollbackBlocks,
 			},
-			wantStr: "SELECT transaction_hash, transaction_bytes, status, block_height FROM pending_transaction " +
-				"WHERE transaction_hash = ?",
+			wantStr: "SELECT sender_address, transaction_hash, transaction_bytes, status, block_height, latest FROM pending_transaction " +
+				"WHERE transaction_hash = ? AND status = ? AND block_height >= ? AND latest = true",
 			wantArgs: []interface{}{
 				make([]byte, 32),
+				model.PendingTransactionStatus_PendingTransactionPending,
+				uint32(0),
 			},
 		},
 	}
@@ -227,7 +243,12 @@ func TestPendingTransactionQuery_GetPendingTransactionByHash(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := ptq.GetPendingTransactionByHash(tt.args.txHash)
+			gotStr, gotArgs := ptq.GetPendingTransactionByHash(
+				tt.args.txHash,
+				tt.args.status,
+				tt.args.currentHeight,
+				tt.args.limit,
+			)
 			if gotStr != tt.wantStr {
 				t.Errorf("GetPendingTransactionByHash() gotStr = %v, want %v", gotStr, tt.wantStr)
 			}
@@ -240,6 +261,7 @@ func TestPendingTransactionQuery_GetPendingTransactionByHash(t *testing.T) {
 
 var (
 	mockInsertPendingTransaction = &model.PendingTransaction{
+		SenderAddress:    "",
 		TransactionHash:  make([]byte, 32),
 		TransactionBytes: make([]byte, 100),
 		Status:           model.PendingTransactionStatus_PendingTransactionExecuted,
@@ -256,11 +278,10 @@ func TestPendingTransactionQuery_InsertPendingTransaction(t *testing.T) {
 		pendingTx *model.PendingTransaction
 	}
 	tests := []struct {
-		name     string
-		fields   fields
-		args     args
-		wantStr  string
-		wantArgs []interface{}
+		name   string
+		fields fields
+		args   args
+		want   [][]interface{}
 	}{
 		{
 			name: "InsertPendingTransaction-Success",
@@ -271,9 +292,17 @@ func TestPendingTransactionQuery_InsertPendingTransaction(t *testing.T) {
 			args: args{
 				pendingTx: mockInsertPendingTransaction,
 			},
-			wantStr: "INSERT INTO pending_transaction (transaction_hash, transaction_bytes, " +
-				"status, block_height) VALUES(? , ? , ? , ? )",
-			wantArgs: mockPendingTransactionQueryInstance.ExtractModel(mockInsertPendingTransaction),
+			want: [][]interface{}{
+				append([]interface{}{
+					"INSERT OR REPLACE INTO pending_transaction (sender_address, transaction_hash, " +
+						"transaction_bytes, status, block_height, latest) VALUES(? , ? , ? , ? , ? , ? )",
+				}, mockPendingTransactionQueryInstance.ExtractModel(mockInsertPendingTransaction)...),
+				{
+					"UPDATE pending_transaction SET latest = false WHERE transaction_hash = ? AND block_height " +
+						"!= 10 AND latest = true",
+					mockInsertPendingTransaction.TransactionHash,
+				},
+			},
 		},
 	}
 	for _, tt := range tests {
@@ -282,12 +311,9 @@ func TestPendingTransactionQuery_InsertPendingTransaction(t *testing.T) {
 				Fields:    tt.fields.Fields,
 				TableName: tt.fields.TableName,
 			}
-			gotStr, gotArgs := ptq.InsertPendingTransaction(tt.args.pendingTx)
-			if gotStr != tt.wantStr {
-				t.Errorf("InsertPendingTransaction() gotStr = %v, want %v", gotStr, tt.wantStr)
-			}
-			if !reflect.DeepEqual(gotArgs, tt.wantArgs) {
-				t.Errorf("InsertPendingTransaction() gotArgs = %v, want %v", gotArgs, tt.wantArgs)
+			got := ptq.InsertPendingTransaction(tt.args.pendingTx)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("InsertPendingTransaction() gotArgs = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -318,9 +344,15 @@ func TestPendingTransactionQuery_Rollback(t *testing.T) {
 			},
 			wantMultiQueries: [][]interface{}{
 				{
-					fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", mockPendingTransactionQueryInstance.TableName),
+					"DELETE FROM pending_transaction WHERE block_height > ?",
 					uint32(10),
 				},
+				{
+					"UPDATE pending_transaction SET latest = ? WHERE latest = ? AND (block_height || '_' || " +
+						"transaction_hash) IN (SELECT (MAX(block_height) || '_' || transaction_hash) as con " +
+						"FROM pending_transaction GROUP BY transaction_hash)",
+					1, 0,
+				},
 			},
 		},
 	}
@@ -351,10 +383,12 @@ func getPendingTransactionQueryScanSuccessRow() *sql.Row {
 	db, mock, _ := sqlmock.New()
 	mockRow := sqlmock.NewRows(mockPendingTransactionQueryInstance.Fields)
 	mockRow.AddRow(
+		"",
 		make([]byte, 32),
 		make([]byte, 100),
 		uint32(0),
 		uint32(10),
+		true,
 	)
 	mock.ExpectQuery("").WillReturnRows(mockRow)
 	return db.QueryRow("")
diff --git a/common/query/transactionQuery.go b/common/query/transactionQuery.go
index 82bb5f29c..54c65c381 100644
--- a/common/query/transactionQuery.go
+++ b/common/query/transactionQuery.go
@@ -13,7 +13,6 @@ type (
 	TransactionQueryInterface interface {
 		InsertTransaction(tx *model.Transaction) (str string, args []interface{})
 		GetTransaction(id int64) string
-		GetTransactions(limit uint32, offset uint64) string
 		GetTransactionsByIds(txIds []int64) (str string, args []interface{})
 		GetTransactionsByBlockID(blockID int64) (str string, args []interface{})
 		ExtractModel(tx *model.Transaction) []interface{}
@@ -47,6 +46,7 @@ func NewTransactionQuery(chaintype chaintype.ChainType) *TransactionQuery {
 			"signature",
 			"version",
 			"transaction_index",
+			"multisig_child",
 		},
 		TableName: "\"transaction\"",
 		ChainType: chaintype,
@@ -60,7 +60,7 @@ func (tq *TransactionQuery) getTableName() string {
 // GetTransaction get a single transaction from DB
 func (tq *TransactionQuery) GetTransaction(id int64) string {
 	query := fmt.Sprintf("SELECT %s from %s", strings.Join(tq.Fields, ", "), tq.getTableName())
-	var queryParam []string
+	var queryParam = []string{"multisig_child = false"}
 	if id != 0 {
 		queryParam = append(queryParam, fmt.Sprintf("id = %d", id))
 	}
@@ -70,19 +70,6 @@ func (tq *TransactionQuery) GetTransaction(id int64) string {
 	return query
 }
 
-// GetTransactions get a set of transaction that satisfies the params from DB
-func (tq *TransactionQuery) GetTransactions(limit uint32, offset uint64) string {
-	query := fmt.Sprintf("SELECT %s from %s", strings.Join(tq.Fields, ", "), tq.getTableName())
-
-	newLimit := limit
-	if limit == 0 {
-		newLimit = uint32(10)
-	}
-
-	query = query + " ORDER BY block_height, timestamp" + fmt.Sprintf(" LIMIT %d,%d", offset, newLimit)
-	return query
-}
-
 // InsertTransaction inserts a new transaction into DB
 func (tq *TransactionQuery) InsertTransaction(tx *model.Transaction) (str string, args []interface{}) {
 	var value = fmt.Sprintf("?%s", strings.Repeat(", ?", len(tq.Fields)-1))
@@ -92,7 +79,7 @@ func (tq *TransactionQuery) InsertTransaction(tx *model.Transaction) (str string
 }
 
 func (tq *TransactionQuery) GetTransactionsByBlockID(blockID int64) (str string, args []interface{}) {
-	query := fmt.Sprintf("SELECT %s FROM %s WHERE block_id = ? "+
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE block_id = ? AND multisig_child = false "+
 		"ORDER BY transaction_index ASC", strings.Join(tq.Fields, ", "), tq.getTableName())
 	return query, []interface{}{blockID}
 }
@@ -103,7 +90,8 @@ func (tq *TransactionQuery) GetTransactionsByIds(txIds []int64) (str string, arg
 	for _, txID := range txIds {
 		txIdsStr = append(txIdsStr, fmt.Sprintf("%d", txID))
 	}
-	query := fmt.Sprintf("SELECT %s FROM %s WHERE id in (%s)", strings.Join(tq.Fields, ", "), tq.getTableName(), strings.Join(txIdsStr, ","))
+	query := fmt.Sprintf("SELECT %s FROM %s WHERE multisig_child = false AND id in (%s)",
+		strings.Join(tq.Fields, ", "), tq.getTableName(), strings.Join(txIdsStr, ","))
 	return query, []interface{}{}
 }
 
@@ -129,6 +117,7 @@ func (*TransactionQuery) ExtractModel(tx *model.Transaction) []interface{} {
 		&tx.Signature,
 		&tx.Version,
 		&tx.TransactionIndex,
+		&tx.MultisigChild,
 	}
 }
 
@@ -153,6 +142,7 @@ func (*TransactionQuery) BuildModel(txs []*model.Transaction, rows *sql.Rows) ([
 			&tx.Signature,
 			&tx.Version,
 			&tx.TransactionIndex,
+			&tx.MultisigChild,
 		)
 		if err != nil {
 			return nil, err
@@ -178,6 +168,7 @@ func (*TransactionQuery) Scan(tx *model.Transaction, row *sql.Row) error {
 		&tx.Signature,
 		&tx.Version,
 		&tx.TransactionIndex,
+		&tx.MultisigChild,
 	)
 	return err
 }
diff --git a/common/query/transactionQuery_test.go b/common/query/transactionQuery_test.go
index aaa763428..d4e94d3e3 100644
--- a/common/query/transactionQuery_test.go
+++ b/common/query/transactionQuery_test.go
@@ -71,7 +71,7 @@ func TestGetTransaction(t *testing.T) {
 			want: "SELECT id, block_id, block_height, sender_account_address, " +
 				"recipient_account_address, transaction_type, fee, timestamp, " +
 				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version, " +
-				"transaction_index from \"transaction\"",
+				"transaction_index, multisig_child from \"transaction\" WHERE multisig_child = false",
 		},
 		{
 			name: "transaction query with ID param only",
@@ -81,8 +81,8 @@ func TestGetTransaction(t *testing.T) {
 			want: "SELECT id, block_id, block_height, sender_account_address, " +
 				"recipient_account_address, transaction_type, fee, timestamp, " +
 				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version, " +
-				"transaction_index from \"transaction\" " +
-				"WHERE id = 1",
+				"transaction_index, multisig_child from \"transaction\" " +
+				"WHERE multisig_child = false AND id = 1",
 		},
 	}
 	for _, tt := range tests {
@@ -96,74 +96,6 @@ func TestGetTransaction(t *testing.T) {
 	}
 }
 
-func TestGetTransactions(t *testing.T) {
-	transactionQuery := NewTransactionQuery(chaintype.GetChainType(0))
-
-	type paramsStruct struct {
-		Limit  uint32
-		Offset uint64
-	}
-
-	tests := []struct {
-		name   string
-		params *paramsStruct
-		want   string
-	}{
-		{
-			name:   "transactions query without condition",
-			params: &paramsStruct{},
-			want: "SELECT id, block_id, block_height, sender_account_address, " +
-				"recipient_account_address, transaction_type, fee, timestamp, " +
-				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version," +
-				" transaction_index from " +
-				"\"transaction\" ORDER BY block_height, timestamp LIMIT 0,10",
-		},
-		{
-			name: "transactions query with limit",
-			params: &paramsStruct{
-				Limit: 10,
-			},
-			want: "SELECT id, block_id, block_height, sender_account_address, " +
-				"recipient_account_address, transaction_type, fee, timestamp, " +
-				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version, " +
-				"transaction_index from " +
-				"\"transaction\" ORDER BY block_height, timestamp LIMIT 0,10",
-		},
-		{
-			name: "transactions query with offset",
-			params: &paramsStruct{
-				Offset: 20,
-			},
-			want: "SELECT id, block_id, block_height, sender_account_address, " +
-				"recipient_account_address, transaction_type, fee, timestamp, " +
-				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version, " +
-				"transaction_index from " +
-				"\"transaction\" ORDER BY block_height, timestamp LIMIT 20,10",
-		},
-		{
-			name: "transactions query with all the params",
-			params: &paramsStruct{
-				Limit:  10,
-				Offset: 20,
-			},
-			want: "SELECT id, block_id, block_height, sender_account_address, " +
-				"recipient_account_address, transaction_type, fee, timestamp, " +
-				"transaction_hash, transaction_body_length, transaction_body_bytes, signature, version, " +
-				"transaction_index from " +
-				"\"transaction\" ORDER BY block_height, timestamp LIMIT 20,10",
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			query := transactionQuery.GetTransactions(tt.params.Limit, tt.params.Offset)
-			if query != tt.want {
-				t.Errorf("GetTransactionError() \ngot = %v \nwant = %v", query, tt.want)
-				return
-			}
-		})
-	}
-}
-
 func TestTransactionQuery_Rollback(t *testing.T) {
 	type fields struct {
 		Fields    []string
@@ -273,8 +205,8 @@ func TestTransactionQuery_GetTransactionsByBlockID(t *testing.T) {
 			name:   "wantSuccess",
 			fields: fields(*mockTransactionQuery),
 			args:   args{blockID: int64(1)},
-			wantStr: fmt.Sprintf("SELECT %s FROM \"transaction\" WHERE block_id = ? ORDER BY "+
-				"transaction_index ASC",
+			wantStr: fmt.Sprintf("SELECT %s FROM \"transaction\" WHERE block_id = ? AND multisig_child = false"+
+				" ORDER BY transaction_index ASC",
 				strings.Join(mockTransactionQuery.Fields, ", "),
 			),
 			wantArgs: []interface{}{int64(1)},
@@ -326,7 +258,7 @@ func TestTransactionQuery_GetTransactionsByIds(t *testing.T) {
 			name:   "wantSuccess",
 			fields: fields(*mockTransactionQuery),
 			args:   args{txIds: txIds},
-			wantStr: fmt.Sprintf("SELECT %s FROM \"transaction\" WHERE id in (%s)",
+			wantStr: fmt.Sprintf("SELECT %s FROM \"transaction\" WHERE multisig_child = false AND id in (%s)",
 				strings.Join(mockTransactionQuery.Fields, ", "),
 				strings.Join(txIdsStr, ","),
 			),
@@ -375,6 +307,7 @@ func (*mockQueryExecutorBuildModel) ExecuteSelect(query string, tx bool, args ..
 			make([]byte, 68),
 			1,
 			1,
+			false,
 		),
 	)
 	return db.Query("")
@@ -446,6 +379,7 @@ func (*mockRowTransactionQueryScan) ExecuteSelectRow(qStr string, args ...interf
 			make([]byte, 68),
 			1,
 			1,
+			false,
 		),
 	)
 	return db.QueryRow("")
diff --git a/common/schema b/common/schema
index 5ef391404..bb1388bf8 160000
--- a/common/schema
+++ b/common/schema
@@ -1 +1 @@
-Subproject commit 5ef39140434481b2ce5cb8f9632477a38756864d
+Subproject commit bb1388bf800324a3132839cac42dce0c82c7239d
diff --git a/common/transaction/multiSignature.go b/common/transaction/multiSignature.go
index a2ccd29bf..4d5f0c6e6 100644
--- a/common/transaction/multiSignature.go
+++ b/common/transaction/multiSignature.go
@@ -2,6 +2,11 @@ package transaction
 
 import (
 	"bytes"
+	"database/sql"
+
+	"golang.org/x/crypto/sha3"
+
+	"github.com/zoobc/zoobc-core/common/query"
 
 	"github.com/zoobc/zoobc-core/common/crypto"
 
@@ -17,23 +22,213 @@ type (
 	// MultiSignatureTransaction represent wrapper transaction type that require multiple signer to approve the transcaction
 	// wrapped
 	MultiSignatureTransaction struct {
-		Body            *model.MultiSignatureTransactionBody
-		NormalFee       fee.FeeModelInterface
-		TransactionUtil UtilInterface
-		TypeSwitcher    TypeActionSwitcher
-		Signature       crypto.SignatureInterface
+		SenderAddress       string
+		Fee                 int64
+		QueryExecutor       query.ExecutorInterface
+		AccountBalanceQuery query.AccountBalanceQueryInterface
+		Body                *model.MultiSignatureTransactionBody
+		NormalFee           fee.FeeModelInterface
+		TransactionUtil     UtilInterface
+		TypeSwitcher        TypeActionSwitcher
+		Signature           crypto.SignatureInterface
+		Height              uint32
+		BlockID             int64
+		MultisigUtil        MultisigTransactionUtilInterface
+		// pending services
+		MultisignatureInfoQuery query.MultisignatureInfoQueryInterface
+		PendingTransactionQuery query.PendingTransactionQueryInterface
+		PendingSignatureQuery   query.PendingSignatureQueryInterface
+		TransactionQuery        query.TransactionQueryInterface
 	}
 )
 
-func (*MultiSignatureTransaction) ApplyConfirmed(blockTimestamp int64) error {
+func (tx *MultiSignatureTransaction) ApplyConfirmed(blockTimestamp int64) error {
+	var (
+		err error
+	)
+	// if have multisig info, MultisigInfoService.AddMultisigInfo() -> noop duplicate
+	if tx.Body.MultiSignatureInfo != nil {
+		address, err := tx.TransactionUtil.GenerateMultiSigAddress(tx.Body.MultiSignatureInfo)
+		if err != nil {
+			return err
+		}
+		tx.Body.MultiSignatureInfo.MultisigAddress = address
+		tx.Body.MultiSignatureInfo.BlockHeight = tx.Height
+		tx.Body.MultiSignatureInfo.Latest = true
+		insertMultisigInfoQ := tx.MultisignatureInfoQuery.InsertMultisignatureInfo(tx.Body.MultiSignatureInfo)
+		err = tx.QueryExecutor.ExecuteTransactions(insertMultisigInfoQ)
+		if err != nil {
+			return err
+		}
+	}
+	// if have transaction bytes, PendingTransactionService.AddPendingTransaction() -> noop duplicate
+	if len(tx.Body.UnsignedTransactionBytes) > 0 {
+		var (
+			pendingTx model.PendingTransaction
+		)
+		innerTx, err := tx.TransactionUtil.ParseTransactionBytes(tx.Body.UnsignedTransactionBytes, false)
+		if err != nil {
+			return blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToParseTransactionBytes",
+			)
+		}
+		txHash := sha3.Sum256(tx.Body.UnsignedTransactionBytes)
+		q, args := tx.PendingTransactionQuery.GetPendingTransactionByHash(
+			txHash[:], model.PendingTransactionStatus_PendingTransactionExecuted,
+			tx.Height, constant.MinRollbackBlocks,
+		)
+		row, _ := tx.QueryExecutor.ExecuteSelectRow(q, false, args...)
+		err = tx.PendingTransactionQuery.Scan(&pendingTx, row)
+		if err == sql.ErrNoRows {
+			pendingTxInsertQ := tx.PendingTransactionQuery.InsertPendingTransaction(&model.PendingTransaction{
+				SenderAddress:    innerTx.SenderAccountAddress,
+				TransactionHash:  txHash[:],
+				TransactionBytes: tx.Body.UnsignedTransactionBytes,
+				Status:           model.PendingTransactionStatus_PendingTransactionPending,
+				BlockHeight:      tx.Height,
+				Latest:           true,
+			})
+			err = tx.QueryExecutor.ExecuteTransactions(pendingTxInsertQ)
+			if err != nil {
+				return blocker.NewBlocker(blocker.DBErr, err.Error())
+			}
+		} else {
+			return blocker.NewBlocker(blocker.ValidationErr, "PendingTransactionAlreadyExecuted")
+		}
+
+	}
+	// if have signature, PendingSignature.AddPendingSignature -> noop duplicate
+	if tx.Body.SignatureInfo != nil {
+		for addr, sig := range tx.Body.SignatureInfo.Signatures {
+			insertPendingSigQ := tx.PendingSignatureQuery.InsertPendingSignature(&model.PendingSignature{
+				TransactionHash: tx.Body.SignatureInfo.TransactionHash,
+				AccountAddress:  addr,
+				Signature:       sig,
+				BlockHeight:     tx.Height,
+				Latest:          true,
+			})
+			err = tx.QueryExecutor.ExecuteTransactions(insertPendingSigQ)
+			if err != nil {
+				return blocker.NewBlocker(blocker.DBErr, err.Error())
+			}
+
+		}
+	}
+	// checks for completion, if musigInfo && txBytes && signatureInfo exist, check if signature info complete
+	txs, err := tx.MultisigUtil.CheckMultisigComplete(tx.Body, tx.Height)
+	if err != nil {
+		return err
+	}
+	// every element in txs will have all three optional field filled, to avoid infinite recursive calls.
+	for _, v := range txs {
+		cpTx := tx
+		cpTx.Body = v
+		// parse the UnsignedTransactionBytes
+		utx, err := tx.TransactionUtil.ParseTransactionBytes(cpTx.Body.UnsignedTransactionBytes, false)
+		if err != nil {
+			return err
+		}
+		utx.Height = tx.Height
+		utxAct, err := tx.TypeSwitcher.GetTransactionType(utx)
+		if err != nil {
+			return err
+		}
+		err = utxAct.UndoApplyUnconfirmed()
+		if err != nil {
+			return blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToApplyUndoUnconfirmedInnerTx",
+			)
+		}
+		// call ApplyConfirmed() to inner transaction
+		err = utxAct.ApplyConfirmed(blockTimestamp)
+		if err != nil {
+			return err
+		}
+		// update pending transaction status
+		pendingTx := &model.PendingTransaction{
+			SenderAddress:    v.MultiSignatureInfo.MultisigAddress,
+			TransactionHash:  v.SignatureInfo.TransactionHash,
+			TransactionBytes: v.UnsignedTransactionBytes,
+			Status:           model.PendingTransactionStatus_PendingTransactionExecuted,
+			BlockHeight:      tx.Height,
+			Latest:           true,
+		}
+		updateQueries := tx.PendingTransactionQuery.InsertPendingTransaction(pendingTx)
+		err = tx.QueryExecutor.ExecuteTransactions(updateQueries)
+
+		if err != nil {
+			return err
+		}
+
+		// save multisig_child transaction
+		utx.MultisigChild = true
+		utx.BlockID = tx.BlockID
+		insertMultisigChildQ, args := tx.TransactionQuery.InsertTransaction(utx)
+		err = tx.QueryExecutor.ExecuteTransaction(insertMultisigChildQ, args...)
+		if err != nil {
+			return err
+		}
+	}
 	return nil
 }
 
-func (*MultiSignatureTransaction) ApplyUnconfirmed() error {
+func (tx *MultiSignatureTransaction) ApplyUnconfirmed() error {
+	var (
+		err error
+	)
+	// reduce fee from sender
+	accountBalanceSenderQ, accountBalanceSenderQArgs := tx.AccountBalanceQuery.AddAccountSpendableBalance(
+		-(tx.Fee),
+		map[string]interface{}{
+			"account_address": tx.SenderAddress,
+		},
+	)
+	err = tx.QueryExecutor.ExecuteTransaction(accountBalanceSenderQ, accountBalanceSenderQArgs...)
+	if err != nil {
+		return err
+	}
+	// Run ApplyUnconfirmed of inner transaction
+	if len(tx.Body.UnsignedTransactionBytes) > 0 {
+		// parse and apply unconfirmed
+		innerTx, err := tx.TransactionUtil.ParseTransactionBytes(tx.Body.UnsignedTransactionBytes, false)
+		if err != nil {
+			return blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToParseTransactionBytes",
+			)
+		}
+		innerTa, err := tx.TypeSwitcher.GetTransactionType(innerTx)
+		if err != nil {
+			return blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToCastInnerTransaction",
+			)
+		}
+		err = innerTa.ApplyUnconfirmed()
+		if err != nil {
+			return blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToApplyUnconfirmedInnerTx",
+			)
+		}
+	}
 	return nil
 }
 
-func (*MultiSignatureTransaction) UndoApplyUnconfirmed() error {
+func (tx *MultiSignatureTransaction) UndoApplyUnconfirmed() error {
+	// recover fee
+	accountBalanceSenderQ, accountBalanceSenderQArgs := tx.AccountBalanceQuery.AddAccountSpendableBalance(
+		+(tx.Fee),
+		map[string]interface{}{
+			"account_address": tx.SenderAddress,
+		},
+	)
+	err := tx.QueryExecutor.ExecuteTransaction(accountBalanceSenderQ, accountBalanceSenderQArgs...)
+	if err != nil {
+		return err
+	}
 	return nil
 }
 
@@ -59,6 +254,9 @@ func (tx *MultiSignatureTransaction) Validate(dbTx bool) error {
 		}
 	}
 	if len(body.UnsignedTransactionBytes) > 0 {
+		var (
+			pendingTx model.PendingTransaction
+		)
 		innerTx, err := tx.TransactionUtil.ParseTransactionBytes(tx.Body.UnsignedTransactionBytes, false)
 		if err != nil {
 			return blocker.NewBlocker(
@@ -80,7 +278,17 @@ func (tx *MultiSignatureTransaction) Validate(dbTx bool) error {
 				"FailToValidateInnerTa",
 			)
 		}
+		txHash := sha3.Sum256(tx.Body.UnsignedTransactionBytes)
 
+		q, args := tx.PendingTransactionQuery.GetPendingTransactionByHash(
+			txHash[:], model.PendingTransactionStatus_PendingTransactionExecuted,
+			tx.Height, constant.MinRollbackBlocks,
+		)
+		row, _ := tx.QueryExecutor.ExecuteSelectRow(q, false, args...)
+		err = tx.PendingTransactionQuery.Scan(&pendingTx, row)
+		if err != sql.ErrNoRows {
+			return blocker.NewBlocker(blocker.ValidationErr, "PendingTransactionAlreadyExecuted")
+		}
 	}
 	if body.SignatureInfo != nil {
 		if body.SignatureInfo.TransactionHash == nil { // transaction hash has to come with at least one signature
diff --git a/common/transaction/multiSignature_test.go b/common/transaction/multiSignature_test.go
index b6f60e53e..0ac431cc9 100644
--- a/common/transaction/multiSignature_test.go
+++ b/common/transaction/multiSignature_test.go
@@ -1,11 +1,14 @@
 package transaction
 
 import (
+	"database/sql"
 	"errors"
 	"math/rand"
 	"reflect"
 	"testing"
 
+	"github.com/zoobc/zoobc-core/common/query"
+
 	"github.com/zoobc/zoobc-core/common/crypto"
 
 	"github.com/zoobc/zoobc-core/common/constant"
@@ -278,9 +281,29 @@ type (
 	validateSignatureValidateSuccess struct {
 		crypto.Signature
 	}
+	validateNoExecutedPendingTxExecutor struct {
+		query.Executor
+	}
+	validateNoExecutedPendingTxQuery struct {
+		query.PendingTransactionQuery
+	}
+	validateDuplicateExecutedPendingTxQuery struct {
+		query.PendingTransactionQuery
+	}
 	// MultiSignatureTransactionValidate mocks
 )
 
+func (*validateNoExecutedPendingTxExecutor) ExecuteSelectRow(string, bool, ...interface{}) (*sql.Row, error) {
+	return nil, nil
+}
+func (*validateNoExecutedPendingTxQuery) Scan(*model.PendingTransaction, *sql.Row) error {
+	return sql.ErrNoRows
+}
+
+func (*validateDuplicateExecutedPendingTxQuery) Scan(*model.PendingTransaction, *sql.Row) error {
+	return nil
+}
+
 func (*validateSignatureValidateFail) VerifySignature(payload, signature []byte, accountAddress string) error {
 	return errors.New("mockedError")
 }
@@ -314,11 +337,13 @@ func (*validateTypeSwitcheGetTxTypeSuccessInnerValidateFail) GetTransactionType(
 }
 func TestMultiSignatureTransaction_Validate(t *testing.T) {
 	type fields struct {
-		Body            *model.MultiSignatureTransactionBody
-		NormalFee       fee.FeeModelInterface
-		TransactionUtil UtilInterface
-		TypeSwitcher    TypeActionSwitcher
-		Signature       crypto.SignatureInterface
+		Body                    *model.MultiSignatureTransactionBody
+		NormalFee               fee.FeeModelInterface
+		TransactionUtil         UtilInterface
+		PendingTransactionQuery query.PendingTransactionQueryInterface
+		Executor                query.ExecutorInterface
+		TypeSwitcher            TypeActionSwitcher
+		Signature               crypto.SignatureInterface
 	}
 	type args struct {
 		dbTx bool
@@ -473,6 +498,26 @@ func TestMultiSignatureTransaction_Validate(t *testing.T) {
 			},
 			wantErr: true,
 		},
+		{
+			name: "MultisignatureTransaction_Validate-Success-TransactionBytesExist-ExecutedTxExist",
+			fields: fields{
+				Body: &model.MultiSignatureTransactionBody{
+					MultiSignatureInfo:       nil,
+					UnsignedTransactionBytes: make([]byte, 100),
+					SignatureInfo:            nil,
+				},
+				NormalFee:               nil,
+				PendingTransactionQuery: &validateDuplicateExecutedPendingTxQuery{},
+				Executor:                &validateNoExecutedPendingTxExecutor{},
+				TransactionUtil:         &validateTransactionUtilParseSuccess{},
+				TypeSwitcher:            &validateTypeSwitcheGetTxTypeSuccessInnerValidateSuccess{},
+				Signature:               nil,
+			},
+			args: args{
+				dbTx: false,
+			},
+			wantErr: true,
+		},
 		{
 			name: "MultisignatureTransaction_Validate-Success-TransactionBytesExist-InnerValidateSuccess",
 			fields: fields{
@@ -481,10 +526,12 @@ func TestMultiSignatureTransaction_Validate(t *testing.T) {
 					UnsignedTransactionBytes: make([]byte, 100),
 					SignatureInfo:            nil,
 				},
-				NormalFee:       nil,
-				TransactionUtil: &validateTransactionUtilParseSuccess{},
-				TypeSwitcher:    &validateTypeSwitcheGetTxTypeSuccessInnerValidateSuccess{},
-				Signature:       nil,
+				NormalFee:               nil,
+				PendingTransactionQuery: &validateNoExecutedPendingTxQuery{},
+				Executor:                &validateNoExecutedPendingTxExecutor{},
+				TransactionUtil:         &validateTransactionUtilParseSuccess{},
+				TypeSwitcher:            &validateTypeSwitcheGetTxTypeSuccessInnerValidateSuccess{},
+				Signature:               nil,
 			},
 			args: args{
 				dbTx: false,
@@ -606,11 +653,13 @@ func TestMultiSignatureTransaction_Validate(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			tx := &MultiSignatureTransaction{
-				Body:            tt.fields.Body,
-				NormalFee:       tt.fields.NormalFee,
-				TransactionUtil: tt.fields.TransactionUtil,
-				TypeSwitcher:    tt.fields.TypeSwitcher,
-				Signature:       tt.fields.Signature,
+				Body:                    tt.fields.Body,
+				NormalFee:               tt.fields.NormalFee,
+				TransactionUtil:         tt.fields.TransactionUtil,
+				TypeSwitcher:            tt.fields.TypeSwitcher,
+				PendingTransactionQuery: tt.fields.PendingTransactionQuery,
+				QueryExecutor:           tt.fields.Executor,
+				Signature:               tt.fields.Signature,
 			}
 			if err := tx.Validate(tt.args.dbTx); (err != nil) != tt.wantErr {
 				t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr)
diff --git a/common/transaction/transaction.go b/common/transaction/transaction.go
index e2ef1fc10..21f891930 100644
--- a/common/transaction/transaction.go
+++ b/common/transaction/transaction.go
@@ -228,6 +228,14 @@ func (ts *TypeSwitcher) GetTransactionType(tx *model.Transaction) (TypeAction, e
 	case 5:
 		switch buf[1] {
 		case 0:
+			// initialize service for pending_tx, pending_sig and multisig_info
+			multisigUtil := NewMultisigTransactionUtil(
+				ts.Executor,
+				query.NewPendingTransactionQuery(),
+				query.NewPendingSignatureQuery(),
+				query.NewMultisignatureInfoQuery(),
+				&Util{},
+			)
 			multiSigTransactionBody, err := new(MultiSignatureTransaction).ParseBodyBytes(tx.GetTransactionBodyBytes())
 			if err != nil {
 				return nil, err
@@ -239,7 +247,16 @@ func (ts *TypeSwitcher) GetTransactionType(tx *model.Transaction) (TypeAction, e
 				TypeSwitcher: &TypeSwitcher{
 					Executor: ts.Executor,
 				},
-				Signature: &crypto.Signature{},
+				Signature:               &crypto.Signature{},
+				Height:                  tx.Height,
+				BlockID:                 tx.BlockID,
+				MultisigUtil:            multisigUtil,
+				QueryExecutor:           ts.Executor,
+				AccountBalanceQuery:     query.NewAccountBalanceQuery(),
+				MultisignatureInfoQuery: query.NewMultisignatureInfoQuery(),
+				PendingTransactionQuery: query.NewPendingTransactionQuery(),
+				PendingSignatureQuery:   query.NewPendingSignatureQuery(),
+				TransactionQuery:        query.NewTransactionQuery(&chaintype.MainChain{}),
 			}, nil
 		default:
 			return nil, nil
diff --git a/common/transaction/transactionGeneral.go b/common/transaction/transactionGeneral.go
index ab02289b5..b4a7e8876 100644
--- a/common/transaction/transactionGeneral.go
+++ b/common/transaction/transactionGeneral.go
@@ -5,6 +5,7 @@ import (
 	"database/sql"
 	"errors"
 	"fmt"
+	"sort"
 	"time"
 
 	"github.com/zoobc/zoobc-core/common/blocker"
@@ -32,6 +33,19 @@ type (
 	}
 
 	Util struct{}
+
+	MultisigTransactionUtilInterface interface {
+		CheckMultisigComplete(
+			tx *model.MultiSignatureTransactionBody, txHeight uint32,
+		) ([]*model.MultiSignatureTransactionBody, error)
+	}
+	MultisigTransactionUtil struct {
+		QueryExecutor           query.ExecutorInterface
+		PendingTransactionQuery query.PendingTransactionQueryInterface
+		PendingSignatureQuery   query.PendingSignatureQueryInterface
+		MultisigInfoQuery       query.MultisignatureInfoQueryInterface
+		TransactionUtil         UtilInterface
+	}
 )
 
 // GetTransactionBytes translate transaction model to its byte representation
@@ -346,6 +360,7 @@ func (tu *Util) GenerateMultiSigAddress(info *model.MultiSignatureInfo) (string,
 	if info == nil {
 		return "", fmt.Errorf("params cannot be nil")
 	}
+	sort.Strings(info.Addresses)
 	var (
 		buff = bytes.NewBuffer([]byte{})
 		sig  = crypto.NewEd25519Signature()
@@ -361,3 +376,281 @@ func (tu *Util) GenerateMultiSigAddress(info *model.MultiSignatureInfo) (string,
 	return sig.GetAddressFromPublicKey(hashed[:])
 
 }
+
+func NewMultisigTransactionUtil(
+	queryExecutor query.ExecutorInterface,
+	pendingTransactionQuery query.PendingTransactionQueryInterface,
+	pendingSignatureQuery query.PendingSignatureQueryInterface,
+	multisigInfoQuery query.MultisignatureInfoQueryInterface,
+	transactionUtil UtilInterface,
+) *MultisigTransactionUtil {
+	return &MultisigTransactionUtil{
+		QueryExecutor:           queryExecutor,
+		PendingTransactionQuery: pendingTransactionQuery,
+		PendingSignatureQuery:   pendingSignatureQuery,
+		MultisigInfoQuery:       multisigInfoQuery,
+		TransactionUtil:         transactionUtil,
+	}
+}
+
+func (mtu *MultisigTransactionUtil) CheckMultisigComplete(
+	body *model.MultiSignatureTransactionBody, txHeight uint32,
+) ([]*model.MultiSignatureTransactionBody, error) {
+	if body.MultiSignatureInfo != nil {
+		var (
+			pendingTxs   []*model.PendingTransaction
+			dbPendingTxs []*model.PendingTransaction
+		)
+		multisigAddress := body.MultiSignatureInfo.MultisigAddress
+		if len(body.UnsignedTransactionBytes) > 0 {
+			txHash := sha3.Sum256(body.UnsignedTransactionBytes)
+			pendingTxs = append(pendingTxs, &model.PendingTransaction{
+				TransactionHash:  txHash[:],
+				TransactionBytes: body.UnsignedTransactionBytes,
+				Status:           model.PendingTransactionStatus_PendingTransactionPending,
+				BlockHeight:      txHeight,
+			})
+		}
+		q, args := mtu.PendingTransactionQuery.GetPendingTransactionsBySenderAddress(
+			multisigAddress, model.PendingTransactionStatus_PendingTransactionPending,
+			txHeight, constant.MinRollbackBlocks,
+		)
+		pendingTxRows, err := mtu.QueryExecutor.ExecuteSelect(q, false, args...)
+		if err != nil {
+			return nil, err
+		}
+		defer pendingTxRows.Close()
+		dbPendingTxs, err = mtu.PendingTransactionQuery.BuildModel(dbPendingTxs, pendingTxRows)
+		if err != nil {
+			return nil, err
+		}
+		pendingTxs = append(pendingTxs, dbPendingTxs...)
+		if len(pendingTxs) < 1 {
+			return nil, nil
+		}
+		var readyTxs []*model.MultiSignatureTransactionBody
+		for _, v := range pendingTxs {
+			var (
+				sigInfo               *model.SignatureInfo
+				pendingSigs           []*model.PendingSignature
+				signatures            = make(map[string][]byte)
+				validSignatureCounter uint32
+			)
+			q, args := mtu.PendingSignatureQuery.GetPendingSignatureByHash(
+				v.TransactionHash,
+				txHeight, constant.MinRollbackBlocks,
+			)
+			pendingSigRows, err := mtu.QueryExecutor.ExecuteSelect(q, false, args...)
+			if err != nil {
+				return nil, err
+			}
+			pendingSigs, err = mtu.PendingSignatureQuery.BuildModel(pendingSigs, pendingSigRows)
+			if err != nil {
+				pendingSigRows.Close()
+				return nil, err
+			}
+			pendingSigRows.Close()
+			if err != nil {
+				return nil, err
+			}
+			for _, sig := range pendingSigs {
+				signatures[sig.AccountAddress] = sig.Signature
+			}
+			if len(pendingSigs) < 1 {
+				return nil, nil
+			}
+			if body.SignatureInfo != nil {
+				if bytes.Equal(v.TransactionHash, body.SignatureInfo.TransactionHash) {
+					for addr, sig := range body.SignatureInfo.Signatures {
+						signatures[addr] = sig
+					}
+				}
+			}
+			sigInfo = &model.SignatureInfo{
+				TransactionHash: pendingSigs[0].TransactionHash,
+				Signatures:      signatures,
+			}
+			for _, addr := range body.MultiSignatureInfo.Addresses {
+				if sigInfo.Signatures[addr] != nil {
+					validSignatureCounter++
+				}
+			}
+			if validSignatureCounter >= body.MultiSignatureInfo.MinimumSignatures {
+				// todo: return ready to applyConfirm tx
+				cpTx := &model.MultiSignatureTransactionBody{
+					MultiSignatureInfo:       body.MultiSignatureInfo,
+					UnsignedTransactionBytes: v.TransactionBytes,
+					SignatureInfo: &model.SignatureInfo{
+						TransactionHash: v.TransactionHash,
+						Signatures:      signatures,
+					},
+				}
+				readyTxs = append(readyTxs, cpTx)
+			}
+		}
+		return readyTxs, nil
+	} else if len(body.UnsignedTransactionBytes) > 0 {
+		var (
+			multisigInfo          model.MultiSignatureInfo
+			pendingSigs           []*model.PendingSignature
+			validSignatureCounter uint32
+		)
+		txHash := sha3.Sum256(body.UnsignedTransactionBytes)
+		innerTx, err := mtu.TransactionUtil.ParseTransactionBytes(body.UnsignedTransactionBytes, false)
+		if err != nil {
+			return nil, blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToParseTransactionBytes",
+			)
+		}
+		q, args := mtu.MultisigInfoQuery.GetMultisignatureInfoByAddress(
+			innerTx.SenderAccountAddress,
+			txHeight, constant.MinRollbackBlocks,
+		)
+		row, _ := mtu.QueryExecutor.ExecuteSelectRow(q, false, args...)
+		err = mtu.MultisigInfoQuery.Scan(&multisigInfo, row)
+		if err != nil {
+			if err == sql.ErrNoRows { // multisig info not present
+				return nil, nil
+			}
+			// other database errors
+			return nil, err
+		}
+		body.MultiSignatureInfo = &multisigInfo
+		if body.SignatureInfo != nil {
+			for addr, sig := range body.SignatureInfo.Signatures {
+				pendingSigs = append(pendingSigs, &model.PendingSignature{
+					TransactionHash: body.SignatureInfo.TransactionHash,
+					AccountAddress:  addr,
+					Signature:       sig,
+					BlockHeight:     txHeight,
+				})
+			}
+		}
+		var dbPendingSigs []*model.PendingSignature
+		q, args = mtu.PendingSignatureQuery.GetPendingSignatureByHash(
+			txHash[:],
+			txHeight, constant.MinRollbackBlocks,
+		)
+		rows, err := mtu.QueryExecutor.ExecuteSelect(q, false, args...)
+		if err != nil {
+			return nil, err
+		}
+		defer rows.Close()
+		dbPendingSigs, err = mtu.PendingSignatureQuery.BuildModel(dbPendingSigs, rows)
+		if err != nil {
+			return nil, err
+		}
+		pendingSigs = append(pendingSigs, dbPendingSigs...)
+		body.SignatureInfo = &model.SignatureInfo{
+			TransactionHash: txHash[:],
+			Signatures:      make(map[string][]byte),
+		}
+		for _, sig := range pendingSigs {
+			body.SignatureInfo.Signatures[sig.AccountAddress] = sig.Signature
+		}
+		if len(body.SignatureInfo.Signatures) < 1 {
+			return nil, nil
+		}
+
+		for _, addr := range multisigInfo.Addresses {
+			if body.SignatureInfo.Signatures[addr] != nil {
+				validSignatureCounter++
+			}
+		}
+		if validSignatureCounter >= multisigInfo.MinimumSignatures {
+			// replace unsigned tx to have status executed
+			pendingTxInsertQ := mtu.PendingTransactionQuery.InsertPendingTransaction(&model.PendingTransaction{
+				SenderAddress:    innerTx.SenderAccountAddress,
+				TransactionHash:  txHash[:],
+				TransactionBytes: body.UnsignedTransactionBytes,
+				Status:           model.PendingTransactionStatus_PendingTransactionExecuted,
+				BlockHeight:      txHeight,
+				Latest:           true,
+			})
+			err = mtu.QueryExecutor.ExecuteTransactions(pendingTxInsertQ)
+			if err != nil {
+				return nil, blocker.NewBlocker(blocker.DBErr, err.Error())
+			}
+			return []*model.MultiSignatureTransactionBody{
+				body,
+			}, nil
+		}
+	} else if body.SignatureInfo != nil {
+		var (
+			pendingTx             model.PendingTransaction
+			pendingSigs           []*model.PendingSignature
+			multisigInfo          model.MultiSignatureInfo
+			validSignatureCounter uint32
+		)
+		txHash := body.SignatureInfo.TransactionHash
+
+		q, args := mtu.PendingTransactionQuery.GetPendingTransactionByHash(
+			txHash, model.PendingTransactionStatus_PendingTransactionPending,
+			txHeight, constant.MinRollbackBlocks,
+		)
+		row, err := mtu.QueryExecutor.ExecuteSelectRow(q, false, args...)
+		if err != nil {
+			return nil, err
+		}
+		err = mtu.PendingTransactionQuery.Scan(&pendingTx, row)
+		if err != nil {
+			if err == sql.ErrNoRows {
+				return nil, nil
+			}
+			return nil, err
+		}
+		body.UnsignedTransactionBytes = pendingTx.TransactionBytes
+		innerTx, err := mtu.TransactionUtil.ParseTransactionBytes(body.UnsignedTransactionBytes, false)
+		if err != nil {
+			return nil, blocker.NewBlocker(
+				blocker.ValidationErr,
+				"FailToParseTransactionBytes",
+			)
+		}
+		q, args = mtu.PendingSignatureQuery.GetPendingSignatureByHash(
+			txHash,
+			txHeight, constant.MinRollbackBlocks,
+		)
+		rowsPendingSigs, err := mtu.QueryExecutor.ExecuteSelect(q, false, args...)
+		if err != nil {
+			return nil, err
+		}
+		pendingSigs, err = mtu.PendingSignatureQuery.BuildModel(pendingSigs, rowsPendingSigs)
+		if err != nil {
+			return nil, err
+		}
+		defer rowsPendingSigs.Close()
+		for _, sig := range pendingSigs {
+			body.SignatureInfo.Signatures[sig.AccountAddress] = sig.Signature
+		}
+		q, args = mtu.MultisigInfoQuery.GetMultisignatureInfoByAddress(
+			innerTx.SenderAccountAddress,
+			txHeight, constant.MinRollbackBlocks,
+		)
+		row, _ = mtu.QueryExecutor.ExecuteSelectRow(q, false, args...)
+		err = mtu.MultisigInfoQuery.Scan(&multisigInfo, row)
+		if err != nil {
+			if err == sql.ErrNoRows {
+				return nil, nil
+			}
+			return nil, err
+		}
+		// validate signature
+		for _, addr := range multisigInfo.Addresses {
+			if body.SignatureInfo.Signatures[addr] != nil {
+				validSignatureCounter++
+			}
+		}
+		if validSignatureCounter >= multisigInfo.MinimumSignatures {
+			cpTx := body
+			cpTx.UnsignedTransactionBytes = pendingTx.TransactionBytes
+			cpTx.MultiSignatureInfo = &multisigInfo
+			return []*model.MultiSignatureTransactionBody{
+				cpTx,
+			}, nil
+		}
+
+	}
+	return nil, nil
+}
diff --git a/common/transaction/transactionGeneral_test.go b/common/transaction/transactionGeneral_test.go
index 10f24a007..76538c0d3 100644
--- a/common/transaction/transactionGeneral_test.go
+++ b/common/transaction/transactionGeneral_test.go
@@ -632,7 +632,7 @@ func TestUtil_GenerateMultiSigAddress(t *testing.T) {
 					"BCZKLvgUYZ1KKx-jtF9KoJskjVPvB9jpIjfzzI6zDW0J",
 				},
 			}},
-			want: "N8IH3smVnNkUwRwJj2ZnRjyS1_2n15lK9GfqhWcApHWa",
+			want: "C1Jgm37Y-xW6ls1l9JW5XsRnsifX0CkWB4QTwZE9keVt",
 		},
 	}
 	for _, tt := range tests {
diff --git a/core/service/blockMainService.go b/core/service/blockMainService.go
index b2653d2ce..ad2a7a373 100644
--- a/core/service/blockMainService.go
+++ b/core/service/blockMainService.go
@@ -430,7 +430,6 @@ func (bs *BlockService) PushBlock(previousBlock, block *model.Block, broadcast,
 			}
 		}
 		rows.Close()
-
 		if block.Height > 0 {
 			err = bs.TransactionCoreService.ValidateTransaction(txType, true)
 			if err != nil {
diff --git a/core/service/mempoolServiceUtil_test.go b/core/service/mempoolServiceUtil_test.go
index eb425ebae..1e101c29e 100644
--- a/core/service/mempoolServiceUtil_test.go
+++ b/core/service/mempoolServiceUtil_test.go
@@ -173,6 +173,7 @@ func (*mockExecutorValidateMempoolTransactionSuccess) ExecuteSelectRow(qStr stri
 			make([]byte, 0),
 			nil,
 			make([]byte, 64),
+			false,
 		),
 	)
 	return db.QueryRow(qStr), nil