public async Task <bool> CheckTransactionSign(string from, string signedTrHex) { Nethereum.Signer.Transaction transaction = new Nethereum.Signer.Transaction(signedTrHex.HexToByteArray()); string signedBy = transaction.Key.GetPublicAddress(); return(_addressUtil.ConvertToChecksumAddress(from) == _addressUtil.ConvertToChecksumAddress(signedBy)); }
public async Task <IActionResult> GetHashWithIdAsync([FromBody] BaseCoinRequestParametersModel model) { if (!ModelState.IsValid) { throw new ClientSideException(ExceptionType.WrongParams, JsonConvert.SerializeObject(ModelState.Errors())); } var guid = Guid.NewGuid(); //IdCheckResult idCheckResult = await _exchangeContractService.CheckId(guid); var amount = BigInteger.Parse(model.Amount); byte[] hash; try { hash = _hashCalculator.GetHash(guid, model.CoinAdapterAddress, _addressUtil.ConvertToChecksumAddress(model.FromAddress), _addressUtil.ConvertToChecksumAddress(model.ToAddress), amount); } catch (Exception e) { await _logger.WriteErrorAsync("HashController", "GetHashWithIdAsync", JsonConvert.SerializeObject(model), e, DateTime.UtcNow); throw; } return(Ok(new HashResponseWithId { HashHex = hash.ToHex(), OperationId = guid })); }
private string FormatAddress(string address) { string trimmed = address.TrimStart(new char[] { '0' }); string formated = _addressUtil.ConvertToChecksumAddress(trimmed).ToLower(); return(formated); }
public bool CheckSign(Guid id, string coinAddress, string clientAddr, string toAddr, BigInteger amount, string sign) { if (string.IsNullOrEmpty(sign)) { return(false); } var fixedSign = sign.EnsureHexPrefix(); var hash = GetHash(id, coinAddress, clientAddr, toAddr, amount); var signer = new MessageSigner(); string sender = signer.EcRecover(hash, sign); var util = new AddressUtil(); string checksumClientAddr = util.ConvertToChecksumAddress(clientAddr); string checksumSender = util.ConvertToChecksumAddress(sender); return(checksumClientAddr == checksumSender); }
public async Task <IActionResult> Cashout([FromBody] CashoutModel model) { if (!ModelState.IsValid) { throw new ClientSideException(ExceptionType.WrongParams, JsonConvert.SerializeObject(ModelState.Errors())); } await Log("Cashout", $"Begin Process {this.GetIp()}", model); var amount = BigInteger.Parse(model.Amount); var operationId = await _pendingOperationService.CashOut(model.Id, model.CoinAdapterAddress, _addressUtil.ConvertToChecksumAddress(model.FromAddress), _addressUtil.ConvertToChecksumAddress(model.ToAddress), amount, model.Sign); await Log("Cashout", "End Process", model, operationId); return(Ok(new OperationIdResponse { OperationId = operationId })); }
public async Task <OperationEstimationResult> EstimateCashoutGas(Guid id, string coinAdapterAddress, string fromAddress, string toAddress, BigInteger amount, string sign) { var blackListedAddress = await _blackListAddressesRepository.GetAsync(toAddress); var whiteListedAddress = await _whiteListAddressesRepository.GetAsync(toAddress); if (blackListedAddress != null && whiteListedAddress == null) { return(new OperationEstimationResult() { GasAmount = Constants.GasForCoinTransaction, IsAllowed = false }); } //It is ok. if (ChaosKitty.MeowButLogically()) { return(new OperationEstimationResult() { GasAmount = 50000, IsAllowed = true }); } var coinAFromDb = await GetCoinWithCheck(coinAdapterAddress); if (string.IsNullOrEmpty(sign)) { sign = await GetSign(id, coinAdapterAddress, fromAddress, toAddress, amount); } ThrowOnWrongSignature(id, coinAdapterAddress, fromAddress, toAddress, amount, sign); var contract = _web3.Eth.GetContract(_settings.MainExchangeContract.Abi, _settings.MainExchangeContract.Address); var cashout = contract.GetFunction("cashout"); var convertedId = EthUtils.GuidToBigInteger(id); //ACTION var estimatedGasForOperation = await cashout.EstimateGasAsync(_settings.EthereumMainAccount, new HexBigInteger(Constants.GasForCoinTransaction), new HexBigInteger(0), convertedId, _addressUtil.ConvertToChecksumAddress(coinAFromDb.AdapterAddress), fromAddress, toAddress, amount, sign.HexToByteArray(), new byte[0]); return(new OperationEstimationResult() { GasAmount = estimatedGasForOperation.Value, IsAllowed = estimatedGasForOperation.Value < Constants.GasForCoinTransaction }); }
public async Task <string> SignRawTransactionAsync(string fromAddress, string rawTransactionHex) { var requestBody = new EthereumTransactionSignRequest() { FromProperty = _addressUtil.ConvertToChecksumAddress(fromAddress), Transaction = rawTransactionHex }; var response = await _signatureApi.ApiEthereumSignPostAsync(requestBody); return(response?.SignedTransaction.EnsureHexPrefix()); }
public async Task <CommandHandlingResult> Handle(StartCashoutCommand command, IEventPublisher eventPublisher) { var asset = await _assetsService.AssetGetAsync(command.AssetId); var amount = EthServiceHelpers.ConvertToContract(command.Amount, asset.MultiplierPower, asset.Accuracy); try { if (asset.Type == AssetType.Erc20Token) { var token = await _assetsService.Erc20TokenGetBySpecificationAsync(new Erc20TokenSpecification(new List <string>() { asset.Id })); var tokenAddress = token?.Items?.FirstOrDefault()?.Address; if (string.IsNullOrEmpty(tokenAddress)) { _logger.WriteWarning(nameof(CashoutCommandHandler), nameof(Handle), $"Can't perform cashout on empty token, {command.Id}"); return(CommandHandlingResult.Ok()); } await _hotWalletService.EnqueueCashoutAsync(new Service.EthereumCore.Core.Repositories.HotWalletOperation() { Amount = amount, OperationId = command.Id.ToString(), FromAddress = command.FromAddress, ToAddress = command.ToAddress, TokenAddress = tokenAddress }); } else { await _pendingOperationService.CashOut(command.Id, asset.AssetAddress, _addressUtil.ConvertToChecksumAddress(command.FromAddress), _addressUtil.ConvertToChecksumAddress(command.ToAddress), amount, string.Empty); } } catch (ClientSideException ex) when(ex.ExceptionType == ExceptionType.EntityAlreadyExists || ex.ExceptionType == ExceptionType.OperationWithIdAlreadyExists) { _logger.WriteWarning(nameof(CashoutCommandHandler), nameof(Handle), $"Operation already exists, {command.Id}", ex); } eventPublisher.PublishEvent(new CashoutCompletedEvent { OperationId = command.Id }); return(CommandHandlingResult.Ok()); }
public static bool ValidateAddress(string address) { try { if (!_addressUtil.IsValidAddressLength(address)) { return(false); } address = _addressUtil.ConvertToChecksumAddress(address); return(_addressUtil.IsChecksumAddress(address)); } catch { return(false); } }
public async Task <int> ProcessBlock(BlockInformation blockInfo) { if (blockInfo == null) { throw new ArgumentNullException(nameof(blockInfo)); } // check if there is any transaction within block if (blockInfo.IsEmpty) { await _log.WriteInfoAsync(nameof(ProcessBlock), $"Network: {_network}, Block: {blockInfo.ToJson()}", $"Block {blockInfo.Height} is empty, therefore skipped"); return(0); } // but even non-empty block can contain zero payment transactions var transactions = await _blockchainReader.GetBlockTransactionsAsync(blockInfo.Height, paymentsOnly : true); var transactionModels = transactions .Select(tx => new TransactionModel() { Amount = UnitConversion.Convert.FromWei(tx.Action.Value.Value), // WEI to ETH BlockId = tx.BlockHash, CreatedUtc = blockInfo.Timestamp.UtcDateTime, Currency = CurrencyType.Eth, PayInAddress = _addressUtil.ConvertToChecksumAddress(tx.Action.To), // lower-case to checksum representation TransactionId = tx.TransactionHash, UniqueId = tx.TransactionHash }) .ToList(); var count = 0; if (transactionModels.Any()) { count = await _commonServiceClient.HandleTransactionsAsync(transactionModels); } await _log.WriteInfoAsync(nameof(ProcessBlock), $"Investments: {count}, Network: {_network}, Block: {blockInfo.ToJson()}", $"Block {blockInfo.Height} processed"); return(count); }
/// <summary> /// Creates an Address instance from a hex string representing an address. /// </summary> /// <param name="localAddress">Hex encoded string, may start with "0x".</param> /// <param name="chainId">Identifier of a DAppChain.</param> public Address(string localAddress, string chainId = kDefaultChainId) { if (String.IsNullOrWhiteSpace(localAddress)) { throw new ArgumentException("Non-empty string expected", nameof(localAddress)); } if (!addressUtil.IsValidAddressLength(localAddress)) { throw new ArgumentException("Address must a be 40-character hex string (not including the 0x prefix)", nameof(localAddress)); } if (String.IsNullOrWhiteSpace(chainId)) { throw new ArgumentException("Non-empty string expected", nameof(chainId)); } LocalAddress = addressUtil.ConvertToChecksumAddress(localAddress); ChainId = chainId; }
public async Task <CommandHandlingResult> Handle(StartTransferCommand command, IEventPublisher eventPublisher) { var asset = await _assetsService.AssetGetAsync(command.AssetId); var amount = EthServiceHelpers.ConvertToContract(command.Amount, asset.MultiplierPower, asset.Accuracy); try { await _pendingOperationService.Transfer(command.Id, asset.AssetAddress, _addressUtil.ConvertToChecksumAddress(command.FromAddress), _addressUtil.ConvertToChecksumAddress(command.ToAddress), amount, command.Sign); } catch (ClientSideException ex) when(ex.ExceptionType == ExceptionType.EntityAlreadyExists || ex.ExceptionType == ExceptionType.OperationWithIdAlreadyExists) { _logger.WriteWarning(nameof(TransferCommandHandler), nameof(Handle), $"Operation already exists, {command.Id}", ex); } eventPublisher.PublishEvent(new TransferCompletedEvent { OperationId = command.Id }); return(CommandHandlingResult.Ok()); }
static async Task SendTransactionFromMainExchange() { string operationId = ""; IPendingOperationService pendingOperationService = ServiceProvider.GetService <IPendingOperationService>(); try { MonitoringOperationJob job = ServiceProvider.GetService <MonitoringOperationJob>(); IExchangeContractService exchangeContractService = ServiceProvider.GetService <IExchangeContractService>(); string filePath = Path.Combine(AppContext.BaseDirectory, "transferTransaction.txt"); var content = File.ReadAllText(filePath); TransferModel model = Newtonsoft.Json.JsonConvert.DeserializeObject <TransferModel>(content); var addressUtil = new AddressUtil(); BigInteger amount = BigInteger.Parse(model.Amount); operationId = await pendingOperationService.TransferWithNoChecks(model.Id, model.CoinAdapterAddress, addressUtil.ConvertToChecksumAddress(model.FromAddress), addressUtil.ConvertToChecksumAddress(model.ToAddress), amount, model.Sign); Console.WriteLine($"OperationId - {operationId}"); await job.ProcessOperation(new Services.New.Models.OperationHashMatchMessage() { OperationId = operationId, }, null, exchangeContractService.TransferWithoutSignCheck); Console.WriteLine("Start removing from processing queue"); await pendingOperationService.RemoveFromPendingOperationQueue(operationId); Console.WriteLine("Stop removing from processing queue"); } catch (Exception e) { Console.WriteLine($"{e.Message} - {e.StackTrace}"); Console.WriteLine("Start removing from processing queue"); await pendingOperationService.RemoveFromPendingOperationQueue(operationId); Console.WriteLine("Stop removing from processing queue"); } }
static async Task <int> DeployTokenAsync( string settingsUrl, string tokenCfgPath) { #region RegisterDependencies var appSettings = GetCurrentSettingsFromUrl(settingsUrl); ContainerBuilder containerBuilder = new ContainerBuilder(); IServiceCollection collection = new Microsoft.Extensions.DependencyInjection.ServiceCollection(); containerBuilder.RegisterInstance(appSettings); containerBuilder.RegisterInstance <IBaseSettings>(appSettings.CurrentValue.EthereumCore); containerBuilder.RegisterInstance <ISlackNotificationSettings>(appSettings.CurrentValue.SlackNotifications); containerBuilder.RegisterInstance(appSettings.Nested(x => x.EthereumCore)); containerBuilder.RegisterInstance(appSettings.CurrentValue); var consoleLogger = new LogToConsole(); collection.AddSingleton <ILog>(consoleLogger); RegisterReposExt.RegisterAzureQueues(containerBuilder, appSettings.Nested(x => x.EthereumCore.Db.DataConnString), appSettings.Nested(x => x.SlackNotifications)); RegisterReposExt.RegisterAzureStorages(containerBuilder, appSettings.Nested(x => x.EthereumCore), appSettings.Nested(x => x.SlackNotifications), consoleLogger); RegisterRabbitQueueEx.RegisterRabbitQueue(collection, appSettings.Nested(x => x.EthereumCore.RabbitMq), appSettings.Nested(x => x.EthereumCore.Db.DataConnString), consoleLogger); RegisterDependency.RegisterServices(collection); RegisterDependency.RegisterServices(containerBuilder); containerBuilder.Populate(collection); containerBuilder.RegisterInstance <ILog>(consoleLogger); var resolver = containerBuilder.Build(); resolver.ActivateRequestInterceptor(); #endregion var web3 = resolver.Resolve <IWeb3>(); var contractService = resolver.Resolve <IContractService>(); var ercInterfaceService = resolver.Resolve <IErcInterfaceService>(); var exchangeContractService = resolver.Resolve <IExchangeContractService>(); var text = File.ReadAllText(tokenCfgPath); var tokenCfg = Newtonsoft.Json.JsonConvert.DeserializeObject <TokenCfg>(text); var addressUtil = new AddressUtil(); if (!exchangeContractService.IsValidAddress(tokenCfg.HotwalletAddress)) { await consoleLogger.WriteInfoAsync(nameof(Main), tokenCfg.ToJson(), $"HotwalletAddress is not a valid address."); return(0); } await consoleLogger.WriteInfoAsync(nameof(Main), "", $"Started Deployment"); foreach (var tokenDescr in tokenCfg.Tokens) { await consoleLogger.WriteInfoAsync(nameof(Main), "", $"Processing {tokenDescr.TokenName}"); if (!BigInteger.TryParse(tokenDescr.InitialSupply, out var initialSupply) || initialSupply == 0) { await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), $"Can't parse initial supply value. It is not a BigInt or zero"); continue; } if (!exchangeContractService.IsValidAddress(tokenDescr.IssuerAddress)) { await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), $"Issuer address is not a valid address."); continue; } var(abi, bytecode) = GetContractDeploymentForTokenType(tokenDescr.TokenType); string address = tokenDescr.TokenType == TokenType.Emissive ? await contractService.CreateContract(abi, bytecode, 4000000, tokenDescr.IssuerAddress, tokenDescr.TokenName, tokenDescr.Divisibility, tokenDescr.TokenSymbol, tokenDescr.Version) : await contractService.CreateContract(abi, bytecode, 4000000, tokenDescr.IssuerAddress, tokenDescr.TokenName, tokenDescr.Divisibility, tokenDescr.TokenSymbol, tokenDescr.Version, initialSupply); await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), $"Deployed at address {address}"); if (tokenDescr.TokenType == TokenType.Emissive) { await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), $"Starting Emission to {tokenCfg.HotwalletAddress}"); var transactionHash = await ercInterfaceService.Transfer(address, addressUtil.ConvertToChecksumAddress(tokenDescr.IssuerAddress), //Should be in SigningService tokenCfg.HotwalletAddress, initialSupply); await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), $"Emission txHash is {transactionHash}. " + $"Waiting for compleation"); WaitForTransactionCompleation(web3, transactionHash); await consoleLogger.WriteInfoAsync(nameof(Main), tokenDescr.ToJson(), "Completed."); } } await consoleLogger.WriteInfoAsync(nameof(Main), "", "Completed processing all tokens."); return(0); }
public async Task <IActionResult> CreateCoinAdapter([FromRoute] string coinAdapterAddress, [FromRoute] string userAddress) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } BigInteger amount = await _assetContractService.GetBalance(coinAdapterAddress, _addressUtil.ConvertToChecksumAddress(userAddress)); return(Ok(new BalanceModel { Amount = amount.ToString() })); }
public async Task <IActionResult> CreateTransferContract([FromBody] CreateTransitionContractModel model) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } string contractAddress = await _transferContractService.CreateTransferContract(_addressUtil.ConvertToChecksumAddress(model.UserAddress), model.CoinAdapterAddress); return(Ok(new RegisterResponse { Contract = contractAddress })); }
public static string ToChecksumAddress(string address) { return(addressUtil.ConvertToChecksumAddress(address)); }