Initial commit
This commit is contained in:
parent
36e6a42e62
commit
9ea871e6e1
|
@ -57,3 +57,4 @@ typings/
|
|||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
.DS_Store
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
const fs = require('fs');
|
||||
|
||||
class MetaMaskWallet {
|
||||
|
||||
constructor() {
|
||||
this.privateKey;
|
||||
this.account;
|
||||
this.networkID;
|
||||
}
|
||||
|
||||
static createMetaMaskWallet(fileName) {
|
||||
var c=new MetaMaskWallet();
|
||||
//by default
|
||||
//c.account="0xF16AB2EA0a7F7B28C267cbA3Ed211Ea5c6e27411";
|
||||
// c.privateKey="03c06a9fab22fe0add145e337c5a8251e140f74468d72eab17ec7419ab812cd0";
|
||||
// c.networkID=4;//1-main network by default
|
||||
c.parser(fileName);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
parser(fileName) {
|
||||
var obj=JSON.parse(fs.readFileSync(fileName,"utf8"));
|
||||
this.account=obj.account;
|
||||
this.privateKey=obj.privateKey;
|
||||
this.networkID=obj.networkID;
|
||||
}
|
||||
|
||||
print() {
|
||||
console.log("account:"+this.account);
|
||||
console.log("privateKey:"+this.privateKey);
|
||||
console.log("networkID:"+this.networkID);
|
||||
}
|
||||
|
||||
}
|
||||
module.exports={
|
||||
MetaMaskWallet:MetaMaskWallet
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,48 @@
|
|||
# POA Network test setup
|
||||
|
||||
## How it works:
|
||||
- [x] gets content of master branch of `poa-network-consensus-contracts` repo
|
||||
- [x] compiles all POA Network contracts
|
||||
- [x] gets binary code of POA Network Consensus contract
|
||||
- [x] gets spec.json from `sokol` branch of `chain-spec` repo
|
||||
- [x] generates custom private, public key and password of MoC and save them to `./keys/moc` folder
|
||||
- [x] updates spec.json with new MoC and binary code of POA Network Consensus contracts
|
||||
- [x] starts MoC Parity node
|
||||
- [x] deploys secondary POA Network contracts
|
||||
- [x] gets content of master branch of `poa-scripts-moc` repo
|
||||
- [x] generates 1 initial key with password and copy it to `./keys/initial_keys` folder
|
||||
- [x] gets content of sokol branch of `poa-dapps-keys-generation` repo
|
||||
- [x] launches Ceremony DApp is locally builded from repo
|
||||
- [x] runs e2e tests on Ceremony DApp
|
||||
- [ ] saves generated production keys with Ceremony DApp to `./keys` folder
|
||||
- [ ] runs miners nodes
|
||||
- [ ] gets content of sokol branch of `poa-dapps-validators` repo
|
||||
- [ ] launches Validators DApp is locally builded from repo
|
||||
- [ ] runs e2e tests on Validators DApp
|
||||
- [ ] gets content of sokol branch of `poa-dapps-voting` repo
|
||||
- [ ] launches Voting DApp is locally builded from repo
|
||||
- [ ] runs e2e tests on Governance DApp
|
||||
|
||||
## Requirements
|
||||
1. Parity 1.9.2+
|
||||
|
||||
## Start test POA setup
|
||||
1. `npm i`
|
||||
2. `npm run start-test-setup`
|
||||
|
||||
At the successful end of POA test setup start you'll see this message `### POA test setup is configured ###`
|
||||
|
||||
### Expected result:
|
||||
- RPC of Parity node with unlocked MoC account will be on http://localhost:8545
|
||||
- Spec of the network is generated to `./spec` folder
|
||||
- MoC keystore file, password, private key is generated to `./keys/moc` folder
|
||||
- Initial key password, private key is generated to `.keys/initial_keys` folder
|
||||
- Parity config of MoC node is generated to `./nodes/parity-moc/moc.toml` file
|
||||
- Addresses of governance smart contracts are generated to `./submodules/poa-network-consensus-contracts/contracts.json`
|
||||
- ABI of smart contracts are generated to `./submodules/poa-network-consensus-contracts/build/contracts`
|
||||
|
||||
## Start e2e Ceremony test
|
||||
`npm run e2e-ceremony-test` (you need start test POA setup before)
|
||||
|
||||
## Finish test POA setup
|
||||
`npm run stop-test-setup`
|
|
@ -0,0 +1,56 @@
|
|||
const utils = require("./utils/utils");
|
||||
const downloadRepo = require("./utils/downloadRepo");
|
||||
const Constants = require("./utils/constants");
|
||||
const constants = Constants.constants;
|
||||
const dir = require('node-dir');
|
||||
const webdriver = require('selenium-webdriver'),
|
||||
chrome = require('selenium-webdriver/chrome');
|
||||
require("chromedriver");
|
||||
|
||||
const metaMaskWallet=require('./MetaMaskWallet.js');
|
||||
const MetaMaskWallet=metaMaskWallet.MetaMaskWallet;
|
||||
const meta=require('./pages/MetaMask.js');
|
||||
const buttonSubmit=require('./pages/MetaMask.js');
|
||||
const ceremony=require('./pages/Ceremony.js');
|
||||
|
||||
const timeout = ms => new Promise(res => setTimeout(res, ms))
|
||||
|
||||
const ceremonyURL = 'http://localhost:3000'
|
||||
|
||||
main()
|
||||
|
||||
async function main() {
|
||||
let options = new chrome.Options();
|
||||
options.addExtensions('./MetaMask_v3.14.1.crx');
|
||||
options.addArguments('start-maximized');
|
||||
options.addArguments('disable-popup-blocking');
|
||||
let driver = new webdriver.Builder()
|
||||
.withCapabilities(options.toCapabilities())
|
||||
.build();
|
||||
|
||||
var files = dir.files(constants.initialKeysFolder, {sync:true});
|
||||
|
||||
var wallet = MetaMaskWallet.createMetaMaskWallet(files[1]);
|
||||
|
||||
var metaMask = new meta.MetaMask(driver, wallet);
|
||||
var ceremonyPage = await new ceremony.Ceremony(driver,ceremonyURL);
|
||||
|
||||
metaMask.open();
|
||||
metaMask.activate();
|
||||
|
||||
ceremonyPage.open();
|
||||
//ceremonyPage.clickButtonGenerateKeys();
|
||||
|
||||
driver.sleep(2000);
|
||||
|
||||
ceremonyPage.clickButtonGenerateKeys();
|
||||
|
||||
driver.sleep(2000);
|
||||
|
||||
metaMask.switchToAnotherPage();
|
||||
driver.sleep(2000);
|
||||
if ( await metaMask.isElementPresent(buttonSubmit.buttonSubmit)) {
|
||||
metaMask.submitTransaction();
|
||||
ceremonyPage.switchToAnotherPage();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
const dir = require('node-dir');
|
||||
const Constants = require("./utils/constants");
|
||||
const constants = Constants.constants;
|
||||
const keythereum = require("keythereum");
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
main()
|
||||
|
||||
function main() {
|
||||
let initial_keys = {};
|
||||
dir.readFiles(constants.scriptsMocOutputFolder,
|
||||
function(err, content, filepath, next) {
|
||||
let filename = path.basename(filepath)
|
||||
|
||||
if (filename == '.gitkeep') {
|
||||
return next();
|
||||
}
|
||||
|
||||
let key = path.parse(filename).name;
|
||||
if (!initial_keys[key])
|
||||
initial_keys[key] = {};
|
||||
if (filename.includes(".json")) {
|
||||
let keyStore = content;
|
||||
initial_keys[key].keyStore = keyStore;
|
||||
} else if (filename.includes(".key")) {
|
||||
initial_keys[key].password = content
|
||||
}
|
||||
|
||||
if (initial_keys[key].password && initial_keys[key].keyStore)
|
||||
initial_keys[key].privateKey = keythereum.recover(initial_keys[key].password, JSON.parse(initial_keys[key].keyStore)).toString('hex');
|
||||
if (err) throw err;
|
||||
next();
|
||||
},
|
||||
function(err, files){
|
||||
for (let initial_key in initial_keys) {
|
||||
let keyObj = {
|
||||
address: `0x${initial_key}`,
|
||||
privateKey: initial_keys[initial_key].privateKey
|
||||
}
|
||||
fs.writeFileSync(`${constants.initialKeysFolder}${keyObj.address}`, JSON.stringify(keyObj, null, 2));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
[parity]
|
||||
chain = "./spec/spec.json"
|
||||
base_path = "./nodes/parity-moc"
|
||||
|
||||
[network]
|
||||
port = 30300
|
||||
|
||||
[rpc]
|
||||
cors = ["null"]
|
||||
hosts = ["all"]
|
||||
port = 8545
|
||||
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
|
||||
|
||||
[account]
|
||||
unlock = []
|
||||
password = ["./keys/moc/moc.pwd"]
|
||||
|
||||
[mining]
|
||||
force_sealing = true
|
||||
engine_signer = ""
|
||||
reseal_on_txs = "none"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
[parity]
|
||||
chain = "./spec/spec.json"
|
||||
base_path = ""
|
||||
|
||||
[network]
|
||||
port = 30301
|
||||
discovery=true
|
||||
reserved_peers="./reserved_peers"
|
||||
|
||||
[rpc]
|
||||
cors = ["null"]
|
||||
hosts = ["all"]
|
||||
port = 8554
|
||||
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
|
||||
|
||||
[account]
|
||||
unlock = []
|
||||
password = []
|
||||
|
||||
[mining]
|
||||
force_sealing = true
|
||||
engine_signer = ""
|
||||
reseal_on_txs = "none"
|
||||
|
||||
[websockets]
|
||||
disable = false
|
||||
port = 8546
|
||||
interface = "all"
|
||||
origins = ["all"]
|
||||
apis = ["web3", "eth", "net", "parity", "traces", "rpc", "secretstore"]
|
||||
hosts = ["all"]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "poa-test-setup",
|
||||
"version": "0.1.0",
|
||||
"private": false,
|
||||
"homepage": "",
|
||||
"dependencies": {
|
||||
"chromedriver": "^2.35.0",
|
||||
"create-poa-crowdsale": "^1.0.33",
|
||||
"download-git-repo": "^1.0.2",
|
||||
"keythereum": "^1.0.2",
|
||||
"node-dir": "^0.1.17",
|
||||
"node-fetch": "^2.0.0",
|
||||
"password-generator": "^2.2.0",
|
||||
"path": "^0.12.7",
|
||||
"selenium-webdriver": "^3.6.0",
|
||||
"toml": "^2.3.3",
|
||||
"toml-js": "0.0.8",
|
||||
"web3": "^1.0.0-beta.29"
|
||||
},
|
||||
"scripts": {
|
||||
"start-test-setup": "npm run download-repos && npm run prepare-contracts-repo && npm run prepare-moc-node && npm run start-moc-node && npm run deploy-secondary-contracts && npm run prepare-scrips-moc-repo && npm run prepare-ceremony-dapp && npm run prepare-ceremony-dapp-more && npm run generate-initial-keys && npm run get-private-initial-keys && npm run start-ceremony && npm run test-setup-is-started",
|
||||
"download-repos": "git submodule update --init --recursive --remote",
|
||||
"prepare-contracts-repo": "bash ./scripts/prepare-contracts-repo",
|
||||
"prepare-moc-node": "node prepareMoCNode",
|
||||
"start-moc-node": "parity --config ./nodes/parity-moc/moc.toml > /dev/null 2>&1 &",
|
||||
"deploy-secondary-contracts": "bash ./scripts/deploy-secondary-contracts",
|
||||
"prepare-scrips-moc-repo": "node prepareMoCScripts",
|
||||
"prepare-ceremony-dapp": "node prepareCeremonyDapp",
|
||||
"prepare-ceremony-dapp-more": "cd ./submodules/poa-dapps-keys-generation && npm i > /dev/null 2>&1",
|
||||
"generate-initial-key": "bash ./scripts/generate-initial-key",
|
||||
"generate-initial-keys": "bash ./scripts/generate-initial-keys",
|
||||
"get-private-initial-keys": "node getPrivateInitialKeys",
|
||||
"start-ceremony": "cd ./submodules/poa-dapps-keys-generation && npm start > /dev/null 2>&1 &",
|
||||
"test-setup-is-started": "echo '### POA test setup is configured ###'",
|
||||
"e2e-ceremony-test": "node e2eCeremonyTest",
|
||||
"stop-test-setup": "rm -rf ./submodules/poa-dapps-keys-generation && rm -rf ./submodules/poa-scripts-moc/generateInitialKey/output/* && git clean -f -d && kill -9 $(lsof -t -i:8545)"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
const page=require('./Page.js');
|
||||
const webdriver = require('selenium-webdriver'),
|
||||
chrome = require('selenium-webdriver/chrome'),
|
||||
firefox = require('selenium-webdriver/firefox'),
|
||||
by = require('selenium-webdriver/lib/by');
|
||||
|
||||
const generateKeysButton = by.By.xpath("//*[@id=\"root\"]/div/section/div/div");
|
||||
|
||||
class Ceremony extends page.Page{
|
||||
|
||||
constructor(driver,URL){
|
||||
super(driver);
|
||||
this.URL=URL;
|
||||
|
||||
}
|
||||
|
||||
open() {
|
||||
this.driver.get(this.URL);
|
||||
}
|
||||
|
||||
clickButtonGenerateKeys(){
|
||||
super.clickWithWait(generateKeysButton);
|
||||
}
|
||||
|
||||
open() {
|
||||
this.driver.get(this.URL);
|
||||
}
|
||||
}
|
||||
module.exports.Ceremony=Ceremony;
|
|
@ -0,0 +1,159 @@
|
|||
const key = require('selenium-webdriver').Key;
|
||||
const page=require('./Page.js');
|
||||
const webdriver = require('selenium-webdriver'),
|
||||
chrome = require('selenium-webdriver/chrome'),
|
||||
firefox = require('selenium-webdriver/firefox'),
|
||||
by = require('selenium-webdriver/lib/by');
|
||||
const By=by.By;
|
||||
//"chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn//popup.html"
|
||||
const IDMetaMask="nkbihfbeogaeaoehlefnkodbefgpgknn";
|
||||
const URL="chrome-extension://"+IDMetaMask+"//popup.html";
|
||||
const passMetaMask="kindzadza";
|
||||
const fieldEnterPass= By.xpath("//*[@id=\"password-box\"]");
|
||||
const buttonUnlock=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[1]/button");
|
||||
const buttonBuy= By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div[2]/button[1]");
|
||||
const buttonSend= By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div[2]/button[2]");
|
||||
const buttonSubmit=By.xpath("//*[@id=\"pending-tx-form\"]/div[3]/input");
|
||||
const fieldGasPrise=By.xpath("//*[@id=\"pending-tx-form\"]/div[1]/div[2]/div[3]/div[2]/div/div/input");
|
||||
///////Imported from TestCircle//////
|
||||
const buttonAccept=By.xpath('//*[@id="app-content"]/div/div[4]/div/button');
|
||||
const agreement=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div/p[1]/strong");
|
||||
const fieldNewPass=By.xpath("//*[@id=\"password-box\"]");
|
||||
const fieldConfirmPass=By.xpath("//*[@id=\"password-box-confirm\"]");
|
||||
const buttonCreate=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button");
|
||||
const fieldSecretWords=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/textarea");
|
||||
const buttonIveCopied=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button[1]");
|
||||
//const popupNetwork=By.xpath("//*[@id=\"network_component\"]/div/i");
|
||||
const popupNetwork=By.className("network-name");
|
||||
//const popupRinkeby=By.className("menu-icon golden-square");
|
||||
const popupRinkeby=By.css("Rinkeby Test Network");
|
||||
|
||||
|
||||
const popupAccount=By.xpath("//*[@id=\"app-content\"]/div/div[1]/div/div[2]/span/div");
|
||||
const popupImportAccount=By.xpath("//*[@id=\"app-content\"]/div/div[1]/div/div[2]/span/div/div/span/div/li[3]/span");
|
||||
const popupImportAccountCSS="#app-content > div > div.full-width > div > div:nth-child(2) > span > div > div > span > div > li:nth-child(4) > span";
|
||||
const fieldPrivateKey=By.xpath("//*[@id=\"private-key-box\"]");
|
||||
const pass="kindzadza";
|
||||
const buttonImport=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/button");
|
||||
const secretWords="mask divorce brief insane improve effort ranch forest width accuse wall ride";
|
||||
const amountEth=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div[2]/div[1]/div/div/div[1]/div[1]");
|
||||
const fieldNewRPCURL=By.id("new_rpc");
|
||||
const buttonSave=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/div/div[2]/button");
|
||||
//const arrowBackRPCURL=By.className("fa fa-arrow-left fa-lg cursor-pointer");
|
||||
const arrowBackRPCURL=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[1]/i");
|
||||
|
||||
var lengthNetworkMenu=6;
|
||||
var networks=[];
|
||||
|
||||
|
||||
|
||||
class MetaMask extends page.Page{
|
||||
|
||||
constructor(driver,wallet) {
|
||||
super(driver);
|
||||
this.URL=URL;
|
||||
this.wallet=wallet;
|
||||
}
|
||||
|
||||
setGasPriceTransaction(price) {
|
||||
super.fillWithWait(fieldGasPrise,price);
|
||||
}
|
||||
|
||||
clickButtonSubmit() {
|
||||
super.clickWithWait(buttonSubmit);
|
||||
}
|
||||
|
||||
clickPopupNetwork() {
|
||||
super.clickWithWait(popupNetwork);
|
||||
}
|
||||
|
||||
isReadyTransaction() {
|
||||
return this.isElementPresent(buttonSubmit);
|
||||
}
|
||||
|
||||
submitTransaction() {
|
||||
this.clickButtonSubmit();
|
||||
}
|
||||
|
||||
unlock() {
|
||||
//this.open();
|
||||
super.fillWithWait(fieldEnterPass,passMetaMask);
|
||||
super.clickWithWait(buttonUnlock);
|
||||
}
|
||||
|
||||
open() {
|
||||
this.driver.get(this.URL);
|
||||
}
|
||||
|
||||
clickDotMenu() {
|
||||
super.clickWithWait(dotMenu);
|
||||
}
|
||||
|
||||
|
||||
getAddressWallet() {
|
||||
//super.clickWithWait(addrWallet);
|
||||
return this.driver.findElement(addrWallet).getText();
|
||||
|
||||
}
|
||||
|
||||
activate() {
|
||||
super.clickWithWait(buttonAccept);
|
||||
const action=this.driver.actions();
|
||||
action.click(this.driver.findElement(agreement)).perform();
|
||||
//this.driver.findElement(agreement).click();
|
||||
// this.driver.sleep(2000);
|
||||
for (var i=0;i<9;i++) {
|
||||
action.sendKeys(key.TAB).perform();
|
||||
//this.driver.findElement(agreement).sendKeys(key.TAB);
|
||||
}
|
||||
super.clickWithWait(buttonAccept);
|
||||
super.fillWithWait(fieldNewPass,pass);
|
||||
super.fillWithWait(fieldConfirmPass,pass);
|
||||
super.clickWithWait(buttonCreate);
|
||||
this.driver.sleep(1500);
|
||||
// this.driver.findElement(fieldSecretWords).getText().then(console.log);
|
||||
super.clickWithWait(buttonIveCopied);
|
||||
this.chooseProvider();
|
||||
|
||||
super.clickWithWait(popupAccount);
|
||||
this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')[2].click();");
|
||||
|
||||
|
||||
super.fillWithWait(fieldPrivateKey,this.wallet.privateKey);
|
||||
this.driver.sleep(1500);
|
||||
super.clickWithWait(buttonImport);
|
||||
// this.driver.sleep(1500);
|
||||
//this.driver.findElement(amountEth).getText().then(console.log);
|
||||
}
|
||||
|
||||
async isElementPresent(element)
|
||||
{
|
||||
return await super.isElementPresent(element);
|
||||
}
|
||||
|
||||
chooseProvider(){
|
||||
super.clickWithWait(popupNetwork);
|
||||
|
||||
var n=4;
|
||||
if (n<=4)this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')["+n+"].click();");
|
||||
}
|
||||
|
||||
addNetwork(){
|
||||
var url="http://localhost:8545";
|
||||
|
||||
this.driver.executeScript("" +
|
||||
"document.getElementsByClassName('dropdown-menu-item')["+(lengthNetworkMenu-1)+"].click();");
|
||||
super.fillWithWait(fieldNewRPCURL,url);
|
||||
super.clickWithWait(buttonSave);
|
||||
|
||||
this.driver.sleep(1000);
|
||||
super.clickWithWait(arrowBackRPCURL);
|
||||
lengthNetworkMenu++;
|
||||
};
|
||||
}
|
||||
|
||||
module.exports={
|
||||
MetaMask:MetaMask,
|
||||
buttonSubmit:buttonSubmit
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
const webdriver = require('selenium-webdriver'),
|
||||
chrome = require('selenium-webdriver/chrome'),
|
||||
firefox = require('selenium-webdriver/firefox'),
|
||||
by = require('selenium-webdriver/lib/by');
|
||||
const key = require('selenium-webdriver').Key;
|
||||
const Twait=20000;
|
||||
|
||||
console.log(module.filename);
|
||||
class Page {
|
||||
|
||||
constructor(driver){
|
||||
this.driver=driver;
|
||||
this.pageID;
|
||||
this.footer;
|
||||
this.header;
|
||||
}
|
||||
|
||||
async isElementPresent(element) {
|
||||
var q;
|
||||
try {
|
||||
q = await this.driver.findElement(element).isDisplayed();
|
||||
} catch (err) {
|
||||
q = false;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
clearField(element){
|
||||
let field = this.driver.wait(webdriver.until.elementLocated(element), Twait);
|
||||
const c=key.chord(key.CONTROL,"a");
|
||||
const action=this.driver.actions();
|
||||
action.click(field).perform();
|
||||
//action.click(field).perform();
|
||||
this.driver.sleep(500);
|
||||
action.sendKeys(c).perform();
|
||||
action.sendKeys(key.DELETE).perform();
|
||||
action.sendKeys(key.DELETE).perform();
|
||||
}
|
||||
|
||||
clickWithWait(element) {
|
||||
let button = this.driver.wait(webdriver.until.elementLocated(element), Twait);
|
||||
button.click();
|
||||
}
|
||||
|
||||
fillWithWait(element,k) {
|
||||
let field = this.driver.wait(webdriver.until.elementLocated(element), Twait);
|
||||
field.sendKeys(k);
|
||||
|
||||
}
|
||||
|
||||
refresh(){
|
||||
this.driver.navigate().refresh();
|
||||
}
|
||||
|
||||
switchToAnotherPage(){
|
||||
let dr=this.driver;
|
||||
|
||||
dr.getWindowHandle().then(function (mainWindowHandle) {
|
||||
|
||||
dr.getAllWindowHandles().then(function (windowHandles) {
|
||||
|
||||
windowHandles.forEach(function(handle){
|
||||
|
||||
if(!(handle===mainWindowHandle))
|
||||
{
|
||||
dr.switchTo().window(handle);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports.Page=Page;
|
|
@ -0,0 +1,22 @@
|
|||
const fs = require('fs');
|
||||
const Constants = require("./utils/constants");
|
||||
const constants = Constants.constants;
|
||||
const utils = require("./utils/utils");
|
||||
|
||||
main()
|
||||
|
||||
function main() {
|
||||
const pathToAddressesJSON = `${constants.pathToContractRepo}/${constants.addressesSourceFile}`;
|
||||
const addresses = JSON.parse(fs.readFileSync(pathToAddressesJSON));
|
||||
|
||||
const addition = `const local = { "KEYS_MANAGER_ADDRESS": "${addresses.KEYS_MANAGER_ADDRESS}" };`
|
||||
|
||||
let addressesFromDapp = fs.readFileSync(`${constants.pathToCeremonyDAppRepo}/src/addresses.js`, 'utf8');
|
||||
let lastImport = `import helpers from "./helpers";`;
|
||||
addressesFromDapp = addressesFromDapp.replace(lastImport, lastImport + addition)
|
||||
addressesFromDapp = addressesFromDapp.replace('resolve({addresses: json', 'resolve({addresses: local')
|
||||
|
||||
fs.writeFileSync(`${constants.pathToCeremonyDAppRepo}/src/addresses.js`, addressesFromDapp);
|
||||
|
||||
console.log("Ceremony Dapp is prepared");
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
const downloadRepo = require("./utils/downloadRepo");
|
||||
const Constants = require("./utils/constants");
|
||||
const constants = Constants.constants;
|
||||
const fs = require('fs');
|
||||
const keythereum = require("keythereum");
|
||||
const generatePassword = require('password-generator');
|
||||
const Web3 = require('web3');
|
||||
const utils = require("./utils/utils");
|
||||
const toml = require('toml');
|
||||
const tomlJS = require('toml-js');
|
||||
|
||||
main()
|
||||
|
||||
async function main() {
|
||||
const consensusObj = JSON.parse(fs.readFileSync(constants.pathToConsensusContract));
|
||||
const consensusBytecode = consensusObj.bytecode;
|
||||
|
||||
const mocPassword = generatePassword(20, false)
|
||||
const keyObject = await generateAddress(mocPassword)
|
||||
|
||||
const moc = `0x${keyObject.address}`;
|
||||
const keyStoreFileName = `${constants.mocKeysFolder}${keyObject.address}.json`;
|
||||
const privateKeyFileName = `${constants.mocKeysFolder}moc.key`;
|
||||
const passwordFileName = `${constants.mocKeysFolder}moc.pwd`;
|
||||
const mocKeyStore = JSON.stringify(keyObject);
|
||||
|
||||
const privateKey = keythereum.recover(mocPassword, keyObject).toString('hex');
|
||||
|
||||
let spec
|
||||
try {
|
||||
spec = await utils.getSpec('sokol');
|
||||
} catch (e) {
|
||||
return console.log(e.message)
|
||||
}
|
||||
|
||||
utils.clearFolder(constants.mocKeysFolder);
|
||||
|
||||
let POAKeysFolder = `${constants.masterNodeKeysFolder}${spec.name}`;
|
||||
if (!fs.existsSync(POAKeysFolder)){
|
||||
fs.mkdirSync(POAKeysFolder);
|
||||
}
|
||||
utils.clearFolder(POAKeysFolder);
|
||||
try { await utils.saveToFile(keyStoreFileName, mocKeyStore) }
|
||||
catch (err) { return console.log(err.message); }
|
||||
console.log(`MoC keystore file ${moc} is generated to ${keyStoreFileName}`);
|
||||
|
||||
const key = {
|
||||
address: moc,
|
||||
privateKey: privateKey
|
||||
}
|
||||
|
||||
try { await utils.saveToFile(privateKeyFileName, JSON.stringify(key, null, 2)) }
|
||||
catch (err) { return console.log(err.message); }
|
||||
console.log(`MoC private key are generated to ${privateKeyFileName}`);
|
||||
|
||||
|
||||
try { await utils.saveToFile(passwordFileName, mocPassword) }
|
||||
catch (err) { return console.log(err.message); }
|
||||
console.log(`MoC password is generated to ${passwordFileName}`);
|
||||
|
||||
utils.clearFolder(constants.masterNodeKeysFolder);
|
||||
const masterNodeKeyStoreFolder = `${constants.masterNodeKeysFolder}${spec.name}`;
|
||||
fs.existsSync(masterNodeKeyStoreFolder) || fs.mkdirSync(masterNodeKeyStoreFolder);
|
||||
const masterNodeParentKeyStorePath = `${masterNodeKeyStoreFolder}/moc_${moc}.json`;
|
||||
try { await utils.saveToFile(masterNodeParentKeyStorePath, mocKeyStore) }
|
||||
catch (err) { return console.log(err.message); }
|
||||
console.log(`Keystore file is copied to ${masterNodeParentKeyStorePath}`);
|
||||
|
||||
web3 = new Web3(new Web3.providers.HttpProvider('https://sokol.poa.network'));
|
||||
const mocABIEncoded = web3.eth.abi.encodeParameters(['address', `address[]`], [moc, []]).substr(2);
|
||||
const newConsensusBytecode = consensusBytecode + mocABIEncoded;
|
||||
|
||||
spec.accounts[moc] = {
|
||||
balance: '252460800000000000000000000'
|
||||
};
|
||||
|
||||
spec.accounts[constants.poaNetworkConsensusContractAddress] = {
|
||||
balance: '1',
|
||||
constructor: newConsensusBytecode
|
||||
};
|
||||
spec.engine.authorityRound.params.validators.multi = {
|
||||
"0": {
|
||||
"safeContract": constants.poaNetworkConsensusContractAddress
|
||||
}
|
||||
};
|
||||
|
||||
utils.clearFolder(constants.specFolder);
|
||||
try { await utils.saveToFile(`${constants.specFolder}spec.json`, JSON.stringify(spec, null, 2)) }
|
||||
catch (err) { return console.log(err.message); }
|
||||
|
||||
console.log(`spec.json is generated to ${constants.specFolder}`);
|
||||
|
||||
const masterNodeExampleTomlPath = `${constants.nodeFolder}node-master.toml`;
|
||||
const masterNodeTomlContent = fs.readFileSync(masterNodeExampleTomlPath, "utf8");
|
||||
const masterNodeToml = toml.parse(masterNodeTomlContent);
|
||||
|
||||
masterNodeToml.account.unlock = [moc];
|
||||
masterNodeToml.mining.engine_signer = moc;
|
||||
const newToml = tomlJS.dump(masterNodeToml);
|
||||
|
||||
utils.removeFolderRecursive(`${constants.masterNodeFolder}cache`);
|
||||
utils.removeFolderRecursive(`${constants.masterNodeFolder}chains`);
|
||||
utils.removeFolderRecursive(`${constants.masterNodeFolder}dapps`);
|
||||
utils.removeFolderRecursive(`${constants.masterNodeFolder}network`);
|
||||
|
||||
const mocTomlPath = `${constants.masterNodeFolder}moc.toml`;
|
||||
try { await utils.saveToFile(`${mocTomlPath}`, newToml)}
|
||||
catch (err) { return console.log(err.message); }
|
||||
|
||||
console.log("MoC node is prepared");
|
||||
}
|
||||
|
||||
|
||||
//generates initial key keystore file
|
||||
function generateAddress(password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let params = { keyBytes: 32, ivBytes: 16 };
|
||||
|
||||
let dk = keythereum.create(params);
|
||||
|
||||
keythereum.create(params, function (dk) {
|
||||
let options = {};
|
||||
keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function (keyObject) {
|
||||
resolve(keyObject);
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
const fs = require('fs');
|
||||
const Constants = require("./utils/constants");
|
||||
const constants = Constants.constants;
|
||||
const utils = require("./utils/utils");
|
||||
|
||||
main()
|
||||
|
||||
function main() {
|
||||
const generateInitialKeyConfig = JSON.parse(fs.readFileSync(constants.scriptsMocConfigPath));
|
||||
const keysManagerObj = JSON.parse(fs.readFileSync(constants.pathToKeysManagerContract));
|
||||
|
||||
const pathToAddressesJSON = `${constants.pathToContractRepo}/${constants.addressesSourceFile}`;
|
||||
|
||||
const addresses = JSON.parse(fs.readFileSync(pathToAddressesJSON));
|
||||
|
||||
generateInitialKeyConfig.Ethereum.contracts.KeysManager.addr = addresses.KEYS_MANAGER_ADDRESS;
|
||||
generateInitialKeyConfig.Ethereum.contracts.KeysManager.abi = keysManagerObj.abi;
|
||||
|
||||
utils.saveToFile(constants.scriptsMocConfigPath, JSON.stringify(generateInitialKeyConfig, null, 2));
|
||||
|
||||
console.log("MoC script is prepared");
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
directory=./submodules/poa-network-consensus-contracts
|
||||
|
||||
consensus="0x8bf38d4764929064f2d4d3a56520a76ab3df415b"
|
||||
moc_object=$(cat ./keys/moc/moc.key)
|
||||
moc=$(node -pe 'JSON.parse(process.argv[1]).address' "${moc_object}")
|
||||
cmd=$(cd ${directory} && SAVE_TO_FILE=true POA_NETWORK_CONSENSUS_ADDRESS=${consensus} MASTER_OF_CEREMONY=${moc} ./node_modules/.bin/truffle migrate --reset --network sokol)
|
||||
#echo ${cmd}
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
directory=./submodules/poa-scripts-moc/generateInitialKey
|
||||
node_modules=${directory}/node_modules
|
||||
if [ ! -d ${node_modules} ]; then
|
||||
|
||||
cmd=$(cd ${directory} && npm i && node generateInitialKey.js)
|
||||
|
||||
else
|
||||
|
||||
cmd2=$(cd ${directory} && node generateInitialKey.js)
|
||||
|
||||
fi
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
initial_keys_number=1
|
||||
for i in {1..${initial_keys_number}}
|
||||
do
|
||||
npm run generate-initial-key
|
||||
done
|
||||
|
||||
echo "All initial keys are generated"
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash
|
||||
|
||||
directory=./submodules/poa-network-consensus-contracts
|
||||
build_dir=${directory}/build
|
||||
|
||||
if [ -d ${directory} ]; then
|
||||
if [ ! -d ${build_dir} ]; then
|
||||
|
||||
cmd=$(cd ${directory} && npm i && bash ./make_flat.sh && ./node_modules/.bin/truffle compile)
|
||||
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,35 @@
|
|||
let constants = {};
|
||||
constants.organization = 'poanetwork';
|
||||
constants.chainSpecRepoName = 'poa-chain-spec';
|
||||
constants.contractsRepoName = 'poa-network-consensus-contracts';
|
||||
constants.pathToContractRepo = `./submodules/${constants.contractsRepoName}`;
|
||||
constants.scriptsMocRepoName = 'poa-scripts-moc';
|
||||
constants.pathToScriptsMocRepo = `./submodules/${constants.scriptsMocRepoName}`;
|
||||
constants.CeremonyDAppRepoName = 'poa-dapps-keys-generation';
|
||||
constants.pathToCeremonyDAppRepo = `./submodules/${constants.CeremonyDAppRepoName}`;
|
||||
constants.scriptsMocConfigPath = `${constants.pathToScriptsMocRepo}/config.json`;
|
||||
constants.scriptsMocOutputFolder = `${constants.pathToScriptsMocRepo}/generateInitialKey/output`;
|
||||
constants.addressesSourceFile = 'contracts.json';
|
||||
constants.contractsFolder = `${constants.pathToContractRepo}/build/contracts`;
|
||||
constants.pathToConsensusContract = `${constants.contractsFolder}/PoaNetworkConsensus.json`;
|
||||
constants.pathToKeysManagerContract = `${constants.contractsFolder}/KeysManager.json`;
|
||||
constants.keysFolder = `./keys/`;
|
||||
constants.nodeFolder = `./nodes/`;
|
||||
constants.masterNodeFolder = `./nodes/parity-moc/`;
|
||||
constants.masterNodeKeysFolder = `${constants.masterNodeFolder}keys/`;
|
||||
constants.specFolder = `./spec/`;
|
||||
constants.mocKeysFolder = `${constants.keysFolder}moc/`;
|
||||
constants.initialKeysFolder = `${constants.keysFolder}initial_keys/`;
|
||||
constants.poaNetworkConsensusContractAddress = '0x8bf38d4764929064f2d4d3a56520a76ab3df415b';
|
||||
constants.ABIsSources = {
|
||||
'KeysManager': 'KeysManager.abi.json',
|
||||
'PoaNetworkConsensus': 'PoaNetworkConsensus.abi.json',
|
||||
'BallotStorage': 'BallotsStorage.abi.json',
|
||||
'ValidatorMetadata': 'ValidatorMetadata.abi.json',
|
||||
'VotingToChangeKeys': 'VotingToChangeKeys.abi.json',
|
||||
'VotingToChangeMinThreshold': 'VotingToChangeMinThreshold.abi.json',
|
||||
'VotingToChangeProxyAddress': 'VotingToChangeProxyAddress.abi.json'
|
||||
};
|
||||
module.exports = {
|
||||
constants
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
const Constants = require("./constants");
|
||||
const constants = Constants.constants;
|
||||
const download = require('download-git-repo');
|
||||
|
||||
|
||||
async function downloadRepo(repoName) {
|
||||
const repo = `${constants.organization}/${repoName}`;
|
||||
download(repo, `./tests/${repoName}`, function (err) {
|
||||
console.log(err ? err.message : `${repo} is downloaded`)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = downloadRepo
|
|
@ -0,0 +1,74 @@
|
|||
const Constants = require("./constants");
|
||||
const constants = Constants.constants;
|
||||
const fetch = require('node-fetch');
|
||||
const fs = require('fs');
|
||||
|
||||
function ABIURL(branch, contract) {
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.chainSpecRepoName}/${branch}/abis/${constants.ABIsSources[contract]}`;
|
||||
return URL;
|
||||
}
|
||||
|
||||
function specURL(branch) {
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.chainSpecRepoName}/${branch}/spec.json`;
|
||||
return URL;
|
||||
}
|
||||
|
||||
function getABI(branch, contract) {
|
||||
let addr = ABIURL(branch, contract);
|
||||
return fetch(addr).then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
}
|
||||
|
||||
function getSpec(branch) {
|
||||
let addr = specURL(branch);
|
||||
return fetch(addr).then(function(response) {
|
||||
return response.json();
|
||||
})
|
||||
}
|
||||
|
||||
let clearFolder = function(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
fs.readdirSync(path).forEach(function(file, index){
|
||||
var curPath = path + "/" + file;
|
||||
if (!fs.lstatSync(curPath).isDirectory()) {
|
||||
if (file != '.gitkeep') {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let removeFolderRecursive = function(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
fs.readdirSync(path).forEach(function(file, index){
|
||||
var curPath = path + "/" + file;
|
||||
if (fs.lstatSync(curPath).isDirectory()) { // recurse
|
||||
removeFolderRecursive(curPath);
|
||||
} else { // delete file
|
||||
if (file != '.gitkeep') {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(path);
|
||||
}
|
||||
};
|
||||
|
||||
function saveToFile(filename, content) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(filename, content, (err) => {
|
||||
if (err) reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSpec,
|
||||
getABI,
|
||||
clearFolder,
|
||||
removeFolderRecursive,
|
||||
saveToFile
|
||||
}
|
Loading…
Reference in New Issue