private static async Task ConvertAddresses(string settingsUrl)
        {
            if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
            {
                Console.WriteLine($"{SettingsUrl} should be a valid uri");

                return;
            }

            var logFactory = LogFactory.Create()
                             .AddConsole();

            var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => {}).Nested(p => p.LiteCoinAPI);

            var oldStorage = AzureTableStorage <ObservableWalletEntity> .Create(settings.Nested(p => p.Db.DataConnString),
                                                                                "ObservableWallets", logFactory);

            var newStorage = AzureTableStorage <ObservableWalletEntity> .Create(settings.Nested(p => p.Db.DataConnString),
                                                                                "ObservableWalletsRef", logFactory);

            string continuationToken = null;
            var    progressCounter   = 0;

            Console.WriteLine("Converting wallets...");

            var batchSize = 10;

            do
            {
                var rangeQuery = new TableQuery <ObservableWalletEntity>
                {
                    TakeCount = batchSize
                };

                var queryResult = await oldStorage.GetDataWithContinuationTokenAsync(rangeQuery, continuationToken);

                if (queryResult.Entities.Any())
                {
                    var entitiesToInsert = queryResult.Entities.Select(ObservableWalletEntity.Create).ToList();


                    foreach (var observableWalletEntity in entitiesToInsert)
                    {
                        await newStorage.InsertOrReplaceAsync(observableWalletEntity);
                    }

                    progressCounter  += entitiesToInsert.Count;
                    continuationToken = queryResult.ContinuationToken;
                }
                else
                {
                    continuationToken = null;
                }

                Console.SetCursorPosition(0, Console.CursorTop);
                Console.Write($"{progressCounter} wallets converted");
            } while (continuationToken != null);
        }
Example #2
0
        private static async Task Execute(string bitcoinCashDataConnString,
                                          string settingsUrl,
                                          string bitcoinCashNetwork,
                                          string blockchainType)
        {
            BCash.Instance.EnsureRegistered();
            var network      = Network.GetNetwork(bitcoinCashNetwork);
            var bcashNetwork = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest;

            var logConsole = LogFactory.Create().AddConsole();
            var settings   = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => {});

            var walletRepo = BlockchainWalletsRepository.Create(settings.Nested(p => p.BlockchainWalletsService.Db.DataConnString),
                                                                logConsole);

            var firstGenerationBlockchainWalletRepository = FirstGenerationBlockchainWalletRepository.Create(settings.Nested(x => x.BlockchainWalletsService.Db.ClientPersonalInfoConnString), logConsole);

            var observableWalletsRepo = ObservableWalletRepository.Create(new ReloadingManagerAdapter <string>(bitcoinCashDataConnString),
                                                                          logConsole);

            var addressValidator = new AddressValidator(network, bcashNetwork);

            Console.WriteLine("Retrieving observable wallets");

            var observableWallets = (await observableWalletsRepo.GetAll()).ToList();

            Console.WriteLine("Processing items");

            var counter = 0;

            foreach (var observableWallet in observableWallets)
            {
                counter++;

                var address = addressValidator.GetBitcoinAddress(observableWallet.Address);

                if (address == null)
                {
                    throw new ArgumentException($"Unrecognized address {observableWallet.Address}",
                                                nameof(observableWallet.Address));
                }

                var oldAdrr = address.ScriptPubKey.GetDestinationAddress(network).ToString();
                var newAddr = address.ScriptPubKey.GetDestinationAddress(bcashNetwork).ToString();

                Console.WriteLine($"Processing {observableWallet.Address}:{oldAdrr}:{newAddr} -- {counter} of {observableWallets.Count}");

                var wallet = await walletRepo.TryGetAsync(blockchainType, oldAdrr);

                if (wallet == null)
                {
                    var prevColor = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine($"Wallet not found {observableWallet.Address} -{blockchainType}. Queued by {oldAdrr}");
                    Console.ForegroundColor = prevColor;

                    continue;
                }

                var oldCredsRecord = new BcnCredentialsRecord
                {
                    Address      = string.Empty,
                    AssetAddress = oldAdrr,
                    ClientId     = wallet.ClientId.ToString(),
                    EncodedKey   = string.Empty,
                    PublicKey    = string.Empty,
                    AssetId      = $"{blockchainType} ({wallet.AssetId})"
                };

                var newCredsRecord = new BcnCredentialsRecord
                {
                    Address      = string.Empty,
                    AssetAddress = newAddr,
                    ClientId     = wallet.ClientId.ToString(),
                    EncodedKey   = string.Empty,
                    PublicKey    = string.Empty,
                    AssetId      = $"{blockchainType} ({wallet.AssetId})"
                };

                await firstGenerationBlockchainWalletRepository.DeleteIfExistAsync(oldCredsRecord);

                await firstGenerationBlockchainWalletRepository.InsertOrReplaceAsync(newCredsRecord);

                await walletRepo.DeleteIfExistsAsync(wallet.BlockchainType, wallet.ClientId, oldAdrr);

                await walletRepo.AddAsync(wallet.BlockchainType, wallet.ClientId, newAddr, wallet.CreatorType);
            }

            Console.WriteLine("All done");
        }
        private static async Task Migrate(string bwSettingsUrl, string bitcoinSettingsUrl, string apiKey)
        {
            if (!ValidateSettingsUrl(bwSettingsUrl))
            {
                return;
            }
            if (!ValidateSettingsUrl(bitcoinSettingsUrl))
            {
                return;
            }


            var logFactory = LogFactory.Create().AddConsole();

            var appSettings     = new SettingsServiceReloadingManager <AppSettings>(bwSettingsUrl, p => {});
            var bitcoinSettings = new SettingsServiceReloadingManager <BitcoinAppSettings>(bitcoinSettingsUrl, p => { })
                                  .CurrentValue.BitcoinService;


            var signingService = RestClient.For <ISigningServiceApi>(new HttpClient {
                BaseAddress = new Uri(bitcoinSettings.SignatureProviderUrl)
            });

            signingService.ApiKey = bitcoinSettings.SigningServiceApiKey;

            var walletRepository = BlockchainWalletsRepository.Create(appSettings.Nested(o => o.BlockchainWalletsService.Db.DataConnString), logFactory);

            var firstGenerationBlockchainWalletRepository = FirstGenerationBlockchainWalletRepository.Create(
                appSettings.Nested(o => o.BlockchainWalletsService.Db.ClientPersonalInfoConnString), logFactory);

            var cqrs = Cqrs.CreateCqrsEngine(appSettings.CurrentValue.BlockchainWalletsService.Cqrs.RabbitConnectionString, logFactory);

            var blockchainSignFacade = new BlockchainSignFacadeClient
                                       (
                appSettings.CurrentValue.BlockchainSignFacadeClient.ServiceUrl,
                apiKey,
                logFactory.CreateLog(nameof(BlockchainSignFacadeClient))
                                       );

            var       counter   = 0;
            const int batchSize = 10;

            await firstGenerationBlockchainWalletRepository.EnumerateBcnCredsByChunksAsync(AssetId, async records =>
            {
                foreach (var batch in records.Batch(batchSize))
                {
                    await batch.SelectAsync(async o =>
                    {
                        await Migrate(walletRepository, signingService, blockchainSignFacade, cqrs, o);
                        return(true);
                    });

                    counter += batchSize;
                    Console.SetCursorPosition(0, Console.CursorTop);
                    Console.Write($"{counter} wallets migrated");
                }
            });

            Console.WriteLine();
            Console.WriteLine("Migration completed");
        }
