Skip to content
This repository has been archived by the owner on Aug 16, 2021. It is now read-only.

Commit

Permalink
3730 - Port over FedKeyPairGen Tool to StratisBitcoinFullNode (#3648)
Browse files Browse the repository at this point in the history
* Created FedKeyPairGen console app.

Imported from Changeset 124

* Upgraded SBFN verison in project files.
Imported from Changeset 150

* Moved Payload into feature
Imported from Changeset 154

* Changed 'passphrase' in FedKeyPairGen to 'password'.
Imported from Changeset 198

* Attempt to merge Enigma and EnigmaChain
Imported from Changeset 201

* Updated the solution with the latest Stratis.Bitcoin nuget packages
Imported from Changeset 202

* Removed name, folder and password from the pubkey generation as  they are not required.

The console app will simply show the user their mnemonic and the pubkey they need to share.

* Removed mine premine stuff and added it to the FedKeyPairGen console app for now.

* Remove custom env mockup helpers (#5)

* created Apex definition

* first bit of cleaning, all the mockup helpers have been removed as no special logic is needed to handle sidechains, they are just another network. Need to add back randomised API port attribution. Need to fix getCoinDetails test if it is being used by anyone (UI ?). The powershell command projects have been removed as they were only here to generate json files that have disappeared.

* delete unused projects

* Bring back FindPorts methods to later find a way to use it

* Fix to get different API ports when creating multiple connected nodes on localhost, fix to GetCoinDetails, a bit basic for the moment, but we'll see how the code evolved

* Put explanatory name on the Class in FederatedSidechains.Tests.Common

* this doesn't work, somehow the constructor is called twice, and once with a null nodesettings, I need to investigate

* Changes after PR comments

* more merge changes ...

* fix get-coindetails logic

* Removed placeholder project and wrongly copied MainchainGeneratorService

* consolidate .Net Sdk

* added code to generate multisig in FedKeyPairGen (#8)

* Jeremy's PR 14 reproduced with pr5 changes in (#15)

* upgrade nuget 1.1.7 to 1.1.9 and 4.0.0.57 and 4.0.0.58

* add NLog

* Add new network properties to Apex

* Update ApexNetwork.cs

* Update ApexNetwork.cs

* Networks project addition (#16)

* upgrade nuget 1.1.7 to 1.1.9 and 4.0.0.57 and 4.0.0.58

* add NLog

* added CoinbaseMaturity, PremineReward, pow reward, pos reward and max reorg for the apex network.

* new project for ApexNetwork

* remove APexD dependency in IntegrationTest

* remove mainchainD and renamed apex to sidechainD (#19)

OK

* Nuget update (#21)

* updated nuget packages

* Replced ApiPort by GetApiPort from the FN

* create custom node without asking for free api

* added maxMoney and coinTicker

* Networkz (#22)

* using Apex throughout solution

* removed unused assert method in Networks

* remove left behind

* remove extra space

* Moved the FederatedPeg project into the FederationGateway project (#36)

* Upgrade 1.1.11 to 1.1.12 (#42)

* upgrade nuget 1.1.7 to 1.1.9 and 4.0.0.57 and 4.0.0.58

* add NLog

* added CoinbaseMaturity, PremineReward, pow reward, pos reward and max reorg for the apex network.

* Add new network properties to Apex

* Update ApexNetwork.cs

* Update ApexNetwork.cs

* upgrade nuget packages

* updated nuget packages (#48)

* upgrade to dotnetcore 2.1, tests as libraries (#98)

well done mate, that is awesome

* Upgrade to fullnode 1.2.1 beta (#110)

* Upgrade NBitcoin and as little dependencies as possible

* Consolidate Stratis.Bitcoin

* Upgrade all other Stratis and external packages

* Trying to resolve genesis hash discrepancies in Apex

* make sure all projects are in full debug mode, needed for code coverage analysis (#127)

* upgrades libraries (#144)

* upgrades to
Stratis.Bitcoin.* 1.2.3-beta
NStratis 4.0.0.67
Microsoft.NET.Test.Sdk 15.9.0
Xunit 2.4.1

That meant removing unused Integration test project which used corrupted Stratis.Bitcoin.IntegrationTests.Common temporarily

* upgrade stratis packages to 1.2.4 and FluentAssertions to 5.5.3 (#181)

* Adding a POA federated peg network (#182)

* Adding a POA federated peg network
Currently no smart contract packages so I have commented out the SC specifics ...

* trying to get rid of Apex references

* refactor network selector usaage
I don't think we need 2 classes for that

* no more need to instantiate a network to get its name

* changes post review

* Change Magic, Cointype and targetSpacingSeconds

* add a "test" to run the different tools from within VisualStudio (#187)

* add a "test" to run the different tools from within VisualStudio

* Clear white spaces.

* Federation Setup Console. (#189)

* Add GenesisMiner and MultisigAddressCreator to console.

Renamed console.

* Changes after PR review.

Changed switch values.

Allow end user to select network.

Allow end user to select quorum.

* Quorum and Fed member argument validation.

* Console OutputUsage update.

* Reduced commandLineArgs in debug from 6 fed addresses down to 5.

Removed actual keys from FederationSetup.OutputUsage().

MultisigAddressCreator now takes fed pubkeys from argument list not hard wired as before.

Generating Fed pubkeys creates two lots.  One for transfer of funds to sidechain and the other for sidechain mining.

* Removed ReadLine() switch check.

* Stratis packages upgrade 1.2.4 to 1.2.5 (#193)

* Add locks and check that the federated wallet manager dealt with any forks (#202)

* Add locks and check fedwalletmanager during forks

* Reformat and reduce whitespace

* Add missing waits

* Back off if errors when send to counter node

* Optimize performance by batching block data

* Avoid large re-orgs

* Add transaction serialization workaround to Initialize method

* Upgrade packages

* Adapted the console app to have a menu (#216)

Changed the console app to have a menu rather than being a command line tool.
The reason for that is that this utility is to be used by federation members and this change makes that easier.
Also changed it so that it loops until the user exits

![image](https://user-images.githubusercontent.com/1867877/49459731-a276c980-f7e7-11e8-8db3-2e8ce39ec441.png)

* Federation Setup tool - small improvements (#217)

* Made Network non-optional
Added text option to genesis block

* Generate pubkeys properly, with file for migning priv key

* Setup of  FederatedPegTest (#221)

* Use SmartContractPoAConsensusFactory for genesis block generation

* No genesis reward for sidechains

* Find (real) Genesis Block for FederatedPegTest

* Increase Console input limit

* Use RegTest for the local sidechain network

* Add mining FedPubKeys and additional network fields

* updtae to ports to be like Stratis+1

* Update FederatedPegTest.cs

* premine reward back to 20 000 000

* Update FederatedPegTest.cs

* upgrade fullnode from 1.2.6 to 1.2.7 (#236)

* upgrade to release version of FullNode (#238)

* upgrade to release version of FullNode
1.2.6-beta => 3.0.0.0
4.0.0.70 => 4.0.0.71

* remove stratis-dev nuget source

* just to trigger a rebuild

* Fixing codestyle issues (#253)

* refactoring

* edits

* var for simple types

* private and readonly

* access modifiers

* access modifier

* fix codestyle violations part 2 (#256)

* package upgrade to 3.0.0.0 to 3.0.0.1 (#257)

* package upgrade to 3.0.0.0 to 3.0.0.1
add --no-build back to the script

* fix FederatedPegBlockDefinition constructor

* Refactored federation setup tool and added menue option to generate powershell script (#286)

* Upgrade stratis nuget packages (#292)

* NuGet update and Dbreeze serialization fix (#309)

Allows the sidechains repo to serialize everything given the changes to the FN Dbreeze serialization and ultimately allows multiple nodes to run in the one process by removing static dependencies.

I haven't actually connected to the network and completed a transfer yet - if someone could do that it would be ace.

* add a arg for passphrase for multisig key derivation (#328)

* add a arg for passphrase for multisig key derivation

* place the passphrase correctly in the do not share section

* FedPegMain definition (#343)

* Moved coinbase text out of the CreateGenesis method

* removed some unused variables

* Brought the name and cointicker of the networks inline with the definition of the networks

* Brought some more network data for Main inline

* Upgrade # of coins to 100M

* Create new genesis block for Main

* updated to SBFN 3.0.0.4 beta (#355)

* WPF Federation Key Generation App (#379)

* Initial commit for fed setup GUI wizard in WPF Blend

* POC for creating the keys with WPF and making sure we can have nugets working

* Changes to FedKeyPairGen/Program.cs to allow to run it from command line
Added Stratis logo on the top of the window and Statis icon

* Add splash screen
Add center window on startup

* Added datadir argument to FederationSetup
Removed redundent files from FederationApp

* Changes to GUI to adopt it to consultancy website

* First working version

* Updated to displayed text, initial working version candidate

* Added handling for pass phrase

* Fixed name on the folder label

* Removed POC projects

* Removed unused left over build references for Xamarin

* Updated FederationSetup.cs with help text for new args
Cleaned up Program.cs and fixed exit SwitchCommand

* Folders restructured

* References fixed

* Network values are updated.

* Coinbase text updated.

* Skipped tests removed.
  • Loading branch information
YakupIpek authored and fassadlr committed Jun 21, 2019
1 parent d9702be commit 6cf7ec0
Show file tree
Hide file tree
Showing 7 changed files with 617 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/FederationSetup/FederationSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Reflection;
using System.Text;

namespace FederationSetup
{
// The FedKeyPairGenManager handles console output and input.
internal static class FederationSetup
{
/// <summary>
/// Print the utility's header and menu.
/// </summary>
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");

Console.WriteLine(builder);
}

/// <summary>
/// Shows the help message woth examples.
/// This is output on -h command and also in some cases if validation fails.
/// </summary>
public static void OutputMenu()
{
var builder = new StringBuilder();

builder.AppendLine("Menu:");
builder.AppendLine("g Create genesis blocks for Mainnet, Testnet and Regtest.");
builder.AppendLine(" args: [-text=\"<text>\"]");
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=<passphrase>] [-datadir=<datadir>] [-ismultisig=<bool>] (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("m Create multi signature addresses for the federation wallets.");
builder.AppendLine(" args: [-network=<network>] [-quorum=<quorum>] [-fedpubkeys=<pubkey1, pubkey2, ..>]");
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(" Example: m -network=testnet -quorum=2 -fedpubkeys=PublicKey1,PublicKey2,PublicKey3,PublicKey4,PublicKey5");
builder.AppendLine("menu Show this menu.");
builder.AppendLine("exit Close the utility.");

Console.WriteLine(builder);
}

/// <summary>
/// Output completion message and secret warning.
/// </summary>
public static void OutputSuccess()
{
Console.WriteLine("Done!");
Console.WriteLine();
}

/// <summary>
/// Shows an error message, in red.
/// </summary>
/// <param name="message">The message to show.</param>
public static void OutputErrorLine(string message)
{
ConsoleColor colorSaved = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(message);
Console.ForegroundColor = colorSaved;
}
}
}
31 changes: 31 additions & 0 deletions src/FederationSetup/FederationSetup.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<StartupObject>FederationSetup.Program</StartupObject>
<RuntimeIdentifiers>win10-x64;</RuntimeIdentifiers>
<DebugType>Full</DebugType>
<CodeAnalysisRuleSet>..\None.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin.Features.PoA\Stratis.Bitcoin.Features.PoA.csproj" />
<ProjectReference Include="..\Stratis.Bitcoin.Networks\Stratis.Bitcoin.Networks.csproj" />
<ProjectReference Include="..\Stratis.Sidechains.Networks\Stratis.Sidechains.Networks.csproj" />
</ItemGroup>

</Project>
130 changes: 130 additions & 0 deletions src/FederationSetup/GenesisMiner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Text;
using NBitcoin;
using NBitcoin.DataEncoders;
using Stratis.Bitcoin.Features.SmartContracts.PoA;
using Stratis.Sidechains.Networks;
using Xunit;
using Xunit.Abstractions;

namespace FederationSetup
{
public class GenesisMiner
{
private readonly ITestOutputHelper output;

public GenesisMiner(ITestOutputHelper output = null)
{
if (output == null) return;
this.output = output;
}

public string MineGenesisBlocks(SmartContractPoAConsensusFactory consensusFactory, string coinbaseText)
{
var output = new StringBuilder();

Console.WriteLine("Looking for genesis blocks for the 3 networks, this might take a while.");
Console.WriteLine(Environment.NewLine);

var targets = new Dictionary<uint256, string>
{
{ 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<uint256, string> target in targets)
{
Block genesisBlock = this.GeneterateBlock(consensusFactory, coinbaseText, target.Key);
output.AppendLine(this.NetworkOutput(genesisBlock, target.Value, coinbaseText));
}

return output.ToString();
}

private Block GeneterateBlock(SmartContractPoAConsensusFactory consensusFactory, string coinbaseText, uint256 target)
{
return MineGenesisBlock(consensusFactory, coinbaseText, new Target(target), Money.Zero);
}

private string NetworkOutput(Block genesisBlock, string network, string coinbaseText)
{
var header = (SmartContractPoABlockHeader) genesisBlock.Header;

var output = new StringBuilder();
output.AppendLine(network);
output.AppendLine("bits: " + header.Bits);
output.AppendLine("nonce: " + header.Nonce);
output.AppendLine("time: " + header.Time);
output.AppendLine("version: " + header.Version);
output.AppendLine("hash: " + genesisBlock.GetHash());
output.AppendLine("merkleroot: " + header.HashMerkleRoot);
output.AppendLine("coinbase text: " + coinbaseText);
output.AppendLine("hash state root: " + header.HashStateRoot);
output.AppendLine(Environment.NewLine);

return output.ToString();
}

public static Block MineGenesisBlock(SmartContractPoAConsensusFactory consensusFactory, string coinbaseText, Target target, Money genesisReward, int version = 1)
{
if (consensusFactory == null)
throw new ArgumentException($"Parameter '{nameof(consensusFactory)}' cannot be null. Use 'new ConsensusFactory()' for Bitcoin-like proof-of-work blockchains and 'new PosConsensusFactory()' for Stratis-like proof-of-stake blockchains.");

if (string.IsNullOrEmpty(coinbaseText))
throw new ArgumentException($"Parameter '{nameof(coinbaseText)}' cannot be null. Use a news headline or any other appropriate string.");

if (target == null)
throw new ArgumentException($"Parameter '{nameof(target)}' cannot be null. Example use: new Target(new uint256(\"0000ffff00000000000000000000000000000000000000000000000000000000\"))");

if (genesisReward == null)
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(
Op.GetPushOp(0),
new Op()
{
Code = (OpcodeType)0x1,
PushData = new[] { (byte)42 }
},
Op.GetPushOp(Encoders.ASCII.DecodeData(coinbaseText)))
});

txNew.AddOutput(new TxOut()
{
Value = genesisReward,
});

Block genesis = consensusFactory.CreateBlock();
genesis.Header.BlockTime = time;
genesis.Header.Bits = target;
genesis.Header.Nonce = 0;
genesis.Header.Version = version;
genesis.Transactions.Add(txNew);
genesis.Header.HashPrevBlock = uint256.Zero;
genesis.UpdateMerkleRoot();

((SmartContractPoABlockHeader)genesis.Header).HashStateRoot = new uint256("21B463E3B52F6201C0AD6C991BE0485B6EF8C092E64583FFA655CC1B171FE856"); // Set StateRoot to empty trie.

// Iterate over the nonce until the proof-of-work is valid.
// This will mean the block header hash is under the target.
while (!genesis.CheckProofOfWork())
{
genesis.Header.Nonce++;
if (genesis.Header.Nonce == 0)
genesis.Header.Time++;
}

return genesis;
}
}
}
39 changes: 39 additions & 0 deletions src/FederationSetup/MultisigAddressCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
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;
}

public string CreateMultisigAddresses(Network mainchainNetwork, Network sidechainNetwork, PubKey[] pubKeys, int quorum = 3)
{
var output = new StringBuilder();

Script payToMultiSig = PayToMultiSigTemplate.Instance.GenerateScriptPubKey(quorum, pubKeys);
output.AppendLine("Redeem script: " + payToMultiSig.ToString());

BitcoinAddress sidechainMultisigAddress = payToMultiSig.Hash.GetAddress(sidechainNetwork);
output.AppendLine("Sidechan P2SH: " + sidechainMultisigAddress.ScriptPubKey);
output.AppendLine("Sidechain Multisig address: " + sidechainMultisigAddress);

BitcoinAddress mainchainMultisigAddress = payToMultiSig.Hash.GetAddress(mainchainNetwork);
output.AppendLine("Mainchain P2SH: " + mainchainMultisigAddress.ScriptPubKey);
output.AppendLine("Mainchain Multisig address: " + mainchainMultisigAddress);

return output.ToString();
}
}
}
Loading

0 comments on commit 6cf7ec0

Please sign in to comment.