public async Task Erc20ServiceUnitTest_WrongSignAndCommitTransaction() { bool isExceptionProcessed = false; string from = TestConstants.PW_ADDRESS; Erc20Transaction ethTransaction = new Erc20Transaction() { FromAddress = from, GasAmount = 21000, GasPrice = 30000000000, ToAddress = _contractAddress, TokenAddress = _contractAddress, TokenAmount = 30000000000 }; string transactionHex = await _erc20Service.GetTransferTransactionRaw(ethTransaction); string wrongKey = _privateKey.Remove(2, 1).Insert(2, "3"); string signedTransaction = SignRawTransaction(transactionHex, wrongKey); try { string transactionHash = await _erc20Service.SubmitSignedTransaction(from, signedTransaction); } catch (ClientSideException exc) when(exc.ExceptionType == ExceptionType.WrongSign) { isExceptionProcessed = true; } Assert.IsTrue(isExceptionProcessed); }
public async Task Erc20ServiceUnitTest_SignAndCommitTransaction() { string from = TestConstants.PW_ADDRESS; Erc20Transaction ethTransaction = new Erc20Transaction() { FromAddress = from, GasAmount = 21000, GasPrice = 30000000000, ToAddress = _contractAddress, TokenAddress = _contractAddress, TokenAmount = 30000000000 }; string transactionHex = await _erc20Service.GetTransferTransactionRaw(ethTransaction); string signedTransaction = SignRawTransaction(transactionHex, _privateKey); string transactionHash = await _erc20Service.SubmitSignedTransaction(from, signedTransaction); Nethereum.Signer.Transaction transaction = new Nethereum.Signer.Transaction(signedTransaction.HexToByteArray()); _client.Verify(x => x.SendRequestAsync <string>(It.IsAny <Nethereum.JsonRpc.Client.RpcRequest>(), null), Times.Once); Assert.AreEqual(from, transaction.Key.GetPublicAddress()); Assert.AreEqual(_nonceCalc._nonceStorage[from].Value, new HexBigInteger(transaction.Nonce.ToHex())); Assert.AreEqual(ethTransaction.GasAmount, new HexBigInteger(transaction.GasLimit.ToHex())); Assert.AreEqual(new HexBigInteger(0).Value, new HexBigInteger(transaction.Value.ToHex())); Assert.AreEqual(ethTransaction.GasPrice, new HexBigInteger(transaction.GasPrice.ToHex())); Assert.AreEqual(ethTransaction.ToAddress.ToLower(), transaction.ReceiveAddress.ToHex().EnsureHexPrefix()); }
public async Task <IActionResult> GetTransaction([FromBody] PrivateWalletErc20Transaction ercTransaction) { if (!ModelState.IsValid) { throw new ClientSideException(ExceptionType.WrongParams, JsonConvert.SerializeObject(ModelState.Errors())); } string serialized = JsonConvert.SerializeObject(ercTransaction); await _log.WriteInfoAsync("PrivateWalletController", "GetTransaction", serialized, "Get transaction for signing", DateTime.UtcNow); Erc20Transaction transaction = new Erc20Transaction() { TokenAddress = ercTransaction.TokenAddress, TokenAmount = BigInteger.Parse(ercTransaction.TokenAmount), FromAddress = ercTransaction.FromAddress, GasAmount = BigInteger.Parse(ercTransaction.GasAmount), GasPrice = BigInteger.Parse(ercTransaction.GasPrice), ToAddress = ercTransaction.ToAddress, Value = BigInteger.Parse(ercTransaction.Value), }; await _erc20Service.ValidateInput(transaction); string transactionHex = await _erc20Service.GetTransferTransactionRaw(transaction); await _log.WriteInfoAsync("PrivateWalletController", "GetTransaction", $"{serialized} + TransactionHex:{transactionHex}", "Recieved transaction for signing", DateTime.UtcNow); return(Ok(new EthTransactionRaw() { FromAddress = ercTransaction.FromAddress, TransactionHex = transactionHex })); }
public async Task <string> GetTransferTransactionRaw(Erc20Transaction erc20Transaction, bool useTxPool = false) { Contract contract = GetContract(erc20Transaction.TokenAddress); Function transferFunction = contract.GetFunction("transfer"); string functionDataEncoded = transferFunction.GetData(erc20Transaction.ToAddress, erc20Transaction.TokenAmount); BigInteger nonce = await _nonceCalculator.GetNonceAsync(erc20Transaction.FromAddress, useTxPool); var transaction = CreateTransactionInput(functionDataEncoded, erc20Transaction.TokenAddress, erc20Transaction.FromAddress, erc20Transaction.GasAmount, erc20Transaction.GasPrice, nonce, 0); string raw = transaction.GetRLPEncoded().ToHex(); return(raw); }
public async Task PrivateWalletServiceTest_TestBroadcastingMultiple() { string fromAddress = "0x46Ea3e8d85A06cBBd8c6a491a09409f5B59BEa28"; Erc20Transaction transaction = new Erc20Transaction() { FromAddress = fromAddress, GasAmount = 200000, GasPrice = 30000000000, ToAddress = "0xaA4981d084120AEf4BbaEeCB9abdBc7D180C7EdB", TokenAddress = "0xce2ef46ecc168226f33b6f6b8a56e90450d0d2c0", TokenAmount = 10 }; string trRaw = await _erc20Service.GetTransferTransactionRaw(transaction); string signedRawTr = SignRawTransaction(trRaw, _privateKey); string trHash1 = await _erc20Service.SubmitSignedTransaction(fromAddress, signedRawTr); }
public async Task Erc20ServiceUnitTest_TestGetTransaction() { string from = TestConstants.PW_ADDRESS; Erc20Transaction ethTransaction = new Erc20Transaction() { FromAddress = from, GasAmount = 21000, GasPrice = 30000000000, ToAddress = _contractAddress, TokenAddress = _contractAddress, TokenAmount = 30000000000 }; string transactionHex = await _erc20Service.GetTransferTransactionRaw(ethTransaction); Nethereum.Signer.Transaction transaction = new Nethereum.Signer.Transaction(transactionHex.HexToByteArray()); Assert.AreEqual(_nonceCalc._nonceStorage[from].Value, new HexBigInteger(transaction.Nonce.ToHex())); Assert.AreEqual(ethTransaction.GasAmount, new HexBigInteger(transaction.GasLimit.ToHex())); Assert.AreEqual(new HexBigInteger(0).Value, new HexBigInteger(transaction.Value.ToHex())); Assert.AreEqual(ethTransaction.GasPrice, new HexBigInteger(transaction.GasPrice.ToHex())); Assert.AreEqual(ethTransaction.ToAddress.ToLower(), transaction.ReceiveAddress.ToHex().EnsureHexPrefix()); Assert.IsNotNull(transaction.Data.ToHex().EnsureHexPrefix()); }
public void Sync(BigInteger fromBlock, BigInteger toBlock) { Console.WriteLine($"Getting transactions from block {fromBlock} to {toBlock}"); bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); bool isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux); string python3 = "python"; if (isLinux) { python3 = "python3"; } // Run etl to extract data System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); // Create command string dir = Directory.GetCurrentDirectory(); if (dir.IndexOf("EtherChain") > 0) { dir = dir.Substring(0, dir.IndexOf("EtherChain") + 10); } dir += "/deps/ethereum-etl"; startInfo.WorkingDirectory = dir; string cmd = ""; if (_blockChain == "ETH") { cmd = $"{python3} ethereumetl.py export_blocks_and_transactions --start-block {fromBlock} --end-block {toBlock} --provider-uri https://mainnet.infura.io --transactions-output tx.csv"; } else if (_blockChain == "ERC20") { cmd = $"{python3} ethereumetl.py export_token_transfers --start-block {fromBlock} --end-block {toBlock} --provider-uri wss://mainnet.infura.io/ws --output erc20.csv -w 1"; } if (_blockChain == "ETC") { cmd = $"{python3} ethereumetl.py export_blocks_and_transactions --start-block {fromBlock} --end-block {toBlock} --provider-uri https://ethereumclassic.network --transactions-output etc.csv"; } if (isWindows) { startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; startInfo.FileName = "cmd.exe"; startInfo.Arguments = $"/C {cmd}"; } else if (isLinux) { startInfo.FileName = "/bin/bash"; startInfo.Arguments = $"-c \"{cmd}\""; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; } process.StartInfo = startInfo; process.Start(); process.WaitForExit(); if (_blockChain == "ETH" && !File.Exists(dir + "/tx.csv")) { Console.WriteLine("ERROR: tx.csv file not created."); Thread.Sleep(1000); return; } if (_blockChain == "ETC" && !File.Exists(dir + "/etc.csv")) { Console.WriteLine("ERROR: etc.csv file not created."); Thread.Sleep(1000); return; } if (_blockChain == "ERC20" && !File.Exists(dir + "/erc20.csv")) { Console.WriteLine("ERROR: erc20.csv file not created."); Thread.Sleep(1000); return; } // Open the tx.csv file and extract it. string filename = "tx.csv"; if (_blockChain == "ETC") { filename = "etc.csv"; } else if (_blockChain == "ERC20") { filename = "erc20.csv"; } string[] lines = File.ReadAllLines(dir + "/" + filename); File.Delete(dir + "/" + filename); int c = 2; Block block = new Block(); BigInteger blockNo = 0; while (c < lines.Length) { var data = lines[c].Split(','); if (_blockChain == "ETH" || _blockChain == "ETC") { /* * 0 hash hex_string * 1 nonce bigint * 2 block_hash hex_string * 3 block_number bigint * 4 transaction_index bigint * 5 from_address address * 6 to_address address * 7 value numeric * 8 gas bigint * 9 gas_price bigint * 10 input hex_string */ Transaction tr = new Transaction { Amount = BigInteger.Parse(data[7]), Block = BigInteger.Parse(data[3]), FromAddress = data[5], Gas = BigInteger.Parse(data[8]), GasPrice = BigInteger.Parse(data[9]), Hash = data[0], ToAddress = data[6], Nonce = BigInteger.Parse(data[1]) }; // Check if we need to create a new block if (string.IsNullOrEmpty(block.Hash)) { block.Hash = data[2]; blockNo = tr.Block; } else if (blockNo != tr.Block) { _db.AddBlock(blockNo, block, _blockChain); block = new Block(); blockNo = tr.Block; } _db.AddTransaction(tr, _blockChain, ref block); } else if (_blockChain == "ERC20") { /* * 0 token_address address * 1 from_address address * 2 to_address address * 3 value numeric * 4 transaction_hash hex_string * 5 log_index bigint * 6 block_number bigint */ var tr = new Erc20Transaction { Amount = BigInteger.Parse(data[3]), Block = BigInteger.Parse(data[6]), FromAddress = data[1], ToAddress = data[2], Hash = data[4], LogIndex = BigInteger.Parse(data[5]) }; // Check if we need to create a new block if (string.IsNullOrEmpty(block.Hash)) { Web3 web3 = getWeb3(); block.Hash = web3.Eth.Blocks.GetBlockWithTransactionsHashesByNumber.SendRequestAsync( new HexBigInteger(tr.Block)).Result.BlockHash; blockNo = tr.Block; } else if (blockNo != tr.Block) { _db.AddBlock(blockNo, block, _blockChain); block = new Block(); blockNo = tr.Block; } _db.AddTransaction(tr, data[0], ref block); } c += 2; } _db.AddBlock(blockNo, block, _blockChain); // Update last synced block _lastSyncedBlock = toBlock; _db.Put("lastblock", _lastSyncedBlock.ToString(), _blockChain); Console.WriteLine($"{_blockChain}: Done getting transactions from block {fromBlock} to {toBlock}"); }
public async Task ValidateInput(Erc20Transaction transaction) { await _transactionValidationService.ValidateAddressBalanceAsync(transaction.FromAddress, transaction.Value, transaction.GasAmount, transaction.GasPrice); await ValidateTokenAddressBalanceAsync(transaction.FromAddress, transaction.TokenAddress, transaction.TokenAmount); }