From 1aadaba46da540835a778711f073517fa70b97e6 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 20 Nov 2020 15:38:56 +0000 Subject: [PATCH] Upgrade --- src/FedKeyPairGen/FederationSetup.cs | 18 +-- src/FedKeyPairGen/FederationSetup.csproj | 19 +-- src/FedKeyPairGen/GenesisMiner.cs | 30 +--- src/FedKeyPairGen/MultisigAddressCreator.cs | 34 +--- src/FedKeyPairGen/Program.cs | 147 +++++++----------- ....FederatedSidechains.Initialisation.csproj | 2 +- src/StratisFederationApp/MainWindow.xaml.cs | 6 +- 7 files changed, 90 insertions(+), 166 deletions(-) diff --git a/src/FedKeyPairGen/FederationSetup.cs b/src/FedKeyPairGen/FederationSetup.cs index 09e459d8..a9a9af9b 100644 --- a/src/FedKeyPairGen/FederationSetup.cs +++ b/src/FedKeyPairGen/FederationSetup.cs @@ -15,7 +15,7 @@ public static void OutputHeader() var builder = new StringBuilder(); builder.AppendLine($"Stratis Federation Set up v{Assembly.GetEntryAssembly().GetName().Version}"); - builder.AppendLine("Copyright (c) 2018 Stratis Group Limited"); + builder.AppendLine("Copyright (c) 2020 Stratis Group Limited"); Console.WriteLine(builder); } @@ -31,20 +31,20 @@ public static void OutputMenu() builder.AppendLine("Menu:"); builder.AppendLine("g Create genesis blocks for Mainnet, Testnet and Regtest."); builder.AppendLine(" args: [-text=\"\"]"); - builder.AppendLine(" text: A bit of text or a url to be included in the genesis block."); + builder.AppendLine(" text: A bit of text or a url to be included in the genesis block."); builder.AppendLine(" Example: g -text=\"https://www.coindesk.com/apple-co-founder-backs-dorsey-bitcoin-become-webs-currency/\""); builder.AppendLine("p Create private and public keys for federation members."); // ask members to create public and private -p (for the specfic network) - 1 pubpriv for signing transactions and 1 for pubpriv key for mining builder.AppendLine(" args: [-passphrase=] [-datadir=] [-ismultisig=] (optional - space character not allowed)"); - builder.AppendLine(" passphrase: a passphrase used to derive the private key from the transaction signing mnenmonic"); - builder.AppendLine(" datadir: optional arg, directory where private key is saved"); - builder.AppendLine(" ismultisig: optional arg, controls output"); - builder.AppendLine(" Example: p -passphrase=h@rd2Gu3ss!"); - builder.AppendLine(" Example: p -passphrase=h@rd2Gu3ss! -datadir=c:\\dev -ismultisig=true"); + builder.AppendLine(" passphrase: a passphrase used to derive the private key from the transaction signing mnenmonic"); + builder.AppendLine(" datadir: optional arg, directory where private key is saved"); + builder.AppendLine(" ismultisig: optional arg, controls output"); + builder.AppendLine(" Example: p -passphrase=h@rd2Gu3ss!"); + builder.AppendLine(" Example: p -passphrase=h@rd2Gu3ss! -datadir=c:\\dev -ismultisig=true"); builder.AppendLine("m Create multi signature addresses for the federation wallets."); builder.AppendLine(" args: [-network=] [-quorum=] [-fedpubkeys=]"); builder.AppendLine(" network: mainnet, testnet or regtest."); builder.AppendLine(" quorum: The minimum number of federated members needed to sign transactions."); - builder.AppendLine(" fedpubkeys: Federation members' public keys. Must have an odd number of up to fifteen members."); // // fed admin will do -m and number (3 qurom + the public keys for the signing of transactions) + builder.AppendLine(" fedpubkeys: Federation members' public keys. Up to fifteen members."); // // fed admin will do -m and number (3 qurom + the public keys for the signing of transactions) builder.AppendLine(" Example: m -network=testnet -quorum=2 -fedpubkeys=PublicKey1,PublicKey2,PublicKey3,PublicKey4,PublicKey5"); builder.AppendLine("menu Show this menu."); builder.AppendLine("exit Close the utility."); @@ -73,4 +73,4 @@ public static void OutputErrorLine(string message) Console.ForegroundColor = colorSaved; } } -} +} \ No newline at end of file diff --git a/src/FedKeyPairGen/FederationSetup.csproj b/src/FedKeyPairGen/FederationSetup.csproj index 72e449e9..d35f4316 100644 --- a/src/FedKeyPairGen/FederationSetup.csproj +++ b/src/FedKeyPairGen/FederationSetup.csproj @@ -9,7 +9,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 FederationSetup.Program win10-x64; Full @@ -17,15 +17,16 @@ - - - + + + + + - - - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/FedKeyPairGen/GenesisMiner.cs b/src/FedKeyPairGen/GenesisMiner.cs index 9bdcfade..d2bbfd84 100644 --- a/src/FedKeyPairGen/GenesisMiner.cs +++ b/src/FedKeyPairGen/GenesisMiner.cs @@ -4,30 +4,12 @@ using NBitcoin; using NBitcoin.DataEncoders; using Stratis.Bitcoin.Features.SmartContracts.PoA; -using Xunit; -using Xunit.Abstractions; +using Stratis.Sidechains.Networks; namespace FederationSetup { public class GenesisMiner { - private readonly ITestOutputHelper output; - - public GenesisMiner(ITestOutputHelper output = null) - { - if (output == null) return; - this.output = output; - } - - //[Fact] - [Fact(Skip = "This is not a test, it is meant to be run upon creating a network")] - public void Run_MineGenesis() - { - var consensusFactory = new SmartContractPoAConsensusFactory(); - string coinbaseText = "https://www.coindesk.com/apple-co-founder-backs-dorsey-bitcoin-become-webs-currency/"; - this.output.WriteLine(this.MineGenesisBlocks(consensusFactory, coinbaseText)); - } - public string MineGenesisBlocks(SmartContractPoAConsensusFactory consensusFactory, string coinbaseText) { var output = new StringBuilder(); @@ -37,9 +19,9 @@ public string MineGenesisBlocks(SmartContractPoAConsensusFactory consensusFactor var targets = new Dictionary { - { new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), "-- MainNet network --" }, - { new uint256("0000ffff00000000000000000000000000000000000000000000000000000000"), "-- TestNet network --" }, - { new uint256("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), "-- RegTest network --" } + { new Target(CirrusNetwork.NetworksSelector.Mainnet().GenesisBits).ToUInt256(), "-- MainNet network --" }, + { new Target(CirrusNetwork.NetworksSelector.Testnet().GenesisBits).ToUInt256(), "-- TestNet network --" }, + { new Target(CirrusNetwork.NetworksSelector.Regtest().GenesisBits).ToUInt256(), "-- RegTest network --" }, }; foreach (KeyValuePair target in targets) @@ -58,7 +40,7 @@ private Block GeneterateBlock(SmartContractPoAConsensusFactory consensusFactory, private string NetworkOutput(Block genesisBlock, string network, string coinbaseText) { - var header = (SmartContractPoABlockHeader) genesisBlock.Header; + var header = (SmartContractPoABlockHeader)genesisBlock.Header; var output = new StringBuilder(); output.AppendLine(network); @@ -90,11 +72,9 @@ public static Block MineGenesisBlock(SmartContractPoAConsensusFactory consensusF throw new ArgumentException($"Parameter '{nameof(genesisReward)}' cannot be null. Example use: 'Money.Coins(50m)'."); DateTimeOffset time = DateTimeOffset.Now; - uint unixTime = Utils.DateTimeToUnixTime(time); Transaction txNew = consensusFactory.CreateTransaction(); txNew.Version = (uint)version; - txNew.Time = unixTime; txNew.AddInput(new TxIn() { ScriptSig = new Script( diff --git a/src/FedKeyPairGen/MultisigAddressCreator.cs b/src/FedKeyPairGen/MultisigAddressCreator.cs index 4e1f843b..dd12c8ba 100644 --- a/src/FedKeyPairGen/MultisigAddressCreator.cs +++ b/src/FedKeyPairGen/MultisigAddressCreator.cs @@ -1,45 +1,15 @@ using System.Text; using NBitcoin; -using NBitcoin.DataEncoders; -using Stratis.Bitcoin.Networks; -using Stratis.Sidechains.Networks; -using Xunit; -using Xunit.Abstractions; namespace FederationSetup { public class MultisigAddressCreator { - private readonly ITestOutputHelper output; - - public MultisigAddressCreator(ITestOutputHelper output = null) - { - if (output == null) return; - this.output = output; - } - - [Fact(Skip = "This is not a test, it is meant to be run upon creating a network")] - public void Run_CreateMultisigAddresses() - { - Network mainchainNetwork = Networks.Stratis.Testnet(); - Network sidechainNetwork = FederatedPegNetwork.NetworksSelector.Testnet(); - - // Create a mnemonic and get the corresponding pubKey. - var pubKeys = new PubKey[1]; - var mnemonic = new Mnemonic(Wordlist.English, WordCount.Twelve); - pubKeys[0] = mnemonic.DeriveExtKey().PrivateKey.PubKey; - - this.output.WriteLine($"Mnemonic - Please note the following 12 words down in a secure place: {string.Join(" ", mnemonic.Words)}"); - this.output.WriteLine($"PubKey - Please share the following public key with the person responsible for the sidechain generation: {Encoders.Hex.EncodeData((pubKeys[0]).ToBytes(false))}"); - - this.output.WriteLine(this.CreateMultisigAddresses(mainchainNetwork, sidechainNetwork, pubKeys)); - } - - public string CreateMultisigAddresses(Network mainchainNetwork, Network sidechainNetwork, PubKey[] pubKeys, int quorum = 3) + public string CreateMultisigAddresses(Network mainchainNetwork, Network sidechainNetwork) { var output = new StringBuilder(); - Script payToMultiSig = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(quorum, pubKeys); + Script payToMultiSig = PayToFederationTemplate.Instance.GenerateScriptPubKey(sidechainNetwork.Federations.GetOnlyFederation().Id); output.AppendLine("Redeem script: " + payToMultiSig.ToString()); BitcoinAddress sidechainMultisigAddress = payToMultiSig.Hash.GetAddress(sidechainNetwork); diff --git a/src/FedKeyPairGen/Program.cs b/src/FedKeyPairGen/Program.cs index 45eb20f7..6dc301b7 100644 --- a/src/FedKeyPairGen/Program.cs +++ b/src/FedKeyPairGen/Program.cs @@ -1,8 +1,8 @@ using System; +using System.Collections.Generic; +using System.Data; using System.IO; using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; using NBitcoin; using NBitcoin.DataEncoders; using Stratis.Bitcoin.Configuration; @@ -10,7 +10,6 @@ using Stratis.Bitcoin.Features.SmartContracts.PoA; using Stratis.Bitcoin.Networks; using Stratis.Sidechains.Networks; -using Xunit.Sdk; namespace FederationSetup { @@ -79,30 +78,30 @@ private static void SwitchCommand(string[] args, string command, string userInpu switch (command) { case SwitchExit: - { - Environment.Exit(0); - break; - } + { + Environment.Exit(0); + break; + } case SwitchMenu: - { - HandleSwitchMenuCommand(args); - break; - } + { + HandleSwitchMenuCommand(args); + break; + } case SwitchMineGenesisBlock: - { - HandleSwitchMineGenesisBlockCommand(userInput); - break; - } + { + HandleSwitchMineGenesisBlockCommand(userInput); + break; + } case SwitchGenerateFedPublicPrivateKeys: - { - HandleSwitchGenerateFedPublicPrivateKeysCommand(args); - break; - } + { + HandleSwitchGenerateFedPublicPrivateKeysCommand(args); + break; + } case SwitchGenerateMultiSigAddresses: - { - HandleSwitchGenerateMultiSigAddressesCommand(args); - break; - } + { + HandleSwitchGenerateMultiSigAddressesCommand(args); + break; + } } } @@ -152,17 +151,17 @@ private static void HandleSwitchGenerateFedPublicPrivateKeysCommand(string[] arg isMultisig = Array.Find(args, element => element.StartsWith("-ismultisig=", StringComparison.Ordinal)); - if (String.IsNullOrEmpty(passphrase)) + if (string.IsNullOrEmpty(passphrase)) throw new ArgumentException("The -passphrase=\"\" argument is missing."); passphrase = passphrase.Replace("-passphrase=", string.Empty); //ToDo wont allow for datadir with equal sign - dataDirPath = String.IsNullOrEmpty(dataDirPath) + dataDirPath = string.IsNullOrEmpty(dataDirPath) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) - : dataDirPath.Replace("-datadir=", String.Empty); + : dataDirPath.Replace("-datadir=", string.Empty); - if (String.IsNullOrEmpty(isMultisig) || isMultisig.Replace("-ismultisig=", String.Empty) == "true") + if (string.IsNullOrEmpty(isMultisig) || isMultisig.Replace("-ismultisig=", string.Empty) == "true") { GeneratePublicPrivateKeys(passphrase, dataDirPath); } @@ -174,29 +173,37 @@ private static void HandleSwitchGenerateFedPublicPrivateKeysCommand(string[] arg FederationSetup.OutputSuccess(); } - private static void HandleSwitchGenerateMultiSigAddressesCommand(string[] args) + private static void ConfirmArguments(TextFileConfiguration config, params string[] args) { - if (args.Length != 4) - throw new ArgumentException("Please enter the exact number of argument required."); + var missing = new Dictionary(); - ConfigReader = new TextFileConfiguration(args); + foreach (string arg in args) + { + if (config.GetOrDefault(arg, null) == null) + { + Console.Write(arg + ": "); + missing[arg] = Console.ReadLine(); + } + } - int quorum = GetQuorumFromArguments(); - string[] federatedPublicKeys = GetFederatedPublicKeysFromArguments(); + new TextFileConfiguration(missing.Select(d => $"{d.Key}={d.Value}").ToArray()).MergeInto(config); - if (quorum > federatedPublicKeys.Length) - throw new ArgumentException("Quorum has to be smaller than the number of members within the federation."); + Console.WriteLine(); + } - if (quorum < federatedPublicKeys.Length / 2) - throw new ArgumentException("Quorum has to be greater than half of the members within the federation."); + private static void HandleSwitchGenerateMultiSigAddressesCommand(string[] args) + { + ConfigReader = new TextFileConfiguration(args); + + ConfirmArguments(ConfigReader, "network"); - (Network mainChain, Network sideChain) = GetMainAndSideChainNetworksFromArguments(); + (_, Network sideChain, Network targetMainChain) = GetMainAndSideChainNetworksFromArguments(); - Console.WriteLine($"Creating multisig addresses for {mainChain.Name} and {sideChain.Name}."); - Console.WriteLine(new MultisigAddressCreator().CreateMultisigAddresses(mainChain, sideChain, federatedPublicKeys.Select(f => new PubKey(f)).ToArray(), quorum)); + Console.WriteLine($"Creating multisig addresses for {targetMainChain.Name} and {sideChain.Name}."); + Console.WriteLine(new MultisigAddressCreator().CreateMultisigAddresses(targetMainChain, sideChain)); } - private static void GeneratePublicPrivateKeys(string passphrase, String keyPath, bool isMultiSigOutput = true) + private static void GeneratePublicPrivateKeys(string passphrase, string keyPath, bool isMultiSigOutput = true) { // Generate keys for signing. var mnemonicForSigningKey = new Mnemonic(Wordlist.English, WordCount.Twelve); @@ -242,71 +249,37 @@ private static void GeneratePublicPrivateKeys(string passphrase, String keyPath, Console.WriteLine(Environment.NewLine); } - private static int GetQuorumFromArguments() - { - int quorum = ConfigReader.GetOrDefault("quorum", 0); - - if (quorum == 0) - throw new ArgumentException("Please specify a quorum."); - - if (quorum < 0) - throw new ArgumentException("Please specify a positive number for the quorum."); - - return quorum; - } - - private static string[] GetFederatedPublicKeysFromArguments() - { - string[] pubKeys = null; - - int federatedPublicKeyCount = 0; - - if (ConfigReader.GetAll("fedpubkeys").FirstOrDefault() != null) - { - pubKeys = ConfigReader.GetAll("fedpubkeys").FirstOrDefault().Split(','); - federatedPublicKeyCount = pubKeys.Count(); - } - - if (federatedPublicKeyCount == 0) - throw new ArgumentException("No federation member public keys specified."); - - if (federatedPublicKeyCount % 2 == 0) - throw new ArgumentException("The federation must have an odd number of members."); - - if (federatedPublicKeyCount > 15) - throw new ArgumentException("The federation can only have up to fifteen members."); - - return pubKeys; - } - - private static (Network mainChain, Network sideChain) GetMainAndSideChainNetworksFromArguments() + private static (Network mainChain, Network sideChain, Network targetMainChain) GetMainAndSideChainNetworksFromArguments() { string network = ConfigReader.GetOrDefault("network", (string)null); if (string.IsNullOrEmpty(network)) throw new ArgumentException("Please specify a network."); - Network mainchainNetwork, sideChainNetwork; + Network mainchainNetwork, sideChainNetwork, targetMainchainNetwork; switch (network) { case "mainnet": - mainchainNetwork = Networks.Stratis.Mainnet(); - sideChainNetwork = FederatedPegNetwork.NetworksSelector.Mainnet(); + mainchainNetwork = null; + sideChainNetwork = CirrusNetwork.NetworksSelector.Mainnet(); + targetMainchainNetwork = Networks.Strax.Mainnet(); break; case "testnet": - mainchainNetwork = Networks.Stratis.Testnet(); - sideChainNetwork = FederatedPegNetwork.NetworksSelector.Testnet(); + mainchainNetwork = null; + sideChainNetwork = CirrusNetwork.NetworksSelector.Testnet(); + targetMainchainNetwork = Networks.Strax.Testnet(); break; case "regtest": - mainchainNetwork = Networks.Stratis.Regtest(); - sideChainNetwork = FederatedPegNetwork.NetworksSelector.Regtest(); + mainchainNetwork = null; + sideChainNetwork = CirrusNetwork.NetworksSelector.Regtest(); + targetMainchainNetwork = Networks.Strax.Regtest(); break; default: throw new ArgumentException("Please specify a network such as: mainnet, testnet or regtest."); } - return (mainchainNetwork, sideChainNetwork); + return (mainchainNetwork, sideChainNetwork, targetMainchainNetwork); } } } diff --git a/src/Stratis.FederatedSidechains.Initialisation/Stratis.FederatedSidechains.Initialisation.csproj b/src/Stratis.FederatedSidechains.Initialisation/Stratis.FederatedSidechains.Initialisation.csproj index 0c4c72d7..7b60915d 100644 --- a/src/Stratis.FederatedSidechains.Initialisation/Stratis.FederatedSidechains.Initialisation.csproj +++ b/src/Stratis.FederatedSidechains.Initialisation/Stratis.FederatedSidechains.Initialisation.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.1 + netcoreapp3.1 Full ..\None.ruleset diff --git a/src/StratisFederationApp/MainWindow.xaml.cs b/src/StratisFederationApp/MainWindow.xaml.cs index bf650a3c..f6028fb1 100644 --- a/src/StratisFederationApp/MainWindow.xaml.cs +++ b/src/StratisFederationApp/MainWindow.xaml.cs @@ -2,8 +2,8 @@ using System.Diagnostics; using System.Windows; using System.Windows.Controls; -using System.Windows.Input; using System.Windows.Forms; +using System.Windows.Input; using System.Windows.Media; namespace StratisFederationApp @@ -50,7 +50,7 @@ private void Button_Click_1(object sender, RoutedEventArgs e) TextBoxPassphrase.Foreground = Brushes.Gray; TextBoxPassphrase.Text = DefaulfPassText; TextBoxMainOutput.Text = null; - System.Windows.Forms.MessageBox.Show("Please enter pass phrase", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + System.Windows.Forms.MessageBox.Show("Please enter pass phrase", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } @@ -60,7 +60,7 @@ private void Button_Click_1(object sender, RoutedEventArgs e) var proc = new Process { - StartInfo = new ProcessStartInfo("cmd.exe", $"/c dotnet netcoreapp2.1/FederationSetup.dll p -passphrase={passPhrase} -datadir={dataDir} -ismultisig={isMultiSig}") + StartInfo = new ProcessStartInfo("cmd.exe", $"/c dotnet FederationSetup/FederationSetup.dll p -passphrase={passPhrase} -datadir={dataDir} -ismultisig={isMultiSig}") { UseShellExecute = false, RedirectStandardOutput = true,