Oracles network keys generation dapp. Initial commit

This commit is contained in:
viktor 2017-06-14 00:13:03 +03:00
commit 173cd6aed2
62 changed files with 2227 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
.DS_Store

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# Oracles PoA Keys Generation Dapp
![](./index.png)
![](./results.png)

BIN
assets/images/bg_footer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
assets/images/bg_header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
assets/images/loading.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/images/logos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
assets/images/logos@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
assets/images/socials.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="20"><path fill="#FBFBFB" fill-rule="evenodd" d="M21.377 14.326L14.152 1.82a3.645 3.645 0 0 0-6.312 0L.488 14.54a3.636 3.636 0 0 0 0 3.64A3.645 3.645 0 0 0 3.644 20h14.712A3.643 3.643 0 0 0 22 16.36c0-.753-.23-1.455-.623-2.034zm-8.821 1.217c0 .861-.663 1.519-1.556 1.519s-1.556-.658-1.556-1.519v-.035c0-.857.663-1.519 1.556-1.519s1.556.658 1.556 1.519v.035zm.036-10.238l-.77 6.717c-.052.484-.373.785-.822.785-.449 0-.77-.305-.822-.785l-.77-6.721c-.051-.519.23-.912.715-.912h1.75c.485.004.771.397.719.916z"/></svg>

After

Width:  |  Height:  |  Size: 571 B

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,48 @@
function addValidator(api, func, validatorViewObj, address, contractAddr, cb) {
var funcHex = func.hexEncode();
var funcParamsNumber = 7;
var standardLength = 32;
SHA3Encrypt(api, funcHex, function(funcEncode) {
var funcEncodePart = funcEncode.substring(0,10);
if (validatorViewObj.miningKey.indexOf("0x") > -1) {
validatorViewObj.miningKey = validatorViewObj.miningKey.substr(2);
}
validatorViewObj.miningKey = validatorViewObj.miningKey.toLowerCase();
var fullNameHex = "0x" + toUnifiedLengthRight(toHexString(toUTF8Array(validatorViewObj.fullName)));
var streetNameHex = "0x" + toUnifiedLengthRight(toHexString(toUTF8Array(validatorViewObj.streetName)));
var stateHex = "0x" + toUnifiedLengthRight(toHexString(toUTF8Array(validatorViewObj.state)));
var parameterLocation1 = standardLength*funcParamsNumber;
var parameterLocation2 = parameterLocation1 + standardLength*(countRows(fullNameHex));
var parameterLocation3 = parameterLocation2 + standardLength*(countRows(streetNameHex));
var data = funcEncodePart
+ toUnifiedLengthLeft(validatorViewObj.miningKey)
+ toUnifiedLengthLeft(validatorViewObj.zip.toString(16))
+ toUnifiedLengthLeft(validatorViewObj.licenseID.toString(16))
+ toUnifiedLengthLeft(validatorViewObj.licenseExpiredAt.toString(16))
+ toUnifiedLengthLeft(parameterLocation1.toString(16))
+ toUnifiedLengthLeft(parameterLocation2.toString(16))
+ toUnifiedLengthLeft(parameterLocation3.toString(16))
+ toUnifiedLengthLeft(bytesCount(validatorViewObj.fullName).toString(16)) + fullNameHex.substring(2)
+ toUnifiedLengthLeft(bytesCount(validatorViewObj.streetName).toString(16)) + streetNameHex.substring(2)
+ toUnifiedLengthLeft(bytesCount(validatorViewObj.state).toString(16)) + stateHex.substring(2);
estimateGas(api, address, contractAddr, data, null, function(estimatedGas, err) {
if (err) {
cb(null, err);
return;
}
estimatedGas += 100000;
sendTx(api, address, contractAddr, data, null, estimatedGas, function(txHash, err) {
if (err) {
cb(txHash, err);
return;
}
cb(txHash);
});
});
});
}

View File

@ -0,0 +1,34 @@
function generateAddress(cb) {
var params = { keyBytes: 32, ivBytes: 16 };
// synchronous
var dk = keythereum.create(params);
// dk:
/*{
privateKey: <Buffer ...>,
iv: <Buffer ...>,
salt: <Buffer ...>
}*/
// asynchronous
keythereum.create(params, function (dk) {
var options = {};
var password = generatePassword();
keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function (keyObject) {
console.log(keyObject);
console.log(JSON.stringify(keyObject));
//keythereum.exportToFile(keyObject);
cb(keyObject, password);
});
});
}
function generatePassword() {
var length = 8,
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
retVal = "";
for (var i = 0, n = charset.length; i < length; ++i) {
retVal += charset.charAt(Math.floor(Math.random() * n));
}
return retVal;
}

