public async void ShouldBuildValidFungibleCurrencyTransaction()
        {
            string address    = "0x0e5e50883f3a1dd73c170c935339bce1b24a96d0";
            string privateKey = "0xac32ae83a4067291cda7a268e316376338bef6b63f66d10b8b516c76093c677e";

            string addressTo = "0xdd15a3ba1287a1069be49a6ebee9ebdb84eafd31";
            string currency  = "0x3e967151f952ec2bef08107e108747f715bb8b70";

            var utxos = await PlasmaAPIService.GetUtxos(address);

            RawTransactionEncoder txEncoder = new RawTransactionEncoder();

            PlasmaCore.Transactions.Transaction tx = FCTransactionBuilder.Build(address, addressTo, utxos, new BigInteger(1), currency);

            var signedEncodedTx = PlasmaCoreTestsHelper.Sign(txEncoder, tx, address, privateKey);

            Assert.Equal("0xf901daf9010cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cd6c58207d08080c5820bb88080c3048080c58203e88001f8b2eb94dd15a3ba1287a1069be49a6ebee9ebdb84eafd31943e967151f952ec2bef08107e108747f715bb8b7001ed940e5e50883f3a1dd73c170c935339bce1b24a96d0943e967151f952ec2bef08107e108747f715bb8b7082d6cfeb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080eb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080",
                         signedEncodedTx.ToLower());

            PlasmaCore.Transactions.Transaction decodedTransaction = txEncoder.CreateTransaction(signedEncodedTx.HexToByteArray());
            Assert.Equal(signedEncodedTx, txEncoder.EncodeSigned(decodedTransaction).ToHex(true));


            // other currency
            currency = "0x3f83c7446190ae039c54506b0f65ea8ee790ee7e";
            tx       = FCTransactionBuilder.Build(address, addressTo, utxos, new BigInteger(1), currency);

            signedEncodedTx = PlasmaCoreTestsHelper.Sign(txEncoder, tx, address, privateKey);
            Assert.Equal("0xf90151f886b8411841224d01b5aad18730b257ceaac891d00c2fee3a90b196b855660569f8f34708031d97603c2664b7580e19090e4037fa679aa262c4f62c771a88190110feb81cb8411841224d01b5aad18730b257ceaac891d00c2fee3a90b196b855660569f8f34708031d97603c2664b7580e19090e4037fa679aa262c4f62c771a88190110feb81cd4c58298581901c58223283f01c3808080c3808080f8b2eb94dd15a3ba1287a1069be49a6ebee9ebdb84eafd31943f83c7446190ae039c54506b0f65ea8ee790ee7e01ed940e5e50883f3a1dd73c170c935339bce1b24a96d0943f83c7446190ae039c54506b0f65ea8ee790ee7e82d47deb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080eb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080",
                         signedEncodedTx.ToLower());

            decodedTransaction = txEncoder.CreateTransaction(signedEncodedTx.HexToByteArray());
            Assert.Equal(signedEncodedTx, txEncoder.EncodeSigned(decodedTransaction).ToHex(true));
        }
        public async void ShouldConsolidateFungibleCurrencyTransactions()
        {
            string address    = "0x0e5e50883f3a1dd73c170c935339bce1b24a96d0";
            string privateKey = "0xac32ae83a4067291cda7a268e316376338bef6b63f66d10b8b516c76093c677e";
            string currency   = "0xda636e31a9800531418213b5c799960f4585c937";

            var utxos = await PlasmaAPIService.GetUtxos(address);

            RawTransactionEncoder txEncoder = new RawTransactionEncoder();
            var consolidator = new FCConsolidator(PlasmaAPIService, txEncoder, address, currency, utxos, 4);

            while (consolidator.CanMerge)
            {
                foreach (var transaction in consolidator.Transactions)
                {
                    var sig = PlasmaCoreTestsHelper.Sign(txEncoder, transaction, address, privateKey);
                    transaction.SetSignature(address, sig.HexToByteArray());
                }
                await consolidator.ProcessTransactions();
            }

            Assert.Equal(4, consolidator.MergedUtxo.Data);
            Assert.True(consolidator.AllConsolidated);
            Assert.Equal(!consolidator.CanMerge, consolidator.AllConsolidated);

            consolidator = new FCConsolidator(PlasmaAPIService, txEncoder, address, currency, utxos);
            while (consolidator.CanMerge)
            {
                foreach (var transaction in consolidator.Transactions)
                {
                    var sig = PlasmaCoreTestsHelper.Sign(txEncoder, transaction, address, privateKey);
                    transaction.SetSignature(address, sig.HexToByteArray());
                }
                await consolidator.ProcessTransactions();
            }

            Assert.Equal(1744, consolidator.MergedUtxo.Data);
            Assert.True(consolidator.AllConsolidated);
            Assert.Equal(!consolidator.CanMerge, consolidator.AllConsolidated);

            consolidator = new FCConsolidator(PlasmaAPIService, txEncoder, address, currency, utxos, 9999999);
            while (consolidator.CanMerge)
            {
                foreach (var transaction in consolidator.Transactions)
                {
                    var sig = PlasmaCoreTestsHelper.Sign(txEncoder, transaction, address, privateKey);
                    transaction.SetSignature(address, sig.HexToByteArray());
                }
                await consolidator.ProcessTransactions();
            }

            Assert.Equal(1744, consolidator.MergedUtxo.Data);
            Assert.True(consolidator.AllConsolidated);
            Assert.Equal(!consolidator.CanMerge, consolidator.AllConsolidated);
        }
        public async void ShouldSendFungibleCurrencyTransaction()
        {
            string address    = "0x0e5e50883f3a1dd73c170c935339bce1b24a96d0";
            string privateKey = "0xac32ae83a4067291cda7a268e316376338bef6b63f66d10b8b516c76093c677e";

            string addressTo = "0xdd15a3ba1287a1069be49a6ebee9ebdb84eafd31";
            string currency  = "0x3e967151f952ec2bef08107e108747f715bb8b70";

            var utxos = await PlasmaAPIService.GetUtxos(address);

            RawTransactionEncoder txEncoder = new RawTransactionEncoder();

            PlasmaCore.Transactions.Transaction tx = FCTransactionBuilder.Build(address, addressTo, utxos, new BigInteger(1), currency);

            var signedEncodedTx = PlasmaCoreTestsHelper.Sign(txEncoder, tx, address, privateKey);

            Assert.Equal("0xf901daf9010cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cb841200d2b4370aac48a5bd9b404224395e6a2395d634973cc7bdf36a2091382a2772670b839b769617e3d2bd992e0dfe6fd1e4515cce060afa5f4f47aec45e555f91cd6c58207d08080c5820bb88080c3048080c58203e88001f8b2eb94dd15a3ba1287a1069be49a6ebee9ebdb84eafd31943e967151f952ec2bef08107e108747f715bb8b7001ed940e5e50883f3a1dd73c170c935339bce1b24a96d0943e967151f952ec2bef08107e108747f715bb8b7082d6cfeb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080eb94000000000000000000000000000000000000000094000000000000000000000000000000000000000080",
                         signedEncodedTx.ToLower());

            TransactionReceipt receipt = await PlasmaAPIService.SubmitTransaction(signedEncodedTx);

            Assert.NotNull(receipt);
        }