public LyraTokenGenesisBlock CreateLyraTokenGenesisBlock(ServiceBlock svcGen) { var openTokenGenesisBlock = new LyraTokenGenesisBlock { Height = 1, AccountType = AccountTypes.Standard, Ticker = LyraGlobal.OFFICIALTICKERCODE, DomainName = LyraGlobal.OFFICIALDOMAIN, ContractType = ContractTypes.Cryptocurrency, Description = LyraGlobal.PRODUCTNAME + " Gas Token", Precision = LyraGlobal.OFFICIALTICKERPRECISION, IsFinalSupply = true, AccountID = _sys.PosWallet.AccountId, Balances = new Dictionary <string, long>(), PreviousHash = svcGen.Hash, ServiceHash = svcGen.Hash, Fee = svcGen.TokenGenerationFee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.Regular, RenewalDate = DateTime.UtcNow.AddYears(100) }; var transaction = new TransactionInfo() { TokenCode = openTokenGenesisBlock.Ticker, Amount = LyraGlobal.OFFICIALGENESISAMOUNT }; openTokenGenesisBlock.Balances.Add(transaction.TokenCode, transaction.Amount.ToBalanceLong()); // This is current supply in atomic units (1,000,000.00) openTokenGenesisBlock.InitializeBlock(null, _sys.PosWallet.PrivateKey, AccountId: _sys.PosWallet.AccountId); return(openTokenGenesisBlock); }
public ConsolidationBlock CreateConsolidationGenesisBlock(ServiceBlock svcGen, LyraTokenGenesisBlock lyraGen, PoolFactoryBlock pf) { var consBlock = new ConsolidationBlock { createdBy = ProtocolSettings.Default.StandbyValidators[0], blockHashes = new List <string>() { svcGen.Hash, lyraGen.Hash, pf.Hash }, totalBlockCount = 3 // not including self }; consBlock.TimeStamp = DateTime.UtcNow.AddSeconds(-18); var mt = new MerkleTree(); mt.AppendLeaf(MerkleHash.Create(svcGen.Hash)); mt.AppendLeaf(MerkleHash.Create(lyraGen.Hash)); mt.AppendLeaf(MerkleHash.Create(pf.Hash)); consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.ServiceHash = svcGen.Hash; consBlock.totalFees = lyraGen.Fee.ToBalanceLong(); consBlock.InitializeBlock(null, _sys.PosWallet.PrivateKey, _sys.PosWallet.AccountId); return(consBlock); }
public LyraTokenGenesisBlock GetLyraTokenGenesisBlock(ServiceBlock svcGen) { // initiate test coins var openTokenGenesisBlock = new LyraTokenGenesisBlock { Height = 1, AccountType = AccountTypes.Standard, Ticker = LyraGlobal.LYRATICKERCODE, DomainName = "Lyra", ContractType = ContractTypes.Cryptocurrency, Description = "Lyra Permissioned Gas Token", Precision = LyraGlobal.LYRAPRECISION, IsFinalSupply = true, AccountID = NodeService.Instance.PosWallet.AccountId, Balances = new Dictionary <string, decimal>(), PreviousHash = svcGen.Hash, ServiceHash = svcGen.Hash, Fee = svcGen.TokenGenerationFee, FeeType = AuthorizationFeeTypes.Regular, Icon = "https://i.imgur.com/L3h0J1K.png", Image = "https://i.imgur.com/B8l4ZG5.png", RenewalDate = DateTime.Now.AddYears(1000) }; var transaction = new TransactionInfo() { TokenCode = openTokenGenesisBlock.Ticker, Amount = LyraGlobal.LYRAGENESISAMOUNT }; openTokenGenesisBlock.Balances.Add(transaction.TokenCode, transaction.Amount); // This is current supply in atomic units (1,000,000.00) openTokenGenesisBlock.InitializeBlock(null, NodeService.Instance.PosWallet.PrivateKey, AccountId: NodeService.Instance.PosWallet.AccountId); return(openTokenGenesisBlock); }
public FeesState(bool isLoading, FeeStats stats, ServiceBlock view, List <Voter> voters) { IsLoading = isLoading; Stats = stats; View = view; Voters = voters; }
public async Task <APIResultCodes> ReceiveAsync() { var blockresult = await _rpcClient.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return(blockresult.ResultCode); } ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; //TransferFee = lastServiceBlock.TransferFee; //TokenGenerationFee = lastServiceBlock.TokenGenerationFee; //TradeFee = lastServiceBlock.TradeFee; try { var lookup_result = await _rpcClient.LookForNewTransferAsync(_accountId, _signer(lastServiceBlock.Hash)); int max_counter = 0; while (lookup_result.Successful() && max_counter < 100) // we don't want to enter an endless loop... { max_counter++; //PrintConLine($"Received new transaction, sending request for settlement..."); var receive_result = await ReceiveTransfer(lookup_result); if (!receive_result.Successful()) { return(receive_result.ResultCode); } lookup_result = await _rpcClient.LookForNewTransferAsync(_accountId, _signer(lastServiceBlock.Hash)); } // the fact that do one sent us any money does not mean this call failed... if (lookup_result.ResultCode == APIResultCodes.NoNewTransferFound) { return(APIResultCodes.Success); } if (lookup_result.ResultCode == APIResultCodes.AccountAlreadyImported) { //PrintConLine($"This account was imported (merged) to another account."); //AccountAlreadyImported = true; return(lookup_result.ResultCode); } return(lookup_result.ResultCode); } catch (Exception e) { //PrintConLine("Exception in SyncIncomingTransfers(): " + e.Message); return(APIResultCodes.UnknownError); } }
public async Task <ServiceBlock> CreateServiceGenesisBlockAsync() { var svcGenesis = new ServiceBlock { NetworkId = Settings.Default.LyraNode.Lyra.NetworkId, Leader = ProtocolSettings.Default.StandbyValidators[0], Height = 1, FeeTicker = LyraGlobal.OFFICIALTICKERCODE, TransferFee = 1, //zero for genesis. back to normal when genesis done TokenGenerationFee = 10000, TradeFee = 0.1m, FeesGenerated = 0 }; // wait for all nodes ready // for unit test if (_localNode == null) // unit test code { svcGenesis.Authorizers = new Dictionary <string, string>(); foreach (var pn in ProtocolSettings.Default.StandbyValidators) { svcGenesis.Authorizers.Add(pn, pn); } } else { while (true) { svcGenesis.Authorizers = new Dictionary <string, string>(); foreach (var pn in ProtocolSettings.Default.StandbyValidators) { if (!_board.ActiveNodes.Any(a => a.AccountID == pn)) { break; } svcGenesis.Authorizers.Add(pn, _board.ActiveNodes.First(a => a.AccountID == pn).AuthorizerSignature); } if (svcGenesis.Authorizers.Count >= LyraGlobal.MINIMUM_AUTHORIZERS) { break; } else { _log.LogInformation($"Waiting for seed nodes to up. Now we have {svcGenesis.Authorizers.Count} of {LyraGlobal.MINIMUM_AUTHORIZERS}"); await Task.Delay(1000); } } } svcGenesis.TimeStamp = DateTime.UtcNow; svcGenesis.InitializeBlock(null, _sys.PosWallet.PrivateKey, _sys.PosWallet.AccountId); return(svcGenesis); }
void client_GetServiceBlockCompleted(object sender, GetServiceBlockCompletedEventArgs e) { ServiceBlock SBlock = e.Result; TextBlock tblock = new TextBlock(); tblock.Text = SBlock.name; tblock.DataContext = SBlock; ((ListBox)((StackPanel)ChoseService.Child).Children.First()).Items.Add(tblock); }
public async Task <ServiceBlock> CreateNewViewAsNewLeaderAsync() { var prevSvcBlock = await _sys.Storage.GetLastServiceBlockAsync(); var svcBlock = new ServiceBlock { NetworkId = prevSvcBlock.NetworkId, Height = prevSvcBlock.Height + 1, FeeTicker = LyraGlobal.OFFICIALTICKERCODE, ServiceHash = prevSvcBlock.Hash, Leader = _board.LeaderCandidate, TransferFee = 1, //zero for genesis. back to normal when genesis done TokenGenerationFee = 10000, TradeFee = 0.1m }; _log.LogInformation($"Adding {_board.AllVoters.Count()} voters..."); svcBlock.Authorizers = new Dictionary <string, string>(); var signAgainst = prevSvcBlock?.Hash ?? ProtocolSettings.Default.StandbyValidators[0]; foreach (var voter in _board.AllVoters) { var node = _board.ActiveNodes.FirstOrDefault(a => a.AccountID == voter); if (node != null && Signatures.VerifyAccountSignature(signAgainst, node.AccountID, node.AuthorizerSignature)) { svcBlock.Authorizers.Add(node.AccountID, node.AuthorizerSignature); } } // unite test only if (Settings.Default.LyraNode.Lyra.NetworkId == "xtest") { svcBlock.Authorizers.Add(_board.CurrentLeader, null); } // fees aggregation _log.LogInformation($"Fee aggregating..."); var allConsBlocks = await _sys.Storage.GetConsolidationBlocksAsync(prevSvcBlock.Hash); svcBlock.FeesGenerated = allConsBlocks.Sum(a => a.totalFees); svcBlock.InitializeBlock(prevSvcBlock, _sys.PosWallet.PrivateKey, _sys.PosWallet.AccountId); return(svcBlock); }
private static BenefitingBlock CreateBenefiting(TransactionBlock lastPft, ServiceBlock sb, Staker target, string relatedTx, decimal amount ) { Console.WriteLine("CR Dividend: CreateBenefiting"); var pftSend = new BenefitingBlock { Height = lastPft.Height + 1, Name = ((IBrokerAccount)lastPft).Name, OwnerAccountId = ((IBrokerAccount)lastPft).OwnerAccountId, AccountID = lastPft.AccountID, Balances = new Dictionary <string, long>(), PreviousHash = lastPft.Hash, ServiceHash = sb.Hash, Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, DestinationAccountId = target.CompoundMode ? target.StkAccount : target.OwnerAccount, // profit specified config PType = ((IProfiting)lastPft).PType, ShareRito = ((IProfiting)lastPft).ShareRito, Seats = ((IProfiting)lastPft).Seats, RelatedTx = relatedTx, StakingAccountId = target.StkAccount }; //TODO: think about multiple token var lastBalance = lastPft.Balances[LyraGlobal.OFFICIALTICKERCODE]; lastBalance -= amount.ToBalanceLong(); pftSend.Balances.Add(LyraGlobal.OFFICIALTICKERCODE, lastBalance); pftSend.AddTag(Block.MANAGEDTAG, ""); // value is always ignored // pool blocks are service block so all service block signed by leader node pftSend.InitializeBlock(lastPft, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); Console.WriteLine($"Benefiting {pftSend.DestinationAccountId.Shorten()} Index {pftSend.Height} who is staking {target.Amount} {amount} LYR hash: {pftSend.Hash} signed by {NodeService.Dag.PosWallet.AccountId.Shorten()}"); return(pftSend); }
public ServiceBlock GetServiceGenesisBlock() { var svcGenesis = new ServiceBlock { NetworkId = NetworkID, Height = 1, TransferFee = 0, //1, zero for genesis. back to normal when genesis done TokenGenerationFee = 0, //100, TradeFee = 0m //0.1m }; svcGenesis.Authorizers = new List <PosNode>(); foreach (var pn in ConsensusService.Board.AllNodes.Values.Where(a => ProtocolSettings.Default.StandbyValidators.Contains(a.AccountID))) { svcGenesis.Authorizers.Add(pn); } svcGenesis.InitializeBlock(null, NodeService.Instance.PosWallet.PrivateKey, NodeService.Instance.PosWallet.AccountId); return(svcGenesis); }
/// <summary> /// сохранение сервисного блока /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Save_Click(object sender, RoutedEventArgs e) { if (ServiceBlockId == null) { MessageBox.Show("Блин, а как же сервисный блок?"); } else { ServiceBlock SBlockToSave = new ServiceBlock(); SBlockToSave.id = ServiceBlockId; SBlockToSave.blocks = new ObservableCollection <Block>(); foreach (var node in Nodes) { node.Datablock.isVerification = node.IsRoot; node.Datablock.links = node.GetDataLinks(); SBlockToSave.blocks.Add(node.Datablock); } client.SaveServiceBlockAsync(SBlockToSave); } }
public ConsolidationBlock GetConsolidationGenesisBlock(ServiceBlock svcGen, LyraTokenGenesisBlock lyraGen) { var consBlock = new ConsolidationBlock { blockHashes = new List <string>() { svcGen.Hash, lyraGen.Hash }, totalBlockCount = 2 // not including self }; var mt = new MerkleTree(); mt.AppendLeaf(MerkleHash.Create(svcGen.Hash)); mt.AppendLeaf(MerkleHash.Create(lyraGen.Hash)); consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.ServiceHash = svcGen.Hash; consBlock.InitializeBlock(null, NodeService.Instance.PosWallet.PrivateKey, NodeService.Instance.PosWallet.AccountId); return(consBlock); }
private void b_Click(object sender, RoutedEventArgs e) { if (((ListBox)((StackPanel)ChoseService.Child).Children.First()).SelectedItem == null) { return; } WorkPlace.Children.Clear(); Nodes.Clear(); ServiceBlock ChosenServiceBlock = ((TextBlock)((ListBox)((StackPanel)ChoseService.Child).Children.First()).SelectedItem).DataContext as ServiceBlock; ServiceBlockId = ChosenServiceBlock.id; ChoseService.IsOpen = false; foreach (var item in ChosenServiceBlock.blocks) { Page node = new Page(item, 0, 0); node.MouseLeftButtonDown += new MouseButtonEventHandler(node_MouseLeftButtonDown); node.MouseLeftButtonUp += new MouseButtonEventHandler(node_MouseLeftButtonUp); node.MouseMove += new MouseEventHandler(node_MouseMove); node.MouseRightButtonDown += new MouseButtonEventHandler(node_MouseRightButtonDown); WorkPlace.Children.Add(node); if (item.isVerification) { node.IsRoot = true; } Nodes.Add(node); } foreach (var node in Nodes) { node.DrawLinks(Nodes); } DrawTree(); }
public async Task <APIResultCodes> SendAsync(decimal Amount, string destAccount, string ticker = LyraGlobal.OFFICIALTICKERCODE) { if (Amount <= 0) { throw new Exception("Amount must > 0"); } TransactionBlock previousBlock = await GetLatestBlockAsync(); if (previousBlock == null) { throw new Exception("No balance"); } var blockresult = await _node.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return(blockresult.ResultCode); } ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; //long atomicamount = (long)(Amount * (decimal)Math.Pow(10, precision)); var balance_change = Amount; //var transaction = new TransactionInfo() { TokenCode = ticker, Amount = atomicamount }; var fee = lastServiceBlock.TransferFee; if (ticker == LyraGlobal.OFFICIALTICKERCODE) { balance_change += fee; } // see if we have enough tokens if (previousBlock.Balances[ticker] < balance_change.ToBalanceLong()) { return(APIResultCodes.InsufficientFunds); //throw new Exception("Insufficient funds"); } // see if we have enough LYR to pay the transfer fee if (ticker != LyraGlobal.OFFICIALTICKERCODE) { if (!previousBlock.Balances.ContainsKey(LyraGlobal.OFFICIALTICKERCODE) || previousBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] < fee.ToBalanceLong()) { //throw new Exception("Insufficient funds to pay transfer fee"); return(APIResultCodes.InsufficientFunds); } } SendTransferBlock sendBlock; sendBlock = new SendTransferBlock() { AccountID = _accountId, VoteFor = previousBlock.VoteFor, ServiceHash = lastServiceBlock.Hash, DestinationAccountId = destAccount, Balances = new Dictionary <string, long>(), //PaymentID = string.Empty, Fee = fee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = fee == 0m ? AuthorizationFeeTypes.NoFee : AuthorizationFeeTypes.Regular }; sendBlock.Balances.Add(ticker, previousBlock.Balances[ticker] - balance_change.ToBalanceLong()); //sendBlock.Transaction = transaction; // for customer tokens, we pay fee in LYR (unless they are accepted by authorizers as a fee - TO DO) if (ticker != LyraGlobal.OFFICIALTICKERCODE) { sendBlock.Balances.Add(LyraGlobal.OFFICIALTICKERCODE, previousBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] - fee.ToBalanceLong()); } // transfer unchanged token balances from the previous block foreach (var balance in previousBlock.Balances) { if (!(sendBlock.Balances.ContainsKey(balance.Key))) { sendBlock.Balances.Add(balance.Key, balance.Value); } } await sendBlock.InitializeBlockAsync(previousBlock, _signer); if (!sendBlock.ValidateTransaction(previousBlock)) { return(APIResultCodes.SendTransactionValidationFailed); //throw new Exception("ValidateTransaction failed"); } //sendBlock.Signature = Signatures.GetSignature(PrivateKey, sendBlock.Hash); AuthorizationAPIResult result; //var stopwatch = Stopwatch.StartNew(); result = await _trans.SendTransferAsync(sendBlock); //stopwatch.Stop(); //PrintConLine($"_node.SendTransfer: {stopwatch.ElapsedMilliseconds} ms."); if (result.ResultCode == APIResultCodes.Success) { LastBlock = sendBlock; } else { LastBlock = null; } return(result.ResultCode); }
public FeesResultAction(FeeStats stats, ServiceBlock view, List <Voter> voters) { this.stats = stats; this.view = view; this.voters = voters; }
public void AuthorizerCountChanged(int count) { if (ConsensusService.IsThisNodeSeed0 && count >= ProtocolSettings.Default.StandbyValidators.Length) { //_log.LogInformation($"AuthorizerCountChanged: {count}"); // look for changes. if necessary create a new svc block. Task.Run(async() => { if (!_creatingSvcBlock) { _creatingSvcBlock = true; try { var prevSvcBlock = await GetLastServiceBlockAsync(); if (prevSvcBlock != null && DateTime.UtcNow - prevSvcBlock.TimeStamp > TimeSpan.FromMinutes(1)) { var comp = new MultiSetComparer <string>(); if (!comp.Equals(prevSvcBlock.Authorizers.Select(a => a.AccountID), ConsensusService.Board.PrimaryAuthorizers)) { _log.LogInformation($"PrimaryAuthorizers Changed: {count} Creating new ServiceBlock."); var svcBlock = new ServiceBlock { NetworkId = prevSvcBlock.NetworkId, Height = prevSvcBlock.Height + 1, ServiceHash = prevSvcBlock.Hash, TransferFee = 1, //zero for genesis. back to normal when genesis done TokenGenerationFee = 100, TradeFee = 0.1m }; svcBlock.Authorizers = new List <PosNode>(); foreach (var accId in ConsensusService.Board.PrimaryAuthorizers) { if (ConsensusService.Board.AllNodes.ContainsKey(accId)) { svcBlock.Authorizers.Add(ConsensusService.Board.AllNodes[accId]); } if (svcBlock.Authorizers.Count() >= LyraGlobal.MAXMIMUMAUTHORIZERS) { break; } } if (svcBlock.Authorizers.Count() >= prevSvcBlock.Authorizers.Count()) { svcBlock.InitializeBlock(prevSvcBlock, NodeService.Instance.PosWallet.PrivateKey, NodeService.Instance.PosWallet.AccountId); await SendBlockToConsensusAsync(svcBlock); } else { _log.LogError($"Authorizers count can't be less than {prevSvcBlock.Authorizers.Count()}"); } } } } finally { await Task.Delay(10000); _creatingSvcBlock = false; } } }); } }
public void SetView(ServiceBlock serviceBlock) { _serviceBlock = serviceBlock; }
private void StartInit() { if (0 == GetBlockCount() && NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[0]) { // do genesis var authGenesis = new ServiceBlock { Index = 1, UIndex = 1, NetworkId = _nodeConfig.Lyra.NetworkId, ShardId = "Primary", TransferFee = 1, TokenGenerationFee = 100, TradeFee = 0.1m, SvcAccountID = NodeService.Instance.PosWallet.AccountId }; authGenesis.InitializeBlock(null, NodeService.Instance.PosWallet.PrivateKey, _nodeConfig.Lyra.NetworkId, authGenesis.ShardId, NodeService.Instance.PosWallet.AccountId); authGenesis.UHash = SignableObject.CalculateHash($"{authGenesis.UIndex}|{authGenesis.Index}|{authGenesis.Hash}"); authGenesis.Authorizations = new List <AuthorizationSignature>(); authGenesis.Authorizations.Add(new AuthorizationSignature { Key = NodeService.Instance.PosWallet.AccountId, Signature = Signatures.GetSignature(NodeService.Instance.PosWallet.PrivateKey, authGenesis.Hash, NodeService.Instance.PosWallet.AccountId) }); // TODO: add more seed's auth info _store.AddBlock(authGenesis); // the first consolidate block var consBlock = new ConsolidationBlock { UIndex = 2, NetworkId = authGenesis.NetworkId, ShardId = authGenesis.ShardId, ServiceHash = authGenesis.Hash, SvcAccountID = NodeService.Instance.PosWallet.AccountId }; consBlock.InitializeBlock(authGenesis, NodeService.Instance.PosWallet.PrivateKey, _nodeConfig.Lyra.NetworkId, authGenesis.ShardId, NodeService.Instance.PosWallet.AccountId); consBlock.UHash = SignableObject.CalculateHash($"{consBlock.UIndex}|{consBlock.Index}|{consBlock.Hash}"); consBlock.Authorizations = new List <AuthorizationSignature>(); consBlock.Authorizations.Add(new AuthorizationSignature { Key = NodeService.Instance.PosWallet.AccountId, Signature = Signatures.GetSignature(NodeService.Instance.PosWallet.PrivateKey, consBlock.Hash + consBlock.ServiceHash, NodeService.Instance.PosWallet.AccountId) }); _store.AddBlock(consBlock); // tell consensus what happened InSyncing = false; var board = new BillBoard(); board.Add(NodeService.Instance.PosWallet.AccountId); // add me! LyraSystem.Singleton.Consensus.Tell(board); LyraSystem.Singleton.Consensus.Tell(new ConsensusService.BlockChainSynced()); _log.LogInformation("Service Genesis Completed."); } else { SyncBlocksFromSeeds(0); } }
public void AddBlock(ServiceBlock serviceBlock) => _store.AddBlock(serviceBlock);
public async Task <AuthorizationAPIResult> SendExAsync(string DestinationAccountId, Dictionary <string, decimal> Amounts, Dictionary <string, string> tags) { if (Amounts.Any(a => a.Value <= 0m)) { throw new Exception("Amount must > 0"); } TransactionBlock previousBlock = await GetLatestBlockAsync(); if (previousBlock == null) { //throw new Exception("Previous block not found"); return(new AuthorizationAPIResult() { ResultCode = APIResultCodes.PreviousBlockNotFound }); } // check tokens exists if (Amounts.Keys.Any(a => !previousBlock.Balances.ContainsKey(a))) { return(new AuthorizationAPIResult() { ResultCode = APIResultCodes.TokenGenesisBlockNotFound }); } var blockresult = await _node.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return new AuthorizationAPIResult() { ResultCode = blockresult.ResultCode } } ; ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; var fee = lastServiceBlock.TransferFee; SendTransferBlock sendBlock = new SendTransferBlock() { AccountID = AccountId, VoteFor = previousBlock.VoteFor, ServiceHash = lastServiceBlock.Hash, DestinationAccountId = DestinationAccountId, Balances = new Dictionary <string, long>(), Tags = tags, Fee = fee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = fee == 0m ? AuthorizationFeeTypes.NoFee : AuthorizationFeeTypes.Regular }; // transfer unchanged token balances from the previous block foreach (var balance in previousBlock.Balances) { if (Amounts.ContainsKey(balance.Key)) { sendBlock.Balances.Add(balance.Key, (balance.Value.ToBalanceDecimal() - Amounts[balance.Key]).ToBalanceLong()); } else { sendBlock.Balances.Add(balance.Key, balance.Value); } } // substract the fee // for customer tokens, we pay fee in LYR (unless they are accepted by authorizers as a fee - TO DO) sendBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] = (sendBlock.Balances[LyraGlobal.OFFICIALTICKERCODE].ToBalanceDecimal() - fee).ToBalanceLong(); await sendBlock.InitializeBlockAsync(previousBlock, _signer); if (!sendBlock.ValidateTransaction(previousBlock)) { return(new AuthorizationAPIResult() { ResultCode = APIResultCodes.SendTransactionValidationFailed }); //throw new Exception("ValidateTransaction failed"); } //sendBlock.Signature = Signatures.GetSignature(PrivateKey, sendBlock.Hash); AuthorizationAPIResult result; //var stopwatch = Stopwatch.StartNew(); result = await _trans.SendTransferAsync(sendBlock); if (result.ResultCode == APIResultCodes.Success) { LastBlock = sendBlock; } else { LastBlock = null; } return(result); }
public async Task AddBlockAsync(ServiceBlock serviceBlock) => await _store.AddBlockAsync(serviceBlock);
public async Task <APIResultCodes> SendAsync(decimal Amount, string destAccount, string ticker = LyraGlobal.OFFICIALTICKERCODE) { if (Amount <= 0) { throw new Exception("Amount must > 0"); } TransactionBlock previousBlock = await GetLatestBlockAsync(); if (previousBlock == null) { throw new Exception("No balance"); } var blockresult = await _rpcClient.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return(blockresult.ResultCode); } ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; //int precision = await FindTokenPrecision(ticker); //if (precision < 0) //{ // return new AuthorizationAPIResult() { ResultCode = APIResultCodes.TokenGenesisBlockNotFound }; //} //long atomicamount = (long)(Amount * (decimal)Math.Pow(10, precision)); var balance_change = Amount; //var transaction = new TransactionInfo() { TokenCode = ticker, Amount = atomicamount }; var fee = lastServiceBlock.TransferFee; if (ticker == LyraGlobal.OFFICIALTICKERCODE) { balance_change += fee; } // see if we have enough tokens if (previousBlock.Balances[ticker] < balance_change.ToBalanceLong()) { return(APIResultCodes.InsufficientFunds); //throw new ApplicationException("Insufficient funds"); } // see if we have enough LYR to pay the transfer fee if (ticker != LyraGlobal.OFFICIALTICKERCODE) { if (!previousBlock.Balances.ContainsKey(LyraGlobal.OFFICIALTICKERCODE) || previousBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] < fee.ToBalanceLong()) { //throw new ApplicationException("Insufficient funds to pay transfer fee"); return(APIResultCodes.InsufficientFunds); } } //var svcBlockResult = await _rpcClient.GetLastServiceBlock(AccountId, SignAPICallAsync()); //if (svcBlockResult.ResultCode != APIResultCodes.Success) //{ // throw new Exception("Unable to get latest service block."); //} SendTransferBlock sendBlock; sendBlock = new SendTransferBlock() { AccountID = _accountId, VoteFor = null, ServiceHash = lastServiceBlock.Hash, DestinationAccountId = destAccount, Balances = new Dictionary <string, long>(), //PaymentID = string.Empty, Fee = fee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = fee == 0m ? AuthorizationFeeTypes.NoFee : AuthorizationFeeTypes.Regular }; sendBlock.Balances.Add(ticker, previousBlock.Balances[ticker] - balance_change.ToBalanceLong()); //sendBlock.Transaction = transaction; // for customer tokens, we pay fee in LYR (unless they are accepted by authorizers as a fee - TO DO) if (ticker != LyraGlobal.OFFICIALTICKERCODE) { sendBlock.Balances.Add(LyraGlobal.OFFICIALTICKERCODE, previousBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] - fee.ToBalanceLong()); } // transfer unchanged token balances from the previous block foreach (var balance in previousBlock.Balances) { if (!(sendBlock.Balances.ContainsKey(balance.Key))) { sendBlock.Balances.Add(balance.Key, balance.Value); } } sendBlock.InitializeBlock(previousBlock, _signer); if (!sendBlock.ValidateTransaction(previousBlock)) { return(APIResultCodes.SendTransactionValidationFailed); //throw new ApplicationException("ValidateTransaction failed"); } AuthorizationAPIResult result; result = await _rpcClient.SendTransferAsync(sendBlock); if (result.ResultCode == APIResultCodes.Success) { LastTxHash = sendBlock.Hash; } else { LastTxHash = ""; } return(result.ResultCode); }
public async Task <AuthorizationAPIResult> CreateTokenAsync( string tokenName, string domainName, string description, sbyte precision, decimal supply, bool isFinalSupply, string owner, // shop name string address, // shop URL string currency, // USD ContractTypes contractType, // reward or discount or custom Dictionary <string, string> tags) { if (string.IsNullOrWhiteSpace(domainName)) { domainName = "Custom"; } string ticker = domainName + "/" + tokenName; var blockresult = await _node.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return new AuthorizationAPIResult() { ResultCode = blockresult.ResultCode } } ; ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; TransactionBlock latestBlock = await GetLatestBlockAsync(); if (latestBlock == null || latestBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] < lastServiceBlock.TokenGenerationFee.ToBalanceLong()) { //throw new Exception("Insufficent funds"); return(new AuthorizationAPIResult() { ResultCode = APIResultCodes.InsufficientFunds }); } var svcBlockResult = await _node.GetLastServiceBlockAsync(); if (svcBlockResult.ResultCode != APIResultCodes.Success) { throw new Exception("Unable to get latest service block."); } // initiate test coins TokenGenesisBlock tokenBlock = new TokenGenesisBlock { Ticker = ticker, DomainName = domainName, Description = description, Precision = precision, IsFinalSupply = isFinalSupply, //CustomFee = 0, //CustomFeeAccountId = string.Empty, AccountID = AccountId, Balances = new Dictionary <string, long>(), ServiceHash = svcBlockResult.GetBlock().Hash, Fee = lastServiceBlock.TokenGenerationFee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.Regular, Owner = owner, Address = address, Currency = currency, Tags = tags, RenewalDate = DateTime.UtcNow.Add(TimeSpan.FromDays(3650)), ContractType = contractType, VoteFor = latestBlock.VoteFor }; // TO DO - set service hash //var transaction = new TransactionInfo() { TokenCode = ticker, Amount = supply * (long)Math.Pow(10, precision) }; var transaction = new TransactionInfo() { TokenCode = ticker, Amount = supply }; tokenBlock.Balances.Add(transaction.TokenCode, transaction.Amount.ToBalanceLong()); // This is current supply in atomic units (1,000,000.00) tokenBlock.Balances.Add(LyraGlobal.OFFICIALTICKERCODE, latestBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] - lastServiceBlock.TokenGenerationFee.ToBalanceLong()); //tokenBlock.Transaction = transaction; // transfer unchanged token balances from the previous block foreach (var balance in latestBlock.Balances) { if (!(tokenBlock.Balances.ContainsKey(balance.Key))) { tokenBlock.Balances.Add(balance.Key, balance.Value); } } await tokenBlock.InitializeBlockAsync(latestBlock, _signer); //tokenBlock.Signature = Signatures.GetSignature(PrivateKey, tokenBlock.Hash); var result = await _trans.CreateTokenAsync(tokenBlock); if (result.ResultCode == APIResultCodes.Success) { LastBlock = tokenBlock; } else { LastBlock = null; } return(result); }
public ServiceBlockCoreTransaction(ServiceBlock serviceBlock, BlockProposalSignatures proposalSignatures, long accountId) : base(CoreTransactionTypes.ServiceBlock, accountId) { ServiceBlock = serviceBlock; ProposalSignatures = proposalSignatures; }
public async Task <APIResultCodes> SendAsync(Dictionary <string, decimal> Amounts, string destAccount) { if (Amounts.Any(a => a.Value <= 0)) { throw new Exception("Amount must > 0"); } TransactionBlock previousBlock = await GetLatestBlockAsync(); if (previousBlock == null) { return(APIResultCodes.InsufficientFunds); } if (Amounts.Any(a => !previousBlock.Balances.ContainsKey(a.Key) || previousBlock.Balances[a.Key].ToBalanceDecimal() < a.Value)) { return(APIResultCodes.InsufficientFunds); } var blockresult = await _rpcClient.GetLastServiceBlockAsync(); if (blockresult.ResultCode != APIResultCodes.Success) { return(blockresult.ResultCode); } ServiceBlock lastServiceBlock = blockresult.GetBlock() as ServiceBlock; var fee = lastServiceBlock.TransferFee; SendTransferBlock sendBlock; sendBlock = new SendTransferBlock() { AccountID = _accountId, VoteFor = null, ServiceHash = lastServiceBlock.Hash, DestinationAccountId = destAccount, Balances = new Dictionary <string, long>(), //PaymentID = string.Empty, Fee = fee, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = fee == 0m ? AuthorizationFeeTypes.NoFee : AuthorizationFeeTypes.Regular }; // transfer unchanged token balances from the previous block foreach (var balance in previousBlock.Balances) { if (Amounts.ContainsKey(balance.Key)) { sendBlock.Balances.Add(balance.Key, (balance.Value.ToBalanceDecimal() - Amounts[balance.Key]).ToBalanceLong()); } else { sendBlock.Balances.Add(balance.Key, balance.Value); } } // substract the fee sendBlock.Balances[LyraGlobal.OFFICIALTICKERCODE] = (sendBlock.Balances[LyraGlobal.OFFICIALTICKERCODE].ToBalanceDecimal() - fee).ToBalanceLong(); await sendBlock.InitializeBlockAsync(previousBlock, _signer); if (!sendBlock.ValidateTransaction(previousBlock)) { return(APIResultCodes.SendTransactionValidationFailed); //throw new Exception("ValidateTransaction failed"); } AuthorizationAPIResult result; result = await _rpcClient.SendTransferAsync(sendBlock); if (result.ResultCode == APIResultCodes.Success) { LastTxHash = sendBlock.Hash; } else { LastTxHash = ""; } return(result.ResultCode); }