View File

@ -0,0 +1,64 @@
function SHA3Encrypt(api, str, cb) {
api._web3.sha3(str).then(function(strEncode) {
cb(strEncode, null);
}).catch(function(err) {
console.log(err);
cb("", err);
});
}
function estimateGas(api, from, to, data, val, cb) {
var props;
if (val)
props = { from: from, value: val, data: null, to: to };
else
props = { from: from, data: data, to: to };
api.eth.estimateGas(props).then(function(res) {
if (!res) {
cb(null, {"code": 500, "title": "Error", "message": "Unexpected error"});
return;
}
var gasWillUsed = res.c[0];
cb(gasWillUsed);
}, function(err) {
console.log(err);
cb(null, err);
}).catch(function(err) {
console.log(err);
cb(null, err);
});
}
function sendTx(api, from, to, data, val, estimatedGas, cb) {
var props;
if (val)
props = { from: from, value: val, to: to, gas: estimatedGas };
else
props = { from: from, data: data, to: to, gas: estimatedGas };
api.eth.sendTransaction(props)
.then(function(txHash) {
cb(txHash);
}).catch(function(err) {
console.log(err);
cb(null, err);
});
}
function call(api, from, to, data, cb) {
var props;
if (from)
props = { from: from, data: data, to: to };
else
props = { data: data, to: to };
api.eth.call(props)
.then(function(data) {
cb(data);
}).catch(function(err) {
console.log(err);
cb(null, err);
});
}

View File

@ -0,0 +1,17 @@
function checkInitialKey(api, config, func, initialKey, contractAddr, cb) {
var funcHex = func.hexEncode();
var funcParamsNumber = 1;
var standardLength = 32;
SHA3Encrypt(api, funcHex, function(funcEncode) {
var funcEncodePart = funcEncode.substring(0,10);
var data = funcEncodePart
+ toUnifiedLengthLeft(initialKey);
call(api, "0x" + initialKey, contractAddr, data, function(respHex) {
console.log(respHex);
cb(parseInt(respHex, 16));
});
});
}

View File