Example #4
0
        private static async Task CreateAllLegacyAssetsForUser(string settingsUrl, string clientId)
        {
            if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
            {
                Console.WriteLine($"{SettingsUrl} should be a valid uri");

                return;
            }

            var logFactory = LogFactory.Create()
                             .AddConsole();

            var appSettings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => { });

            var builder = new ContainerBuilder();

            builder.RegisterInstance(logFactory)
            .As <ILogFactory>()
            .SingleInstance();

            builder
            .RegisterModule(new CqrsModule(appSettings.CurrentValue.BlockchainWalletsService.Cqrs))
            .RegisterModule(new RepositoriesModule(appSettings.Nested(x => x.BlockchainWalletsService.Db)))
            .RegisterModule(new ServiceModule(
                                appSettings.CurrentValue.BlockchainsIntegration,
                                appSettings.CurrentValue.BlockchainSignFacadeClient,
                                appSettings.CurrentValue,
                                appSettings.CurrentValue.AssetsServiceClient,
                                appSettings.CurrentValue.BlockchainWalletsService));

            var resolver = builder.Build();

            var assetsServiceWithCache = resolver.Resolve <IAssetsServiceWithCache>();
            var walletService          = resolver.Resolve <IWalletService>();

            var allAssets = await assetsServiceWithCache.GetAllAssetsAsync(false);

            var coloredAsset = allAssets.FirstOrDefault(x => x.Blockchain == Blockchain.Bitcoin &&
                                                        !string.IsNullOrEmpty(x.BlockChainAssetId));

            //DEV assets
            var assetListToTest = new List <string>()
            {
                SpecialAssetIds.BitcoinAssetId,
                SpecialAssetIds.SolarAssetId,
                "a61a3cad-bd63-422a-82a6-3464234856b0", //erc20
                coloredAsset?.Id                        //ColoredCoin
            };

            var depositsList = new List <string>();

            foreach (var id in assetListToTest)
            {
                //var deposit = await walletService.CreateWalletAsync(SpecialBlockchainTypes.FirstGenerationBlockchain,
                //    id,
                //    Guid.Parse(clientId));
                //
                //depositsList.Add(deposit.BaseAddress);

                var result = await walletService.TryGetFirstGenerationBlockchainAddressAsync(id,
                                                                                             Guid.Parse(clientId));
            }
        }
