public override async Task <decimal> GetContractBalanceAsync(EthereumAddress contractAddress, EthereumAddress address, int decimals) { var held = await RpcClient.GetContractBalanceAsync(contractAddress, address, decimals); // We don't know what the new stake address is yet. if (symbol == Shared.Enums.Symbol.IHF) { foreach (var stake in stakeSettings) { var stakingAddress = stake.GetStakingAddress(symbol); // Find out how much they've staked and add it here. var stakes = await RpcClient.ListContractTransfersAsync(contractAddress, address, stakingAddress, decimals); var redemptions = await RpcClient.ListContractTransfersAsync(contractAddress, stakingAddress, address, decimals); var penalties = await RpcClient.ListContractEventsAsync <PenaltyFeeSentToTreasuryEvent, string, string>(stakingAddress, contractAddress.Address, address.Address); held += stakes.Sum(x => x.Data); held -= redemptions.Sum(x => x.Data); held -= penalties.Sum(x => x.Data.GetQuantity(decimals)); } } return(held); }
public Task <TFunction> GetDataAsync <TFunction>(EthereumAddress contractAddress, string data) where TFunction : class, new() { return(ExecuteAsync(web3 => { var outputs = web3.Eth .GetContractHandler(contractAddress) .GetFunction <TFunction>() .DecodeInput(data); if (outputs != null) { var t = typeof(TFunction); var function = new TFunction(); foreach (var prop in t.GetProperties().Where(x => x.CanWrite)) { var attr = prop.GetCustomAttribute <ParameterAttribute>(true); if (attr != null) { var output = outputs.SingleOrDefault(x => x.Parameter.Name.Equals(attr.Name, StringComparison.OrdinalIgnoreCase)); if (output != null) { prop.SetMethod.Invoke(function, new object[] { output.Result }); } } } return Task.FromResult(function); } return Task.FromResult(default(TFunction)); })); }
public async Task <UniswapPairResult> GetUniswapPairAsync(EthereumAddress pairAddress) { var response = await PostAsync <UniswapPairRequest, UniswapResponse <UniswapPairData> >( "/subgraphs/name/uniswap/uniswap-v2", new UniswapPairRequest(pairAddress)); return(new UniswapPairResult() { PoolAddress = pairAddress, Volume = response.Data.Pair.Volume.FromBigInteger(), Tokens = new List <UniswapTokenResult>() { new UniswapTokenResult() { Symbol = response.Data.Pair.Token0.Symbol, Name = response.Data.Pair.Token0.Name, Decimals = int.Parse(response.Data.Pair.Token0.Decimals), ContractAddress = new EthereumAddress(response.Data.Pair.Token0.ContractAddress), PricePerToken = response.Data.Pair.Price1.FromBigInteger(), PoolSupply = response.Data.Pair.Supply0.FromBigInteger() }, new UniswapTokenResult() { Symbol = response.Data.Pair.Token1.Symbol, Name = response.Data.Pair.Token1.Name, Decimals = int.Parse(response.Data.Pair.Token1.Decimals), ContractAddress = new EthereumAddress(response.Data.Pair.Token1.ContractAddress), PricePerToken = response.Data.Pair.Price0.FromBigInteger(), PoolSupply = response.Data.Pair.Supply1.FromBigInteger() } } }); }
public UniswapTokenPerformanceRequest(EthereumAddress contractAddress, DateTimeOffset from, DateTimeOffset to) { Query = Template .Replace("%CONTRACT_ADDRESS%", contractAddress.Address) .Replace("%FROM%", from.ToUnixTimeSeconds().ToString()) .Replace("%TO%", to.ToUnixTimeSeconds().ToString()); }
public void Construction() { EthereumAddress address = new EthereumAddress(Constants.TestEthereumAddress); Assert.AreEqual(Constants.TestEthereumAddress, address.ToString()); Assert.IsTrue(address.IsChecksumAddress, "Address should be checksummed"); }
private async IAsyncEnumerable <EthereumTransactionHash> ListAddressHashesAsync( EthereumAddress address, Symbol symbol, string indexName, string attributeName) { var key = dataKeyProvider.GetKey(symbol); var lastEvaluatedKey = new Dictionary <string, AttributeValue>(); while (!CancellationToken.IsCancellationRequested) { var response = await DynamoDB.QueryAsync( new QueryRequest() { TableName = TableName, IndexName = indexName, Select = Select.ALL_PROJECTED_ATTRIBUTES, KeyConditionExpression = string.Format( "#{0} = :{0}Val AND #{1} = :{1}Val", attributeName, nameof(DataOperation.ContractAddress)), ExpressionAttributeNames = new Dictionary <string, string>() { [$"#{attributeName}"] = attributeName, [$"#{nameof(DataOperation.ContractAddress)}"] = nameof(DataOperation.ContractAddress) }, ExpressionAttributeValues = new Dictionary <string, AttributeValue>() { [$":{attributeName}Val"] = new AttributeValue(address), [$":{nameof(DataOperation.ContractAddress)}Val"] = new AttributeValue(key) }, ExclusiveStartKey = lastEvaluatedKey.Any() ? lastEvaluatedKey : null }, CancellationToken); if (response.HttpStatusCode != HttpStatusCode.OK) { throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}"); } else { lastEvaluatedKey = response.LastEvaluatedKey; } foreach (var attributes in response.Items) { if (attributes.ContainsKey(nameof(DataOperation.Hash))) { yield return(new EthereumTransactionHash(attributes[nameof(DataOperation.Hash)].S)); } } if (!lastEvaluatedKey.Any()) { break; } } }
private async Task <long> GetBlockNumberAsync(EthereumAddress address, bool latest) { var response = await DynamoDB.QueryAsync( new QueryRequest() { TableName = TableName, IndexName = BlockNumberIndexName, ScanIndexForward = !latest, Select = Select.ALL_PROJECTED_ATTRIBUTES, KeyConditionExpression = $"#{nameof(DataTransaction.Address)} = :{nameof(DataTransaction.Address)}Val", ExpressionAttributeNames = new Dictionary <string, string>() { [$"#{nameof(DataTransaction.Address)}"] = nameof(DataTransaction.Address), }, ExpressionAttributeValues = new Dictionary <string, AttributeValue>() { [$":{nameof(DataTransaction.Address)}Val"] = new AttributeValue(address.Address) }, Limit = 1 }, CancellationToken); if (response.HttpStatusCode != HttpStatusCode.OK) { throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}"); } if (response.Items.Count == 1 && response.Items.Single().ContainsKey(nameof(DataTransaction.BlockNumber)) && long.TryParse(response.Items.Single()[nameof(DataTransaction.BlockNumber)].N, out long blockNumber)) { return(blockNumber); } return(default);
private DataTransaction MapTransaction( EthereumTransactionHash hash, EthereumAddress address, BloxyTokenTransfer summary, EthplorerTransaction transaction) { return(new DataTransaction() { Address = address, BlockNumber = transaction.BlockNumber, Confirmations = transaction.Confirmations, Hash = hash, ConfirmedAt = summary.ConfirmedAt.UtcDateTime, Sender = string.IsNullOrWhiteSpace(transaction.From) ? EthereumAddress.Empty.Address : transaction.From, Recipient = string.IsNullOrWhiteSpace(transaction.To) ? EthereumAddress.Empty.Address : transaction.To, Input = transaction.Input, Gas = transaction.GasUsed, GasLimit = transaction.GasLimit, Eth = transaction.Value, Success = transaction.Success }); }
/// <summary> /// Signature signing /// </summary> /// <param name="exchangeAddress">Exchange contract address</param> /// <param name="privateKey">Private key</param> /// <returns>Order signature (currently only EIP712 signature type is supported)</returns> public byte[] Sign(EthereumAddress exchangeAddress, string privateKey) { EthereumSignature signature = EIP712Service.Sign(EIP712Order, GetEIP712Domain(exchangeAddress), privateKey); return(ByteUtil.Merge(signature.V, signature.R, signature.S, Constants.EIP712SignatureType)); }
private async Task SyncTransactionsAsync( IEthplorerClient ethplorerClient, IBloxyClient bloxyClient, ITransactionRepository transactionService, IOperationRepository operationService, EthereumAddress contractAddress, DateTime startDate, DateTime endDate) { Console.WriteLine($"[{contractAddress}] Processing Batch: {startDate} -> {endDate}"); await foreach (var transactionSummary in bloxyClient.ListTransactionsAsync(contractAddress, startDate, endDate)) { var hash = new EthereumTransactionHash(transactionSummary.Hash); var transaction = await ethplorerClient.GetTransactionAsync(hash); if (transaction != null) { Console.WriteLine($"[{contractAddress}] Discovering Hash {hash} with ({transaction.Operations.Count}) operations."); var dynamoTransaction = MapTransaction(hash, contractAddress, transactionSummary, transaction); await transactionService.UploadItemsAsync(dynamoTransaction); var dynamoOperations = Enumerable.Range(0, transaction.Operations.Count) .Select(i => MapOperation(hash, transaction.Operations[i], i)) .ToArray(); await operationService.UploadItemsAsync(dynamoOperations); } } Console.WriteLine($"[{contractAddress}] Finished Batch: {startDate} -> {endDate}"); }
private async Task <DataStakingPower> GetByBoundsAsync(EthereumAddress contractAddress, bool latest) { var response = await DynamoDB.QueryAsync( new QueryRequest() { TableName = TableName, ScanIndexForward = !latest, Select = Select.ALL_ATTRIBUTES, KeyConditionExpression = $"#{nameof(DataStakingPower.Address)} = :{nameof(DataStakingPower.Address)}Val", ExpressionAttributeNames = new Dictionary <string, string>() { [$"#{nameof(DataStakingPower.Address)}"] = nameof(DataStakingPower.Address), }, ExpressionAttributeValues = new Dictionary <string, AttributeValue>() { [$":{nameof(DataStakingPower.Address)}Val"] = new AttributeValue(contractAddress) }, Limit = 1 }, CancellationToken); if (response.HttpStatusCode != HttpStatusCode.OK) { throw new HttpRequestException($"Response code did not indicate success: {response.HttpStatusCode}"); } if (response.Items.Count == 1) { return(Map(response.Items.Single())); } return(null); }
public async Task ExchangeTokensViaSender() { EthereumAddress exchangeAddress = (EthereumAddress)ExchangeAddress; ExchangeContract exchange = new ExchangeContract(RpcURL, exchangeAddress, new Account(SenderPrivateKey)); Order order = new Order { MakerAddress = (EthereumAddress)MakerAddress, TakerAddress = (EthereumAddress)TakerAddress, SenderAddress = exchange.CallerAccount.Address, FeeRecipientAddress = exchange.CallerAccount.Address, MakerFee = 10, TakerFee = 10, MakerAssetAmount = 100, TakerAssetAmount = 100, MakerAsset = ERC20Asset.Create((EthereumAddress)MakerTokenAddress), TakerAsset = ERC20Asset.Create((EthereumAddress)TakerTokenAddress), ExpirationTime = DateTime.UtcNow + new TimeSpan(1, 0, 0), Salt = Random.GenerateSalt() }; byte[] makerSignature = order.Sign(exchangeAddress, MakerPrivateKey); Transaction tx = ExchangeContract.FillOrderGet0xTx(order, order.TakerAssetAmount, makerSignature); byte[] takerSignature = tx.Sign(exchangeAddress, TakerPrivateKey); string hash = await exchange.FillOrderAsync( order, order.TakerAssetAmount, makerSignature, takerSignature, tx.Salt, new TxParameters(1000000)); }
private EIP712Domain GetEIP712Domain(EthereumAddress exchangeAddress) => new EIP712Domain { Name = "0x Protocol", Version = "2", VerifyingContract = exchangeAddress.ToString() };
protected SmartContract(string rpcUrl, EthereumAddress contractAddress, Account callerAccount) { rpcUrl = rpcUrl ?? throw new ArgumentNullException(nameof(rpcUrl)); ContractAddress = contractAddress ?? throw new ArgumentNullException(nameof(contractAddress)); CallerAccount = callerAccount ?? throw new ArgumentNullException(nameof(callerAccount)); _web3 = new Web3(new Nethereum.Web3.Accounts.Account(CallerAccount.PrivateKey), rpcUrl); }
public void EqualityChecksum() { // Checksum should not affect equality of addresses EthereumAddress a = new EthereumAddress(Constants.TestEthereumAddress); EthereumAddress nonChecksumAddr = new EthereumAddress(Constants.TestEthereumAddress.ToLowerInvariant()); Assert.AreEqual(a, nonChecksumAddr); Assert.IsTrue(a == nonChecksumAddr); }
public void Inequality() { EthereumAddress a = new EthereumAddress(Constants.TestEthereumAddress); Assert.AreNotEqual(a, EthereumAddress.ZeroAddress); Assert.AreNotEqual(EthereumAddress.ZeroAddress, a); Assert.IsTrue(a != EthereumAddress.ZeroAddress); Assert.IsTrue(EthereumAddress.ZeroAddress != a); }
public async Task <decimal> GetUniswapPriceAsync(EthereumAddress pairAddress, EthereumAddress contractAddress) { var pair = await GetUniswapPairAsync(pairAddress); var token = pair.Tokens .SingleOrDefault(x => x.ContractAddress == contractAddress); return(token?.PricePerToken ?? decimal.Zero); }
public IAsyncEnumerable <DataTransaction> ListOutboundTransactionsAsync( Symbol symbol, EthereumAddress address, EthereumAddress?filterAddress = null, DateTime?from = null, DateTime?to = null) { return(ListAddressTransactionsAsync(symbol, address, true, filterAddress, from, to)); }
public void AfterEthereumAddress() { EthereumAddress address = new EthereumAddress(new string('a', 40)); EthereumAddress otherAddress = new EthereumAddress(new string('b', 40)); bool areSame = address == otherAddress; // StringComparision type? }
public IAsyncEnumerable <DataTransaction> ListInboundTransactionsAsync( EthereumAddress contractAddress, EthereumAddress address, EthereumAddress?filterAddress = null, DateTime?from = null, DateTime?to = null) { return(ListAddressTransactionsAsync(contractAddress, address, false, filterAddress, from, to)); }
// Potentially async in the future due to fact some signature types require interaction with Ethereum network /// <summary> /// Verifies order signature /// </summary> /// <param name="exchangeAddress">Exchange contract address</param> /// <param name="signerAddress">Signer address</param> /// <param name="signature">Signature</param> /// <returns><c>true</c> if signature is valid, false otherwise</returns> public bool VerifySignature(EthereumAddress exchangeAddress, EthereumAddress signerAddress, byte[] signature) { if (signature[65] != Constants.EIP712SignatureType[0]) { throw new NotImplementedException("Only EIP712 signature types are supported"); } return(EIP712Service.VerifySignature(EIP712Order, GetEIP712Domain(exchangeAddress), signerAddress, ReformatSignature(signature))); }
/// <summary> /// Creates an ERC721 asset /// </summary> /// <param name="tokenAddress">Address of ERC721 token</param> /// <param name="tokenId">Token id to exchange</param> /// <returns><see cref="ERC721Asset"/> representing ERC721 asset</returns> /// <exception cref="ArgumentNullException">tokenAddress is null</exception> /// <exception cref="ArgumentException">tokenId invalid value</exception> public static ERC721Asset Create(EthereumAddress tokenAddress, BigInteger tokenId) { tokenAddress = tokenAddress ?? throw new ArgumentNullException(nameof(tokenAddress)); if (tokenId > IntType.MAX_UINT256_VALUE || tokenId < 0) { throw new ArgumentException("Token id invalid value", nameof(tokenId)); } return(new ERC721Asset(tokenAddress, tokenId)); }
public async Task <decimal> GetEthBalanceAsync(EthereumAddress address, ulong?blockNumber = null) { var balance = await ExecuteAsync(web3 => { return(blockNumber.HasValue ? web3.Eth.GetBalance.SendRequestAsync(address, new BlockParameter(blockNumber.Value)) : web3.Eth.GetBalance.SendRequestAsync(address)); }); return(Web3.Convert.FromWei(balance.Value)); }
/// <summary> /// Hashes given order /// </summary> /// <param name="exchangeAddress">Exchange contract address</param> /// <returns>Order signature</returns> /// <exception cref="ArgumentNullException">exchangeAddress is <c>null</c></exception> public byte[] Hash(EthereumAddress exchangeAddress) { if (exchangeAddress == null) { throw new ArgumentNullException(nameof(exchangeAddress)); } EIP712Domain domain = GetEIP712Domain(exchangeAddress); return(EIP712Service.Hash(EIP712Order, domain)); }
public override async Task <decimal> GetContractBalanceAsync(EthereumAddress contractAddress, EthereumAddress address, int decimals) { var held = await RpcClient.GetEthBalanceAsync(address); // Find out how much they've staked and add it here. var stakes = await RpcClient.ListContractTransfersAsync(contractAddress, address, StakingAddress, decimals); var redemptions = await RpcClient.ListContractTransfersAsync(contractAddress, StakingAddress, address, decimals); return(held + stakes.Sum(x => x.Data) - redemptions.Sum(x => x.Data)); }
/// <summary> /// Constructs <see cref="CallData"/> object for cancelOrder call /// </summary> /// <param name="order">0x order</param> /// <param name="exchangeAddress">Exchange contract address</param> /// <param name="web3">Nethereum <see cref="Web3"/> object</param> /// <returns><see cref="CallData"/> instance</returns> /// <exception cref="ArgumentNullException">Any of the arguments is equal to null</exception> public static CallData CancelOrderCallData(Order order, EthereumAddress exchangeAddress, Web3 web3) { order = order ?? throw new ArgumentNullException(nameof(order)); exchangeAddress = exchangeAddress ?? throw new ArgumentNullException(nameof(exchangeAddress)); web3 = web3 ?? throw new ArgumentNullException(nameof(web3)); Function cancelOrder = web3.Eth.GetContract(_abi, exchangeAddress).GetFunction("cancelOrder"); object[] parameters = new object[] { order.EIP712Order }; return(new CallData(cancelOrder, parameters)); }
public async Task <IInvestment> GetInvestmentAsync(EthereumAddress address, Symbol symbol, CurrencyCode currencyCode) { if (symbol.IsFund()) { var fund = await fundService.GetFundAsync(symbol, currencyCode); var tokenCount = await quantityProviderFactory .CreateProvider(fund.Token.Symbol.ToString()) .GetContractBalanceAsync(fund.Token.ContractAddress, address, fund.Token.Decimals); var subInvestments = new List <ISubInvestment>(); foreach (var asset in fund.Assets) { var held = asset.Holding.ContractAddress.HasValue ? await quantityProviderFactory .CreateProvider(asset.Holding.Symbol) .GetContractBalanceAsync(asset.Holding.ContractAddress.Value, address, asset.Holding.Decimals.Value) : decimal.Zero; if (held > decimal.Zero) { subInvestments.Add(new BusinessSubInvestment() { Holding = asset.Holding, Held = held, MarketValue = CurrencyConverter.Convert(asset.PricePerToken, currencyCode) * held }); } } var stakeEvents = new List <IStakeEvent>(); foreach (var stake in GetStakes()) { stakeEvents.AddRange( await stakeService .ListStakeEventsAsync(stake.Symbol, address, fund.Token.Symbol) .ToListAsync(CancellationToken)); } return(new BusinessInvestment() { Fund = fund, Held = tokenCount, Legacy = tokenCount == default, SubInvestments = subInvestments, Stakes = stakeEvents });
protected EthereumAddress GetAddress(string address) { var ethAddress = new EthereumAddress(address); if (HttpContext.Response.Headers.ContainsKey(Headers.Address)) { HttpContext.Response.Headers[Headers.Address] = ethAddress.Address; } else { HttpContext.Response.Headers.TryAdd(Headers.Address, ethAddress.Address); } return(ethAddress); }
public void Equality() { EthereumAddress a1 = new EthereumAddress(Constants.TestEthereumAddress); EthereumAddress a2 = new EthereumAddress(Constants.TestEthereumAddress); Assert.AreEqual(a1, a2); Assert.AreEqual(a2, a1); Assert.AreEqual(a1, a1); Assert.AreEqual(a2, a2); #pragma warning disable CS1718 Assert.IsTrue(a1 == a1); Assert.IsTrue(a2 == a2); #pragma warning restore CS1718 Assert.IsTrue(a1 == a2); Assert.IsTrue(a2 == a1); }
public ReturnObject UpdateAddress(string id, string networkName, string label) { try { switch (networkName) { case CryptoCurrency.BTC: using (var bitcoinAddressRepository = new BitcoinAddressRepository(_connectionDb)) { BitcoinAddress bitcoinAddress = bitcoinAddressRepository.FindById(id); bitcoinAddress.Label = label; return(bitcoinAddressRepository.Update(bitcoinAddress)); } case CryptoCurrency.ETH: using (var ethereumAddressRepository = new EthereumAddressRepository(_connectionDb)) { EthereumAddress ethereumAddress = ethereumAddressRepository.FindById(id); ethereumAddress.Label = label; return(ethereumAddressRepository.Update(ethereumAddress)); } case CryptoCurrency.VAKA: using (var vakacoinAddressRepository = new VakacoinAccountRepository(_connectionDb)) { VakacoinAccount vakacoinAccount = vakacoinAddressRepository.FindById(id); vakacoinAccount.Label = label; return(vakacoinAddressRepository.Update(vakacoinAccount)); } default: return(new ReturnObject { Status = Status.STATUS_ERROR }); } } catch (Exception e) { Console.WriteLine(e); return(new ReturnObject { Status = Status.STATUS_ERROR }); } }