@ -0,0 +1,80 @@
function toUnifiedLengthLeft(strIn) {//for numbers
var strOut = "";
for (var i = 0; i < 64 - strIn.length; i++) {
strOut += "0"
}
strOut += strIn;
return strOut;
}
function countRows(strIn) {
var rowsCount = 0;
if (strIn.length%64 > 0)
rowsCount = parseInt(strIn.length/64) + 1;
else
rowsCount = parseInt(strIn.length/64);
return rowsCount;
}
function toUnifiedLengthRight(strIn) {//for strings
var strOut = "";
strOut += strIn;
var rowsCount = countRows(strIn);
for (var i = 0; i < rowsCount*64 - strIn.length; i++) {
strOut += "0"
}
return strOut;
}
String.prototype.hexEncode = function(){
var hex, i;
var result = "";
for (i=0; i<this.length; i++) {
hex = this.charCodeAt(i).toString(16);
result += hex.slice(-4);
}
return result
}
function toUTF8Array(str) {
var utf8 = [];
for (var i=0; i < str.length; i++) {
var charcode = str.charCodeAt(i);
if (charcode < 0x80) utf8.push(charcode);
else if (charcode < 0x800) {
utf8.push(0xc0 | (charcode >> 6),
0x80 | (charcode & 0x3f));
}
else if (charcode < 0xd800 || charcode >= 0xe000) {
utf8.push(0xe0 | (charcode >> 12),
0x80 | ((charcode>>6) & 0x3f),
0x80 | (charcode & 0x3f));
}
// surrogate pair
else {
i++;
// UTF-16 encodes 0x10000-0x10FFFF by
// subtracting 0x10000 and splitting the
// 20 bits of 0x0-0xFFFFF into two halves
charcode = 0x10000 + (((charcode & 0x3ff)<<10)
| (str.charCodeAt(i) & 0x3ff));
utf8.push(0xf0 | (charcode >>18),
0x80 | ((charcode>>12) & 0x3f),
0x80 | ((charcode>>6) & 0x3f),
0x80 | (charcode & 0x3f));
}
}
return utf8;
}
function toHexString(byteArray) {
return byteArray.map(function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
function bytesCount(s) {
return encodeURI(s).split(/%..|./).length - 1;
}

View File

@ -0,0 +1,27 @@
function createKeys(api, func, keys, address, contractAddr, cb) {
var funcHex = func.hexEncode();
var funcParamsNumber = 3;
var standardLength = 32;
var parameterLocation = standardLength*funcParamsNumber;
SHA3Encrypt(api, funcHex, function(funcEncode) {
var funcEncodePart = funcEncode.substring(0,10);
var data = funcEncodePart
+ toUnifiedLengthLeft(keys.miningKey.miningKeyObject.address)
+ toUnifiedLengthLeft(keys.payoutKey.payoutKeyObject.address)
+ toUnifiedLengthLeft(keys.votingKey.votingKeyObject.address);
estimateGas(api, address, contractAddr, data, null, function(estimatedGas) {
estimatedGas += 100000;
sendTx(api, address, contractAddr, data, null, estimatedGas, function(txHash, err) {
if (err) {
cb(txHash, err);
return;
}
cb(txHash);
});
});
});
}

View File

@ -0,0 +1,12 @@
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}

View File

@ -0,0 +1,213 @@
$(function() {
$(".loading-container").hide();
var keys = {
"miningKey": {},
"payoutKey": {},
"votingKey": {}
};
var api = window.parity.api;
var config;
$.getJSON("./assets/javascripts/config.json", function(_config) {
config = _config;
});
$(".create-keys-button").click(function() {
$("#initialKeySource").click();
})
$("#initialKeySource").change(initialKeyChosen);
function initialKeyChosen() {
$(this).remove();
$("<input type='file' id='initialKeySource' />").change(initialKeyChosen).appendTo($(".create-keys"));
var file = $(this).prop('files')[0];
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
try {
a = JSON.parse(evt.target.result);
} catch(e) {
swal("Error", "Invalid key file", "error");
return;
}
var keyJSON = JSON.parse(evt.target.result);
var address = keyJSON.address;
if (!address) {
swal("Error", "No address in key file", "error");
return;
}
checkInitialKey(api,
config,
"checkInitialKey(address)",
address,
config.Ethereum[config.environment].contractAddress,
function(_isNew) {
_isNew = !!+_isNew;
if (!_isNew) {
swal("Error", "Initial key is already activated", "error");
return;
}
$(".loading-container").show();
setTimeout(function() {
if (!config) {
$.getJSON("./assets/javascripts/config.json", function(_config) {
config = _config;
configLoadedCallBack(api, config, address);
});
} else {
configLoadedCallBack(api, config, address);
}
}, 500)
}
);
}
reader.onerror = function (evt) {
swal("Error", "Error in reading file", "error");
}
}
function configLoadedCallBack(api, config, address) {
var keysCount = 0;
for (var i in keys) {
keysCount++;
}
var keysIterator = 0;
generateAddress(function(_miningKeyObject, password) {
keysIterator++;
keys.miningKey = {};
_miningKeyObject.name = "miningKey";
keys.miningKey.miningKeyObject = _miningKeyObject;
keys.miningKey.password = password;
if (keysIterator == keysCount) {
addressesGeneratedCallBack(keys, address);
}
});
generateAddress(function(_payoutKeyObject, password) {
keysIterator++;
keys.payoutKey = {};
_payoutKeyObject.name = "payoutKey";
keys.payoutKey.payoutKeyObject = _payoutKeyObject;
keys.payoutKey.password = password;
if (keysIterator == keysCount) {
addressesGeneratedCallBack(keys, address);
}
});
generateAddress(function(_votingKeyObject, password) {
keysIterator++;
keys.votingKey = {};
_votingKeyObject.name = "votingKey";
keys.votingKey.votingKeyObject = _votingKeyObject;
keys.votingKey.password = password;
if (keysIterator == keysCount) {
addressesGeneratedCallBack(keys, address);
}
});
}
function addressesGeneratedCallBack(keys, address) {
var validatorViewObj = {
miningKey: "0x" + keys.miningKey.miningKeyObject.address,
fullName: $("#full-name").val(),
streetName: $("#address").val(),
state: $("#state").val(),
zip: $("#zip").val(),
licenseID: $("#license-id").val(),
licenseExpiredAt: new Date($("#license-expiration").val()).getTime() / 1000,
};
addValidator(api,
"addValidator(address,uint256,uint256,uint256,string,string,string)",
validatorViewObj,
address,
config.Ethereum[config.environment].contractAddress,
function(txHash, err) {
if (err) {
$(".loading-container").hide();
console.log(err.message);
if (err.type != "REQUEST_REJECTED")
swal("Error", "Error in addresses addition to contract", "error");
return;
}
createKeys(api,
"createKeys(address,address,address)",
keys,
address,
config.Ethereum[config.environment].contractAddress,
function(res, err) {
if (err) {
$(".loading-container").hide();
console.log(err.message);
if (err.type != "REQUEST_REJECTED")
swal("Error", "Error in addresses addition to contract", "error");
return;
}
addressesAddedToContractCallBack(address, err);
}
);
}
);
}
function addressesAddedToContractCallBack(address, error) {
if (error) {
$(".loading-container").hide();
swal("Error", error.message, "error");
return;
}
//send ether to payoutKey
api._eth.getBalance(address).then(function(balanceObj){
var balance = balanceObj.toNumber();
var to = "0x" + keys.payoutKey.payoutKeyObject.address;
api._eth.gasPrice().then(function(gasPrice) {
console.log("gasPrice: " + gasPrice);
var estimatedGas = web3.eth.estimateGas({from: address, value: parseInt(balance/2), data: null, to: to});
var ammountToSend = balance - 10*estimatedGas*gasPrice;
console.log("ammountToSend: " + ammountToSend);
web3.eth.sendTransaction({gas: estimatedGas, from: address, to: to, value: ammountToSend}, function(err, txHash) {
if (err) {
console.log(err);
$(".loading-container").hide();
return;
}
$(".loading-container").hide();
swal("Sucess", "Keys are created", "success");
$('.content').empty();
$('.content').load("./keys.html", function() {
$("#miningKey").text("0x" + keys.miningKey.miningKeyObject.address);
$("#payoutKey").text("0x" + keys.payoutKey.payoutKeyObject.address);
$("#votingKey").text("0x" + keys.votingKey.votingKeyObject.address);
$("#miningKeyPass").text(keys.miningKey.password);
$("#payoutKeyPass").text(keys.payoutKey.password);
$("#votingKeyPass").text(keys.votingKey.password);
$("#miningKeyDownload").click(function() {
download("key_" + keys.miningKey.miningKeyObject.address, JSON.stringify(keys.miningKey.miningKeyObject));
});
$("#payoutKeyDownload").click(function() {
download("key_" + keys.payoutKey.payoutKeyObject.address, JSON.stringify(keys.payoutKey.payoutKeyObject));
});
$("#votingKeyDownload").click(function() {
download("key_" + keys.votingKey.votingKeyObject.address, JSON.stringify(keys.votingKey.votingKeyObject));
});
});
});
});
});
}
});