Example #5
0
        private static async Task Migrate(string settingsUrl)
        {
            if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
            {
                Console.WriteLine($"{SettingsUrl} should be a valid uri");

                return;
            }

            var logFactory = LogFactory.Create().AddConsole();

            var settings     = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, p => { });
            var settingsRepo = settings.Nested(x => x.BlockchainWalletsService.Db.DataConnString);

            var builder     = new ContainerBuilder();
            var appSettings = settings;

            builder.RegisterInstance(logFactory).As <ILogFactory>();

            builder
            .RegisterModule(new CqrsModule(appSettings.CurrentValue.BlockchainWalletsService.Cqrs))
            .RegisterModule(new RepositoriesModule(appSettings.Nested(x => x.BlockchainWalletsService.Db)))
            .RegisterModule(new ServiceModule(
                                appSettings.CurrentValue.BlockchainsIntegration,
                                appSettings.CurrentValue.BlockchainSignFacadeClient,
                                appSettings.CurrentValue,
                                appSettings.CurrentValue.AssetsServiceClient,
                                appSettings.CurrentValue.BlockchainWalletsService));

            var container = builder.Build();

            var cqrsEngine = container.Resolve <ICqrsEngine>();

            var archiveWalletsTable = AzureTableStorage <BlockchainWalletEntity> .Create
                                      (
                settingsRepo,
                "BlockchainWalletsArchive",
                logFactory
                                      );

            var defaultWalletsRepository    = (WalletRepository)WalletRepository.Create(settingsRepo, logFactory);
            var blockchainWalletsRepository = (BlockchainWalletsRepository)AzureRepositories.BlockchainWalletsRepository.Create(settingsRepo, logFactory);

            string continuationToken = null;

            Console.WriteLine("Creating indexes for default wallets...");

            var       progressCounter = 0;
            const int batchSize       = 10;

            //Commented code recreates all wallets with indicies
            //do
            //{
            //    try
            //    {
            //        IEnumerable<WalletDto> wallets;
            //        (wallets, continuationToken) = await blockchainWalletsRepository.GetAllAsync(100, continuationToken);

            //        foreach (var batch in wallets.Batch(batchSize))
            //        {
            //            await Task.WhenAll(batch.Select(o =>
            //                blockchainWalletsRepository.DeleteIfExistsAsync(o.BlockchainType, o.ClientId, o.Address)));
            //            progressCounter += batchSize;
            //            Console.SetCursorPosition(0, Console.CursorTop);
            //            Console.Write($"{progressCounter} indexes created");
            //        }
            //    }
            //    catch (Exception e)
            //    {
            //        Console.WriteLine(e.StackTrace + " " + e.Message);
            //    }

            //} while (continuationToken != null);

            //do
            //{
            //    try
            //    {
            //        IEnumerable<BlockchainWalletEntity> wallets;
            //        (wallets, continuationToken) = await archiveWalletsTable.GetDataWithContinuationTokenAsync(100, continuationToken);

            //        foreach (var batch in wallets.Batch(batchSize))
            //        {
            //            await Task.WhenAll(batch.Select(async o =>
            //            {
            //                await blockchainWalletsRepository.AddAsync(o.IntegrationLayerId, o.ClientId, o.Address,
            //                    o.CreatedBy);

            //                var @event = new WalletCreatedEvent
            //                {
            //                    Address = o.Address,
            //                    BlockchainType = o.IntegrationLayerId,
            //                    IntegrationLayerId = o.IntegrationLayerId,
            //                    CreatedBy = CreatorType.LykkeWallet,
            //                    ClientId = o.ClientId
            //                };

            //                cqrsEngine.PublishEvent
            //                (
            //                    @event,
            //                    BlockchainWalletsBoundedContext.Name
            //                );
            //            }));
            //            progressCounter += batchSize;
            //            Console.SetCursorPosition(0, Console.CursorTop);
            //            Console.Write($"{progressCounter} indexes created");
            //        }
            //    }
            //    catch (Exception e)
            //    {
            //        Console.WriteLine(e.StackTrace + " " + e.Message);
            //    }

            //} while (continuationToken != null);

            do
            {
                try
                {
                    IEnumerable <WalletDto> wallets;
                    (wallets, continuationToken) = await defaultWalletsRepository.GetAllAsync(100, continuationToken);

                    foreach (var batch in wallets.Batch(batchSize))
                    {
                        await Task.WhenAll(batch.Select(async o =>
                        {
                            await blockchainWalletsRepository.AddAsync(o.BlockchainType, o.ClientId, o.Address,
                                                                       CreatorType.LykkeWallet);

                            var @event = new WalletCreatedEvent
                            {
                                Address            = o.Address,
                                BlockchainType     = o.BlockchainType,
                                IntegrationLayerId = o.BlockchainType,
                                CreatedBy          = CreatorType.LykkeWallet,
                                ClientId           = o.ClientId
                            };

                            cqrsEngine.PublishEvent
                            (
                                @event,
                                BlockchainWalletsBoundedContext.Name
                            );
                        }));

                        progressCounter += batchSize;
                        Console.SetCursorPosition(0, Console.CursorTop);
                        Console.Write($"{progressCounter} indexes created");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace + " " + e.Message);
                }
            } while (continuationToken != null);
            Console.WriteLine();
            Console.WriteLine("Conversion completed");
        }
        private static async Task Execute(string settingsUrl, string blockchainType, string bitcoinCashNetwork)
        {
            {
                if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
                {
                    throw new ArgumentException("SettingsUrl should be a valid uri", nameof(settingsUrl));
                }

                BCash.Instance.EnsureRegistered();
                var network          = Network.GetNetwork(bitcoinCashNetwork);
                var bcashNetwork     = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest;
                var addressValidator = new AddressValidator(network, bcashNetwork);

                var logFactory = LogFactory.Create().AddConsole();

                var appSettings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl, options => { });

                var enrolledBalanceStorage = AzureTableStorage <EnrolledBalanceEntity> .Create(
                    appSettings.Nested(p => p.BlockchainCashinDetectorJob.Db.DataConnString),
                    "EnrolledBalance",
                    logFactory);

                var enrolledBalanceRepository = EnrolledBalanceRepository.Create(
                    appSettings.Nested(p => p.BlockchainCashinDetectorJob.Db.DataConnString), logFactory);


                Console.WriteLine("Retrieving enrolled balances");
                var enrolledBalances = (await enrolledBalanceStorage.GetDataAsync())
                                       .Where(p => p.BlockchainType == blockchainType)
                                       .ToList();

                var counter = 0;
                foreach (var enrolledBalanceEntity in enrolledBalances)
                {
                    counter++;
                    Console.WriteLine("Processing " +
                                      $"{enrolledBalanceEntity} : {enrolledBalanceEntity.Balance} : {enrolledBalanceEntity.Block} " +
                                      $"--- {counter} of {enrolledBalances.Count}");

                    var address = addressValidator.GetBitcoinAddress(enrolledBalanceEntity.DepositWalletAddress);

                    if (address == null)
                    {
                        throw new ArgumentException(
                                  $"Unable to recognize address {enrolledBalanceEntity.DepositWalletAddress}",
                                  nameof(enrolledBalanceEntity.DepositWalletAddress));
                    }
                    var oldAdrr = address.ScriptPubKey.GetDestinationAddress(network).ToString();
                    var newAddr = address.ScriptPubKey.GetDestinationAddress(bcashNetwork).ToString();

                    Console.WriteLine("Processing " +
                                      $"{enrolledBalanceEntity.DepositWalletAddress}:{oldAdrr}:{newAddr} " +
                                      $"--- {enrolledBalanceEntity.Balance} " +
                                      $"--- {enrolledBalanceEntity.Block} " +
                                      $"| {counter} of {enrolledBalances.Count}");


                    if (!string.Equals(enrolledBalanceEntity.DepositWalletAddress, oldAdrr, StringComparison.InvariantCultureIgnoreCase))
                    {
                        var prevColor = Console.ForegroundColor;
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine($"{enrolledBalanceEntity.DepositWalletAddress} not in obsolete format. Old format: {oldAdrr} | New Format {newAddr}. Skipping.");
                        Console.ForegroundColor = prevColor;

                        continue;
                    }

                    await enrolledBalanceRepository.SetBalanceAsync(new DepositWalletKey(enrolledBalanceEntity.BlockchainAssetId,
                                                                                         enrolledBalanceEntity.BlockchainType,
                                                                                         newAddr),
                                                                    enrolledBalanceEntity.Balance,
                                                                    enrolledBalanceEntity.Block);

                    await enrolledBalanceRepository.ResetBalanceAsync(new DepositWalletKey(
                                                                          enrolledBalanceEntity.BlockchainAssetId,
                                                                          enrolledBalanceEntity.BlockchainType,
                                                                          oldAdrr), enrolledBalanceEntity.Block);
                }

                Console.WriteLine("All done");
            }
        }
