public async Task GetBlockCount() { while (true) { try { ApiResponse response = await BlockChainEngineApi.GetBlockCount(); if (response.HasError) { throw new Exception(); } else { long result = response.GetResult <long>(); Assert.IsNotNull(result); } Thread.Sleep(8000); } catch (Exception ex) { Assert.Fail(); } } }
public async Task ApplicationClosed() { /* 当应用程序关闭的时候不能直接关闭,因为某些程序可能还在运行,如果立即结束,有可能造成数据丢失 * 1、当应用程序关闭的时候需要即时判断BlockChainStatus的状态,如果是Stoped就可以结束了,如果是Stopping或者Running不能结束 * 需要用try catch捕获异常来判断是否关闭 */ //应用程序关闭的时候先调用StopEngine的接口 await BlockChainEngineApi.StopEngine(); //即时判断BlockChainStatus try { Schedule(async() => { ApiResponse response = await BlockChainEngineApi.GetBlockChainStatus(); if (!response.HasError) { BlockChainStatus result = response.GetResult <BlockChainStatus>(); if (result.RpcService == "Stopped") { //这个其实什么都不用写,因为接口服务关闭后,你只能获取到错误 //Application.Exit(); } } }).ToRunNow().AndEvery(1).Seconds(); } catch { //在这里捕获错误,然后关闭整个Application //Application.Exit(); } }
public async Task GetBlockHash() { ApiResponse response = await BlockChainEngineApi.GetBlockHash(29); Assert.IsFalse(response.HasError); string result = response.GetResult <string>(); Assert.IsNotNull(result); }
public async Task GenerateNewBlock() { ApiResponse response = await BlockChainEngineApi.GenerateNewBlock("Zhangsan", "", 1); Assert.IsFalse(response.HasError); BlockInfoOM result = response.GetResult <BlockInfoOM>(); Assert.IsNotNull(result); }
public async Task GetBlockChainStatus() { ApiResponse response = await BlockChainEngineApi.GetBlockChainStatus(); Assert.IsFalse(response.HasError); BlockChainStatus result = response.GetResult <BlockChainStatus>(); Assert.IsNotNull(result); }
public async Task GetDifficulty() { ApiResponse response = await BlockChainEngineApi.GetDifficulty(); Assert.IsFalse(response.HasError); BlockDifficultyOM result = response.GetResult <BlockDifficultyOM>(); Assert.IsNotNull(result); }
public async Task <BlockChainStatus> GetChainStatus() { ApiResponse api = await BlockChainEngineApi.GetBlockChainStatus(); if (!api.HasError) { return(api.GetResult <BlockChainStatus>()); } else { return(null); } }
public IResult AppClosed() { /* 当应用程序关闭的时候不能直接关闭,因为某些程序可能还在运行,如果立即结束,有可能造成数据丢失 * 1、当应用程序关闭的时候需要即时判断BlockChainStatus的状态,如果是Stoped就可以结束了,如果是Stopping或者Running不能结束 * 需要用try catch捕获异常来判断是否关闭 */ //应用程序关闭的时候先调用StopEngine的接口 Result result = new Result(); AutoResetEvent autoResetEvent = new AutoResetEvent(false); Task stopEngineTask = new Task(async() => { await BlockChainEngineApi.StopEngine(); }); stopEngineTask.Start(); //即时判断BlockChainStatus try { Task task = new Task(async() => { ApiResponse response = await BlockChainEngineApi.GetBlockChainStatus(); if (!response.HasError) { bool flag = true; while (flag) { BlockChainStatus blockChainStatus = response.GetResult <BlockChainStatus>(); if (blockChainStatus.RpcService == "Stopped") { flag = false; autoResetEvent.Set(); } Thread.Sleep(1000); } } }); task.Start(); } catch { //在这里捕获错误,然后关闭整个Application result.IsFail = true; autoResetEvent.Set(); } autoResetEvent.WaitOne(); result.IsFail = false; return(result); }
public async Task GetChainTips() { ApiResponse response = await BlockChainEngineApi.GetChainTips(); Assert.IsFalse(response.HasError); if (response.Result != null) { ChainTipsOM[] result = response.GetResult <ChainTipsOM[]>(); Assert.IsNotNull(result); } else { Assert.IsNull(response.Result); } }
public async Task GetBlockHeader() { ApiResponse response = await BlockChainEngineApi.GetBlockHeader("B6D9FD10775254A86E836F211205D8A21D0F3FF3821C9E6F1F99377BFB4DADFA", 1); Assert.IsFalse(response.HasError); if (response.Result != null) { BlockHeaderOM result = response.GetResult <BlockHeaderOM>(); Assert.IsNotNull(result); } else { Assert.IsNull(response.Result); } }
public Result <BlockChainStatus> GetBlockChainStatus() { if (chainStatus == null) { ApiResponse apiResponse = BlockChainEngineApi.GetBlockChainStatus().Result; return(GetResult <BlockChainStatus>(apiResponse)); } else { return new Result <BlockChainStatus>() { Value = chainStatus, IsFail = false } }; } }
public async Task TestSendToAddress() { ApiResponse blockChainResponse = await BlockChainEngineApi.GetBlockChainStatus(); if (!blockChainResponse.HasError) { //地址 string address = "fiiitCPyohiEPn9q11AXCdvVDouoVvgojXBcVj"; //地址校验 BlockChainStatus blockChainStatus = blockChainResponse.GetResult <BlockChainStatus>(); //验证address if (AddressTools.AddressVerfy(blockChainStatus.ChainNetwork, address)) { //判断是否加密 ApiResponse transactionResponse = await TransactionApi.GetTxSettings(); if (!transactionResponse.HasError) { TransactionFeeSetting settingResult = transactionResponse.GetResult <TransactionFeeSetting>(); if (settingResult.Encrypt) { //先解锁 string password = "******"; ApiResponse unlockResponse = await WalletManagementApi.WalletPassphrase(password); if (!unlockResponse.HasError) { ApiResponse response = await TransactionApi.SendToAddress(address, 50000000, "this is your request", "John", false); Assert.IsFalse(response.HasError); string result = response.GetResult <string>(); Assert.IsNotNull(result); } ApiResponse lockResponse = await WalletManagementApi.WalletLock(); } else { ApiResponse response = await TransactionApi.SendToAddress(address, 50000000, "this is your request", "John", false); Assert.IsFalse(response.HasError); string result = response.GetResult <string>(); Assert.IsNotNull(result); } } } } }
public IResult AppClosed() { Result result = new Result(); AutoResetEvent autoResetEvent = new AutoResetEvent(false); Task stopEngineTask = new Task(async() => { await BlockChainEngineApi.StopEngine(); }); stopEngineTask.Start(); try { Task task = new Task(async() => { ApiResponse response = await BlockChainEngineApi.GetBlockChainStatus(); if (!response.HasError) { bool flag = true; while (flag) { BlockChainStatus blockChainStatus = response.GetResult <BlockChainStatus>(); if (blockChainStatus.RpcService == "Stopped") { result.IsFail = response.HasError; result.ApiResponse = response; flag = false; autoResetEvent.Set(); break; } Thread.Sleep(1000); } } }); task.Start(); } catch { //在这里捕获错误,然后关闭整个Application result.IsFail = true; autoResetEvent.Set(); } autoResetEvent.WaitOne(); return(result); }
public async Task AddNewAddressBookItem() { //fiiit6ZgKDM5ZyDYhkSWDsUmRZpkbRQf7NWiKT //先根据接口获取网络类型 ApiResponse blockChainResponse = await BlockChainEngineApi.GetBlockChainStatus(); if (!blockChainResponse.HasError) { BlockChainStatus blockChainStatus = blockChainResponse.GetResult <BlockChainStatus>(); //验证address if (AddressTools.AddressVerfy(blockChainStatus.ChainNetwork, "fiiit6ZgKDM5ZyDYhkSWDsUmRZpkbRQf7NWiKT")) { ApiResponse addressBookResponse = await AddressBookApi.AddNewAddressBookItem("fiiit6ZgKDM5ZyDYhkSWDsUmRZpkbRQf7NWiKT", "label or comment"); if (!addressBookResponse.HasError) { //do something } } } }
public async Task StopEngine() { ApiResponse response = await BlockChainEngineApi.StopEngine(); Assert.IsFalse(response.HasError); }
static void Run(string[] args) { var app = new CommandLineApplication(false); app.HelpOption("-?|-h|--help"); app.OnExecute(() => { app.ShowHelp(); return; }); app.Command("mining", command => { command.Description = "begin mining"; command.HelpOption("-?|-h|--help"); CommandArgument nameArgument = command.Argument("[minerName]", "minerName"); CommandArgument addressArgument = command.Argument("[walletAddress]", "walletAddress"); command.OnExecute(async() => { if (nameArgument != null && !string.IsNullOrEmpty(nameArgument.Value) && addressArgument != null && !string.IsNullOrEmpty(addressArgument.Value)) { string name = nameArgument.Value; string address = addressArgument.Value; Program program = new Program(); BlockChainStatus chainStatus = await program.GetChainStatus(); if (chainStatus == null) { app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain"); return; } //验证本地区块高度和网络区块高度 ApiResponse response = await NetworkApi.GetBlockChainInfo(); if (!response.HasError) { BlockChainInfo info = response.GetResult <BlockChainInfo>(); if (info.IsRunning) { if (info.RemoteLatestBlockHeight <= info.LocalLastBlockHeight) { command.Out.WriteLine($"current network is {chainStatus.ChainNetwork}"); //validate wallet address if (AddressTools.AddressVerfy(chainStatus.ChainNetwork, address)) { command.Out.WriteLine($"address verify success. prepare to mine"); await BlockMining.MiningAsync(name, address); } else { command.Out.WriteLine($"address verify fail. address: {address} is invalid"); return; } } else { command.Out.WriteLine("Block Chain is in sync, please try it later"); return; } } else { command.Out.WriteLine("Block Chain has stopped"); return; } } else { command.Out.WriteLine(response.Error.Message); return; } } else { command.ShowHelp(); return; } }); }); app.Command("height", command => { command.Description = "view current block height"; command.OnExecute(async() => { Program program = new Program(); BlockChainStatus chainStatus = await program.GetChainStatus(); if (chainStatus == null) { app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain"); return; } ApiResponse response = await BlockChainEngineApi.GetBlockCount(); if (!response.HasError) { long result = response.GetResult <long>(); command.Out.WriteLine($"current block height is {result}"); } else { command.Out.WriteLine($"{response.Error.Message}"); } }); }); app.Command("balance", command => { command.Description = "view wallet balance"; command.OnExecute(async() => { Program program = new Program(); BlockChainStatus chainStatus = await program.GetChainStatus(); if (chainStatus == null) { app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain"); return; } ApiResponse response = await UtxoApi.GetTxOutSetInfo(); if (!response.HasError) { TxOutSet set = response.GetResult <TxOutSet>(); command.Out.WriteLine($"wallet balance is :{set.Total_amount}"); } }); }); app.Command("transaction", command => { command.Description = "view recent transaction record(default 5 content)"; CommandArgument recordArgument = command.Argument("[count]", "record content"); command.OnExecute(async() => { if (recordArgument != null && !string.IsNullOrEmpty(recordArgument.Value)) { if (int.TryParse(recordArgument.Value, out int count)) { Program program = new Program(); BlockChainStatus chainStatus = await program.GetChainStatus(); if (chainStatus == null) { app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain"); return; } ApiResponse response = await TransactionApi.ListTransactions("*", count); if (!response.HasError) { List <Payment> result = response.GetResult <List <Payment> >(); if (result != null && result.Count > 0) { command.Out.WriteLine("recent transaction record blow:"); foreach (var item in result) { //time(需要转换为DataTime), comment, amount string time = new DateTime(1970, 1, 1).AddMilliseconds(item.Time).ToString("yyyy-MM-dd HH:mm:ss"); command.Out.WriteLine($"Time:{time}; Comment:{item.Comment}; Amount:{item.Amount}"); } } else { command.Out.WriteLine("no recent transaction record."); } } } else { command.ShowHelp(); } } else { Program program = new Program(); BlockChainStatus chainStatus = await program.GetChainStatus(); if (chainStatus == null) { app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain"); return; } ApiResponse response = await TransactionApi.ListTransactions(); if (!response.HasError) { List <Payment> result = response.GetResult <List <Payment> >(); if (result != null && result.Count > 0) { command.Out.WriteLine("recent transaction record blow:"); foreach (var item in result) { //time(需要转换为DataTime), comment, amount string time = new DateTime(1970, 1, 1).AddMilliseconds(item.Time).ToString("yyyy-MM-dd HH:mm:ss"); command.Out.WriteLine($"Time:{time}; Comment:{item.Comment}; Amount:{item.Amount}"); } } else { command.Out.WriteLine("no recent transaction record."); } } } }); }); /* * if (args.Length > 1 && args[0].ToLower() == "fiiipay" && IsContainsCommand(args[1])) * { * List<string> list = new List<string>(args); * list.RemoveAt(0); * app.Execute(list.ToArray()); * } */ if (args != null && args.Length > 0 && IsContainsCommand(args[0])) { app.Execute(args); } else { app.Execute(new[] { "-?" }); } }
public static async Task MiningAsync(string minerName, string walletAddress) { while (true) { try { Console.WriteLine("new mining start"); bool isStop = false; bool isHeightChanged = false; ApiResponse response = await BlockChainEngineApi.GenerateNewBlock(minerName, walletAddress, 1); if (!response.HasError) { BlockInfoOM block = response.GetResult <BlockInfoOM>(); List <byte> blockData = new List <byte>(); foreach (BlockTransactionsOM tx in block.Transactions) { blockData.AddRange(tx.Serialize()); } string strDifficulty = string.Empty; ApiResponse difficultyResponse = await BlockChainEngineApi.GetDifficulty(); if (!difficultyResponse.HasError) { BlockDifficultyOM blockDifficulty = difficultyResponse.GetResult <BlockDifficultyOM>(); strDifficulty = blockDifficulty.HashTarget; } else { Logger.Singleton.Error(difficultyResponse.Error.Code.ToString()); Logger.Singleton.Error(difficultyResponse.Error.Message); Console.WriteLine(response.Error.Message); return; } //var cts = new CancellationTokenSource(); //var ct = cts.Token; //开启新线程 /* * Task task1 = Task.Run(async () => * { * try * { * Console.WriteLine("new thread validate block height"); * int count = 0; * while (!isStop) * { * ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); * if (!tempResponse.HasError) * { * count = 0; * Logger.Singleton.Info($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); * long height = tempResponse.GetResult<long>(); * Console.WriteLine($"current height of the chain is {height}"); * if (height >= block.Header.Height) * { * isStop = true; * isHeightChanged = true; * ct.ThrowIfCancellationRequested(); * cts.Cancel(); * } * } * else * { * count++; * Logger.Singleton.Warn($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); * if (count >= 5) * { * Logger.Singleton.Error(tempResponse.Error.Code.ToString()); * Logger.Singleton.Error(tempResponse.Error.Message); * isStop = true; * ct.ThrowIfCancellationRequested(); * cts.Cancel(); * } * } * * Console.WriteLine("thread will sleep 5 seconds"); * Thread.Sleep(3000); * } * } * catch (Exception ex) * { * cts.Cancel(); * Console.WriteLine($"something wrong with the application interface, {ex.ToString()}"); * isStop = true; * } * }, ct); */ Thread checkHeightThread = new Thread(async() => { try { Console.WriteLine("new thread validate block height"); int count = 0; while (!isStop) { ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); if (!tempResponse.HasError) { count = 0; //Logger.Singleton.Info($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); long height = tempResponse.GetResult <long>(); Console.WriteLine($"current height of the chain is {height}"); if (height >= block.Header.Height) { isStop = true; isHeightChanged = true; //ct.ThrowIfCancellationRequested(); //cts.Cancel(); } } else { count++; Logger.Singleton.Warn($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); if (count >= 3) { Logger.Singleton.Error(tempResponse.Error.Code.ToString()); Logger.Singleton.Error(tempResponse.Error.Message); isStop = true; //ct.ThrowIfCancellationRequested(); //cts.Cancel(); } } Console.WriteLine("thread will sleep 5 seconds"); Thread.Sleep(3000); } } catch (Exception ex) { //cts.Cancel(); Console.WriteLine($"something wrong with the application interface, {ex.ToString()}"); isStop = true; } }); checkHeightThread.Priority = ThreadPriority.Highest; checkHeightThread.Start(); Parallel.For(0L, Int64.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = 10 }, async(i, loopState) => { if (isStop) { Console.WriteLine($"new thread has been stopped, stop main thread"); loopState.Stop(); return; } List <byte> newBuffer = new List <byte>(blockData.ToArray()); byte[] nonceBytes = BitConverter.GetBytes(i); if (BitConverter.IsLittleEndian) { Array.Reverse(nonceBytes); } newBuffer.AddRange(nonceBytes); string result = Base16.Encode( HashHelper.Hash( newBuffer.ToArray() )); Console.WriteLine($"current nonce is {i}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); if (BlockInfoOM.Verify(strDifficulty, result)) { loopState.Stop(); //区块头的时间戳 block.Header.Timestamp = TimeHelper.EpochTime; //区块头的随机数 block.Header.Nonce = i; //区块头的hash block.Header.Hash = block.Header.GetHash(); //提交区块 Console.WriteLine($"verify success. nonce is {i}, block hash is {block.Header.Hash}"); ApiResponse submitResponse = await BlockChainEngineApi.SubmitBlock(Base16.Encode(block.Serialize())); if (!submitResponse.HasError) { //停止循环 //break; Logger.Singleton.Debug("A New Block " + block.Header.Height + "has been created, the correct nonce is " + i); } else { Console.WriteLine(submitResponse.Error.Message); Console.WriteLine(submitResponse.Error.Code.ToString()); if (submitResponse.Error.Code == 2060001) { isStop = true; isHeightChanged = true; } else { Environment.Exit(0); } } } }); if (isStop) { if (isHeightChanged) { Console.WriteLine("block height changed, new loop will start"); continue; } else { Console.WriteLine("something wrong with the application interface, system exit"); Environment.Exit(0); return; } } } else { Logger.Singleton.Error(response.Error.Code.ToString()); Logger.Singleton.Error(response.Error.Message); Console.WriteLine(response.Error.Message); Environment.Exit(0); return; } } catch (Exception ex) { Logger.Singleton.Error(ex.ToString()); Logger.Singleton.Error(ex.ToString()); Environment.Exit(0); return; } } }
public async Task SubmitBlock() { ApiResponse response = await BlockChainEngineApi.SubmitBlock("1234567890ABCDEF"); Assert.IsFalse(response.HasError); }
public async Task BlockMining() { bool isStop = false; ApiResponse response = await BlockChainEngineApi.GenerateNewBlock("Zhangsan", "", 1); if (!response.HasError) { BlockInfoOM block = response.GetResult <BlockInfoOM>(); List <byte> blockData = new List <byte>(); foreach (BlockTransactionsOM tx in block.Transactions) { blockData.AddRange(tx.Serialize()); } string strDifficulty = string.Empty; //long blockHeight = 0; ApiResponse difficultyResponse = await BlockChainEngineApi.GetDifficulty(); if (!difficultyResponse.HasError) { BlockDifficultyOM blockDifficulty = difficultyResponse.GetResult <BlockDifficultyOM>(); strDifficulty = blockDifficulty.HashTarget; } //ApiResponse heightResponse = await BlockChainEngineApi.GetBlockCount(); //if (!heightResponse.HasError) //{ // blockHeight = heightResponse.GetResult<long>(); //} var cts = new CancellationTokenSource(); var ct = cts.Token; //开启新线程 Task task1 = Task.Run(async() => { Console.WriteLine("New Task Start"); while (!isStop) { Console.WriteLine("Loop is start"); ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); if (!tempResponse.HasError) { long height = tempResponse.GetResult <long>(); if (height >= block.Header.Height) { isStop = true; cts.Cancel(); } } Console.WriteLine("I will sleep 5000 millseconds"); Thread.Sleep(5000); } }, ct); Parallel.For(0L, Int64.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = 2 }, async(i, loopState) => { Console.WriteLine("Parallel start"); //根据BlockData初始化一个List<byte> List <byte> newBuffer = new List <byte>(blockData.ToArray()); //获取随机的64位数的字节 byte[] nonceBytes = BitConverter.GetBytes(i); //存储在此计算机体系结构中的字节顺序 if (BitConverter.IsLittleEndian) { //翻转整个byte[]顺序 Array.Reverse(nonceBytes); } //随机数添加到List<byte>的末尾 newBuffer.AddRange(nonceBytes); //List<byte>转化为byte[]数组先Hash后Base16编码 string result = Base16.Encode( HashHelper.Hash( newBuffer.ToArray() )); Console.WriteLine("begin verify data"); //block头验证,校验不成功,继续循环 if (BlockInfoOM.Verify(strDifficulty, result)) { Console.WriteLine("Verify success"); //区块头的时间戳 block.Header.Timestamp = TimeHelper.EpochTime; //区块头的随机数 block.Header.Nonce = i; //区块头的hash block.Header.Hash = block.Header.GetHash(); //提交区块 ApiResponse submitResponse = await BlockChainEngineApi.SubmitBlock(Base16.Encode(block.Serialize())); if (!submitResponse.HasError) { //停止循环 loopState.Stop(); Logger.Singleton.Debug("A New Block " + block.Header.Height + "has been created, the correct nonce is " + i); } } if (isStop) { ct.ThrowIfCancellationRequested(); cts.Cancel(); await BlockMining(); } }); } }