860
assets/javascripts/config.json Executable file

File diff suppressed because one or more lines are too long

20
assets/javascripts/keythereum.min.js vendored Executable file

File diff suppressed because one or more lines are too long

1
assets/javascripts/sweetalert.min.js vendored Executable file

File diff suppressed because one or more lines are too long

3
assets/javascripts/vendor/index.js vendored Executable file
View File

@ -0,0 +1,3 @@
//=require jquery.min.js
//=require parity.js
//=require web3.js

4
assets/javascripts/vendor/jquery.min.js vendored Executable file

File diff suppressed because one or more lines are too long

1
assets/javascripts/vendor/parity.js vendored Executable file

File diff suppressed because one or more lines are too long

1
assets/javascripts/vendor/web3.js vendored Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
@import './index/*';

View File

@ -0,0 +1,24 @@
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
html,
body {
color: #333;
line-height: 1;
font-size: 14px;
font-family: 'Open Sans', sans-serif;
-webkit-font-smoothing: antialiased;
}

View File

@ -0,0 +1,10 @@
@mixin image-2x($image, $width: 100%, $height: 100%) {
@media (min--moz-device-pixel-ratio: 1.3),
(-o-min-device-pixel-ratio: 2.6/2),
(-webkit-min-device-pixel-ratio: 1.3),
(min-device-pixel-ratio: 1.3),
(min-resolution: 1.3dppx) {
background-image: url($image);
background-size: $width $height;
}
}

