|
@@ -12,6 +12,7 @@ using System.Text.RegularExpressions;
|
|
using QRCoder;
|
|
using QRCoder;
|
|
using System.IO;
|
|
using System.IO;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
+using System.Numerics;
|
|
|
|
|
|
//0xe5D682717955d6C35d465A3485625C64655a04f4 - HCB in rinkeby
|
|
//0xe5D682717955d6C35d465A3485625C64655a04f4 - HCB in rinkeby
|
|
//0xb504ba124b74333d8536db534f7fcdc174d6ee3d - system address rinkeby
|
|
//0xb504ba124b74333d8536db534f7fcdc174d6ee3d - system address rinkeby
|
|
@@ -55,13 +56,14 @@ namespace HyperCube.Models
|
|
}
|
|
}
|
|
set { }
|
|
set { }
|
|
}
|
|
}
|
|
- public const string MultiOwnerContractRinkeby = "0x862A2Ac8D1dB37085c786981A8F5bd54594f7162";
|
|
|
|
|
|
+ public const string MultiOwnerContractRinkeby = "0x7eca4E373De5E9ad27Be283612a75e632aCB81f2";
|
|
public const string HCBAddress = "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
public const string HCBAddress = "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
|
|
+ public const string QNMAddress = "0xE895a91B041e8450A1AFb9F54b8362a8ae3bb3d3";
|
|
public static string tokenName;
|
|
public static string tokenName;
|
|
public static string decimals;
|
|
public static string decimals;
|
|
public static string symbol;
|
|
public static string symbol;
|
|
public static string tokenBalance;
|
|
public static string tokenBalance;
|
|
- public static string balanceHCB;
|
|
|
|
|
|
+ public static string balanceToken;
|
|
|
|
|
|
public static Dictionary<int, Blockchain> supported;
|
|
public static Dictionary<int, Blockchain> supported;
|
|
//public static string Connected
|
|
//public static string Connected
|
|
@@ -144,8 +146,8 @@ namespace HyperCube.Models
|
|
transObj.data += zerofill(address, 64, true);
|
|
transObj.data += zerofill(address, 64, true);
|
|
//answer = await RunFunction2("eth_call", to, AccountModel.Current.GetActualAddress(this));
|
|
//answer = await RunFunction2("eth_call", to, AccountModel.Current.GetActualAddress(this));
|
|
answer = await RunFunction2("eth_call", transObj, "latest");
|
|
answer = await RunFunction2("eth_call", transObj, "latest");
|
|
- balanceHCB = ((double)AccountModel.ConvertBalance(ParseStringAnswer(answer)[0]) / 1000000000000000000.0).ToString();
|
|
|
|
- return null;
|
|
|
|
|
|
+ balanceToken = ((double)AccountModel.ConvertBalance(ParseStringAnswer(answer)[0]) / 1000000000000000000.0).ToString();
|
|
|
|
+ return balanceToken;
|
|
}
|
|
}
|
|
|
|
|
|
public async Task<string> Initialize()
|
|
public async Task<string> Initialize()
|
|
@@ -165,17 +167,27 @@ namespace HyperCube.Models
|
|
{
|
|
{
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
transObj.from = address;
|
|
transObj.from = address;
|
|
- transObj.to = ERC20Address;// "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
|
|
- transObj.gas = "9000";
|
|
|
|
|
|
+ transObj.to = ERC20Address;
|
|
transObj.data = await compileFunction($"function transferOwnership(address newOwner)");
|
|
transObj.data = await compileFunction($"function transferOwnership(address newOwner)");
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public async Task ChangeOwnerMulti()
|
|
|
|
+ {
|
|
|
|
+ TransactionObject transObj = new TransactionObject();
|
|
|
|
+ transObj.from = address;
|
|
|
|
+ transObj.to = MultiOwnerContractRinkeby;
|
|
|
|
+ //transObj.data = zerofill(dec2hex(36), 64, true); //36 bytes len of data. Для ремикса это не нужно, он сам вставляет длину массива
|
|
|
|
+ transObj.data += await compileFunction($"function transferOwnership(address newOwner)"); //4 bytes
|
|
|
|
+ transObj.data += zerofill("0xD3ae749f1253b320ea2b90dc235ed72c80447AFF", 64, true); //32 bytes
|
|
|
|
+ Console.WriteLine($"transObj.data {transObj.data}");
|
|
|
|
+ //var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
|
|
+ }
|
|
|
|
+
|
|
public async Task Transactions(string multiOwnerContract)
|
|
public async Task Transactions(string multiOwnerContract)
|
|
{
|
|
{
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
- transObj.to = multiOwnerContract;// "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
|
|
- transObj.gas = "9000";
|
|
|
|
|
|
+ transObj.to = multiOwnerContract;
|
|
transObj.data = await compileFunction($"transactionCount");
|
|
transObj.data = await compileFunction($"transactionCount");
|
|
var answer = await RunFunction2("eth_call", transObj, "latest");
|
|
var answer = await RunFunction2("eth_call", transObj, "latest");
|
|
}
|
|
}
|
|
@@ -184,18 +196,17 @@ namespace HyperCube.Models
|
|
{
|
|
{
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
transObj.from = owner;
|
|
transObj.from = owner;
|
|
- transObj.to = tokenAddress;// "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
|
|
- transObj.gas = "9000";
|
|
|
|
|
|
+ transObj.to = tokenAddress;
|
|
transObj.data = await compileFunction($"function approve(address spender, uint256 amount)");
|
|
transObj.data = await compileFunction($"function approve(address spender, uint256 amount)");
|
|
if (tokenAddress != null)
|
|
if (tokenAddress != null)
|
|
{
|
|
{
|
|
transObj.data += zerofill(spender, 64, true);
|
|
transObj.data += zerofill(spender, 64, true);
|
|
- transObj.data += zerofill(dec2hex(Convert.ToInt32(amount)), 64, true);
|
|
|
|
|
|
+ transObj.data += zerofill(dec2hex(amount), 64, true);
|
|
}
|
|
}
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
}
|
|
}
|
|
|
|
|
|
- public async Task<string> SubmitTransaction(string owner, int tokenvalue, string receiver, string tokenAddress = HCBAddress)
|
|
|
|
|
|
+ public async Task<string> SubmitTransaction(string owner, long tokenvalue, string receiver, string tokenAddress = QNMAddress)
|
|
{
|
|
{
|
|
//"submitTransaction(address destination, uint value, address tokenAddress)"
|
|
//"submitTransaction(address destination, uint value, address tokenAddress)"
|
|
//var tokenAmount = float.Parse(tokenvalue, System.Globalization.CultureInfo.InvariantCulture);// * 1000000000000000000;
|
|
//var tokenAmount = float.Parse(tokenvalue, System.Globalization.CultureInfo.InvariantCulture);// * 1000000000000000000;
|
|
@@ -205,7 +216,6 @@ namespace HyperCube.Models
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
transObj.from = owner;
|
|
transObj.from = owner;
|
|
transObj.to = MultiOwnerContractRinkeby;
|
|
transObj.to = MultiOwnerContractRinkeby;
|
|
- transObj.gas = "9000";
|
|
|
|
transObj.data = await compileFunction($"function submitTransaction(address destination, uint256 value, address tokenAddress)");
|
|
transObj.data = await compileFunction($"function submitTransaction(address destination, uint256 value, address tokenAddress)");
|
|
if (tokenvalue > 0)
|
|
if (tokenvalue > 0)
|
|
{
|
|
{
|
|
@@ -217,31 +227,65 @@ namespace HyperCube.Models
|
|
return ParseStringAnswer(answer)[0];
|
|
return ParseStringAnswer(answer)[0];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ //
|
|
|
|
+ //ETHtoERC20 - шлем эфир на контракт, контракт шлет юзеру ERC20 по курсу со своего счета через transfer
|
|
|
|
+
|
|
|
|
+ //ETHtoERC20 - шлем ERC20 на контракт, получаем эфир по курсу
|
|
|
|
+ //запуск контрактом TransferFrom юзером на адрес контракта
|
|
|
|
+ //контракт шлет юзеру эфир по курсу со своего счета
|
|
|
|
|
|
//нужна проверка балансов системы и юзера перед обменом
|
|
//нужна проверка балансов системы и юзера перед обменом
|
|
- public async Task ChangeCurrency(string from_token_selected, string to_token_selected, string tokenAddress, string sender, string from, string to, string fi, string ti)
|
|
|
|
|
|
+ public async Task ExchangeCurrency(string from_token_selected, string to_token_selected, string tokenAddress, string senderAccountAddress, string fi, string ti)
|
|
{
|
|
{
|
|
- var val = float.Parse(fi, System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
- var tokenAmount = val;// * 1000000000000000000;
|
|
|
|
- val = float.Parse(ti, System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
- var ethAmount = val / 5; // /5
|
|
|
|
- //ETHtoERC20(address tokenAddress)
|
|
|
|
|
|
+ //ETHtoERC20(address tokenAddress, uint256 tokenAmount)
|
|
//ERC20toETH(address tokenAddress, address sender, uint256 tokenAmount, uint256 ethAmount) public payable returns(bool)
|
|
//ERC20toETH(address tokenAddress, address sender, uint256 tokenAmount, uint256 ethAmount) public payable returns(bool)
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
- transObj.from = sender;
|
|
|
|
|
|
+ transObj.from = senderAccountAddress;
|
|
transObj.to = MultiOwnerContractRinkeby;
|
|
transObj.to = MultiOwnerContractRinkeby;
|
|
- transObj.gas = "9000";
|
|
|
|
- transObj.data = await compileFunction($"function ERC20toETH(address tokenAddress, address sender, uint256 tokenAmount, uint256 ethAmount)");
|
|
|
|
- if (tokenAddress != null && tokenAmount != null)
|
|
|
|
|
|
+ transObj.gas = dec2hex("90000");
|
|
|
|
+
|
|
|
|
+ var valFrom = decimal.Parse(fi, System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
+ var valTo = decimal.Parse(ti, System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
+
|
|
|
|
+ if (to_token_selected == "qnm")
|
|
|
|
+ {
|
|
|
|
+ transObj.data = await compileFunction($"function ETHtoERC20(address tokenAddress, uint256 tokenAmount)");
|
|
|
|
+ BigInteger tokenAmount = (BigInteger)(valTo * 1000000000000000000m);
|
|
|
|
+ BigInteger ethAmount = (BigInteger)(valFrom * 1000000000000000000m);
|
|
|
|
+ Console.WriteLine($"######################################ETHtoERC20 valTo {valTo} tokenAmount {tokenAmount} valFrom {valFrom} ethAmount {ethAmount}");
|
|
|
|
+ transObj.value = dec2hex(ethAmount);
|
|
|
|
+ if (tokenAddress != null && tokenAmount > 0)
|
|
|
|
+ {
|
|
|
|
+ transObj.data += zerofill(tokenAddress, 64, true);
|
|
|
|
+ transObj.data += zerofill(dec2hex(tokenAmount), 64, true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- transObj.data += zerofill(tokenAddress, 64, true);
|
|
|
|
- transObj.data += zerofill(sender, 64, true);
|
|
|
|
- transObj.data += zerofill(dec2hex(Convert.ToInt32(tokenAmount)), 64, true);
|
|
|
|
- transObj.data += zerofill(dec2hex(Convert.ToInt32(ethAmount)), 64, true);
|
|
|
|
|
|
+ BigInteger tokenAmount = (BigInteger)(valFrom * 1000000000000000000);
|
|
|
|
+ BigInteger ethAmount = (BigInteger)(valTo * 1000000000000000000);
|
|
|
|
+ //сначала нужен аппрув перевода!
|
|
|
|
+ //from=erc20 to=eth
|
|
|
|
+ var amount = float.Parse(fi, System.Globalization.CultureInfo.InvariantCulture);
|
|
|
|
+ var appr = Approve(senderAccountAddress, MultiOwnerContractRinkeby, tokenAmount.ToString(), QNMAddress);
|
|
|
|
+ await Task.WhenAll(appr);
|
|
|
|
+
|
|
|
|
+ //sender возможно можно заменить на msg.sender
|
|
|
|
+ transObj.data = await compileFunction($"function ERC20toETH(address tokenAddress, address sender, uint256 tokenAmount, uint256 ethAmount)");
|
|
|
|
+ Console.WriteLine($"######################################ERC20toETH valTo {valTo} tokenAmount {tokenAmount} valFrom {valFrom} ethAmount {ethAmount}");
|
|
|
|
+ if (tokenAddress != null && tokenAmount != null)
|
|
|
|
+ {
|
|
|
|
+ transObj.data += zerofill(tokenAddress, 64, true);
|
|
|
|
+ transObj.data += zerofill(senderAccountAddress, 64, true);
|
|
|
|
+ transObj.data += zerofill(dec2hex(tokenAmount), 64, true);
|
|
|
|
+ transObj.data += zerofill(dec2hex(ethAmount), 64, true);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ //ETHtoERC20(address tokenAddress, uint256 tokenAmount)
|
|
public async Task<string> Verify(AccountModel verifier, ArticleModel article)
|
|
public async Task<string> Verify(AccountModel verifier, ArticleModel article)
|
|
{
|
|
{
|
|
Console.WriteLine($"Verify starting");
|
|
Console.WriteLine($"Verify starting");
|
|
@@ -266,9 +310,17 @@ namespace HyperCube.Models
|
|
return "Verify failed";
|
|
return "Verify failed";
|
|
}
|
|
}
|
|
|
|
|
|
- public static string dec2hex(int decValue, bool prefix = true)
|
|
|
|
|
|
+ public static string dec2hex(BigInteger decValue, bool prefix = true)
|
|
|
|
+ {
|
|
|
|
+ var hexValue = decValue.ToString("X");
|
|
|
|
+ if (prefix)
|
|
|
|
+ hexValue = "0x" + hexValue;
|
|
|
|
+ return hexValue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static string dec2hex(string decValue, bool prefix = true)
|
|
{
|
|
{
|
|
- string hexValue = decValue.ToString("X");
|
|
|
|
|
|
+ var hexValue = BigInteger.Parse(decValue, System.Globalization.CultureInfo.InvariantCulture).ToString("X");
|
|
if (prefix)
|
|
if (prefix)
|
|
hexValue = "0x" + hexValue;
|
|
hexValue = "0x" + hexValue;
|
|
return hexValue;
|
|
return hexValue;
|
|
@@ -432,9 +484,9 @@ namespace HyperCube.Models
|
|
{
|
|
{
|
|
var ret = await RunFunction("eth_getBalance", $"\"{address}\",\"latest\"");
|
|
var ret = await RunFunction("eth_getBalance", $"\"{address}\",\"latest\"");
|
|
var balanceWei = AccountModel.ConvertBalance(ret);
|
|
var balanceWei = AccountModel.ConvertBalance(ret);
|
|
- var balanceToken = Math.Round((double)balanceWei / 1000000000000000000.0, 4);
|
|
|
|
- Console.WriteLine($"GetBalance balanceToken {balanceToken}");
|
|
|
|
- balance = balanceToken.ToString();
|
|
|
|
|
|
+ var balanceEth = Math.Round((double)balanceWei / 1000000000000000000.0, 4);
|
|
|
|
+ Console.WriteLine($"GetBalance balanceEth {balanceEth}");
|
|
|
|
+ balance = balanceEth.ToString();
|
|
return balance;
|
|
return balance;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -460,6 +512,10 @@ namespace HyperCube.Models
|
|
paramDict["from"] = to.from;
|
|
paramDict["from"] = to.from;
|
|
if (to.to != null)
|
|
if (to.to != null)
|
|
paramDict["to"] = to.to;
|
|
paramDict["to"] = to.to;
|
|
|
|
+ if (to.gas != null)
|
|
|
|
+ paramDict["gas"] = to.gas;
|
|
|
|
+ if (to.value != null)
|
|
|
|
+ paramDict["value"] = to.value;
|
|
if (to.data != null)
|
|
if (to.data != null)
|
|
{
|
|
{
|
|
paramDict["data"] = "0x"+to.data;
|
|
paramDict["data"] = "0x"+to.data;
|
|
@@ -668,32 +724,13 @@ namespace HyperCube.Models
|
|
//mint(address to, uint256 amount)
|
|
//mint(address to, uint256 amount)
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
transObj.from = address;
|
|
transObj.from = address;
|
|
- transObj.to = "0xe5D682717955d6C35d465A3485625C64655a04f4";
|
|
|
|
|
|
+ transObj.to = QNMAddress;
|
|
transObj.gas = "9000";
|
|
transObj.gas = "9000";
|
|
- transObj.value = tokenAmount;
|
|
|
|
transObj.data = await compileFunction($"function mint(address to, uint256 amount)");
|
|
transObj.data = await compileFunction($"function mint(address to, uint256 amount)");
|
|
if (addressTo != null && tokenAmount != null)
|
|
if (addressTo != null && tokenAmount != null)
|
|
{
|
|
{
|
|
transObj.data += zerofill(addressTo, 64, true);
|
|
transObj.data += zerofill(addressTo, 64, true);
|
|
- transObj.data += zerofill(dec2hex(Convert.ToInt32(tokenAmount)), 64, true);
|
|
|
|
- }
|
|
|
|
- var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //approve transfer amount from sender by contract to any address: approve(address spender, uint256 amount)
|
|
|
|
- public async Task ApproveExchange(string tokenContract, AccountModel owner, AccountModel spender, string tokenAmount)
|
|
|
|
- {
|
|
|
|
- TransactionObject transObj = new TransactionObject();
|
|
|
|
- transObj.from = owner.GetActualAddress(this);
|
|
|
|
- transObj.to = tokenContract;
|
|
|
|
- transObj.gas = "9000";
|
|
|
|
- transObj.value = tokenAmount; //тут должен быть эфир!
|
|
|
|
- transObj.data = await compileFunction($"function approve(address spender, uint256 amount)");
|
|
|
|
- if (tokenContract != null && tokenAmount != null)
|
|
|
|
- {
|
|
|
|
- transObj.data += zerofill(spender.GetActualAddress(this), 64, true);
|
|
|
|
- transObj.data += zerofill(dec2hex(Convert.ToInt32(tokenAmount)), 64, true);
|
|
|
|
|
|
+ transObj.data += zerofill(dec2hex(tokenAmount), 64, true);
|
|
}
|
|
}
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
var answer = await RunFunction2("eth_sendTransaction", transObj);
|
|
}
|
|
}
|
|
@@ -704,8 +741,6 @@ namespace HyperCube.Models
|
|
TransactionObject transObj = new TransactionObject();
|
|
TransactionObject transObj = new TransactionObject();
|
|
transObj.from = sender;
|
|
transObj.from = sender;
|
|
transObj.to = tokenContract;
|
|
transObj.to = tokenContract;
|
|
- transObj.gas = "9000";
|
|
|
|
- transObj.value = tokenAmount; //тут должен быть эфир!
|
|
|
|
transObj.data = await compileFunction($"function transfer(address recipient, uint256 amount)");
|
|
transObj.data = await compileFunction($"function transfer(address recipient, uint256 amount)");
|
|
if (addressTo != null && tokenAmount != null)
|
|
if (addressTo != null && tokenAmount != null)
|
|
{
|
|
{
|