Example #7
0
        public static void Main(string[] args)
        {
            if (args == null || !args.Any())
            {
                throw new Exception("Specify parameters! url to EtherteumCore service");
            }

            var exit = false;

            string settingsArg = args.First();

            var settings = new SettingsServiceReloadingManager <AppSettings>(settingsArg);

            SaveSettings(settings);

            ContainerBuilder   containerBuilder = new ContainerBuilder();
            IServiceCollection collection       = new Microsoft.Extensions.DependencyInjection.ServiceCollection();

            containerBuilder.RegisterInstance(settings);
            containerBuilder.RegisterInstance <IBaseSettings>(settings.CurrentValue.EthereumCore);
            containerBuilder.RegisterInstance <ISlackNotificationSettings>(settings.CurrentValue.SlackNotifications);
            containerBuilder.RegisterInstance(settings.Nested(x => x.EthereumCore));
            containerBuilder.RegisterInstance(settings.CurrentValue);
            var consoleLogger = new LogToConsole();

            collection.AddSingleton <ILog>(consoleLogger);

            //TODO: Uncomment and fix registrations
            RegisterReposExt.RegisterAzureQueues(containerBuilder, settings.Nested(x => x.EthereumCore.Db.DataConnString),
                                                 settings.Nested(x => x.SlackNotifications));
            RegisterReposExt.RegisterAzureStorages(containerBuilder, settings.Nested(x => x.EthereumCore),
                                                   settings.Nested(x => x.SlackNotifications), consoleLogger);
            RegisterRabbitQueueEx.RegisterRabbitQueue(collection,
                                                      settings.Nested(x => x.EthereumCore.RabbitMq),
                                                      settings.Nested(x => x.EthereumCore.Db.DataConnString),
                                                      consoleLogger);
            RegisterDependency.RegisterServices(collection);
            RegisterDependency.RegisterServices(containerBuilder);
            //Lykke.Job.EthereumCore.Config.RegisterDependency.RegisterJobs(collection);
            //var web3 = ServiceProvider.GetService<Web3>();
            //web3.Eth.GetBalance.SendRequestAsync("");
            // web3.Eth.Transactions.SendTransaction.SendRequestAsync(new Nethereum.RPC.Eth.DTOs.TransactionInput()
            //{
            //
            //}).Result;
            //var key = EthECKey.GenerateKey().GetPrivateKeyAsBytes();
            //var stringKey = Encoding.Unicode.GetString(key);
            GetAllContractInJson();
            containerBuilder.Populate(collection);
            ServiceProvider = containerBuilder.Build();
            ServiceProvider.ActivateRequestInterceptor();
            //var signApi = ServiceProvider.Resolve<ILykkeSigningAPI>();
            //var signed = signApi.ApiEthereumSignPostWithHttpMessagesAsync(new EthereumTransactionSignRequest()
            //{
            //    FromProperty = "0x406561F72e25af10fD28b41200FA3D52badC5A21",
            //    Transaction = "f86b8201618483215600830186a094db6ea754f2afb4257b9bea0828771b19504aeac380b844a9059cbb00000000000000000000000033c6b8907d65d5a53cc301c544abf99f2e783242000000000000000000000000000000000000000000000000000000000000000c808080"
            //}).Result;
            //var xa = 1;
            //var lykkeSigningAPI = ServiceProvider.Resolve<ILykkeSigningAPI>();
            //var key1 = lykkeSigningAPI.ApiEthereumKeyGetAsync().Result;

            //var eventService = ServiceProvider.GetService<ITransactionEventsService>();
            //eventService.IndexCashinEventsForAdapter("0x1c4ca817d1c61f9c47ce2bec9d7106393ff981ce",
            //    "0x512867d36f1d6ee43f2056a7c41606133bce514fbc8e911c1834eeae80800ceb").Wait();

            //#region EmissiveErc223 TOKEN

            //string tokenAddress = "";
            //string depositAddress = "";
            //Contract contract;

            //var web3 = ServiceProvider.Resolve<IWeb3>();
            //{
            //    var abi = GetFileContent("Erc20DepositContract.abi");
            //    var bytecode = GetFileContent("Erc20DepositContract.bin");
            //    depositAddress = string.IsNullOrEmpty(depositAddress) ?
            //        ServiceProvider.Resolve<IContractService>()
            //        .CreateContract(abi,
            //                bytecode,
            //                4000000)
            //        .Result : depositAddress;
            //}
            //{
            //    //address issuer,
            //    //string tokenName,
            //    //uint8 divisibility,
            //    //string tokenSymbol,
            //    //string version
            //    var abi = GetFileContent("EmissiveErc223Token.abi");
            //    var bytecode = GetFileContent("EmissiveErc223Token.bin");
            //    tokenAddress = string.IsNullOrEmpty(tokenAddress) ?
            //        ServiceProvider.Resolve<IContractService>()
            //        .CreateContract(abi,
            //                bytecode,
            //                4000000,
            //                settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //                "LykkeErc223Token",
            //                18,
            //                "LTE223",
            //                "1.0.0")
            //        .Result : tokenAddress;
            //    contract = web3.Eth.GetContract(abi, tokenAddress);
            //}

            //{
            //    //Transfer to the deposit contract
            //    var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>();
            //    var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(depositAddress, tokenAddress).Result;
            //    var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //        depositAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result;
            //    WaitForTransactionCompleation(web3, transactionHash);
            //    var balance = erc20Service.GetBalanceForExternalTokenAsync(depositAddress, tokenAddress).Result;
            //    var isPossibleToWithdrawWithTokenFallback = erc20Service.CheckTokenFallback(depositAddress).Result;
            //    var isPossibleToWithdrawToExternal =
            //        erc20Service.CheckTokenFallback("0x856924997fa22efad8dc75e83acfa916490989a4").Result;
            //}

            //{
            //    //Transfer to the account managed by external private key
            //    var toAddress = "0x856924997fa22efad8dc75e83acfa916490989a4";
            //    var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>();
            //    var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(toAddress, tokenAddress).Result;
            //    var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //        toAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result;
            //    WaitForTransactionCompleation(web3, transactionHash);
            //    var balance = erc20Service.GetBalanceForExternalTokenAsync(toAddress, tokenAddress).Result;
            //}

            //{
            //    //Transfer to the contract without fallback function
            //    string contractWithoutFallback = "0xd6ff42fa358403e0f9462c08e78c4baea1093945";
            //    var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>();
            //    var balanceOld = erc20Service.GetBalanceForExternalTokenAsync(contractWithoutFallback, tokenAddress).Result;
            //    var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //        contractWithoutFallback, System.Numerics.BigInteger.Parse("1000000000000000000")).Result;
            //    WaitForTransactionCompleation(web3, transactionHash);
            //    var balance = erc20Service.GetBalanceForExternalTokenAsync(contractWithoutFallback, tokenAddress).Result;
            //    var isPossibleToWithdrawWithoutTokenFallback = erc20Service.CheckTokenFallback(contractWithoutFallback).Result;
            //}

            //#endregion

            //#region DBE TOKEN

            //{
            //    //var abi = GetFileContent("Erc20DepositContract.abi");
            //    //var bytecode = GetFileContent("Erc20DepositContract.bin");
            //    //depositAddress =
            //    //    ServiceProvider.Resolve<IContractService>()
            //    //    .CreateContract(abi, bytecode, 4000000)
            //    //    .Result;
            //}
            //{


            //    var abi = GetFileContent("debtoken.abi");
            //    var bytecode = GetFileContent("debtoken.bin");
            //    //tokenAddress =
            //    //    ServiceProvider.Resolve<IContractService>()
            //    //    .CreateContract(abi, bytecode, 4000000)
            //    //    .Result;
            //    contract = web3.Eth.GetContract(abi, tokenAddress);
            //}

            //{
            //    //var unfreezeFunc = contract.GetFunction("unfreeze");
            //    //var transactionHash = unfreezeFunc.SendTransactionAsync(settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //    //            new HexBigInteger(BigInteger.Parse("200000")), new HexBigInteger(0)).Result;
            //}

            //{
            //    var erc20Service = ServiceProvider.Resolve<IErcInterfaceService>();
            //    var transactionHash = erc20Service.Transfer(tokenAddress, settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //        depositAddress, System.Numerics.BigInteger.Parse("1000000000000000000")).Result;
            //}


            //#endregion

            //#region StatusExamples
            ////var service = ServiceProvider.GetService<ICoinTransactionService>();
            ////{
            ////    //fail
            ////    var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage()
            ////    {
            ////        TransactionHash = "0xf86efe1b8de285b8255519ca7d0ac76088132e6c5306f88dfc27312c6d7127ea",
            ////    }).Result;
            ////}

            ////{
            ////    //ok
            ////    var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage()
            ////    {
            ////        TransactionHash = "0xa237230df97a0d6710241597a0186662928afa373c13b8d4eac86f36aa678985",
            ////    }).Result;
            ////}

            ////{
            ////    //fail
            ////    var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage()
            ////    {
            ////        TransactionHash = "0xb63ac4f94006cbbfe58a1d651e173c56dc74a45e4d1141ac57fc51a0d4202e95",
            ////    }).Result;
            ////}

            ////{
            ////    //fail
            ////    var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage()
            ////    {
            ////        TransactionHash = "0x1df50ee79d0af8b433f7f0be2a84cbb5dc3e29e5822e78b9c6a7ec33d027e286",
            ////    }).Result;
            ////}

            ////{
            ////    //fail
            ////    var x = service.ProcessTransaction(new Services.Coins.Models.CoinTransactionMessage()
            ////    {
            ////        TransactionHash = "0xa3d4c1da523273371fe45c928b9236b353976e7b9e6d2b31e659f7a4c781a764",
            ////    }).Result;
            ////}

            //#endregion

            //0xf86efe1b8de285b8255519ca7d0ac76088132e6c5306f88dfc27312c6d7127ea      0x0
            //0xa237230df97a0d6710241597a0186662928afa373c13b8d4eac86f36aa678985      0x1
            //0xb63ac4f94006cbbfe58a1d651e173c56dc74a45e4d1141ac57fc51a0d4202e95

            //var service = ServiceProvider.Resolve<IErcInterfaceService>();
            //service.Transfer("0x5adbf411faf2595698d80b7f93d570dd16d7f4b2", settings.CurrentValue.EthereumCore.EthereumMainAccount,
            //    "0xae4d8b0c887508750ddb6b32752a82431941e2e7", System.Numerics.BigInteger.Parse("10000000000000000000")).Wait();
            //var paymentService = ServiceProvider.GetService<IPaymentService>();
            //    string result = paymentService.SendEthereum(settings.EthereumMainAccount,
            //    "0xbb0a9c08030898cdaf1f28633f0d3c8556155482", new System.Numerics.BigInteger(5000000000000000)).Result;
            //var coinEv = ServiceProvider.GetService<ICoinEventService>();
            //var ev1 = coinEv.GetCoinEvent("0xbfb8d6a561c1a088c347efb989e19cb02c1028b34a337e001b146fd1360dc714").Result;
            //var ev2 = coinEv.GetCoinEvent("0xa0876a676d695ab145fcf70ac0b2ae02e8b00351a5193352ffb37ad37dce6848").Result;
            //coinEv.InsertAsync(ev1).Wait();
            //coinEv.InsertAsync(ev2).Wait();
            //var paymentService = ServiceProvider.GetService<ICoinTransactionService>();
            //paymentService.PutTransactionToQueue("0xbfb8d6a561c1a088c347efb989e19cb02c1028b34a337e001b146fd1360dc714").Wait();
            //paymentService.PutTransactionToQueue("0xa0876a676d695ab145fcf70ac0b2ae02e8b00351a5193352ffb37ad37dce6848").Wait();
            //var pendingOperationService = ServiceProvider.GetService<IPendingOperationService>();
            //var op = pendingOperationService.GetOperationAsync("40017691-1656-4d71-a8a6-4187200dca73").Result;
            //pendingOperationService.CreateOperation(op).Wait();
            //var op2 = pendingOperationService.GetOperationAsync("41e19fd5-2660-469b-9315-b768f701e742").Result;
            //pendingOperationService.CreateOperation(op2).Wait();

            while (!exit)
            {
                Console.WriteLine("Choose number: ");
                //Console.WriteLine("1. Deploy main contract from local json file");
                Console.WriteLine("2. Deploy main exchange contract");
                Console.WriteLine("3. Deploy coin contract using local json file");
                Console.WriteLine("4. Deploy transfer");
                Console.WriteLine("5. Deploy BCAP Token");
                Console.WriteLine("6. Deploy main exchange contract with multiple owners!(Make sure that jobs are stopped)");
                Console.WriteLine("7. Add more owners to Main Exchange Contract with multiple owners!(Add addresses with some eth on it)");
                Console.WriteLine("9. Deploy And Migrate To NM!(Make sure that jobs are stopped)");
                Console.WriteLine("10. Send transaction to MainExchange!(Make sure that jobs are stopped)");
                Console.WriteLine("0. Exit");

                var input = Console.ReadLine();

                switch (input)
                {
                case "2":
                    DeployMainExchangeContract().Wait();
                    break;

                case "3":
                    //DeployCoinContract().Wait();
                    break;

                case "4":
                    DeployTokenTransferContract().Wait();
                    break;

                case "0":
                    exit = true;
                    break;

                case "5":
                    DeployBCAP().Wait();
                    break;

                case "6":
                    DeployAndMigrateMainExchangeContractWithMultipleOwners().Wait();
                    break;

                case "7":
                    AddOwners().Wait();
                    break;

                //case "8":
                //    MigrateAdapter(,).Wait();
                //    break;
                case "9":
                    DeployAndMigrateToNM().Wait();
                    break;

                case "10":
                    SendTransactionFromMainExchange().Wait();
                    break;

                default:
                    Console.WriteLine("Bad input!");
                    continue;
                }

                Console.WriteLine("Done!");
            }
        }
        private static async Task Execute(string settingsUrl)
        {
            if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
            {
                Console.WriteLine($"{SettingsUrl}: {settingsUrl} should be a valid uri");

                return;
            }

            var logFactory = LogFactory.Create().AddConsole();

            var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl).Nested(x => x.BitcoinCashApi);

            BCash.Instance.EnsureRegistered();
            var network      = Network.GetNetwork(settings.CurrentValue.Network);
            var bcashNetwork = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest;

            var addressValidator = new AddressValidator(network, bcashNetwork);

            var observableWalletRepository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create(
                                                                                settings.Nested(p => p.Db.DataConnString),
                                                                                "ObservableWallets", logFactory));

            var observableWalletV2Repository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create(
                                                                                  settings.Nested(p => p.Db.DataConnString),
                                                                                  "ObservableWalletsV2", logFactory));

            var walletBalanceV2Repo = new WalletBalanceRepository(
                AzureTableStorage <WalletBalanceEntity> .Create(settings.Nested(p => p.Db.DataConnString),
                                                                "WalletBalancesV2", logFactory));

            var bcProvider = new RpcBlockchainProvider(new RPCClient(
                                                           new NetworkCredential(settings.CurrentValue.Rpc.UserName, settings.CurrentValue.Rpc.Password),
                                                           new Uri(settings.CurrentValue.Rpc.Host),
                                                           bcashNetwork), addressValidator, logFactory.CreateLog("temp"));

            var walletBalanceService = new WalletBalanceService(walletBalanceV2Repo,
                                                                observableWalletV2Repository,
                                                                bcProvider,
                                                                new OperationsConfirmationsSettings
            {
                MinConfirmationsToDetectOperation = settings.CurrentValue.MinConfirmationsToDetectOperation
            });

            Console.WriteLine("Retrieving observable wallets");

            var observableWallets = (await observableWalletRepository.GetAll()).ToList();

            var obserwabletWalletsTransformation = observableWallets.ToDictionary(observableWallet => observableWallet.Address, observableWallet =>
            {
                var addr = addressValidator.GetBitcoinAddress(observableWallet.Address);

                if (addr == null)
                {
                    throw new ArgumentException($"Unable to recognize address {observableWallet.Address}", nameof(observableWallet.Address));
                }

                var oldAdrr = addr.ScriptPubKey.GetDestinationAddress(network).ToString();
                var newAddr = addr.ScriptPubKey.GetDestinationAddress(bcashNetwork).ToString();

                if (!string.Equals(observableWallet.Address, oldAdrr, StringComparison.InvariantCultureIgnoreCase))
                {
                    var prevColor           = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine($"{observableWallet.Address} not in obsolete format. Old format: {oldAdrr} | New Format {newAddr}");
                    Console.ForegroundColor = prevColor;
                }

                return(newAddr);
            });

            var refillingProgress = 0;

            Console.WriteLine("Filling table ObservableWalletsV2");
            await observableWallets.ForEachAsyncSemaphore(8, async observableWallet =>
            {
                var progress   = Interlocked.Increment(ref refillingProgress);
                var newAddress = obserwabletWalletsTransformation[observableWallet.Address];

                Console.WriteLine($"Inserting obserwablewallet record {observableWallet.Address} => {newAddress} " +
                                  $"-- {progress} of {observableWallets.Count}");

                await observableWalletV2Repository.Insert(ObservableWallet.Create(newAddress));
            });

            var updatingBalanceProgress = 0;

            Console.WriteLine("Filling table WalletBalancesV2");
            await observableWallets.ForEachAsyncSemaphore(8, async observableWallet =>
            {
                var progress = Interlocked.Increment(ref updatingBalanceProgress);

                var newAddress = obserwabletWalletsTransformation[observableWallet.Address];

                Console.WriteLine($"Updating balance record {observableWallet.Address} => {newAddress} " +
                                  $"-- {progress} of {observableWallets.Count}");

                await walletBalanceService.UpdateBalance(newAddress);
            });

            Console.WriteLine("All done!");
        }
        private static async Task Import(string settingsUrl, string hotwallet, string timestamp, string batchSize)
        {
            if (!Uri.TryCreate(settingsUrl, UriKind.Absolute, out _))
            {
                Console.WriteLine($"{SettingsUrl}: {settingsUrl} should be a valid uri");

                return;
            }

            DateTime timeStampTyped;

            if (!DateTime.TryParse(timestamp, out timeStampTyped))
            {
                Console.WriteLine($"{Timestamp}: {timestamp} should be Date time ");

                return;
            }

            if (!DateTime.TryParse(timestamp, out timeStampTyped))
            {
                Console.WriteLine($"{Timestamp}: {timestamp} should be a valid Date time ");

                return;
            }

            if (!int.TryParse(batchSize, out var batchSizeTyped))
            {
                Console.WriteLine($"{BatchSize}: {batchSize} should be a valid integer ");

                return;
            }

            var logFactory = LogFactory.Create().AddConsole();

            var settings = new SettingsServiceReloadingManager <AppSettings>(settingsUrl).Nested(x => x.BitcoinCashApi);

            var network          = Network.GetNetwork(settings.CurrentValue.Network);
            var bcashNetwork     = network == Network.Main ? BCash.Instance.Mainnet : BCash.Instance.Regtest;
            var addressValidator = new AddressValidator(network, bcashNetwork);
            var hotwalletTyped   = addressValidator.GetBitcoinAddress(hotwallet);

            if (hotwalletTyped == null)
            {
                Console.WriteLine($"{HotWallet}: {hotwallet} should be a valid bitcoin address");

                return;
            }

            var authTokenBytes = Encoding.ASCII.GetBytes($"{settings.CurrentValue.Rpc.UserName}:{settings.CurrentValue.Rpc.Password}");
            var authToken      = Convert.ToBase64String(authTokenBytes);
            var httpClient     = new HttpClient
            {
                BaseAddress           = new Uri(settings.CurrentValue.Rpc.Host),
                Timeout               = TimeSpan.FromMinutes(30),
                DefaultRequestHeaders =
                {
                    Authorization = new AuthenticationHeaderValue("Basic", authToken)
                }
            };

            var observableWalletRepository = new ObservableWalletRepository(AzureTableStorage <ObservableWalletEntity> .Create(
                                                                                settings.Nested(p => p.Db.DataConnString),
                                                                                "ObservableWalletsV2", logFactory));

            Console.WriteLine("Retrieving observable wallets");

            var observableWallets = await observableWalletRepository.GetAll();

            var walletsToImport = observableWallets
                                  .Select(p => addressValidator.GetBitcoinAddress(p.Address))
                                  .Concat(new[] { hotwalletTyped })
                                  .ToList();

            Console.WriteLine($"Importing {walletsToImport.Count} addresses in node started at {DateTime.UtcNow}. Timestamp {timeStampTyped}. Batch size {batchSize}");

            var batchNum = 1;

            foreach (var batch in walletsToImport.Batch(batchSizeTyped))
            {
                Console.WriteLine($"{DateTime.UtcNow} Importing batch {batchNum++}...");

                var payload = new
                {
                    jsonrpc = "1.0",
                    id      = Guid.NewGuid().ToString(),
                    method  = "importmulti",
                    @params = new object[]
                    {
                        batch.Select(address => new
                        {
                            scriptPubKey = new ImportMultiAddress.ScriptPubKeyObject(address),
                            timestamp    = Utils.DateTimeToUnixTime(new DateTimeOffset(timeStampTyped))
                        }),
                        new
                        {
                            rescan = true
                        }
                    }
                };

                await Policy
                .Handle <Exception>()
                .RetryAsync(5, (e, i) =>
                {
                    Console.WriteLine($"Retrying ({i})...");
                })
                .ExecuteAsync(async() =>
                {
                    using (var content = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"))
                    {
                        using (var response = await httpClient.PostAsync("", content))
                        {
                            if (response.StatusCode != HttpStatusCode.OK)
                            {
                                Console.WriteLine($"Failed to execute RPC call. Response: {response.StatusCode}");
                                throw new InvalidOperationException($"Failed to execute RPC call. Response: {response.StatusCode}, {await response.Content.ReadAsStringAsync()}");
                            }
                        }
                    }
                });

                Console.WriteLine($"{DateTime.UtcNow} Batch imported");
            }

            Console.WriteLine($"Import completed at {DateTime.UtcNow}");
        }