View File

@ -0,0 +1,41 @@
%stretch-width {
left: 0;
right: 0;
}
%title {
color: #333;
text-transform: uppercase;
font-size: 16px;
font-weight: bold;
}
%description {
color: #8197a2;
line-height: 24px;
font-size: 14px;
font-weight: normal;
}
%btn {
transition: 0.3s background-color;
border-radius: 3px;
padding: 0 15px 0 32px;
background-repeat: no-repeat;
background-size: 12px 12px;
background-position: left 15px center;
color: #fff;
line-height: 36px;
font-size: 13px;
text-decoration: none;
text-transform: uppercase;
font-weight: bold;
}
%item {
margin-bottom: 30px;
border-radius: 8px;
border: 1px solid #eee;
background-color: #fff;
color: #333;
}

View File

@ -0,0 +1,42 @@
html,
body {
margin: 0;
padding: 0;
}
p, h1, h2, h3, h4 {
margin: 0;
padding: 0;
font-family: 'Open Sans', sans-serif;
}
html {
height: 100%;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
background-position: center center;
}
body {
position: relative;
display: table;
width: 100%;
min-width: 960px;
height: 100%;
box-sizing: border-box;
padding: 80px 0 60px;
}
.container {
max-width: 960px;
margin: 0 auto;
}
.content {
vertical-align: middle;
padding: 30px 10px 0px 10px;
background-color: #fdfdfd;
margin-left: 140px;
margin-right: 140px;
}

View File

