Blockchain.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. using System;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Newtonsoft.Json;
  7. using Console = HyperCube.Utils.AdvConsole;
  8. using System.Text.RegularExpressions;
  9. //0xe5D682717955d6C35d465A3485625C64655a04f4 - HCB in rinkeby
  10. //0xb504ba124b74333d8536db534f7fcdc174d6ee3d - system address rinkeby
  11. //0x413D9500A675d9b645034aC5f4325BF12ddeb7c1 bitcoin
  12. namespace HyperCube.Models
  13. {
  14. public struct TransactionObject
  15. {
  16. public string from;
  17. public string to;
  18. public string data;
  19. public string gas;
  20. public string value;
  21. }
  22. public class Blockchain
  23. {
  24. public static Blockchain Dev
  25. {
  26. get {
  27. return loaded[0];
  28. }
  29. set { }
  30. }
  31. public static string tokenName;
  32. public static string decimals;
  33. public static string symbol;
  34. public static string tokenBalance;
  35. public static Dictionary<int, Blockchain> supported;
  36. public static string Connected
  37. {
  38. get {
  39. var bc = GetMain();
  40. if (bc != null)
  41. return $"{bc.name}";
  42. return "none";
  43. }
  44. }
  45. public static string URLdefault = "127.0.0.1";
  46. //public static int defaultPort = 8545;
  47. public static int defaultPort = 8666;
  48. public static string defaultName = "Ethereum dev network";
  49. public static bool blockChainsInitialized = false;
  50. public static Dictionary<int, Blockchain> loaded = new();
  51. public Dictionary<int, SmartContract> contracts = new();
  52. public Dictionary<string, SmartContract> contractNames = new();
  53. public int id;
  54. public int port;
  55. public string url;
  56. public string address = "";
  57. public string name;
  58. public string balance;
  59. static Blockchain instance;
  60. public async static Task RegisterNetworks()
  61. {
  62. if (!blockChainsInitialized)
  63. {
  64. Console.WriteLine($"RegisterNetworks");
  65. var ethDev = new Blockchain(0, "Ethereum Dev Network", "127.0.0.1", 8545);
  66. var ethRinkeby = new Blockchain(1, "Ethereum Test Network", "127.0.0.1", 8666);
  67. await ethDev.Initialize();
  68. await ethRinkeby.Initialize();
  69. blockChainsInitialized = true;
  70. }
  71. }
  72. public static Blockchain Find(int id)
  73. {
  74. if (loaded.ContainsKey(id))
  75. return loaded[id];
  76. return null;
  77. }
  78. public async Task<string> Initialize()
  79. {
  80. if (!loaded.ContainsKey(id))
  81. loaded.Add(id, this);
  82. Console.WriteLine($"Initialize: {name}, loaded blockchains " + loaded.Count);
  83. string addr = await ListAccounts();
  84. await LoadContracts();
  85. Console.WriteLine("LoadContracts count " + contracts.Count);
  86. Console.WriteLine("connected " + Connected);
  87. return $"{name} {url}:{port}";
  88. }
  89. public static string dec2hex(int decValue, bool prefix = true)
  90. {
  91. string hexValue = decValue.ToString("X");
  92. if (prefix)
  93. hexValue = "0x" + hexValue;
  94. return hexValue;
  95. }
  96. public static int hex2dec(string hexValue)
  97. {
  98. return Convert.ToInt32(hexValue, 16);
  99. }
  100. //public static Blockchain GetInstance()
  101. //{
  102. // if (instance == null)
  103. // instance = new Blockchain(URLdefault, defaultPort);
  104. // return instance;
  105. //}
  106. //Blockchain()
  107. //{
  108. //}
  109. public Blockchain(int id, string name, string url, int port)
  110. {
  111. this.id = id;
  112. this.url = url;
  113. this.port = port;
  114. this.name = name;
  115. }
  116. public async Task<string> CreateBlockchainAccount(AccountModel account, string pass)
  117. {
  118. Console.WriteLine($"Run CreateBlockchainAccount {account}");
  119. var res = await RunFunction("personal_newAccount", $"\"{pass}\"");
  120. string query;
  121. if (account != null)
  122. {
  123. Console.WriteLine($"CreateBlockchainAccount {account}: {res}");
  124. //query = $"update aspnetusers set eth_address='{res}' where UserName='{account.Name}'";
  125. var addr = account.GetActualAddress(this);
  126. if (addr == null)
  127. query = $"insert into account_wallets (uuid, blockchain_id, account_uuid, password_plain) values ('{res}',{id},'{account.UUID}','{account.PWDHash}')";
  128. else
  129. query = $"update account_wallets set uuid='{res}', password_plain='{account.PWDHash}' where account_uuid='{account.UUID}' and blockchain_id={id}";
  130. account.SetActualAddress(res, this);
  131. Console.WriteLine($"CreateBlockchainAccount query {query}");
  132. await MySQLConnector.Instance().SQLInsert(query);
  133. }
  134. else
  135. Console.WriteLine($"CreateBlockchainAccount {id}: {res}");
  136. query = $"update blockchains set address_main='{res}' where id={id}";
  137. address = res;
  138. Console.WriteLine($"CreateBlockchainAccount query {query}");
  139. await MySQLConnector.Instance().SQLInsert(query);
  140. return res;
  141. }
  142. public static string hex2bin(string hexstring)
  143. {
  144. string binarystring = String.Join(String.Empty, hexstring.Select( c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0') ));
  145. Console.WriteLine("bin " + binarystring);
  146. return binarystring;
  147. }
  148. public static string bin2hex(string code)
  149. {
  150. //code = "0x".bin2hex('getCount()');
  151. var bytes = Encoding.UTF8.GetBytes(code);
  152. var hex = BitConverter.ToString(bytes).Replace("-", "");
  153. Console.WriteLine("hex " + hex);
  154. return "0x" + hex;
  155. }
  156. public static string zerofill(string hex, int charCount, bool hexPrefix0x)
  157. {
  158. if (hexPrefix0x)
  159. hex = hex.Remove(0, 2);
  160. Console.WriteLine($"zerofill input {hex} count {hex.Length}");
  161. var res = hex.PadLeft(charCount, '0');
  162. Console.WriteLine($"zerofill out {hex} count {res.Length}");
  163. return res;
  164. }
  165. public static Blockchain GetMain()
  166. {
  167. if (loaded.Count > AccountModel.GetCurrent()?.blockchain_selected)
  168. {
  169. var bc = loaded[AccountModel.GetCurrent().blockchain_selected];
  170. Console.WriteLine($"GetMain blockchain_selected {AccountModel.GetCurrent().blockchain_selected} " + bc.address);
  171. return bc;
  172. }
  173. else
  174. Console.WriteLine($"Error: blockchains loaded {loaded.Count}");
  175. return null;
  176. }
  177. public async Task<string> ListAccounts()
  178. {
  179. Console.WriteLine($"ListAccounts blockchain {id}");
  180. string answer = "no";
  181. //{ "jsonrpc":"2.0","method":"eth_getCode","params":["0x938cae6f6c21ed9d55196e96ef880f562e530553", "latest" ],"id":1}
  182. //string req = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getCode\",\"params\":[\"0x874c6a51e62680d4594cd2555ed8fa47b63ed253\",\"latest\"],\"id\":1}";
  183. string req = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_accounts\", \"params\":[],\"id\":1}";
  184. answer = await Post.PostRequestAsync(this, req);
  185. //string json = Encoding.UTF8.GetString(bytedata, 1, bytedata.Length - 1);
  186. //try
  187. //{
  188. Console.WriteLine("Json string " + answer);
  189. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  190. var res = (Newtonsoft.Json.Linq.JArray)jsonDe.result;
  191. if (res.Count > 0 && id == 0) //Dev
  192. {
  193. address = jsonDe.result[0];
  194. }
  195. else
  196. {
  197. address = await GetAddress();
  198. if (address == "" || address == null)
  199. address = await CreateEthAddress("test_Password_212");
  200. }
  201. var query = $"update blockchains set address_main='{address}' where id={id}";
  202. Console.WriteLine("query " + query);
  203. await MySQLConnector.Instance().SQLInsert(query);
  204. Console.WriteLine("Json addr " + jsonDe.result[0]);
  205. return address;
  206. }
  207. public async Task<string> CreateEthAddress(string pass)
  208. {
  209. return await CreateBlockchainAccount(null, pass);
  210. }
  211. public async Task LoadContracts()
  212. {
  213. MySQLConnector dbCon = MySQLConnector.Instance();
  214. contracts = await dbCon.SQLSelectContracts(id);
  215. foreach (var contract in contracts.Values)
  216. {
  217. await contract.LoadFunction();
  218. }
  219. }
  220. public async Task<string> GetSHA3(string code)
  221. {
  222. var hex = bin2hex(code);
  223. var req = $"{{ \"jsonrpc\":\"2.0\",\"method\":\"web3_sha3\",\"params\":[\"{hex}\"], \"id\":1}}";
  224. var answer = await Post.PostRequestAsync(this, req);
  225. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  226. Console.WriteLine("result " + jsonDe.result);
  227. return jsonDe.result;
  228. }
  229. public async Task<string> GetBalance(AccountModel account)
  230. {
  231. var addr = await account.GetOrCreateActualAddress(this);
  232. //var ret = await RunFunction("eth_getBalance", $"\"{addr}\",\"latest\"");
  233. Console.WriteLine($"GetBalance AccountModel addr {addr}");
  234. return await GetBalance(addr);
  235. }
  236. public async Task<string> GetBalance()
  237. {
  238. return await GetBalance(address);
  239. }
  240. //eth.getBalance('0xb504ba124b74333D8536DB534F7fcdC174d6Ee3d')
  241. public async Task<string> GetBalance(string address)
  242. {
  243. var ret = await RunFunction("eth_getBalance", $"\"{address}\",\"latest\"");
  244. var balanceWei = AccountModel.ConvertBalance(ret);
  245. var balanceToken = (double)balanceWei / 1000000000000000000.0;
  246. Console.WriteLine($"GetBalance balanceToken {balanceToken}");
  247. balance = balanceToken.ToString();
  248. return balance;
  249. }
  250. public async Task<string> RunFunction(string name, string parms)
  251. {
  252. Console.WriteLine($"RunFunction {name} params {parms}");
  253. var req = $"{{ \"jsonrpc\":\"2.0\",\"method\":\"{name}\",\"params\":[{parms}], \"id\":1}}";
  254. var answer = await Post.PostRequestAsync(this, req);
  255. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  256. Console.WriteLine("RunFunction result " + jsonDe.result);
  257. return jsonDe.result;
  258. //return "test answer";
  259. }
  260. public async Task<string> RunFunction2(string name, TransactionObject to, string defaultBlock = null)
  261. {
  262. //транзакция добавления контракта 0x00bdbf1571aa69a2cf8c8c7913a01eaca3a4b7e5e7e49fc787cb81c0df2c2682
  263. Dictionary<string, string> paramDict = new Dictionary<string, string>();
  264. string parms = "{";
  265. if (to.from != null)
  266. paramDict["from"] = to.from;
  267. if (to.to != null)
  268. paramDict["to"] = to.to;
  269. if (to.data != null)
  270. {
  271. paramDict["data"] = "0x"+to.data;
  272. }
  273. int count = 0;
  274. foreach (var p in paramDict)
  275. {
  276. parms += $"\"{p.Key}\":\"{p.Value}\"";
  277. count++;
  278. if (paramDict.Count > count)
  279. {
  280. parms += ",";
  281. }
  282. }
  283. parms += "}";
  284. if (defaultBlock != null)
  285. parms += $", \"{defaultBlock}\"";
  286. Console.WriteLine($"RunFunction {name} params {parms} active bc: {this.address}");
  287. var req = $"{{ \"jsonrpc\":\"2.0\",\"method\":\"{name}\",\"params\":[{parms}], \"id\":1}}";
  288. var answer = await Post.PostRequestAsync(this, req);
  289. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  290. Console.WriteLine("RunFunction result " + jsonDe.result);
  291. return jsonDe.result;
  292. //return "test answer";
  293. }
  294. async Task<string> mySHA3(string code)
  295. {
  296. var res = await GetSHA3(code);
  297. Console.WriteLine($"GetSHA3 {code} {res}");
  298. var ret = res.Substring(2, 8);
  299. return ret;
  300. }
  301. public async Task<string> compileFunction(string input, bool getsha = true)
  302. {
  303. //\s = пробел
  304. //\S = любой символ, кроме промельного
  305. //+ одно или более вхождений
  306. //. любой сивол, кроме перевода строки
  307. //* ноль или более вхождений «а»
  308. //скобки без экранирования = группы
  309. //function transfer(address recipient, uint256 amount)
  310. string pattern = @"function\s+(\S+)\s*\((.*)\).*";
  311. string replacement_name = "$1"; //номер найденной группы
  312. string replacement_params = "$2";
  313. string resultname = Regex.Replace(input, pattern, replacement_name).Trim();
  314. string param_pattern = @"(uint8|address|uint256)";
  315. string final = resultname + "(";
  316. if (input != resultname)
  317. {
  318. string resultparams = Regex.Replace(input, pattern, replacement_params).Trim();
  319. if (input != resultparams)
  320. {
  321. int i = 0;
  322. foreach (Match match in Regex.Matches(resultparams, param_pattern))
  323. {
  324. if (i > 0)
  325. final += "," + match.Value;
  326. else
  327. final += match.Value;
  328. i++;
  329. }
  330. }
  331. }
  332. string function_processed = final + ")";
  333. Console.WriteLine($"function_processed {function_processed}");
  334. if (getsha)
  335. {
  336. function_processed = await mySHA3(function_processed);
  337. }
  338. return function_processed;
  339. }
  340. //public double UInt256Conv(string input)
  341. //{
  342. // System.Numerics.BigInteger bigint1 = System.Numerics.BigInteger.Parse("329974300448100608374211110737048701521");
  343. // System.Numerics.BigInteger bigint2 = new System.Numerics.BigInteger(18);
  344. // return bigint1 / 18.0;
  345. //}
  346. public static string HextoString(string InputText)
  347. {
  348. byte[] bb = Enumerable.Range(0, InputText.Length)
  349. .Where(x => x % 2 == 0)
  350. .Select(x => Convert.ToByte(InputText.Substring(x, 2), 16))
  351. .ToArray();
  352. //return System.Text.Encoding.ASCII.GetString(bb);
  353. // or System.Text.Encoding.UTF7.GetString
  354. return System.Text.Encoding.UTF8.GetString(bb);
  355. // or System.Text.Encoding.Unicode.GetString
  356. // or etc.
  357. }
  358. public string[] ParseStringAnswer(string answer)
  359. {
  360. var ret = new string[] { };
  361. if (answer.Length > 2)
  362. {
  363. answer = answer.Substring(2, answer.Length - 2);
  364. int words = answer.Length / 64;
  365. ret = new string[words];
  366. for (int i = 0; i < words; i++)
  367. {
  368. var word = answer.Substring(i * 64, 64);
  369. ret[i] = word;
  370. Console.WriteLine($"word {i} {word}");
  371. Console.WriteLine($"str {i} {HextoString(word)}");
  372. var testbalance1 = (double)(AccountModel.ConvertBalance(word)/ 1000000000000000000);
  373. var testbalance2 = ((double)AccountModel.ConvertBalance(word) / 1000000000000000000.0);
  374. Console.WriteLine($"testbalance1 {testbalance1} testbalance2 {testbalance2} ");
  375. }
  376. }
  377. return ret;
  378. }
  379. public async Task TransferToken(string sender, string tokenContract, string addressTo, string tokenAmount)
  380. {
  381. //transfer(address recipient, uint256 amount)
  382. TransactionObject transObj = new TransactionObject();
  383. transObj.from = sender;
  384. transObj.to = tokenContract;
  385. transObj.gas = "9000";
  386. transObj.value = tokenAmount;
  387. transObj.data = await compileFunction($"function transfer(address recipient, uint256 amount)");
  388. if (addressTo != null && tokenAmount != null)
  389. {
  390. transObj.data += zerofill(addressTo, 64, true);
  391. transObj.data += zerofill(dec2hex(Convert.ToInt32(tokenAmount)), 64, true);
  392. }
  393. var answer = await RunFunction2("eth_sendTransaction", transObj);
  394. }
  395. public async Task ImportERC20(string contractAddress)
  396. {
  397. //var gbh = await GetTByHash("0x00bdbf1571aa69a2cf8c8c7913a01eaca3a4b7e5e7e49fc787cb81c0df2c2682");
  398. //Console.WriteLine("GetTByHash " + gbh );
  399. //runfunction balanceOf totalSupply symbol name
  400. //RunContractRead
  401. TransactionObject transObj = new TransactionObject();
  402. transObj.to = contractAddress;
  403. //compile data
  404. //to.data = await compileFunction("decimals");
  405. transObj.data = await compileFunction("name");
  406. var answer = await RunFunction2("eth_call", transObj, "latest");
  407. //Console.WriteLine("ImportERC20 len "+ answer.Length + " answer " + answer);
  408. var parsed = ParseStringAnswer(answer);
  409. int tokenlen = hex2dec(parsed[1]);
  410. tokenName = HextoString(parsed[2]).Substring(0,tokenlen);
  411. //to.data = await compileFunction("balanceOf(address)");
  412. transObj.data = await compileFunction("symbol");
  413. answer = await RunFunction2("eth_call", transObj, "latest");
  414. parsed = ParseStringAnswer(answer);
  415. int symlen = hex2dec(parsed[1]);
  416. symbol = HextoString(parsed[2]).Substring(0, symlen);
  417. //Console.WriteLine("ImportERC20 len " + answer.Length + " answer " + answer);
  418. transObj.data = await compileFunction("decimals");
  419. answer = await RunFunction2("eth_call", transObj, "latest");
  420. decimals = hex2dec(ParseStringAnswer(answer)[0]).ToString();
  421. transObj.data = await compileFunction($"function balanceOf(address account)");
  422. if (address != null)
  423. transObj.data += zerofill("0xb504ba124b74333D8536DB534F7fcdC174d6Ee3d", 64, true);
  424. //answer = await RunFunction2("eth_call", to, AccountModel.Current.GetActualAddress(this));
  425. answer = await RunFunction2("eth_call", transObj, "latest");
  426. tokenBalance = ((double)AccountModel.ConvertBalance(ParseStringAnswer(answer)[0]) / 1000000000000000000.0).ToString();
  427. }
  428. public async void RunContractRead()
  429. {
  430. string answer = "no";
  431. string req = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"to\":\"0x874c6a51e62680d4594cd2555ed8fa47b63ed253\", \"data\":\"0xa87d942c\"},\"latest\"],\"id\":1}";
  432. //string req = "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x0000000000000000000000000000000000000000000000000000000000000004\"}";
  433. //Console.WriteLine($"req " + req);
  434. await Post.PostRequestAsync(this, req);
  435. //Console.WriteLine($"answer {answer} len {answer.Length}" );
  436. address = answer;
  437. }
  438. public async Task<string> SendTransaction(string fromAddress, string toAddress, int wei)
  439. {
  440. var sum = dec2hex(wei);
  441. var gas = await GetEstimatedGasTransaction(wei);
  442. Console.WriteLine($"SendTransaction from {fromAddress} to {toAddress} sum {sum}");
  443. var answer = await RunFunction("eth_sendTransaction", $"{{\"from\":\"{address}\",\"to\":\"{toAddress}\",\"gas\":\"{gas}\", \"data\":\"\", \"value\":\"{sum}\"}}");
  444. return answer;
  445. }
  446. //{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{ "from":"0xD81eeE6b39d9556c3067A3551A3FB2882b92F327", "to":"0x119b58faddcdbc09cafcd272530aa079cec10004", "gas":"0x31b2ef", "data":"0x11111111"}], "id":1}
  447. public async Task<string> RunContractWrite(string contractAddress, string data, string gas, string value)
  448. {
  449. Console.WriteLine("RunContract contractAddress " + contractAddress);
  450. var answer = await RunFunction("eth_sendTransaction", $"{{\"from\":\"{address}\",\"to\":\"{contractAddress}\",\"gas\":\"{gas}\", \"data\":\"{data}\", \"value\":\"{value}\"}}");
  451. //$"{{ \"jsonrpc\":\"2.0\",\"method\":\"eth_sendTransaction\",\"params\":[{{\"from\":\"{address}\",\"to\":\"{contractAddress}\",\"gas\":\"0x31b2ef\", \"data\":\"{data}\"}}], \"id\":1}}";
  452. //var answer = await Post.PostRequestAsync(req);
  453. //dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  454. //Console.WriteLine("result " + answer);
  455. return answer;
  456. }
  457. public async Task<string> GetTByHash(string transactionAddress)
  458. {
  459. string req = $"{{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionByHash\",\"params\":[\"{transactionAddress}\"],\"id\":1}}";
  460. Console.WriteLine("GetTByHash " + req);
  461. return await Post.PostRequestAsync(this, req);
  462. }
  463. public async Task<string> GetReceipt(string transactionAddress, bool returnAddress = false)
  464. {
  465. Console.WriteLine("transactionAddress " + transactionAddress);
  466. var req = $"{{ \"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"{transactionAddress}\"], \"id\":1}}";
  467. var answer = await Post.PostRequestAsync(this, req);
  468. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  469. if (jsonDe.result != null)
  470. {
  471. var blockHash = jsonDe.result.blockHash;
  472. var blockNumber = jsonDe.result.blockNumber;
  473. var contractAddress = jsonDe.result.contractAddress;
  474. await MySQLConnector.Instance().SQLInsert($"insert into transactions (result, name) values ('{Convert.ToString(jsonDe.result)}', 'eth_getTransactionReceipt')");
  475. Console.WriteLine("result " + answer);
  476. if (returnAddress)
  477. return contractAddress;
  478. else
  479. return Convert.ToString(jsonDe.result);
  480. }
  481. else
  482. {
  483. Console.WriteLine("eth_getTransactionReceipt reuslt NULL " + transactionAddress);
  484. return null;
  485. }
  486. }
  487. //TODO add GAS!!!
  488. public async Task<object[]> AddContract(string name, string code, string bytecode)
  489. {
  490. Console.WriteLine("bytecode " + bytecode);
  491. var gas = await GetEstimatedGasContractAdd(bytecode);
  492. var req = $"{{ \"jsonrpc\":\"2.0\",\"method\":\"eth_sendTransaction\",\"params\":[{{\"from\":\"{address}\",\"gas\":\"{gas}\", \"data\":\"{bytecode}\"}}], \"id\":1}}";
  493. var answer = await Post.PostRequestAsync(this, req);
  494. dynamic jsonDe = JsonConvert.DeserializeObject(answer);
  495. var res = jsonDe.result;
  496. Console.WriteLine("result AddContract transactionAddress: " + res);
  497. if (res != null)
  498. {
  499. SmartContract newctr = new SmartContract(name, code, bytecode, this.id, gas);
  500. if (gas == null)
  501. gas = "invalid";
  502. long id = await MySQLConnector.Instance().SQLInsert($"insert into smart_contracts (code, bytecode, name, date_add, gas_cost, blockchain_id) values ('{code}','{bytecode}','{name}',NOW(), '{gas}', {this.id})");
  503. newctr.ID = (int) id;
  504. contracts.Add((int)id, newctr);
  505. contractNames.Add(name, newctr);
  506. return new object[] { res, newctr };
  507. }
  508. return null;
  509. }
  510. public async Task<string> GetEstimatedGasTransaction(int weiAmount)
  511. {
  512. if (weiAmount > 0)
  513. {
  514. var ret = await RunFunction("eth_estimateGas", $"{{\"from\":\"{address}\",\"value\":\"{dec2hex(weiAmount)}\"}}");
  515. Console.WriteLine("GetEstimatedGas " + ret);
  516. return ret;
  517. }
  518. return null;
  519. }
  520. public async Task<string> GetEstimatedGasContractAdd(string bytecode)
  521. {
  522. var ret = await RunFunction("eth_estimateGas", $"{{\"from\":\"{address}\",\"data\":\"{bytecode}\"}}");
  523. Console.WriteLine("GetEstimatedGasContractAdd " + ret);
  524. return ret;
  525. }
  526. public async Task<string> GetAddress()
  527. {
  528. if (address == "")
  529. {
  530. address = await MySQLConnector.Instance().SQLSelectUUID("select address_main from blockchains where id="+id);
  531. }
  532. return address;
  533. //post запрос
  534. }
  535. }
  536. }