public DataChain(int chainId, uint chainIndex, Node.Node node, CoreChain coreChain, ServiceChain serviceChain, ChainKeyStore keyStore, int attachementKey) : base(ChainType.Data, chainId, chainIndex, node) { _coreChain = coreChain; _serviceChain = serviceChain; Attachements = node.AttachementManager; ChainKeyIndex = keyStore.KeyIndex; ChainKey = keyStore.DecryptedKey; KeyStore = keyStore; AttachementKey = attachementKey; var endPoints = new HashSet <AvailableEndPoint>(); var chainInfo = _coreChain.GetChainInfo(ChainId); if (chainInfo != null) { var cep = chainInfo.GetPublicEndpoints(); foreach (var ep in cep) { var e = new Uri(ep); if (IsValidAvailableEndPoint(e)) { endPoints.Add(new AvailableEndPoint(e)); } } } AvailableEndpoints = new List <AvailableEndPoint>(endPoints); }
public ServiceChain(int chainId, Node.Node node, CoreChain coreChain, ChainKeyStore keyStore) : base(ChainType.Service, chainId, 0, node) { CoreChain = coreChain; var endPoints = new HashSet <AvailableEndPoint>(); _chainKeyIndex = keyStore.KeyIndex; _chainKey = keyStore.DecryptedKey; KeyStore = keyStore; var chainInfo = CoreChain.GetChainInfo(ChainId); if (chainInfo != null) { var cep = chainInfo.GetPublicEndpoints(); foreach (var ep in cep) { var e = new Uri(ep); if (IsValidAvailableEndPoint(e)) { endPoints.Add(new AvailableEndPoint(e)); } } } AvailableEndpoints = new List <AvailableEndPoint>(endPoints); }
public async Task <bool> SetChainAccount(ChainKeyStore account, string password) { if (await UnlockAccount(account, password, KeyStoreTypes.Chain)) { CurrentChainAccount = account; } return(account == null || CurrentCoreAccount != null); }
public GenesisBlockResult(CoreBlock block, BlockSignatures signature, Key networkPublicKey, ChainKeyStore voteKey, string votePassword, Dictionary <int, List <ServiceTransaction> > serviceTransactions) { Block = block; Signature = signature; NetworkPublicKey = networkPublicKey; NetworkVoteKey = voteKey; NetworkVotePassword = votePassword; ServiceTransactions = serviceTransactions; }
public async Task <KeyStore> StoreAccount(string name, PublicChainKey publicChainKey, Key key, string password) { return(await Task.Run(async() => { var keyStore = new ChainKeyStore(name, publicChainKey, key, password); await StoreAccount(keyStore); await keyStore.DecryptKeyAsync(password, false); return keyStore; })); }
public ChainKeyInfo(ChainKeyStore chainKeyStore, int attachementKey) { ChainKeyStore = chainKeyStore; AttachementKey = attachementKey; }
public static async Task UpdateChain(ChainKeyStore chainKey, string password, string chainName, string chainWebsite, WalletClient.ChainKey[] chainKeys, Uri[] endPoints, PurchaseInfo[] purchases, short[] revokedChainKeys, Uri[] revokedEndPoints, int[] revokedPurchases) { if (CurrentCoreAccount == null) { return; } HeleusClientResponse result = null; ChainInfo chainInfo = null; if (_busy) { result = new HeleusClientResponse(HeleusClientResultTypes.Busy); goto end; } _busy = true; try { await chainKey.DecryptKeyAsync(password, true); await Client.SetChainAccount(chainKey, password); } catch { result = new HeleusClientResponse(HeleusClientResultTypes.PasswordError); goto end; } try { var transaction = Client.NewChainUpdateTransaction(true); if (chainKeys != null) { foreach (var ck in chainKeys) { transaction.AddChainKey(ck.SignedPublicKey); } } if (endPoints != null) { foreach (var ep in endPoints) { transaction.AddPublicEndpoint(ep.AbsoluteUri); } } if (purchases != null) { foreach (var p in purchases) { transaction.AddPurchase(p); } } if (revokedChainKeys != null) { foreach (var key in revokedChainKeys) { transaction.RevokeChainKey(key); } } if (revokedEndPoints != null) { foreach (var ep in revokedEndPoints) { transaction.RemovePublicEndPoint(ep.AbsoluteUri); } } if (revokedPurchases != null) { foreach (var p in revokedPurchases) { transaction.RemovePurchase(p); } } transaction.UpdateChainName(chainName); transaction.UpdateChainWebsite(chainWebsite); if (!await Client.SetTargetChain(Protocol.CoreChainId)) { result = new HeleusClientResponse(HeleusClientResultTypes.EndpointConnectionError); goto end; } result = await Client.UpdateChain(transaction, chainKeys); if (result.TransactionResult == TransactionResultTypes.Ok) { chainInfo = (await Client.DownloadChainInfo((result.Transaction as ChainInfoOperation).ChainId)).Data; } } catch (Exception ex) { Log.IgnoreException(ex); } end: await UIApp.PubSub.PublishAsync(new ChainRegistrationEvent(result, chainInfo)); if (result.ResultType != HeleusClientResultTypes.Busy) { _busy = false; } }
public NodeConfiguration(NodeConfig nodeConfig, CoreKeyConfig coreKeyConfig, ChainConfig chainConfig) { try { if (!string.IsNullOrEmpty(nodeConfig.NodePrivateKey)) { LocaleNodePrivateKey = Key.Restore(nodeConfig.NodePrivateKey); if (LocaleNodePrivateKey.KeyType != Protocol.MessageKeyType) { Log.Warn("Stored node key has the wrong key type."); LocaleNodePrivateKey = null; } } } catch (Exception ex) { Log.Error("Stored node key is invalid."); Log.IgnoreException(ex); } if (LocaleNodePrivateKey == null) { Log.Trace("Generating new node key."); LocaleNodePrivateKey = Key.Generate(Protocol.MessageKeyType); nodeConfig.NodePrivateKey = LocaleNodePrivateKey.HexString; Config.Save(nodeConfig); } var beacons = new List <Uri>(); foreach (var beacon in nodeConfig.BeaconNodes) { if (!beacon.IsNullOrEmpty()) { beacons.Add(new Uri(beacon)); } } BeaconNodes = beacons; var trusted = new List <Hash>(); foreach (var nodeId in nodeConfig.TrustedNodeIds) { trusted.Add(Hash.Restore(nodeId)); } TrustedNodeIds = trusted; var autoConnect = new List <Uri>(); foreach (var endPoint in nodeConfig.AutoConnectNodes) { autoConnect.Add(new Uri(endPoint)); } AutoConnectNodes = autoConnect; var keyCollector = new NodeInfoKeyCollector(); if (coreKeyConfig != null) { try { var keyStore = KeyStore.Restore <ChainKeyStore>(coreKeyConfig.Key); keyStore.DecryptKeyAsync(coreKeyConfig.Password, true).Wait(); CoreKey = keyStore; var keyFlags = keyStore.Flags; keyCollector.AddNodeInfoKey(Protocol.CoreChainId, 0, keyStore.KeyIndex, keyFlags, keyStore.DecryptedKey); } catch (Exception ex) { Log.Error("Core vote key or password invalid."); Log.IgnoreException(ex); } } var chains = new List <ChainConfiguration>(); if (chainConfig != null && chainConfig.Chains.Count > 0) { try { foreach (var sc in chainConfig.Chains) { var chainKeys = new List <ChainConfiguration.ChainKeyInfo>(); foreach (var sk in sc.ChainKeys) { var chainKey = KeyStore.Restore <ChainKeyStore>(sk.ChainKey); try { chainKey.DecryptKeyAsync(sk.ChainKeyPassword, true).Wait(); } catch (Exception ex) { Log.Error($"Invalid chain key {chainKey.ChainId}/{chainKey.ChainIndex} password ({sc.Service})"); throw ex; } chainKeys.Add(new ChainConfiguration.ChainKeyInfo(chainKey, sk.AttachementKey)); var chainId = chainKey.ChainId; if (chainKey.ChainId > Protocol.CoreChainId) { var keyFlags = chainKey.Flags; keyCollector.AddNodeInfoKey(chainKey.ChainId, chainKey.ChainIndex, chainKey.KeyIndex, keyFlags, chainKey.DecryptedKey); } } chains.Add(new ChainConfiguration(chainKeys, sc.Service, sc.ServiceSearchPath, sc.ServiceConfig)); } } catch (Exception ex) { Log.Error($"Chain config key or password is invalid."); Log.IgnoreException(ex); } } ChainConfigurations = chains; EnableClientConnections = nodeConfig.Node.EnableClientConnections; if (!nodeConfig.NetworkPublicKey.IsNullOrWhiteSpace()) { NetworkPublicKey = Key.Restore(nodeConfig.NetworkPublicKey); Uri publicEndPoint = null; if (nodeConfig.Node.IsPublic && !string.IsNullOrWhiteSpace(nodeConfig.Node.PublicEndpoint)) { publicEndPoint = new Uri(nodeConfig.Node.PublicEndpoint); } LocaleNodeInfo = new NodeInfo(NetworkPublicKey, LocaleNodePrivateKey, publicEndPoint, keyCollector); } }
public static GenesisBlockResult Generate(Base.Storage storage) { (var networkKeyStore, var networkKey, _) = LoadCoreAccountKey(storage, "Network Account", "Heleus Core"); if (networkKeyStore == null) { networkKey = Key.Generate(KeyTypes.Ed25519); var networkPassword = Hex.ToString(Rand.NextSeed(32)); networkKeyStore = new CoreAccountKeyStore("Heleus Core Network Account", CoreAccount.NetworkAccountId, networkKey, networkPassword); SaveCoreAccountKey(storage, networkKeyStore, "Network Account", networkPassword, "Heleus Core"); } Console.WriteLine($"Heleus Core Network Account Key: {networkKey.PublicKey.HexString}."); var networkKeys = new List <NetworkKey>(); var networkChainKeys = new List <PublicChainKey>(); for (var i = 0; i < 3; i++) { var keyFlags = GetCoreKeyFlags(i); var keyName = $"Network {GetKeyName(keyFlags, true)}"; (var store, var key, var storePassword) = LoadKeyStore <ChainKeyStore>(storage, null, keyName, "Heleus Core"); if (store == null) { key = Key.Generate(KeyTypes.Ed25519); storePassword = Hex.ToString(Rand.NextSeed(32)); var publicChainKey = new PublicChainKey(keyFlags, CoreChain.CoreChainId, 0, 0, (short)i, key); store = new ChainKeyStore($"Heleus Core {keyName}", publicChainKey, key, storePassword); SaveKeyStore(storage, store, storePassword, null, keyName, "Heleus Core"); } Console.WriteLine($"Heleus Core {keyName}: {key.PublicKey.HexString}."); networkKeys.Add(new NetworkKey { Key = key, Password = storePassword, PublicKey = store.PublicChainKey, Store = store }); networkChainKeys.Add(store.PublicChainKey); } var timestamp = Time.Timestamp; timestamp = Protocol.GenesisTime; var coreOperations = new List <CoreOperation>(); var endPoints = new List <string>(); Console.WriteLine("Type the core chain name (default: Heleus Core)"); var name = Program.IsDebugging ? "Heleus Core" : Console.ReadLine(); if (string.IsNullOrWhiteSpace(name)) { name = "Heleus Core"; } Console.WriteLine($"Chain name: {name}"); Console.WriteLine("Type the core chain website (default: https://heleuscore.com)"); var website = Program.IsDebugging ? "https://heleuscore.com" : Console.ReadLine(); if (string.IsNullOrWhiteSpace(website)) { website = "https://heleuscore.com"; } Console.WriteLine($"Chain Website: {website}"); Console.WriteLine("Type the core chain endpoints. (none for none, default: https://heleusnode.heleuscore.com)"); while (true) { if (Program.IsDebugging) { var ips = GetLocalIPV4Addresss(); foreach (var ip in ips) { endPoints.Add($"http://{ip}:54321/"); } break; } var ep = Console.ReadLine(); if (string.IsNullOrWhiteSpace(ep)) { if (endPoints.Count == 0) { endPoints.Add("https://heleusnode.heleuscore.com"); } break; } if (ep.IsValdiUrl(false)) { Console.WriteLine($"Added endpoint {ep}"); endPoints.Add(ep); } if (ep == "none") { break; } } Console.WriteLine($"Chain Endpoints: {string.Join(", ", endPoints)}"); var useGenesisInfo = false; var useCoreChainEndpoint = false; if (storage.FileExists("genesisservices.txt")) { Console.WriteLine("Process genesisservices.txt [yes/no] (default: yes)"); var p = Program.IsDebugging ? "yes" : Console.ReadLine(); if (string.IsNullOrWhiteSpace(p) || p.ToLower() == "yes") { Console.WriteLine("Processing genesisservices.txt"); useGenesisInfo = true; if (endPoints.Count > 0) { Console.WriteLine("Use first core chain endpoint, not endpoint from genesisservices.txt [yes/no] (default: no)"); var p2 = Program.IsDebugging ? "yes" : Console.ReadLine()?.ToLower(); if (p2 == "yes") { useCoreChainEndpoint = true; Console.WriteLine($"Using endpoint {endPoints[0]} for all services from genesisservices.txt"); } } } } coreOperations.Add((ChainInfoOperation) new ChainInfoOperation(CoreChain.CoreChainId, CoreAccount.NetworkAccountId, name, website, timestamp, networkChainKeys, endPoints, new List <PurchaseInfo>()).UpdateOperationId(Operation.FirstTransactionId)); coreOperations.Add((AccountOperation) new AccountOperation(CoreAccount.NetworkAccountId, networkKey.PublicKey, timestamp).UpdateOperationId(coreOperations.Count + 1)); // network account coreOperations.Add(((AccountUpdateOperation) new AccountUpdateOperation().UpdateOperationId(Operation.FirstTransactionId + 2)).AddAccount(CoreAccount.NetworkAccountId, coreOperations.Count + 1, long.MaxValue / 2).AddTransfer(CoreAccount.NetworkAccountId, CoreAccount.NetworkAccountId, long.MaxValue / 2, null, timestamp)); var blockStateOperation = new BlockStateOperation(); var nextChainId = CoreChain.CoreChainId + 1; var nextTransactionId = coreOperations.Count + 1; var nextAccountId = CoreAccount.NetworkAccountId + 1; var accounts = new List <AccountOperation>(); var serviceTransactionsList = new Dictionary <int, List <ServiceTransaction> >(); if (useGenesisInfo) { try { var json = storage.ReadFileText("genesisservices.txt"); if (json != null) { var services = Newtonsoft.Json.JsonConvert.DeserializeObject <List <GenesisService> >(json); if (services != null) { foreach (var service in services) { if (!service.Valid) { continue; } var serviceKeys = new List <PublicChainKey>(); var ep = useCoreChainEndpoint ? endPoints[0] : service.Endpoint; var accountId = service.AccountId; if (accountId != CoreAccount.NetworkAccountId) { var found = accounts.Find((a) => a.AccountId == accountId) != null; if (!found) { (var store, var key, var accountPassword) = LoadCoreAccountKey(storage, "Core Account " + accountId, "Core Accounts"); if (store == null) { key = Key.Generate(KeyTypes.Ed25519); accountPassword = Hex.ToString(Rand.NextSeed(32)); store = new CoreAccountKeyStore(service.AccountName, accountId, key, accountPassword); SaveCoreAccountKey(storage, store, "Core Account " + accountId, accountPassword, "Core Accounts"); } if (accountId == nextAccountId) { var ao = new AccountOperation(accountId, key.PublicKey, timestamp); ao.UpdateOperationId(nextTransactionId); coreOperations.Add(ao); accounts.Add(ao); nextTransactionId++; nextAccountId++; } else { Console.WriteLine($"Invalid account id for {service.Title}, should be {nextAccountId}, but is {accountId}."); continue; } } } Console.WriteLine($"Adding Service {service.Title} with endpoint {ep}."); var count = 2 + service.DataChainCount; for (var i = 0; i < count; i++) { var keyFlags = GetServiceKeyFlags(i); var keyName = $"{service.Name} {GetKeyName(keyFlags, false)}"; var dataChain = i >= 2; if (dataChain) { keyName += $" (ChainIndex {i - 2})"; } (var store, var key, var servicePassword) = LoadKeyStore <ChainKeyStore>(storage, null, keyName, service.Name); if (store == null) { key = Key.Generate(KeyTypes.Ed25519); servicePassword = Hex.ToString(Rand.NextSeed(32)); var signedKey = new PublicChainKey(keyFlags, nextChainId, dataChain ? (uint)i - 2 : 0, 0, (short)i, key); store = new ChainKeyStore($"{service.Name} {keyName}", signedKey, key, servicePassword); SaveKeyStore(storage, store, servicePassword, null, keyName, service.Name); } Console.WriteLine($"{service.Name} {keyName}: {key.PublicKey.HexString}."); serviceKeys.Add(store.PublicChainKey); } var pc = new ChainInfoOperation(nextChainId, accountId, service.Title, service.Website, timestamp, serviceKeys, new List <string> { ep }, new List <PurchaseInfo>()); pc.UpdateOperationId(nextTransactionId); coreOperations.Add(pc); nextTransactionId++; if (service.Revenue > 0) { var rev = new ChainRevenueInfoOperation(nextChainId, service.Revenue, service.RevenueAccountFactor, timestamp); rev.UpdateOperationId(nextTransactionId); coreOperations.Add(rev); nextTransactionId++; } if (service.Accounts > 0) { var serviceTransactions = new List <ServiceTransaction>(); for (var i = 0; i < service.Accounts; i++) { (var accountStore, var accountKey, var accountPassword) = LoadCoreAccountKey(storage, "Core Account " + nextAccountId, "Core Accounts"); if (accountStore == null) { accountKey = Key.Generate(KeyTypes.Ed25519); accountPassword = Hex.ToString(Rand.NextSeed(32)); accountStore = new CoreAccountKeyStore($"Core Account {nextAccountId}", nextAccountId, accountKey, accountPassword); SaveCoreAccountKey(storage, accountStore, "Core Account " + nextAccountId, accountPassword, "Core Accounts"); } (var serviceAccountStore, var serviceAccountKey, var serviceAccountPassword) = LoadKeyStore <ServiceAccountKeyStore>(storage, null, $"{service.Name} Service Account {nextAccountId}", $"{service.Name}/Service Accounts"); if (serviceAccountStore == null) { serviceAccountKey = Key.Generate(KeyTypes.Ed25519); serviceAccountPassword = Hex.ToString(Rand.NextSeed(32)); var signedPublicKey = PublicServiceAccountKey.GenerateSignedPublicKey(nextAccountId, nextChainId, 0, 0, serviceAccountKey.PublicKey, accountKey); serviceAccountStore = new ServiceAccountKeyStore($"{service.Name} Service Account {nextAccountId}", signedPublicKey, serviceAccountKey, serviceAccountPassword); SaveKeyStore(storage, serviceAccountStore, serviceAccountPassword, null, $"{service.Name} Service Account {nextAccountId}", $"{service.Name}/Service Accounts"); } var join = new JoinServiceTransaction(serviceAccountStore.SignedPublicKey) { SignKey = accountKey }; join.ToArray(); serviceTransactions.Add(join); var ao = new AccountOperation(nextAccountId, accountKey.PublicKey, timestamp); ao.UpdateOperationId(nextTransactionId); coreOperations.Add(ao); accounts.Add(ao); nextTransactionId++; nextAccountId++; } blockStateOperation.AddBlockState(nextChainId, Protocol.GenesisBlockId, 0, 0, serviceTransactions.Count); serviceTransactionsList[nextChainId] = serviceTransactions; } nextChainId++; } } } } catch (Exception ex) { Log.HandleException(ex, LogLevels.Error); } } coreOperations.Add(blockStateOperation); blockStateOperation.UpdateOperationId(nextTransactionId); blockStateOperation.AddBlockState(Protocol.CoreChainId, Protocol.GenesisBlockId, Protocol.GenesisBlockNetworkKeyIssuer, 0, nextTransactionId); var block = new CoreBlock(Protocol.GenesisBlockId, Protocol.GenesisBlockNetworkKeyIssuer, 0, timestamp, nextAccountId, nextChainId, Hash.Empty(Protocol.TransactionHashType), Hash.Empty(ValidationOperation.ValidationHashType), coreOperations, new List <CoreTransaction>()); var signatures = new BlockSignatures(block); signatures.AddSignature(block.Issuer, block, networkKey); return(new GenesisBlockResult(block, signatures, networkKey.PublicKey, networkKeys[1].Store, networkKeys[1].Password, serviceTransactionsList)); }
public ChainPage(ChainInfo chainInfo, ChainKeyStore chainKey) : base("ChainPage") { ChainInfo = chainInfo; _chainKey = chainKey; Subscribe <ChainRegistrationEvent>(Chain); if (chainInfo != null) { var endPoints = chainInfo.GetPublicEndpoints(); foreach (var endPoint in endPoints) { _endPoints.Add(new ChainItem <string>(ChainItemStatus.Live, endPoint)); } foreach (var key in chainInfo.GetRevokeableChainKeys()) { _chainKeys.Add(new ChainKeyItem(key.IsRevoked ? ChainItemStatus.Revoked : ChainItemStatus.Live, key.Item)); } foreach (var purchase in chainInfo.GetChainPurchases()) { _purchases.Add(new ChainItem <PurchaseInfo>(purchase.IsRevoked ? ChainItemStatus.Revoked : ChainItemStatus.Live, purchase.Item)); } } AddTitleRow("Title"); AddHeaderRow("Info"); _name = AddEntryRow(null, "Name"); _name.SetDetailViewIcon(Icons.Pencil); if (chainInfo != null) { _name.Edit.Text = chainInfo.Name; } _website = AddEntryRow(null, "Website"); _website.SetDetailViewIcon(Icons.RowLink); if (chainInfo != null) { _website.Edit.Text = chainInfo.Website; } AddFooterRow(); AddHeaderRow("ChainKeys"); _chainKeysButton = AddButtonRow("ChainKeysButton", NewChainKey); Status.AddBusyView(_chainKeysButton); AddFooterRow(); AddHeaderRow("EndPoints"); _endPointsButton = AddButtonRow("EndPointsButton", NewEndPoint); Status.AddBusyView(_endPointsButton); AddFooterRow(); /* * AddHeaderRow("Purchases"); * _purchasesButton = AddButtonRow("PurchasesButton", NewPurchase); * Status.AddBusyView(_purchasesButton); * AddFooterRow(); */ Status.Add(_name.Edit, T("NameStatus"), (view, entry, newText, oldTex) => { if (string.IsNullOrEmpty(newText)) { return(false); } return(true); }). Add(_website.Edit, T("WebsiteStatus"), (view, entry, newText, oldText) => { if (string.IsNullOrEmpty(newText)) { return(true); } return(newText.IsValdiUrl(true)); }); _adminKeyStatus = Status.Add(T("AdminKeyStatus"), (sv) => { foreach (var key in _chainKeys) { if ((key.Status == ChainItemStatus.Live || key.Status == ChainItemStatus.New) && ((key.Item.Flags & PublicChainKeyFlags.ChainAdminKey) != 0)) { return(true); } } return(false); }); _endPointStatus = Status.Add(T("EndPointStatus"), (sv) => { return(_endPoints.Any((a) => a.Status == ChainItemStatus.New || a.Status == ChainItemStatus.Live)); }); AddIndex = AddSubmitRow("Submit", Submit); AddIndexBefore = true; if (_chainKey != null) { _keyPassword = AddPasswordRow("", "KeyPassword"); Status.Add(_keyPassword.Edit, T("PasswordStatus"), (sv, entry, newText, oldText) => { return(_chainKey.IsPasswordValid(newText)); }); } AddIndex = null; AddIndexBefore = false; UpdateChainKeys(); UpdateEndpoints(); UpdatePurchases(); }