protected override void EndProcessing() { var config = this.ReadConfig(); IAccountDerivation accountDerivation; if (string.IsNullOrWhiteSpace(Mnemonic)) { var hdWalletAccountDerivation = HDAccountDerivation.Create(); accountDerivation = hdWalletAccountDerivation; Host.UI.WriteLine($"Using mnemonic phrase: '{hdWalletAccountDerivation.MnemonicPhrase}'"); Host.UI.WriteErrorLine("Warning: this private key generation is not secure and should not be used in production."); } else { accountDerivation = new HDAccountDerivation(Mnemonic); } var accountKeys = new List <(Address Address, EthereumEcdsa Account)>(); foreach (var account in EthereumEcdsa.Generate(config.AccountCount, accountDerivation)) { // Get an account from the public key hash. var address = account.EcdsaKeyPairToAddress(); accountKeys.Add((address, account)); } var accounts = accountKeys.ToArray(); GlobalVariables.AccountKeys = accounts; Console.WriteLine($"Created {accounts.Length} accounts. Use '{CmdLetExtensions.GetCmdletName<WriteAccountsCommand>()}' to save account keys to disk."); }
protected override void EndProcessing() { // Configure Out-Default to automatically place set last command output into variable "$__" // See: https://tommymaynard.com/three-ways-to-set-psdefaultparametervalues-2017/ var psDefaultParameterValues = SessionState.PSVariable.Get("PSDefaultParameterValues"); var paramDict = (DefaultParameterDictionary)psDefaultParameterValues.Value; paramDict["Out-Default:OutVariable"] = "__"; if (Setup.Equals(WORKSPACE_MANUAL, StringComparison.OrdinalIgnoreCase)) { if (!CheckManualSetup()) { return; } } if (!Config.CheckFileExists(SessionState.Path.CurrentLocation.Path)) { var configResult = this.Execute <ConfigCommand>((nameof(ConfigCommand.Workspace), Setup)); } var config = this.ReadConfig(); string rpcServerUri; if (Setup.Equals(WORKSPACE_DEVELOPMENT, StringComparison.OrdinalIgnoreCase)) { var startTestServerResult = this.Execute <StartTestServerCommand>(); rpcServerUri = GlobalVariables.TestNodeServer.RpcServer.ServerAddresses[0]; } else { var networkHost = config.NetworkHost; if (!networkHost.StartsWith("http:", StringComparison.OrdinalIgnoreCase) && !networkHost.StartsWith("https:", StringComparison.OrdinalIgnoreCase)) { networkHost = "http://" + networkHost; } if (!Uri.TryCreate(networkHost, UriKind.Absolute, out var hostUri)) { Host.UI.WriteErrorLine($"Invalid network host / URI specified: '{networkHost}'"); return; } var uriBuilder = new UriBuilder(hostUri); bool portSpecifiedInHost = config.NetworkHost.Contains(":" + uriBuilder.Port, StringComparison.Ordinal); if (config.NetworkPort == 0 && !portSpecifiedInHost) { Host.UI.WriteWarningLine($"The RPC server port is not specified in '{nameof(Config.NetworkHost)}' or '{nameof(Config.NetworkPort)}' config. The default port {uriBuilder.Uri.Port} for {uriBuilder.Scheme} will be used."); } if (config.NetworkPort != 0) { if (portSpecifiedInHost) { Host.UI.WriteWarningLine($"A network port is specified in both config options {nameof(Config.NetworkHost)}={uriBuilder.Port} and {nameof(Config.NetworkPort)}={config.NetworkPort}. Only {uriBuilder.Port} will be used."); } else { uriBuilder.Port = (int)config.NetworkPort; } } rpcServerUri = $"{uriBuilder.Scheme}://{uriBuilder.Host}:{uriBuilder.Port}"; } var jsonRpcClient = JsonRpcClient.Create( new Uri(rpcServerUri), defaultGasLimit: config.DefaultGasLimit, defaultGasPrice: config.DefaultGasPrice); // Perform a json rpc version check to ensure rpc server is reachable try { var networkVersion = jsonRpcClient.Version().GetResultSafe(); Host.UI.WriteLine($"RPC client connected to server {rpcServerUri}. Network version: {networkVersion}"); } catch (Exception ex) { Host.UI.WriteErrorLine(ex.ToString()); Host.UI.WriteErrorLine($"RPC client could not connect to RPC server at {rpcServerUri}. Check your network configuration with '{CmdLetExtensions.GetCmdletName<ConfigCommand>()}'."); if (Setup.Equals(WORKSPACE_MANUAL, StringComparison.OrdinalIgnoreCase)) { if (GlobalVariables.TestNodeServer != null) { Host.UI.WriteErrorLine($"A test RPC server is running at {GlobalVariables.TestNodeServer.RpcServer.ServerAddresses.First()}."); } else { Host.UI.WriteErrorLine($"To start an test RPC server run '{CmdLetExtensions.GetCmdletName<StartTestServerCommand>()}'."); } } return; } SessionState.SetRpcClient(jsonRpcClient); Address[] accounts; if (config.UseLocalAccounts) { uint chainID; if (config.ChainID != 0) { chainID = config.ChainID; } else { try { var verString = jsonRpcClient.Version().GetResultSafe(); chainID = uint.Parse(verString, CultureInfo.InvariantCulture); } catch (Exception ex) { Host.UI.WriteErrorLine(ex.ToString()); Host.UI.WriteErrorLine($"Could not detect chainID from server. Set '{nameof(Config.ChainID)}' using with '{CmdLetExtensions.GetCmdletName<ConfigCommand>()}'."); Host.UI.WriteLine($"Use {nameof(Config.ChainID)} of 1 for mainnet. See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids for more information."); return; } } if ((GlobalVariables.AccountKeys?.Length).GetValueOrDefault() == 0) { var localAcountsFile = LocalAccountsUtil.GetDefaultFilePath(SessionState.Path.CurrentLocation.Path); if (File.Exists(localAcountsFile)) { if (LocalAccountsUtil.IsEncrypted(localAcountsFile)) { WriteWarning($"Local account files exists but is encrypted. The session must be started manually to load encryped accounts. New accounts will be generated in memory instead."); var newAccountsResult = this.Execute <NewAccountsCommand>(); } else { var loadAccountsResult = this.Execute <LoadAccountsCommand>(); } } else { var newAccountsResult = this.Execute <NewAccountsCommand>(); } } accounts = GlobalVariables.AccountKeys.Select(a => a.Address).ToArray(); GlobalVariables.ChainID = chainID; jsonRpcClient.RawTransactionSigner = CreateRawTransactionSigner(); jsonRpcClient.TransactionReceiptPollInterval = TimeSpan.FromMilliseconds(500); } else { accounts = jsonRpcClient.Accounts().GetResultSafe(); } SessionState.SetAccounts(accounts); string solSourceDir = Util.GetSolSourcePath(config, SessionState); if (!Directory.Exists(solSourceDir)) { Directory.CreateDirectory(solSourceDir); } if (Directory.EnumerateFiles(solSourceDir, "*.sol", SearchOption.AllDirectories).Any()) { var compileSolResult = this.Execute <CompileSolidityCommand>(); } var watchSolResult = this.Execute <WatchSolidityCommand>(); bool failed = false; if (failed) { Environment.Exit(-1); } }
protected override void EndProcessing() { if (GlobalVariables.AccountKeys == null || GlobalVariables.AccountKeys.Length == 0) { Host.UI.WriteErrorLine($"No accounts are loaded. Use '{CmdLetExtensions.GetCmdletName<NewAccountsCommand>()}' to generate accounts."); return; } string filePath; if (Path.IsPathRooted(FilePath)) { filePath = Path.GetFullPath(FilePath); } else { filePath = Path.GetFullPath(Path.Join(SessionState.Path.CurrentLocation.Path, FilePath)); } if (EncryptData && string.IsNullOrWhiteSpace(Password)) { Host.UI.WriteErrorLine($"No '{nameof(Password)}' parameter is provided. To write without encryption set the '{nameof(EncryptData)}' parameter to false"); return; } if (!string.IsNullOrWhiteSpace(Password) && !EncryptData) { Host.UI.WriteErrorLine($"The '{nameof(EncryptData)}' parameter is set to false but the '{nameof(Password)}' parameter is provided. Pick one."); return; } var accounts = GlobalVariables.AccountKeys; var accountArrayHex = accounts .Select(a => new[] { a.Address.ToString(hexPrefix: true), HexUtil.GetHexFromBytes(a.Account.ToPrivateKeyArray(), hexPrefix: true) }) .ToArray(); JObject dataObj = new JObject(); if (EncryptData) { var accountJson = JsonConvert.SerializeObject(accountArrayHex, Formatting.Indented); var encrypedAccountsString = AesUtil.EncryptString(accountJson, Password); dataObj[LocalAccountsUtil.JSON_ENCRYPTED_ACCOUNTS_KEY] = encrypedAccountsString; } else { dataObj[LocalAccountsUtil.JSON_ACCOUNTS_KEY] = JArray.FromObject(accountArrayHex); } if (File.Exists(filePath)) { var choices = new Collection <ChoiceDescription>(new[] { new ChoiceDescription("Cancel"), new ChoiceDescription("Overwrite") }); var overwrite = Host.UI.PromptForChoice($"File already exists at {filePath}", "Continue and overwite existing file?", choices, 0); if (overwrite != 1) { Host.UI.WriteErrorLine("Accounts not saved to file."); return; } } var dataJson = dataObj.ToString(Formatting.Indented); File.WriteAllText(filePath, dataJson); if (EncryptData) { Host.UI.WriteLine($"Wrote {accounts.Length} encrypted accounts to: {filePath}"); } else { Host.UI.WriteLine($"Wrote {accounts.Length} unencrypted accounts to: {filePath}"); } }
bool CheckManualSetup() { if (!Config.CheckFileExists(SessionState.Path.CurrentLocation.Path)) { WriteWarning($"Cannot initialize workspace without configuration. Run '{CmdLetExtensions.GetCmdletName<ConfigCommand>()}' then run '{CmdLetExtensions.GetCmdletName<InitializeWorkspaceCommand>()}'"); return(false); } var config = this.ReadConfig(); if (config.UseLocalAccounts && (GlobalVariables.AccountKeys?.Length).GetValueOrDefault() == 0) { var localAcountsFile = LocalAccountsUtil.GetDefaultFilePath(SessionState.Path.CurrentLocation.Path); if (!File.Exists(localAcountsFile)) { WriteWarning($"Accounts must be first created to initialize workspace using local accounts. Run '{CmdLetExtensions.GetCmdletName<NewAccountsCommand>()}' then run '{CmdLetExtensions.GetCmdletName<InitializeWorkspaceCommand>()}'"); return(false); } if (LocalAccountsUtil.IsEncrypted(localAcountsFile)) { WriteWarning($"Accounts are encrypted and must be loaded with a password before initialize workspace. Run '{CmdLetExtensions.GetCmdletName<LoadAccountsCommand>()}' then run '{CmdLetExtensions.GetCmdletName<InitializeWorkspaceCommand>()}'"); return(false); } } return(true); }