Exemple #1
0
        private static IMessage GetMessage(JObject msg)
        {
            try
            {
                var msgType = msg["type"].ToObject <int>();
                var payload = msg["payload"].ToObject <string>().FromHex();

                switch (MessageTypeExtension.GetRawValue(msgType))
                {
                case MessageType.PLAIN_MESSAGE:
                    if (payload.Length <= 0)
                    {
                        return(EmptyMessage.Create());
                    }
                    return(PlainMessage.Create(Encoding.UTF8.GetString(payload)));

                case MessageType.SECURED_MESSAGE:
                    return(SecureMessage.CreateFromEncodedPayload(payload));

                default:
                    return(EmptyMessage.Create());
                }
            }
            catch (Exception)
            {
                return(EmptyMessage.Create());
            }
        }
        public async Task AnnounceTransferTransactionWithMultipleMosaicsWithoutMessage()
        {
            var keyPair =
                KeyPair.CreateFromPrivateKey(Config.PrivateKeyMain);

            var transaction = TransferTransaction.Create(
                NetworkType.Types.MIJIN_TEST,
                Deadline.CreateHours(2),
                Address.CreateFromEncoded("SAAA57-DREOPY-KUFX4O-G7IQXK-ITMBWK-D6KXTV-BBQP"),
                new List <Mosaic>()
            {
                Mosaic.CreateFromIdentifier("happy:test2", 10),
                Mosaic.CreateFromIdentifier("nem:xem", 10),
            },
                EmptyMessage.Create()
                ).SignWith(keyPair);

            await new TransactionHttp("http://" + Config.Domain + ":3000").Announce(transaction);

            listener.TransactionStatus(Address.CreateFromPublicKey(transaction.Signer, NetworkType.Types.MIJIN_TEST))
            .Subscribe(e => Console.WriteLine(e.Status));

            var status = await listener.ConfirmedTransactionsGiven(Address.CreateFromPublicKey(transaction.Signer, NetworkType.Types.MIJIN_TEST)).Take(1);

            Assert.AreEqual(keyPair.PublicKeyString, status.Signer.PublicKey);
        }
        public async Task <object> TestingTransfer(string from, string privateKey, string to, IAsset asset, decimal amount)
        {
            var nodeHttp    = new NodeHttp(_nemUrl);
            var networkType = await nodeHttp.GetNetworkType();

            var networkTime    = (int)(await nodeHttp.GetExtendedNodeInfo()).NisInfo.CurrentTime;
            var toAddressParts = to.Split(AddressSeparator);
            var message        = toAddressParts.Length > 1
                ? PlainMessage.Create(toAddressParts[1]) as IMessage
                : EmptyMessage.Create();
            var mosaic = Mosaic.CreateFromIdentifier(asset.AssetId, (ulong)asset.ToBaseUnit(amount));
            var fee    = await TransferTransaction.CalculateFee(networkType, message, new[] { mosaic }, new NamespaceMosaicHttp(_nemUrl));

            var tx = TransferTransaction.Create(
                networkType,
                new Deadline(networkTime + _expiresInSeconds),
                fee.fee,
                Address.CreateFromEncoded(toAddressParts[0]),
                new List <Mosaic> {
                mosaic
            },
                message,
                networkTime);
            var signed = tx.SignWith(KeyPair.CreateFromPrivateKey(privateKey));
            var result = await new TransactionHttp(_nemUrl).Announce(signed);

            return(result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TransferTransaction"/> class.
 /// </summary>
 /// <param name="networkType">Type of the network.</param>
 /// <param name="version">The version.</param>
 /// <param name="deadline">The deadline.</param>
 /// <param name="fee">The fee.</param>
 /// <param name="recipient">The recipient.</param>
 /// <param name="mosaics">The mosaics.</param>
 /// <param name="message">The message.</param>
 /// <exception cref="System.ArgumentNullException">recipient</exception>
 internal TransferTransaction(NetworkType.Types networkType, byte version, Deadline deadline, ulong fee, Address recipient, List <Mosaic> mosaics, IMessage message)
 {
     Address         = recipient ?? throw new ArgumentNullException(nameof(recipient));
     TransactionType = TransactionTypes.Types.Transfer;
     Version         = version;
     Deadline        = deadline;
     Message         = message ?? EmptyMessage.Create();
     Mosaics         = mosaics ?? new List <Mosaic>();;
     NetworkType     = networkType;
     Fee             = fee == 0 ? CalculateFee() : fee;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TransferTransaction"/> class.
 /// </summary>
 /// <param name="networkType">Type of the network.</param>
 /// <param name="version">The version.</param>
 /// <param name="deadline">The deadline.</param>
 /// <param name="fee">The fee.</param>
 /// <param name="recipient">The recipient.</param>
 /// <param name="mosaics">The mosaics.</param>
 /// <param name="message">The message.</param>
 /// <param name="signature">The signature.</param>
 /// <param name="signer">The signer.</param>
 /// <param name="transactionInfo">The transaction information.</param>
 /// <exception cref="System.ArgumentNullException">recipient</exception>
 internal TransferTransaction(NetworkType.Types networkType, int version, Deadline deadline, ulong fee, Address recipient, List <Mosaic> mosaics, IMessage message, string signature, PublicAccount signer, TransactionInfo transactionInfo)
 {
     Address         = recipient ?? throw new ArgumentNullException(nameof(recipient));
     Mosaics         = mosaics ?? new List <Mosaic>();
     TransactionType = TransactionTypes.Types.Transfer;
     Version         = version;
     Deadline        = deadline;
     Message         = message ?? EmptyMessage.Create();
     NetworkType     = networkType;
     Signature       = signature;
     Signer          = signer;
     TransactionInfo = transactionInfo;
     Fee             = fee == 0 ? CalculateFee() : fee;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TransferTransaction" /> class.
 /// </summary>
 /// <param name="networkType">Type of the network.</param>
 /// <param name="version">The version.</param>
 /// <param name="deadline">The deadline.</param>
 /// <param name="fee">The fee.</param>
 /// <param name="recipient">The recipient.</param>
 /// <param name="mosaics">The mosaics.</param>
 /// <param name="message">The message.</param>
 /// <exception cref="ArgumentNullException">mosaics
 /// or
 /// recipient</exception>
 internal TransferTransaction(NetworkType.Types networkType, int version, Deadline deadline, ulong fee, Address recipient, List <Mosaic> mosaics, IMessage message)
 {
     if (mosaics == null)
     {
         throw new ArgumentNullException(nameof(mosaics));
     }
     Address         = recipient ?? throw new ArgumentNullException(nameof(recipient));
     TransactionType = TransactionTypes.Types.Transfer;
     Version         = version;
     mosaics.Sort((c1, c2) => string.CompareOrdinal(c1.MosaicId.MosaicName, c2.MosaicId.MosaicName));
     Deadline    = deadline;
     Message     = message ?? EmptyMessage.Create();
     Mosaics     = mosaics;
     NetworkType = networkType;
     Fee         = fee;
 }
Exemple #7
0
        // [TestMethod]
        public void ShouldSignTransaction()
        {
            Account             account             = new Account("787225aaff3d2c71f4ffa32d4f19ec4922f3cd869747f267378f81f8e3fcb12d", NetworkType.Types.MIJIN_TEST);
            TransferTransaction transferTransaction = TransferTransaction.Create(
                NetworkType.Types.MIJIN_TEST,
                Deadline.CreateHours(0),
                Address.CreateFromEncoded("SDUP5PLHDXKBX3UU5Q52LAY4WYEKGEWC6IB3VBFM"),
                new List <Mosaic>()
            {
                new Mosaic(new MosaicId("nem:xem"), 100)
            },
                EmptyMessage.Create()
                );

            SignedTransaction signedTransaction = account.Sign(transferTransaction);

            Assert.AreEqual("A50000003400097BF12505E4138374A1B5AFB01E183F53F5EF1416C0D1E84BBE8CA29819722063922E8006B7738080DF1BDA819BF4D937765E941D025BE1C61B345975061026D70E1954775749C6811084D6450A3184D977383F0E4282CD47118AF37755039054410000000000000000000000000000000090E8FEBD671DD41BEE94EC3BA5831CB608A312C2F203BA84AC0100010029CF5FD941AD25D56400000000000000", signedTransaction.Payload);
            Assert.AreEqual("4877AFCC92D1CCA47FDB65F1E7B70BB25D196287E8C9177BCF46F644887B7BA3", signedTransaction.Hash);
        }
        public async Task AnnounceTransferTransactionWithMultipleMosaicsWithoutMessage()
        {
            var keyPair =
                new KeyPair(Config.PrivateKeyMain);

            var transaction = TransferTransaction.Create(
                NetworkType.Types.TEST_NET,
                Deadline.CreateHours(2),
                new Address("TALICE-ROONSJ-CPHC63-F52V6F-Y3SDMS-VAEUGH-MB7C"),
                new List <MosaicAmount>()
            {
                new MosaicAmount("nem:xem", 10)
            },
                EmptyMessage.Create()
                ).SignWith(keyPair);

            var response = await new TransactionHttp(host).Announce(transaction);

            Assert.AreEqual("SUCCESS", response.Message);
        }
        public async Task AnnounceTransferTransactionWithMultipleMosaicsWithoutMessage()
        {
            var keyPair =
                KeyPair.CreateFromPrivateKey(Config.PrivateKeyMain);

            var transaction = TransferTransaction.Create(
                NetworkType.Types.TEST_NET,
                Deadline.CreateHours(2),
                Address.CreateFromEncoded("TALICE-ROONSJ-CPHC63-F52V6F-Y3SDMS-VAEUGH-MB7C"),
                new List <Mosaic>()
            {
                Mosaic.CreateFromIdentifier("nem:xem", 10)
            },
                EmptyMessage.Create()
                ).SignWith(keyPair);

            var response = await new TransactionHttp("http://" + Config.Domain + ":7890").Announce(transaction);

            Assert.AreEqual("SUCCESS", response.Message);
        }
 protected TransferTransaction ToTransferTransaction(JObject tx, TransactionInfo txInfo)
 {
     return(new TransferTransaction(
                ExtractNetworkType(int.Parse(tx["version"].ToString())),
                ExtractVersion(int.Parse(tx["version"].ToString())),
                new Deadline(int.Parse(tx["deadline"].ToString())),
                ulong.Parse(tx["fee"].ToString()),
                Address.CreateFromEncoded(tx["recipient"].ToString()),
                tx["mosaics"] == null
             ? new List <Mosaic>()
     {
         new Mosaic("nem", "xem", ulong.Parse(tx["amount"].ToString()))
     }
             : tx["mosaics"]?.Select(m => new Mosaic(m["mosaicId"]["namespaceId"].ToString(), m["mosaicId"]["name"].ToString(), ulong.Parse(m["quantity"].ToString()))).ToList(),
                tx["message"].ToString() == "{}" ? EmptyMessage.Create() : RetrieveMessage(tx["message"].ToObject <JObject>()),
                tx["signature"]?.ToString(),
                new PublicAccount(tx["signer"].ToString(), ExtractNetworkType(int.Parse(tx["version"].ToString()))),
                txInfo
                ));
 }
        public async Task AnnounceTransferTransactionWithMosaicWithMessage()
        {
            KeyPair keyPair = KeyPair.CreateFromPrivateKey(Config.PrivateKeyMain);

            TransferTransaction transaction = TransferTransaction.Create(
                NetworkType.Types.TEST_NET,
                Deadline.CreateHours(2),
                Address.CreateFromEncoded("TACOPE-XRLZTU-WBQA3U-XV66R4-55L76E-NWK6OY-ITBJ"),
                new List <Mosaic> {
                Mosaic.CreateFromIdentifier("nem:xem", 1)
            },
                EmptyMessage.Create()
                );

            SignedTransaction signedTransaction = transaction.SignWith(keyPair);

            Console.WriteLine(signedTransaction.Hash);
            Console.WriteLine(transaction.Fee);
            TransactionResponse response = await new TransactionHttp("http://" + Config.Domain + ":7890").Announce(signedTransaction);

            Assert.AreEqual("SUCCESS", response.Message);
        }
        internal new TransferTransaction Apply(string input)
        {
            var tx = JsonConvert.DeserializeObject <TransferTransactionInfoDTO>(input);

            var txInfo   = TransactionInfo.Create(tx.Meta.Height, tx.Meta.Index, tx.Meta.Id, tx.Meta.Hash, tx.Meta.MerkleComponentHash);
            var deadline = new Deadline(tx.Transaction.Deadline);
            var mosaics  = tx.Transaction.Mosaics.Select(m => new Mosaic(new MosaicId(BitConverter.ToUInt64(m.MosaicId.FromHex(), 0)), m.Amount)).ToList();

            IMessage message;

            try
            {
                message = PlainMessage.Create(Encoding.UTF8.GetString(tx.Transaction.Message.Payload.FromHex()));
            }
            catch (Exception)
            {
                try
                {
                    message = PlainMessage.Create(tx.Transaction.Message.Payload);
                }
                catch (Exception)
                {
                    message = EmptyMessage.Create();
                }
            }

            return(new TransferTransaction(
                       ExtractNetworkType(tx.Transaction.Version),
                       ExtractTransactionVersion(tx.Transaction.Version),
                       deadline,
                       tx.Transaction.Fee,
                       Address.CreateFromEncoded(tx.Transaction.Recipient),
                       mosaics,
                       message,
                       tx.Transaction.Signature,
                       new PublicAccount(tx.Transaction.Signer, ExtractNetworkType(tx.Transaction.Version)),
                       txInfo
                       ));
        }
        public async Task AnnounceTransferTransactionWithMosaicWithMessage()
        {
            KeyPair keyPair = new KeyPair(Config.PrivateKeyMain);

            TransferTransaction transaction = TransferTransaction.Create(
                NetworkType.Types.TEST_NET,
                Deadline.CreateHours(2),
                new Address("TACOPE-XRLZTU-WBQA3U-XV66R4-55L76E-NWK6OY-ITBJ"),
                new List <MosaicAmount> {
                new MosaicAmount("nem:xem", 1)
            },
                EmptyMessage.Create()
                );

            SignedTransaction signedTransaction = transaction.SignWith(keyPair);

            Console.WriteLine(signedTransaction.Hash);
            Console.WriteLine(transaction.Fee);
            TransactionResponse response = await new TransactionHttp(host).Announce(signedTransaction);

            Assert.AreEqual("SUCCESS", response.Message);
        }
Exemple #14
0
        public void CreateAAggregateTransactionViaStaticConstructor()
        {
            TransferTransaction transferTx = TransferTransaction.Create(
                NetworkType.Types.MIJIN_TEST,
                Deadline.CreateHours(2),
                new Address("SDGLFW-DSHILT-IUHGIB-H5UGX2-VYF5VN-JEKCCD-BR26", NetworkType.Types.MIJIN_TEST),
                new List <Mosaic>(),
                EmptyMessage.Create()
                );

            AggregateTransaction aggregateTx = AggregateTransaction.CreateComplete(
                NetworkType.Types.MIJIN_TEST,
                Deadline.CreateHours(2),
                new List <Transaction>()
            {
                transferTx.ToAggregate(new PublicAccount("9A49366406ACA952B88BADF5F1E9BE6CE4968141035A60BE503273EA65456B24", NetworkType.Types.MIJIN_TEST))
            });

            Assert.AreEqual(NetworkType.Types.MIJIN_TEST, aggregateTx.NetworkType);
            Assert.IsTrue(144 == aggregateTx.NetworkType.GetNetworkByte());
            Assert.IsTrue(DateTime.Now > aggregateTx.Deadline.GetLocalDateTime());
            Assert.AreEqual((ulong)0, aggregateTx.Fee);
            Assert.AreEqual(1, aggregateTx.InnerTransactions.Count);
        }
Exemple #15
0
 public TransferTransactionBuilder() : base(EntityType.TRANSFER, EntityVersion.TRANSFER.GetValue())
 {
     Message = EmptyMessage.Create();
     Mosaics = new List <Mosaic>();
 }
        public async Task <(string transactionContext, decimal fee, long expiration)> BuildTransactionAsync(Guid operationId,
                                                                                                            IAsset asset, IReadOnlyList <IOperationAction> actions, bool includeFee)
        {
            // from one side NEM supports single sender and single receiver per transaction,
            // from the other side we support single asset per transaction,
            // finally only single transfers are allowed

            if (actions.Count != 1)
            {
                throw new ArgumentException("Transaction must contain a single transfer only");
            }

            var nodeHttp    = new NodeHttp(_nemUrl);
            var networkType = await nodeHttp.GetNetworkType();

            var action         = actions[0];
            var toAddressParts = action.To.Split(AddressSeparator);
            var toAddress      = toAddressParts[0];
            var memo           = toAddressParts.Length > 1
                ? toAddressParts[1]
                : "";
            var message = !string.IsNullOrEmpty(memo)
                ? PlainMessage.Create(memo) as IMessage
                : EmptyMessage.Create();
            var mosaic = Mosaic.CreateFromIdentifier(asset.AssetId, (ulong)asset.ToBaseUnit(action.Amount));
            var fee    = await TransferTransaction.CalculateFee(networkType, message, new[] { mosaic }, new NamespaceMosaicHttp(_nemUrl));

            if (includeFee)
            {
                try
                {
                    checked
                    {
                        if (mosaic.NamespaceName == Xem.NamespaceName &&
                            mosaic.MosaicName == Xem.MosaicName)
                        {
                            mosaic.Amount -= fee.fee;
                        }

                        // only single transfers are supported,
                        // so there must be single levy

                        var levy = fee.levies.SingleOrDefault();

                        if (levy != null &&
                            mosaic.NamespaceName == levy.NamespaceName &&
                            mosaic.MosaicName == levy.MosaicName)
                        {
                            mosaic.Amount -= levy.Amount;
                        }
                    }
                }
                catch (OverflowException)
                {
                    throw new BlockchainException(BlockchainErrorCode.AmountIsTooSmall, "Amount is less than fee");
                }
            }

            // check balances of FromAddress for all required assets

            var fromAddress = action.From.Split(AddressSeparator)[0];
            var owned       = await new AccountHttp(_nemUrl).MosaicsOwned(Address.CreateFromEncoded(fromAddress));
            var required    = fee.levies
                              .Append(Xem.CreateAbsolute(fee.fee))
                              .Append(mosaic)
                              .GroupBy(m => new { m.NamespaceName, m.MosaicName })
                              .Select(g => new Mosaic(g.Key.NamespaceName, g.Key.MosaicName, g.Aggregate(0UL, (v, m) => v += m.Amount)))
                              .ToList();

            foreach (var req in required)
            {
                var own = owned.FirstOrDefault(m => m.NamespaceName == req.NamespaceName && m.MosaicName == req.MosaicName)?.Amount ?? 0UL;
                if (own < req.Amount)
                {
                    throw new BlockchainException(BlockchainErrorCode.NotEnoughBalance,
                                                  $"Not enough {req.NamespaceName}:{req.MosaicName}");
                }
            }

            var networkTime = (int)(await nodeHttp.GetExtendedNodeInfo()).NisInfo.CurrentTime;

            var tx = TransferTransaction.Create(
                networkType,
                new Deadline(networkTime + _expiresInSeconds),
                fee.fee,
                Address.CreateFromEncoded(toAddress),
                new List <Mosaic> {
                mosaic
            },
                message,
                networkTime);

            return(
                tx.ToJson(),
                Convert.ToDecimal(fee.fee * 1e-6),
                tx.Deadline.GetInstant()
                );
        }
        /// <summary>
        /// Generates the bytes.
        /// </summary>
        /// <returns>The transaction bytes.</returns>
        internal override byte[] GenerateBytes()
        {
            var builder = new FlatBufferBuilder(1);

            var signer          = TransferTransactionBuffer.CreatePublicKeyVector(builder, GetSigner());
            var recipientVector = TransferTransactionBuffer.CreateRecipientVector(builder, Encoding.UTF8.GetBytes(Address.Plain));

            if (Message == null)
            {
                Message = EmptyMessage.Create();
            }
            var messageBytePayload = Message.GetPayload();
            var payload            = MessageBuffer.CreatePayloadVector(builder, messageBytePayload);

            var messageBuff = new Offset <MessageBuffer> [1];

            MessageBuffer.StartMessageBuffer(builder);

            if (messageBytePayload.Length > 0)
            {
                MessageBuffer.AddType(builder, Message.GetMessageType().GetValue());
            }
            if (messageBytePayload.Length > 0)
            {
                MessageBuffer.AddPayloadLen(builder, messageBytePayload.Length);
            }
            if (messageBytePayload.Length > 0)
            {
                MessageBuffer.AddPayload(builder, payload);
            }

            messageBuff[0] = MessageBuffer.EndMessageBuffer(builder);

            var messageVector = TransferTransactionBuffer.CreateMessageVector(builder, messageBuff);

            var mosaics = new Offset <MosaicBuffer> [Mosaics.Count];

            for (var index = 0; index < Mosaics.Count; index++)
            {
                var mosaic           = Mosaics[index];
                var namespaceVector  = MosaicBuffer.CreateNamespaceStringVector(builder, Encoding.UTF8.GetBytes(mosaic.NamespaceName));
                var mosaicNameVector = MosaicBuffer.CreateMosaicIdStringVector(builder, Encoding.UTF8.GetBytes(mosaic.MosaicName));

                MosaicBuffer.StartMosaicBuffer(builder);

                var nsLen = Encoding.Default.GetBytes(mosaic.NamespaceName).Length;
                var msLen = Encoding.Default.GetBytes(mosaic.MosaicName).Length;

                MosaicBuffer.AddMosaicStructureLen(builder, 20 + nsLen + msLen);
                MosaicBuffer.AddMosaicIdStructureLen(builder, nsLen + msLen + 8);
                MosaicBuffer.AddNamespaceIdLen(builder, nsLen);
                MosaicBuffer.AddNamespaceString(builder, namespaceVector);
                MosaicBuffer.AddMosaicIdLen(builder, msLen);
                MosaicBuffer.AddMosaicIdString(builder, mosaicNameVector);
                MosaicBuffer.AddQuantity(builder, mosaic.Amount);

                mosaics[index] = MosaicBuffer.EndMosaicBuffer(builder);
            }

            var mosaicsVector = TransferTransactionBuffer.CreateMosaicsVector(builder, mosaics);

            TransferTransactionBuffer.StartTransferTransactionBuffer(builder);

            TransferTransactionBuffer.AddTransactionType(builder, TransactionType.GetValue());
            TransferTransactionBuffer.AddVersion(builder, BitConverter.ToInt16(new byte[] { ExtractVersion(Version), 0 }, 0));
            TransferTransactionBuffer.AddNetwork(builder, BitConverter.ToInt16(new byte[] { 0, NetworkType.GetNetwork() }, 0));
            TransferTransactionBuffer.AddTimestamp(builder, NetworkTime.EpochTimeInMilliSeconds());
            TransferTransactionBuffer.AddPublicKeyLen(builder, 32);
            TransferTransactionBuffer.AddPublicKey(builder, signer);
            TransferTransactionBuffer.AddFee(builder, Fee);
            TransferTransactionBuffer.AddDeadline(builder, Deadline.Ticks);
            TransferTransactionBuffer.AddRecipientLen(builder, 40);
            TransferTransactionBuffer.AddRecipient(builder, recipientVector);
            TransferTransactionBuffer.AddAmount(builder, 1000000);
            TransferTransactionBuffer.AddMessageFieldLen(builder, Message.GetLength() == 0 ? 0 : Message.GetLength() + 8);
            TransferTransactionBuffer.AddMessage(builder, messageVector);
            TransferTransactionBuffer.AddNoOfMosaics(builder, Mosaics.Count);
            TransferTransactionBuffer.AddMosaics(builder, mosaicsVector);

            var codedTransfer = TransferTransactionBuffer.EndTransferTransactionBuffer(builder);

            builder.Finish(codedTransfer.Value);

            return(new TransferTransactionSchema().Serialize(builder.SizedByteArray()));
        }
        /// <summary>
        /// Generates the bytes.
        /// </summary>
        /// <returns>The transaction bytes.</returns>
        internal override byte[] GenerateBytes()
        {
            var builder = new FlatBufferBuilder(1);

            // create vectors
            var signatureVector = TransferTransactionBuffer.CreateSignatureVector(builder, new byte[64]);
            var signerVector    = TransferTransactionBuffer.CreateSignerVector(builder, GetSigner());
            var feeVector       = TransferTransactionBuffer.CreateFeeVector(builder, Fee.ToUInt8Array());
            var deadlineVector  = TransferTransactionBuffer.CreateDeadlineVector(builder, Deadline.Ticks.ToUInt8Array());
            var recipientVector = TransferTransactionBuffer.CreateRecipientVector(builder, Address.Plain.FromBase32String());

            ushort version = ushort.Parse(NetworkType.GetNetworkByte().ToString("X") + "0" + Version.ToString("X"), System.Globalization.NumberStyles.HexNumber);

            if (Message == null)
            {
                Message = EmptyMessage.Create();
            }

            // create message vector
            var bytePayload = Message.GetPayload();
            var payload     = MessageBuffer.CreatePayloadVector(builder, bytePayload);

            MessageBuffer.StartMessageBuffer(builder);
            if (bytePayload != null)
            {
                MessageBuffer.AddType(builder, Message.GetMessageType());
            }
            MessageBuffer.AddPayload(builder, payload);
            var message = MessageBuffer.EndMessageBuffer(builder);

            // create mosaics vector
            var mosaics = new Offset <MosaicBuffer> [Mosaics.Count];

            for (var index = 0; index < Mosaics.Count; index++)
            {
                var mosaic       = Mosaics[index];
                var idPayload    = MosaicBuffer.CreateIdVector(builder, mosaic.MosaicId.Id.ToUInt8Array());
                var amountVector = MosaicBuffer.CreateAmountVector(builder, mosaic.Amount.ToUInt8Array());
                MosaicBuffer.StartMosaicBuffer(builder);
                MosaicBuffer.AddId(builder, idPayload);
                MosaicBuffer.AddAmount(builder, amountVector);

                mosaics[index] = MosaicBuffer.EndMosaicBuffer(builder);
            }

            var mosaicsVector = TransferTransactionBuffer.CreateMosaicsVector(builder, mosaics);

            // add vectors
            TransferTransactionBuffer.StartTransferTransactionBuffer(builder);
            TransferTransactionBuffer.AddSize(builder, (uint)(/*fixed size*/ 148 + 16 * Mosaics.Count + Message.GetLength()));
            TransferTransactionBuffer.AddSignature(builder, signatureVector);
            TransferTransactionBuffer.AddSigner(builder, signerVector);
            TransferTransactionBuffer.AddVersion(builder, version);
            TransferTransactionBuffer.AddType(builder, TransactionTypes.Types.Transfer.GetValue());
            TransferTransactionBuffer.AddFee(builder, feeVector);
            TransferTransactionBuffer.AddDeadline(builder, deadlineVector);
            TransferTransactionBuffer.AddRecipient(builder, recipientVector);
            TransferTransactionBuffer.AddNumMosaics(builder, (byte)Mosaics.Count);
            TransferTransactionBuffer.AddMessageSize(builder, (byte)Message.GetLength());
            TransferTransactionBuffer.AddMessage(builder, message);
            TransferTransactionBuffer.AddMosaics(builder, mosaicsVector);

            // end build
            var codedTransfer = TransferTransactionBuffer.EndTransferTransactionBuffer(builder);

            builder.Finish(codedTransfer.Value);

            return(new TransferTransactionSchema().Serialize(builder.SizedByteArray()));
        }