@ -0,0 +1,39 @@
.hidden {
display:none;
}
input[type=file]{position:absolute; top:-100px;}
button:focus {outline:0;}
#createKeys {
position: absolute;
top: -webkit-calc(50% - 20px);
left: -webkit-calc(50% - 50px);
}
.loader {
border: 16px solid grey;
border-radius: 50%;
border-top: 16px solid white;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
position: absolute;
top: -webkit-calc(50% - 76px);
left: -webkit-calc(50% - 76px);
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.password-label {
color: #333;
}

View File

@ -0,0 +1,95 @@
.create-keys {
@extend %item;
padding: 30px 20px;
h1 {
@extend %title;
margin-bottom: 20px;
}
h2 {
@extend %description;
margin-bottom: 20px;
}
&-button {
@extend %btn;
margin-top: 20px;
display: inline-block;
background-color: #08b3f2;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAFVBMVEX///////////////////////////9nSIHRAAAABnRSTlMASUrk5udXTd49AAAAOUlEQVR42tXQsQEAIAgDQcAn+4+snRZxAK79KokrIcNBwgYdc0Migwxk8Qsd1TJWDf/KQWobqt+9G4coA99W7as5AAAAAElFTkSuQmCC);
&:hover {
background-color: #079dd4;
}
}
&-inputs {
overflow: hidden;
display: table;
width: 100%;
}
.left {
padding-right: 10px;
}
.right {
padding-left: 10px;
}
.left,
.right {
display: table-cell;
width: 48%;
}
label {
&:not(.radio) {
display: block;
margin-bottom: 15px;
margin-top: 20px;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
}
}
button,
input,
textarea {
outline: none;
font-family: 'Open Sans', sans-serif;
}
input,
textarea {
transition: 0.3s border-color;
width: 100%;
border-radius: 3px;
box-sizing: border-box;
border: 1px solid #eee;
&:focus {
border-color: #08b3f2;
}
}
textarea {
padding: 15px;
height: 110px;
resize: none;
}
input {
padding: 0 15px;
height: 36px;
}
input[type="radio"] {
display: none;
&:checked + .radio:after {
opacity: 1;
}
}
}

View File

@ -0,0 +1,38 @@
.footer {
@extend %stretch-width;
position: absolute;
z-index: 1;
bottom: 0;
padding: 15px 10px;
color: #fff;
line-height: 30px;
font-size: 12px;
background-image: url(../images/bg_footer.png);
background-repeat: no-repeat;
background-size: cover;
.container {
position: relative;
overflow: hidden;
}
&-logo {
@include image-2x('../images/logos@2x.png', 163px, 66px);
position: relative;
z-index: 2;
display: inline-block;
vertical-align: middle;
width: 100px;
height: 24px;
background-image: url(../images/logos.png);
background-position: 0 0;
}
&-rights {
@extend %stretch-width;
position: absolute;
z-index: 1;
top: 0;
text-align: center;
}
}

View File

@ -0,0 +1,19 @@
.header {
@extend %stretch-width;
position: absolute;
z-index: 1;
top: 0;
padding: 18px 10px;
background-image: url(../images/bg_header.png);
background-repeat: no-repeat;
background-size: cover;
&-logo {
@include image-2x('../images/logos@2x.png', 163px, 66px);
float: left;
width: 149px;
height: 35px;
background-image: url(../images/logos.png);
background-position: 0 -24px;
}
}

View File

@ -0,0 +1,119 @@
.keys {
display: table;
width: 100%;
margin-bottom: 60px;
text-align: left;
$_this: &;
&-i {
position: relative;
display: table-cell;
vertical-align: top;
width: 33.33%;
box-sizing: border-box;
padding: 0 15px 60px 15px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
&:not(:first-child) {
border-left: 1px solid #e1e1e1;
}
}
&-title {
margin-bottom: 10px;
@extend %title;
}
&-hash {
height: 30px;
color: #6d2eae;
line-height: 16px;
font-size: 12px;
}
&-description {
@extend %description;
line-height: 18px;
font-size: 12px;
}
&-footer {
position: absolute;
left: 15px;
right: 15px;
bottom: 0;
#{$_this}-i:first-child & {
left: 0;
}
}
&-download,
&-read-more {
display: inline-block;
vertical-align: middle;
}
&-download {
@extend %btn;
background-color: #6d2eae;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAANlBMVEX///////////////////////////////////////////////////////////////////////8BOg0gAAAAEXRSTlMASUtWV1hZXF1e5ebn6Orr/GN0dVoAAABnSURBVHja1cnJDYBADENRDzBsYYn7bxaCFFmMaADf/B+0YlbwNSPtE3jvv9Ad29DCsB0dVtKnN8xOGowhCdm5o/eUgOw+AktKQPYFkDygLglQhyRAXZLzWV2iLlFvRb2V7O3qeVa9C41xDOyv+UmuAAAAAElFTkSuQmCC);
&:hover {
background-color: #5d2795;
}
}
&-read-more {
margin-left: 10px;
color: #6d2eae;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
&-note {
overflow: hidden;
position: relative;
border: 1px solid #6d2eae;
border-radius: 5px;
padding: 20px 15px 20px 53px;
background-color: rgba(109, 46, 174, 0.1);
color: #6d2eae;
text-align: left;
&:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 42px;
background-color: #6d2eae;
background-image: url(../images/warning.svg);
background-repeat: no-repeat;
background-position: center center;
}
&-title {
margin-bottom: 10px;
text-transform: uppercase;
font-size: 14px;
font-weight: bold;
}
&-description {
font-size: 12px;
}
}
}

View File

