public async Task PrivateWalletServiceTest_TestBroadcastingMultiple() { string fromAddress = "0x46Ea3e8d85A06cBBd8c6a491a09409f5B59BEa28"; EthTransaction transaction = new EthTransaction() { FromAddress = fromAddress, GasAmount = 21000, GasPrice = 50000000000, ToAddress = "0xaA4981d084120AEf4BbaEeCB9abdBc7D180C7EdB", Value = 5000000000 }; for (int i = 0; i < 2; i++) { string trRaw = await _privateWallet.GetTransactionForSigning(transaction); string signedRawTr = SignRawTransaction(trRaw, _privateKey); string transactionHash; if (!await _transactionValidationService.IsTransactionErc20Transfer(signedRawTr)) { transactionHash = await _privateWallet.SubmitSignedTransaction(fromAddress, signedRawTr); } else { throw new Exception("Can;t reach it"); } } }
public async Task <IActionResult> SubmitSignedTransaction([FromBody] PrivateWalletEthSignedTransaction ethTransactionSigned) { if (!ModelState.IsValid) { throw new ClientSideException(ExceptionType.WrongParams, JsonConvert.SerializeObject(ModelState.Errors())); } string serialized = JsonConvert.SerializeObject(ethTransactionSigned); await _log.WriteInfoAsync("PrivateWalletController", "SubmitSignedTransaction", serialized , "StartSubmitSignedTransaction", DateTime.UtcNow); string transactionHash; if (!await _transactionValidationService.IsTransactionErc20Transfer(ethTransactionSigned.SignedTransactionHex)) { transactionHash = await _privateWalletService.SubmitSignedTransaction(ethTransactionSigned.FromAddress, ethTransactionSigned.SignedTransactionHex); } else { transactionHash = await _erc20Service.SubmitSignedTransaction(ethTransactionSigned.FromAddress, ethTransactionSigned.SignedTransactionHex); } await _log.WriteInfoAsync("PrivateWalletController", "SubmitSignedTransaction", $"{serialized}-TransactionHash:{transactionHash}", "EndSubmitSignedTransaction", DateTime.UtcNow); return(Ok(new HashResponse() { HashHex = transactionHash })); }
/// <summary> /// /// </summary> /// <param name="hotWalletCashout"></param> /// <returns>transaction hash</returns> public async Task <string> StartCashoutAsync(string operationId) { IHotWalletOperation cashout = await _hotWalletCashoutRepository.GetAsync(operationId); if (cashout == null || cashout.OperationType != HotWalletOperationType.Cashout) { await _log.WriteWarningAsync(nameof(HotWalletService), nameof(StartCashoutAsync), $"operationId - {operationId}", "No cashout info for operation", DateTime.UtcNow); return(null); } var gasPrice = await _gasPriceRepository.GetAsync(); var currentGasPriceHex = await _web3.Eth.GasPrice.SendRequestAsync(); var currentGasPrice = currentGasPriceHex.Value; BigInteger selectedGasPrice = currentGasPrice * _baseSettings.GasPricePercentage / 100; if (selectedGasPrice > gasPrice.Max) { selectedGasPrice = gasPrice.Max; } else if (selectedGasPrice < gasPrice.Min) { selectedGasPrice = gasPrice.Min; } string transactionForSigning = null; string signedTransaction = null; string transactionHash = null; bool isErc20Transfer = !string.IsNullOrEmpty(cashout.TokenAddress); SemaphoreSlim semaphore = _semaphores.GetOrAdd(cashout.FromAddress, f => new SemaphoreSlim(1, 1)); try { await semaphore.WaitAsync(); //Erc20 transfer if (isErc20Transfer) { transactionForSigning = await _erc20PrivateWalletService.GetTransferTransactionRaw(new Lykke.Service.EthereumCore.BusinessModels.PrivateWallet.Erc20Transaction() { FromAddress = cashout.FromAddress, GasAmount = Constants.GasForHotWalletTransaction, GasPrice = selectedGasPrice, ToAddress = cashout.ToAddress, TokenAddress = cashout.TokenAddress, TokenAmount = cashout.Amount, Value = 0, }, useTxPool : true); } //Eth transfer else { transactionForSigning = await _privateWalletService.GetTransactionForSigning(new Lykke.Service.EthereumCore.BusinessModels.PrivateWallet.EthTransaction() { FromAddress = cashout.FromAddress, GasAmount = Constants.GasForHotWalletTransaction, GasPrice = selectedGasPrice, ToAddress = cashout.ToAddress, Value = cashout.Amount }, useTxPool : true); } signedTransaction = await _signatureService.SignRawTransactionAsync(cashout.FromAddress, transactionForSigning); if (string.IsNullOrEmpty(signedTransaction)) { throw new ClientSideException(ExceptionType.WrongSign, "Wrong signature"); } var transactionExecutionCosts = await _privateWalletService.EstimateTransactionExecutionCost(cashout.FromAddress, signedTransaction); if (!transactionExecutionCosts.IsAllowed) { throw new Exception($"Transaction will not be successfull {JsonSerialisersExt.ToJson(cashout)}"); } transactionHash = isErc20Transfer ? await _erc20PrivateWalletService.SubmitSignedTransaction(cashout.FromAddress, signedTransaction) : await _privateWalletService.SubmitSignedTransaction(cashout.FromAddress, signedTransaction); } finally { semaphore.Release(); } if (string.IsNullOrEmpty(transactionHash)) { throw new Exception("Transaction was not sent"); } CoinTransactionMessage message = new CoinTransactionMessage() { OperationId = operationId, TransactionHash = transactionHash }; await _hotWalletCashoutTransactionRepository.SaveAsync(new HotWalletCashoutTransaction() { OperationId = operationId, TransactionHash = transactionHash }); await _hotWalletTransactionMonitoringQueue.PutRawMessageAsync(Newtonsoft.Json.JsonConvert.SerializeObject(message)); return(transactionHash); }