@ -0,0 +1,79 @@
@keyframes fadeOut {
0% {
opacity: .2;
}
20% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: .2;
transform: scale(0.3);
}
}
.loading {
display: flex;
justify-content: space-between;
position: absolute;
left: 50%;
top: 50%;
width: 146px;
margin: -30px 0 0 -81.5px;
padding-top: 50px;
&:before {
@include image-2x('../images/loading@2x.png');
content: '';
position: absolute;
left: 0;
top: 0;
width: 146px;
height: 35px;
background-image: url(../images/loading.png);
background-position: 0 0;
}
&-container {
position: fixed;
z-index: 1000000;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: fade-out(#231d73, 0.2);
}
&-i {
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: fadeOut;
animation-timing-function: linear;
opacity:.2;
width: 9px;
height: 9px;
border-radius: 50%;
background-color: #fff;
&:nth-child(2) {
animation-delay: .1s;
}
&:nth-child(3) {
animation-delay: .2s;
}
&:nth-child(4) {
animation-delay: .3s;
}
&:nth-child(5) {
animation-delay: .4s;
}
&:nth-child(6) {
animation-delay: .5s;
}
}
}

View File

@ -0,0 +1,60 @@
.socials {
position: relative;
z-index: 2;
float: right;
font-size: 0;
&-i {
transition: 0.3s background-color;
position: relative;
display: inline-block;
vertical-align: top;
width: 30px;
height: 30px;
margin-left: 10px;
border-radius: 50%;
background-color: fade-out(#fff, 0.8);
&:hover {
@media screen and (min-width: 768px) {
background-color: fade-out(#fff, 0.6);
}
}
&:before {
@include image-2x('../images/socials@2x.png', 15px, 40px);
content: '';
position: absolute;
left: 50%;
top: 50%;
background-image: url(../images/socials.png);
}
&_reddit {
&:before {
width: 15px;
height: 13px;
margin: -6.5px 0 0 -7.5px;
background-position: 0 -15px;
}
}
&_twitter {
&:before {
width: 15px;
height: 12px;
margin: -6px 0 0 -7.5px;
background-position: 0 -28px;
}
}
&_bitcoin {
&:before {
width: 11px;
height: 15px;
margin: -7.5px 0 0 -5.5px;
background-position: 0 0;
}
}
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

BIN
favicons/fav_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
favicons/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
favicons/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
favicons/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

18
favicons/manifest.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-256x256.png",
"sizes": "256x256",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

BIN
favicons/mstile-150x150.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

39
gulpfile.js Executable file
View File

@ -0,0 +1,39 @@
'use strict';
const gulp = require('gulp');
const sass = require('gulp-sass');
const sassGlob = require('gulp-sass-glob');
const autoprefixer = require('gulp-autoprefixer');
const uglifycss = require('gulp-uglifycss');
const include = require('gulp-include');
const addsrc = require('gulp-add-src');
const order = require('gulp-order');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');
gulp.task('sass', function() {
return gulp.src(['assets/stylesheets/*.scss'])
.pipe(sassGlob())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(uglifycss())
.pipe(gulp.dest('assets/stylesheets/'));
});
gulp.task('javascript', function() {
return gulp.src('assets/javascripts/application/*.js')
.pipe(addsrc('assets/javascripts/vendor/index.js'))
.pipe(order([
"assets/javascripts/vendor/index.js",
"assets/javascripts/application/*.js"
], {base: '.'}))
.pipe(include())
.pipe(concat('application.js'))
.pipe(uglify())
.pipe(gulp.dest('assets/javascripts'));
});
gulp.task('watch', function() {
gulp.watch('assets/stylesheets/**/*.scss', ['sass']);
gulp.watch('assets/javascripts/application/*.js', ['javascript']);
});

82
index.html Executable file
View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="theme-color" content="#6151cc">
<meta name="msapplication-config" content="./favicons/browserconfig.xml">
<!-- <meta property="og:title" content="">
<meta property="og:description" content=""> -->
<!-- <meta property="og:url" content="https://oracles.org/"> -->
<!-- <meta property="og:image" content="https://www.notarycoin.com/assets/images/share.png"> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./assets/stylesheets/index.css">
<link rel="stylesheet" type="text/css" href="./assets/stylesheets/sweetalert.css">
<link rel="apple-touch-icon" href="./favicons/favicon-192x192.png">
<link rel="icon" type="image/png" sizes="192x192" href="./favicons/favicon-192x192.png">
<link rel="mask-icon" color="#6151cc" href="./favicons/safari-pinned-tab.svg">
<link rel="manifest" href="./favicons/manifest.webmanifest">
</head>
<body>
<header class="header">
<div class="container">
<a href="#" class="header-logo"></a>
</div>
</header>
<section class="content">
<div class="create-keys">
<h1>Create keys from initial key</h1>
<h2>
In this application, you will create mining, payout and voting keys.
The app will make your initial key unusable after the process.
Please proceed with care, don't lose your keys and follow instructions.
</h2>
<div class="create-keys-inputs">
<div class="left">
<label for="full-name">Full name</label>
<input type="text" id="full-name">
<label for="address">Address</label>
<input type="text" id="address">
<label for="state">State</label>
<input type="text" id="state">
<a href="#" class="create-keys-button">Create keys</a>
</div>
<div class="right">
<label for="zip">Zip code</label>
<input type="number" id="zip">
<label for="license-id">License id</label>
<input type="number" id="license-id">
<label for="license-expiration">License expiration</label>
<input type="date" id="license-expiration">
</div>
</div>
<input type="file" id="initialKeySource"/>
</div>
</section>
<div class="loading-container">
<div class="loading">
<div class="loading-i"></div>
<div class="loading-i"></div>
<div class="loading-i"></div>
<div class="loading-i"></div>
<div class="loading-i"></div>
<div class="loading-i"></div>
</div>
</div>
<footer class="footer">
<div class="container">
<a href="#" class="footer-logo"></a>
<div class="socials">
<a href="#" class="socials-i socials-i_reddit"></a>
<a href="https://twitter.com/notarycoin" class="socials-i socials-i_twitter"></a>
<a href="#" class="socials-i socials-i_bitcoin"></a>
</div>
<p class="footer-rights">2017 Oracles. All rights reserved.</p>
</div>
</footer>
<script src="./assets/javascripts/sweetalert.min.js" type="text/javascript"></script>
<script src="./assets/javascripts/application.js?v=1.1" type="text/javascript"></script>
<script src="./assets/javascripts/keythereum.min.js" type="text/javascript"></script>
</body>
</html>

BIN
index.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

51
keys.html Normal file
View File

@ -0,0 +1,51 @@
<div class="container">
<div class="keys">
<div class="keys-i">
<p class="keys-title">Mining key</p>
<p class="keys-hash" id="miningKey"></p>
<p class="keys-hash"><span class="password-label">Password: </span><span id="miningKeyPass"></span></p>
<p class="keys-description">
Download this key and use it in your mining node to
validate blocks in the network. Mined coins will be
deposited to your payout account.
</p>
<div class="keys-footer">
<a href="#" class="keys-download" id="miningKeyDownload">Download key</a>
<a href="#" class="keys-read-more">Read More</a>
</div>
</div>
<div class="keys-i">
<p class="keys-title">Payout key</p>
<p class="keys-hash" id="payoutKey"></p>
<p class="keys-hash"><span class="password-label">Password: </span><span id="payoutKeyPass"></span></p>
<p class="keys-description">
Download this key and use it on your client
node/wallet to spend earned coins.
</p>
<div class="keys-footer">
<a href="#" class="keys-download" id="payoutKeyDownload">Download key</a>
<a href="#" class="keys-read-more">Read More</a>
</div>
</div>
<div class="keys-i">
<p class="keys-title">Voting key</p>
<p class="keys-hash" id="votingKey"></p>
<p class="keys-hash"><span class="password-label">Password: </span><span id="votingKeyPass"></span></p>
<p class="keys-description">
Download this key and use it on your client node to
vote for necessary ballots, such as adding or
removing miners from the network.
</p>
<div class="keys-footer">
<a href="#" class="keys-download" id="votingKeyDownload">Download key</a>
<a href="#" class="keys-read-more">Read More</a>
</div>
</div>
</div>
<div class="keys-note">
<p class="keys-note-title">Important</p>
<p class="keys-note-description">
Do not close this tab until you download all keys. Keep keys secure and protected. If you lose your keys, you will need to get a new initial key using Voting DAPP.
</p>
</div>
</div>

8
manifest.json Normal file
View File

@ -0,0 +1,8 @@
{
"id": "KeysGenerator",
"name": "Keys Generator",
"description": "Oracles Keys Generator",
"version": "1.0.0",
"author": "Oracles",
"iconUrl": "./favicons/fav_2.png"
}

38
package.json Executable file
View File

@ -0,0 +1,38 @@
{
"name": "",
"version": "1.0.0",
"description": "",
"main": "gulpfile.js",
"devDependencies": {
"web3": "^0.18.2",
"gulp": "^3.9.1",
"gulp-add-src": "^0.2.0",
"gulp-autoprefixer": "^3.1.1",
"gulp-concat": "^2.6.1",
"gulp-include": "^2.3.1",
"gulp-order": "^1.1.1",
"gulp-postcss": "^6.2.0",
"gulp-sass": "^2.3.2",
"gulp-sass-glob": "^1.0.6",
"gulp-uglify": "^2.0.0",
"gulp-uglifycss": "^1.0.6",
"http-server": "^0.9.0"
},
"scripts": {
"sass": "gulp sass",
"coffee": "gulp javascript",
"watch": "gulp watch",
"start": "http-server -a localhost -p 8000"
},
"repository": {
"type": "git",
"url": ""
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "/issues"
},
"homepage": "#README"
}

BIN
results.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB