Merge pull request #50 from rstormsf/core
(Feature) Add dropdown for selecting mining key, add limit notification
This commit is contained in:
commit
93ded37229
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true
|
||||
}
|
||||
}
|
|
@ -4588,6 +4588,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
|
@ -4597,13 +4604,6 @@
|
|||
"strip-ansi": "3.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.0.1"
|
||||
}
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"bundled": true,
|
||||
|
@ -10293,6 +10293,14 @@
|
|||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"string-length": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz",
|
||||
|
@ -10335,14 +10343,6 @@
|
|||
"function-bind": "1.1.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "poa-dapps-voting",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"homepage": "https://poanetwork.github.io/poa-dapps-voting",
|
||||
"homepage": "https://poanetwork.github.io/",
|
||||
"dependencies": {
|
||||
"autoprefixer": "7.1.6",
|
||||
"babel-core": "6.26.0",
|
||||
|
|
|
@ -38,9 +38,10 @@ class App extends Component {
|
|||
const { commonStore } = this.props;
|
||||
const currentPath = this.props.location.pathname;
|
||||
let showNavPan =
|
||||
currentPath == `${commonStore.rootPath}`
|
||||
|| currentPath == `${commonStore.rootPath}/`
|
||||
|| currentPath == `${commonStore.rootPath}/active`;
|
||||
currentPath === `${commonStore.rootPath}`
|
||||
|| currentPath === "/"
|
||||
|| currentPath === `${commonStore.rootPath}/`
|
||||
|| currentPath === `${commonStore.rootPath}/active`;
|
||||
return showNavPan;
|
||||
}
|
||||
|
||||
|
@ -61,6 +62,7 @@ class App extends Component {
|
|||
{loading}
|
||||
<Header />
|
||||
{nav}
|
||||
<Route exact path={`/`} render={this.onBallotsRender}/>
|
||||
<Route exact path={`${commonStore.rootPath}/`} render={this.onBallotsRender}/>
|
||||
<Route exact path={`${commonStore.rootPath}/active`} render={this.onActiveBallotsRender}/>
|
||||
<Route path={`${commonStore.rootPath}/new`} render={this.onNewBallotRender}/>
|
||||
|
|
|
@ -772,6 +772,10 @@ button {
|
|||
|
||||
.ballots-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between; }
|
||||
.ballots-footer-left {
|
||||
display: inline-flex;
|
||||
align-items: center; }
|
||||
@media screen and (max-width: 768px) {
|
||||
.ballots-footer {
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
.ballots-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&-left {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
@media screen and (max-width: $tablet-width) {
|
||||
padding-top: $tablet-indent;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { observable, action, computed } from "mobx";
|
||||
import { observable, action, computed, autorun } from "mobx";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { toAscii } from "../helpers";
|
||||
import { constants } from "../constants";
|
||||
|
@ -265,6 +265,15 @@ export class BallotKeysCard extends React.Component {
|
|||
this.getProgress();
|
||||
this.getIsFinalized();
|
||||
}
|
||||
componentDidMount() {
|
||||
this.interval = setInterval(() => {
|
||||
this.calcTimeToFinish()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.clearInterval(this.interval);
|
||||
}
|
||||
|
||||
hideCard = () => {
|
||||
let { commonStore } = this.props;
|
||||
|
@ -360,9 +369,12 @@ export class BallotKeysCard extends React.Component {
|
|||
</div>
|
||||
<hr />
|
||||
<div className="ballots-footer">
|
||||
<div className="ballots-footer-left">
|
||||
<button type="button" onClick={(e) => this.finalize(e)} className="ballots-footer-finalize">Finalize ballot</button>
|
||||
<p>{constants.CARD_FINALIZE_DESCRIPTION}</p>
|
||||
</div>
|
||||
<div type="button" className="ballots-i--vote ballots-i--vote_no">Keys Ballot ID: {this.props.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import React from 'react';
|
||||
import React from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Select from "react-select";
|
||||
import "react-select/dist/react-select.css";
|
||||
|
||||
@inject("ballotStore")
|
||||
@inject("ballotStore", "contractsStore")
|
||||
@observer
|
||||
export class BallotKeysMetadata extends React.Component {
|
||||
render() {
|
||||
const options = this.props.contractsStore.validatorsMetadata.slice();
|
||||
const { ballotStore } = this.props;
|
||||
return (
|
||||
<div>
|
||||
|
@ -24,9 +27,12 @@ export class BallotKeysMetadata extends React.Component {
|
|||
<div className="right">
|
||||
<div className="form-el">
|
||||
<label htmlFor="key">Mining Key</label>
|
||||
<input type="text" id="key"
|
||||
<Select.Creatable
|
||||
name="form-field-name"
|
||||
id="key"
|
||||
value={ballotStore.ballotKeys.miningKey}
|
||||
onChange={e => ballotStore.changeBallotMetadata(e, "miningKey", "ballotKeys")}
|
||||
onChange={ballotStore.setMiningKey}
|
||||
options={options}
|
||||
/>
|
||||
<p className="hint">
|
||||
Mining key address of validator to vote for. Example: 0xc70760D23557A4FDE612C0bE63b26EBD023C51Ee.
|
||||
|
|
|
@ -6,6 +6,8 @@ import { toAscii } from "../helpers";
|
|||
import { constants } from "../constants";
|
||||
import swal from 'sweetalert2';
|
||||
|
||||
const ACCEPT = 1;
|
||||
const REJECT = 2;
|
||||
@inject("commonStore", "contractsStore", "routing")
|
||||
@observer
|
||||
export class BallotMinThresholdCard extends React.Component {
|
||||
|
@ -132,7 +134,7 @@ export class BallotMinThresholdCard extends React.Component {
|
|||
return isActive;
|
||||
}
|
||||
|
||||
vote = async (e, _type) => {
|
||||
vote = async ({choice}) => {
|
||||
const { commonStore, contractsStore, id } = this.props;
|
||||
const { push } = this.props.routing;
|
||||
if (!contractsStore.isValidVotingKey) {
|
||||
|
@ -146,7 +148,7 @@ export class BallotMinThresholdCard extends React.Component {
|
|||
swal("Warning!", constants.INVALID_VOTE_MSG, "warning");
|
||||
return;
|
||||
}
|
||||
contractsStore.votingToChangeMinThreshold.vote(id, _type, contractsStore.votingKey)
|
||||
contractsStore.votingToChangeMinThreshold.vote(id, choice, contractsStore.votingKey)
|
||||
.on("receipt", () => {
|
||||
commonStore.hideLoading();
|
||||
swal("Congratulations!", constants.VOTED_SUCCESS_MSG, "success").then((result) => {
|
||||
|
@ -249,26 +251,26 @@ export class BallotMinThresholdCard extends React.Component {
|
|||
</div>
|
||||
<div className="ballots-i-scale">
|
||||
<div className="ballots-i-scale-column">
|
||||
<button type="button" onClick={(e) => this.vote(e, this.props.id, 1)} className="ballots-i--vote ballots-i--vote_yes">Vote</button>
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">Yes</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesForNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesForPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_yes" style={{width: `${this.votesForPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ballots-i-scale-column">
|
||||
<button type="button" onClick={(e) => this.vote({choice: REJECT})} className="ballots-i--vote ballots-i--vote_no">No</button>
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">No</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesAgainstNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesAgainstPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_no" style={{width: `${this.votesAgainstPercents}%`}}></div>
|
||||
<div className="vote-scale--fill vote-scale--fill_yes" style={{width: `${this.votesAgainstPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" onClick={(e) => this.vote(e, 2)} className="ballots-i--vote ballots-i--vote_no">Vote</button>
|
||||
</div>
|
||||
<div className="ballots-i-scale-column">
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">Yes</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesForNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesForPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_no" style={{width: `${this.votesForPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" onClick={(e) => this.vote({choice: ACCEPT})} className="ballots-i--vote ballots-i--vote_yes">Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="info">
|
||||
|
@ -276,9 +278,12 @@ export class BallotMinThresholdCard extends React.Component {
|
|||
</div>
|
||||
<hr />
|
||||
<div className="ballots-footer">
|
||||
<div className="ballots-footer-left">
|
||||
<button type="button" onClick={(e) => this.finalize(e)} className="ballots-footer-finalize">Finalize ballot</button>
|
||||
<p>{constants.CARD_FINALIZE_DESCRIPTION}</p>
|
||||
</div>
|
||||
<div type="button" className="ballots-i--vote ballots-i--vote_no">Consensus Ballot ID: {this.props.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import { toAscii } from "../helpers";
|
|||
import { constants } from "../constants";
|
||||
import swal from 'sweetalert2';
|
||||
|
||||
const ACCEPT = 1;
|
||||
const REJECT = 2;
|
||||
@inject("commonStore", "contractsStore", "ballotStore", "routing")
|
||||
@observer
|
||||
export class BallotProxyCard extends React.Component {
|
||||
|
@ -140,7 +142,7 @@ export class BallotProxyCard extends React.Component {
|
|||
return isActive;
|
||||
}
|
||||
|
||||
vote = async (e, _type) => {
|
||||
vote = async ({choice}) => {
|
||||
const { commonStore, contractsStore, id } = this.props;
|
||||
const { push } = this.props.routing;
|
||||
if (!contractsStore.isValidVotingKey) {
|
||||
|
@ -154,7 +156,7 @@ export class BallotProxyCard extends React.Component {
|
|||
swal("Warning!", constants.INVALID_VOTE_MSG, "warning");
|
||||
return;
|
||||
}
|
||||
contractsStore.votingToChangeProxy.vote(id, _type, contractsStore.votingKey)
|
||||
contractsStore.votingToChangeProxy.vote(id, choice, contractsStore.votingKey)
|
||||
.on("receipt", () => {
|
||||
commonStore.hideLoading();
|
||||
swal("Congratulations!", constants.VOTED_SUCCESS_MSG, "success").then((result) => {
|
||||
|
@ -267,26 +269,26 @@ export class BallotProxyCard extends React.Component {
|
|||
</div>
|
||||
<div className="ballots-i-scale">
|
||||
<div className="ballots-i-scale-column">
|
||||
<button type="button" onClick={(e) => this.vote(e, 1)} className="ballots-i--vote ballots-i--vote_yes">Vote</button>
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">Yes</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesForNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesForPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_yes" style={{width: `${this.votesForPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ballots-i-scale-column">
|
||||
<button type="button" onClick={(e) => this.vote({choice: REJECT})} className="ballots-i--vote ballots-i--vote_no">No</button>
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">No</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesAgainstNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesAgainstPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_no" style={{width: `${this.votesAgainstPercents}%`}}></div>
|
||||
<div className="vote-scale--fill vote-scale--fill_yes" style={{width: `${this.votesAgainstPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" onClick={(e) => this.vote(e, 2)} className="ballots-i--vote ballots-i--vote_no">Vote</button>
|
||||
</div>
|
||||
<div className="ballots-i-scale-column">
|
||||
<div className="vote-scale--container">
|
||||
<p className="vote-scale--value">Yes</p>
|
||||
<p className="vote-scale--votes">Votes: {this.votesForNumber}</p>
|
||||
<p className="vote-scale--percentage">{this.votesForPercents}%</p>
|
||||
<div className="vote-scale">
|
||||
<div className="vote-scale--fill vote-scale--fill_no" style={{width: `${this.votesForPercents}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" onClick={(e) => this.vote({choice: ACCEPT})} className="ballots-i--vote ballots-i--vote_yes">Yes</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="info">
|
||||
|
@ -294,9 +296,12 @@ export class BallotProxyCard extends React.Component {
|
|||
</div>
|
||||
<hr />
|
||||
<div className="ballots-footer">
|
||||
<div className="ballots-footer-left">
|
||||
<button type="button" onClick={(e) => this.finalize(e)} className="ballots-footer-finalize">Finalize ballot</button>
|
||||
<p>{constants.CARD_FINALIZE_DESCRIPTION}</p>
|
||||
</div>
|
||||
<div type="button" className="ballots-i--vote ballots-i--vote_no">Proxy Ballot ID: {this.props.id}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ export class NewBallot extends React.Component {
|
|||
commonStore.hideLoading();
|
||||
return false;
|
||||
}
|
||||
|
||||
let isMiningKeyAddress = contractsStore.web3Instance.isAddress(ballotStore.ballotKeys.miningKey);
|
||||
|
||||
if (!isMiningKeyAddress) {
|
||||
|
@ -105,7 +104,6 @@ export class NewBallot extends React.Component {
|
|||
ballotStore.ballotKeys.keysBallotType,
|
||||
contractsStore.votingKey
|
||||
];
|
||||
console.log(inputToMethod)
|
||||
let method = contractsStore.votingToChangeKeys.createVotingForKeys(
|
||||
...inputToMethod
|
||||
);
|
||||
|
@ -120,7 +118,6 @@ export class NewBallot extends React.Component {
|
|||
ballotStore.ballotMinThreshold.proposedValue,
|
||||
contractsStore.votingKey
|
||||
];
|
||||
console.log(inputToMethod)
|
||||
let method = contractsStore.votingToChangeMinThreshold.createBallotToChangeThreshold(
|
||||
...inputToMethod
|
||||
);
|
||||
|
@ -189,7 +186,7 @@ export class NewBallot extends React.Component {
|
|||
let validator = ballotStore.isNewValidatorPersonalData ? <Validator />: "";
|
||||
let keysTypes = ballotStore.isBallotForKey ? <KeysTypes />: "";
|
||||
let metadata
|
||||
let minThreshold
|
||||
let minThreshold = 0;
|
||||
switch (ballotStore.ballotType) {
|
||||
case ballotStore.BallotType.keys:
|
||||
metadata = <BallotKeysMetadata />;
|
||||
|
@ -218,7 +215,7 @@ export class NewBallot extends React.Component {
|
|||
checked={ballotStore.isBallotForKey}
|
||||
onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.keys)}
|
||||
/>
|
||||
<label htmlFor="ballot-for-validators" className="radio">Ballot for validators</label>
|
||||
<label htmlFor="ballot-for-validators" className="radio">Validator Management Ballot</label>
|
||||
<p className="hint">
|
||||
Ballot to add, remove or swap any type of key for existing or new validators.
|
||||
</p>
|
||||
|
@ -231,7 +228,7 @@ export class NewBallot extends React.Component {
|
|||
checked={ballotStore.isBallotForMinThreshold}
|
||||
onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.minThreshold)}
|
||||
/>
|
||||
<label htmlFor="ballot-for-consensus" className="radio">Ballot for consensus</label>
|
||||
<label htmlFor="ballot-for-consensus" className="radio">Consenus Threshold Ballot</label>
|
||||
<p className="hint">
|
||||
Ballot to change the minimum threshold for consensus to vote for keys.
|
||||
</p>
|
||||
|
@ -244,7 +241,7 @@ export class NewBallot extends React.Component {
|
|||
checked={ballotStore.isBallotForProxy}
|
||||
onChange={e => ballotStore.changeBallotType(e, ballotStore.BallotType.proxy)}
|
||||
/>
|
||||
<label htmlFor="ballot-for-proxy" className="radio">Ballot for proxy</label>
|
||||
<label htmlFor="ballot-for-proxy" className="radio">Modify Proxy Contract Ballot</label>
|
||||
<p className="hint">
|
||||
Ballot to change one of the proxy contracts.
|
||||
</p>
|
||||
|
@ -257,7 +254,10 @@ export class NewBallot extends React.Component {
|
|||
{metadata}
|
||||
<div className="new-form-footer">
|
||||
<div className="info">
|
||||
Minimum {minThreshold} from {contractsStore.validatorsLength} validators required to pass the proposal
|
||||
Minimum {minThreshold} from {contractsStore.validatorsLength} validators required to pass the proposal<br />
|
||||
You can create {contractsStore.validatorLimits.keys} ballot for keys<br />
|
||||
You can create {contractsStore.validatorLimits.minThreshold} ballot for consensus<br />
|
||||
You can create {contractsStore.validatorLimits.proxy} ballot for proxy<br />
|
||||
</div>
|
||||
<button type="button" className="add-ballot" onClick={e => this.onClick(e)}>Add ballot</button>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import ballotsStorageAbi from './ballotsStorage.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import {BALLOTS_STORAGE_ADDRESS} from './addresses';
|
||||
import networkAddresses from './addresses';
|
||||
|
||||
console.log('Ballots Storage Address ' , BALLOTS_STORAGE_ADDRESS)
|
||||
export default class POAConsensus {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {BALLOTS_STORAGE_ADDRESS} = networkAddresses(netId);
|
||||
console.log('Ballots Storage Address ' , BALLOTS_STORAGE_ADDRESS);
|
||||
let web3_10 = new Web3(web3.currentProvider);
|
||||
this.ballotsStorageInstance = new web3_10.eth.Contract(ballotsStorageAbi, BALLOTS_STORAGE_ADDRESS);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,14 @@
|
|||
import poaConsensusAbi from './poaConsensus.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import {POA_ADDRESS} from './addresses';
|
||||
import networkAddresses from './addresses';
|
||||
|
||||
console.log('POA Address ' , POA_ADDRESS)
|
||||
export default class POAConsensus {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {POA_ADDRESS} = networkAddresses(netId);
|
||||
console.log('POA Address ' , POA_ADDRESS)
|
||||
let web3_10 = new Web3(web3.currentProvider);
|
||||
this.poaInstance = new web3_10.eth.Contract(poaConsensusAbi, POA_ADDRESS);
|
||||
}
|
||||
}
|
||||
async getValidators(){
|
||||
return await this.poaInstance.methods.getValidators().call();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import MetadataAbi from './validatorMetadata.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import moment from 'moment';
|
||||
import {METADATA_ADDRESS} from './addresses';
|
||||
import networkAddresses from './addresses';
|
||||
var toAscii = function(hex) {
|
||||
var str = '',
|
||||
i = 0,
|
||||
|
@ -17,14 +17,14 @@ var toAscii = function(hex) {
|
|||
return str;
|
||||
};
|
||||
|
||||
console.log('Metadata contract:', METADATA_ADDRESS)
|
||||
|
||||
export default class Metadata {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
this.web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {METADATA_ADDRESS} = networkAddresses(netId);
|
||||
console.log('Metadata contract:', METADATA_ADDRESS)
|
||||
this.web3_10 = new Web3(web3.currentProvider);
|
||||
this.metadataInstance = new this.web3_10.eth.Contract(MetadataAbi, METADATA_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
async getValidatorData({votingKey, miningKey}){
|
||||
miningKey = miningKey || await this.getMiningByVoting(votingKey);
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import votingToChangeKeysABI from './votingToChangeKeys.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import {VOTING_TO_CHANGE_KEYS_ADDRESS} from './addresses'
|
||||
import networkAddresses from './addresses';
|
||||
|
||||
console.log('VotingToChangeKeys ', VOTING_TO_CHANGE_KEYS_ADDRESS)
|
||||
export default class VotingToChangeKeys {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {VOTING_TO_CHANGE_KEYS_ADDRESS} = networkAddresses(netId);
|
||||
console.log('VotingToChangeKeys ', VOTING_TO_CHANGE_KEYS_ADDRESS);
|
||||
let web3_10 = new Web3(web3.currentProvider);
|
||||
this.votingToChangeKeysInstance = new web3_10.eth.Contract(votingToChangeKeysABI, VOTING_TO_CHANGE_KEYS_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
//setters
|
||||
createVotingForKeys(startTime, endTime, affectedKey, affectedKeyType, miningKey, ballotType, sender) {
|
||||
|
@ -68,4 +67,18 @@ export default class VotingToChangeKeys {
|
|||
getAffectedKey(_id) {
|
||||
return this.votingToChangeKeysInstance.methods.getAffectedKey(_id).call();
|
||||
}
|
||||
|
||||
getMiningByVotingKey(_votingKey) {
|
||||
return this.votingToChangeKeysInstance.methods.getMiningByVotingKey(_votingKey).call();
|
||||
}
|
||||
|
||||
async getValidatorActiveBallots(_votingKey) {
|
||||
const miningKey = await this.getMiningByVotingKey(_votingKey);
|
||||
return await this.votingToChangeKeysInstance.methods.validatorActiveBallots(miningKey).call();
|
||||
}
|
||||
|
||||
async getBallotLimit(_votingKey) {
|
||||
const currentLimit = await this.votingToChangeKeysInstance.methods.getBallotLimitPerValidator().call();
|
||||
return currentLimit - await this.getValidatorActiveBallots(_votingKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import votingToChangeMinThresholdABI from './votingToChangeMinThreshold.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import {VOTING_TO_CHANGE_MIN_THRESHOLD} from './addresses'
|
||||
import networkAddresses from './addresses';
|
||||
|
||||
console.log('VotingToChangeMinThreshold ', VOTING_TO_CHANGE_MIN_THRESHOLD)
|
||||
export default class VotingToChangeMinThreshold {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {VOTING_TO_CHANGE_MIN_THRESHOLD} = networkAddresses(netId);
|
||||
let web3_10 = new Web3(web3.currentProvider);
|
||||
console.log('VotingToChangeMinThreshold ', VOTING_TO_CHANGE_MIN_THRESHOLD)
|
||||
this.votingToChangeMinThresholdInstance = new web3_10.eth.Contract(votingToChangeMinThresholdABI, VOTING_TO_CHANGE_MIN_THRESHOLD);
|
||||
}
|
||||
}
|
||||
|
||||
//setters
|
||||
createBallotToChangeThreshold(startTime, endTime, proposedValue, sender) {
|
||||
|
@ -60,4 +59,18 @@ export default class VotingToChangeMinThreshold {
|
|||
getProposedValue(_id) {
|
||||
return this.votingToChangeMinThresholdInstance.methods.getProposedValue(_id).call();
|
||||
}
|
||||
|
||||
getMiningByVotingKey(_votingKey) {
|
||||
return this.votingToChangeMinThresholdInstance.methods.getMiningByVotingKey(_votingKey).call();
|
||||
}
|
||||
|
||||
async getValidatorActiveBallots(_votingKey) {
|
||||
const miningKey = await this.getMiningByVotingKey(_votingKey);
|
||||
return await this.votingToChangeMinThresholdInstance.methods.validatorActiveBallots(miningKey).call();
|
||||
}
|
||||
|
||||
async getBallotLimit(_votingKey) {
|
||||
const currentLimit = await this.votingToChangeMinThresholdInstance.methods.getBallotLimitPerValidator().call();
|
||||
return currentLimit - await this.getValidatorActiveBallots(_votingKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import votingToChangeProxyABI from './votingToChangeProxy.abi.json'
|
||||
import Web3 from 'web3';
|
||||
import {VOTING_TO_CHANGE_PROXY} from './addresses'
|
||||
import networkAddresses from './addresses';
|
||||
|
||||
console.log('VotingToChangeProxy ', VOTING_TO_CHANGE_PROXY)
|
||||
export default class VotingToChangeProxy {
|
||||
constructor(){
|
||||
if(window.web3.currentProvider){
|
||||
let web3_10 = new Web3(window.web3.currentProvider);
|
||||
constructor({web3, netId}){
|
||||
const {VOTING_TO_CHANGE_PROXY} = networkAddresses(netId);
|
||||
console.log('VotingToChangeProxy ', VOTING_TO_CHANGE_PROXY)
|
||||
let web3_10 = new Web3(web3.currentProvider);
|
||||
this.votingToChangeProxyInstance = new web3_10.eth.Contract(votingToChangeProxyABI, VOTING_TO_CHANGE_PROXY);
|
||||
}
|
||||
}
|
||||
|
||||
//setters
|
||||
createBallotToChangeProxyAddress(startTime, endTime, proposedValue, contractType, sender) {
|
||||
|
@ -64,4 +63,18 @@ export default class VotingToChangeProxy {
|
|||
getContractType(_id) {
|
||||
return this.votingToChangeProxyInstance.methods.getContractType(_id).call();
|
||||
}
|
||||
|
||||
getMiningByVotingKey(_votingKey) {
|
||||
return this.votingToChangeProxyInstance.methods.getMiningByVotingKey(_votingKey).call();
|
||||
}
|
||||
|
||||
async getValidatorActiveBallots(_votingKey) {
|
||||
const miningKey = await this.getMiningByVotingKey(_votingKey);
|
||||
return await this.votingToChangeProxyInstance.methods.validatorActiveBallots(miningKey).call();
|
||||
}
|
||||
|
||||
async getBallotLimit(_votingKey) {
|
||||
const currentLimit = await this.votingToChangeProxyInstance.methods.getBallotLimitPerValidator().call();
|
||||
return currentLimit - await this.getValidatorActiveBallots(_votingKey);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,38 @@
|
|||
module.exports = {
|
||||
// const local = {
|
||||
// VOTING_TO_CHANGE_KEYS_ADDRESS: '0x758492834ed6454f41d6d3d6b73d6e46d4555429',
|
||||
// VOTING_TO_CHANGE_MIN_THRESHOLD: '0xcbf043db3498b5064bd62341be0c0e3fb0344b1b',
|
||||
// VOTING_TO_CHANGE_PROXY: '0xcb3f870269a3f7215eb87d9548ee5b7eff6396dd',
|
||||
// BALLOTS_STORAGE_ADDRESS: '0x144947d78b932ea0dff14d75e1f7cd1b2f131426',
|
||||
// METADATA_ADDRESS: '0x3111c94b9243a8a99d5a867e00609900e437e2c0',
|
||||
// POA_ADDRESS: '0xf472e0e43570b9afaab67089615080cf7c20018d',
|
||||
// }
|
||||
|
||||
const CORE_ADDRESSES = {
|
||||
VOTING_TO_CHANGE_KEYS_ADDRESS: '0x49df4ec19243263e5db22da5865b4f482b8323a0',
|
||||
VOTING_TO_CHANGE_MIN_THRESHOLD: '0x8829ebe113535826e8af17ed51f83755f675789a',
|
||||
VOTING_TO_CHANGE_PROXY: '0x6b728399b41a38d4109f7af2213d4cc31ca87812',
|
||||
BALLOTS_STORAGE_ADDRESS: '0x0d7590c7aedf1e7e85fc9a1ee88f6f17d3ba762f',
|
||||
METADATA_ADDRESS: '0xcBB2912666c7e8023B7ec78B6842702eB26336aC',
|
||||
POA_ADDRESS: '0x8bf38d4764929064f2d4d3a56520a76ab3df415b',
|
||||
BALLOTS_STORAGE_ADDRESS: '0x0d7590c7aedf1e7e85fc9a1ee88f6f17d3ba762f'
|
||||
}
|
||||
|
||||
const SOKOL_ADDRESSES = {
|
||||
VOTING_TO_CHANGE_KEYS_ADDRESS: '0x145a3d3bd5db8a0ad863b4949b6088d133726cdb',
|
||||
VOTING_TO_CHANGE_MIN_THRESHOLD: '0xad623f870298774765bc5e56ebeafac721028867',
|
||||
VOTING_TO_CHANGE_PROXY: '0x6fb85b2030a68a76ab237d2392b09e28e6f03fa9',
|
||||
BALLOTS_STORAGE_ADDRESS: '0x1e0eaa06d02f965be2dfe0bc9ff52b2d82133461',
|
||||
METADATA_ADDRESS: '0xce9ff1123223d13672cce06dd073d3749764daa6',
|
||||
POA_ADDRESS: '0x8bf38d4764929064f2d4d3a56520a76ab3df415b',
|
||||
}
|
||||
|
||||
module.exports = (netId) => {
|
||||
switch (netId) {
|
||||
case '77':
|
||||
return SOKOL_ADDRESSES
|
||||
case '99':
|
||||
return CORE_ADDRESSES
|
||||
default:
|
||||
return CORE_ADDRESSES
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ let getWeb3 = () => {
|
|||
errorMsg = constants.WRONG_NETWORK_MSG
|
||||
console.log('This is an unknown network.', netId)
|
||||
}
|
||||
document.title = `${netIdName} - POA Network Governance DApp`
|
||||
var defaultAccount = web3.eth.defaultAccount || null;
|
||||
if(defaultAccount === null){
|
||||
reject({message: constants.NO_METAMASK_MSG})
|
||||
|
|
23
src/index.js
23
src/index.js
|
@ -27,24 +27,27 @@ class AppMainRouter extends Component {
|
|||
commonStore.showLoading();
|
||||
|
||||
getWeb3().then(async (web3Config) => {
|
||||
contractsStore.setWeb3Instance(web3Config);
|
||||
await contractsStore.setWeb3Instance(web3Config);
|
||||
await contractsStore.setPoaConsensus(web3Config);
|
||||
contractsStore.setBallotsStorage(web3Config);
|
||||
await contractsStore.setBallotsStorage(web3Config);
|
||||
await contractsStore.setVotingToChangeKeys(web3Config);
|
||||
await contractsStore.setVotingToChangeMinThreshold(web3Config);
|
||||
await contractsStore.setVotingToChangeProxy(web3Config);
|
||||
await contractsStore.setValidatorMetadata(web3Config);
|
||||
contractsStore.getValidatorsLength();
|
||||
await contractsStore.getKeysBallotThreshold();
|
||||
contractsStore.getKeysBallotThreshold();
|
||||
contractsStore.getMinThresholdBallotThreshold();
|
||||
contractsStore.getProxyBallotThreshold();
|
||||
contractsStore.setVotingToChangeKeys(web3Config);
|
||||
contractsStore.setVotingToChangeMinThreshold(web3Config);
|
||||
contractsStore.setVotingToChangeProxy(web3Config);
|
||||
contractsStore.setValidatorMetadata(web3Config);
|
||||
contractsStore.setVotingKey(web3Config);
|
||||
contractsStore.getAllKeysBallots();
|
||||
contractsStore.getAllMinThresholdBallots();
|
||||
contractsStore.getAllProxyBallots();
|
||||
contractsStore.setVotingKey(web3Config);
|
||||
await contractsStore.setMiningKey(web3Config);
|
||||
console.log("votingKey", contractsStore.votingKey)
|
||||
console.log("miningKey", contractsStore.miningKey)
|
||||
contractsStore.getValidatorActiveBallots();
|
||||
contractsStore.getAllValidatorMetadata();
|
||||
console.log("votingKey", contractsStore.votingKey);
|
||||
console.log("miningKey", contractsStore.miningKey);
|
||||
commonStore.hideLoading();
|
||||
}).catch((error) => {
|
||||
commonStore.hideLoading();
|
||||
swal({
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { observable, computed, action } from 'mobx';
|
||||
import { observable, computed, action, toJS } from 'mobx';
|
||||
import moment from 'moment';
|
||||
|
||||
class BallotStore {
|
||||
|
@ -25,6 +25,7 @@ class BallotStore {
|
|||
5: 'BallotsStorage'
|
||||
}
|
||||
@observable ballotType;
|
||||
@observable keysBallotType;
|
||||
@observable endTime;
|
||||
|
||||
@observable ballotKeys;
|
||||
|
@ -33,12 +34,12 @@ class BallotStore {
|
|||
|
||||
|
||||
constructor() {
|
||||
this.ballotType = this.BallotType.keys;
|
||||
this.ballotType = null;
|
||||
this.endTime = "";
|
||||
|
||||
this.ballotKeys = {
|
||||
keyType: this.KeyType.mining,
|
||||
keysBallotType: this.KeysBallotType.add,
|
||||
keyType: null,
|
||||
keysBallotType: null,
|
||||
//memo: "",
|
||||
affectedKey: "",
|
||||
miningKey: ""
|
||||
|
@ -126,7 +127,12 @@ class BallotStore {
|
|||
this[parent][field] = newVal;
|
||||
else
|
||||
this[field] = newVal;
|
||||
console.log("ballot metadata", field, parent?this[parent][field]:this[field])
|
||||
console.log("ballot metadata", field, parent?this[parent][field]:this[field]);
|
||||
}
|
||||
@action("change ballot metadata")
|
||||
setMiningKey = (value) => {
|
||||
this.ballotKeys.miningKey = value;
|
||||
console.log("ballot mining key", toJS(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import "babel-polyfill";
|
|||
|
||||
class ContractsStore {
|
||||
@observable activeKeysBallotsIDs;
|
||||
|
||||
@observable poaConsensus;
|
||||
@observable ballotsStorage;
|
||||
@observable votingToChangeKeys;
|
||||
|
@ -33,12 +32,15 @@ class ContractsStore {
|
|||
@observable keysBallotThreshold;
|
||||
@observable minThresholdBallotThreshold;
|
||||
@observable proxyBallotThreshold;
|
||||
@observable validatorLimits;
|
||||
@observable validatorsMetadata;
|
||||
|
||||
constructor() {
|
||||
this.votingKey = null;
|
||||
this.miningKey = null;
|
||||
this.activeKeysBallotsIDs = [];
|
||||
|
||||
this.validatorsMetadata = [];
|
||||
this.validatorLimits = {keys: null, minThreshold: null, proxy: null};
|
||||
getWeb3().then(async (web3Config) => {
|
||||
contractsStore.setWeb3Instance(web3Config);
|
||||
})
|
||||
|
@ -55,8 +57,8 @@ class ContractsStore {
|
|||
}
|
||||
|
||||
@action("Get min threshold ballot threshold")
|
||||
getMinThresholdBallotThreshold() {
|
||||
this.minThresholdBallotThreshold = this.keysBallotThreshold;
|
||||
async getMinThresholdBallotThreshold() {
|
||||
this.minThresholdBallotThreshold = await this.ballotsStorage.ballotsStorageInstance.methods.getBallotThreshold(1).call();
|
||||
}
|
||||
|
||||
@action("get proxy ballot threshold")
|
||||
|
@ -67,47 +69,54 @@ class ContractsStore {
|
|||
@action("Set web3Instance")
|
||||
setWeb3Instance = (web3Config) => {
|
||||
this.web3Instance = web3Config.web3Instance;
|
||||
this.netId = web3Config.netId;
|
||||
}
|
||||
|
||||
@action("Set PoA Consensus contract")
|
||||
setPoaConsensus = (web3Config) => {
|
||||
this.poaConsensus = new PoaConsensus({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
@action("Set Ballots Storage contract")
|
||||
setBallotsStorage = (web3Config) => {
|
||||
this.ballotsStorage = new BallotsStorage({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
@action("Set VotingToChangeKeys contract")
|
||||
setVotingToChangeKeys = (web3Config) => {
|
||||
this.votingToChangeKeys = new VotingToChangeKeys({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
@action("Set VotingToChangeMinThreshold contract")
|
||||
setVotingToChangeMinThreshold = (web3Config) => {
|
||||
this.votingToChangeMinThreshold = new VotingToChangeMinThreshold({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
@action("Set VotingToChangeProxy contract")
|
||||
setVotingToChangeProxy = (web3Config) => {
|
||||
this.votingToChangeProxy = new VotingToChangeProxy({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
@action("Set ValidatorMetadata contract")
|
||||
setValidatorMetadata = (web3Config) => {
|
||||
this.validatorMetadata = new ValidatorMetadata({
|
||||
web3: web3Config.web3Instance
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -173,6 +182,25 @@ class ContractsStore {
|
|||
commonStore.hideLoading();
|
||||
}
|
||||
}
|
||||
@action
|
||||
async getValidatorActiveBallots() {
|
||||
if(this.web3Instance && this.netId){
|
||||
await this.setVotingToChangeKeys({web3Instance: this.web3Instance, netId: this.netId})
|
||||
await this.setVotingToChangeMinThreshold({web3Instance: this.web3Instance, netId: this.netId})
|
||||
await this.setVotingToChangeProxy({web3Instance: this.web3Instance, netId: this.netId})
|
||||
this.validatorLimits.keys = await this.votingToChangeKeys.getBallotLimit(this.web3Instance.eth.defaultAccount);
|
||||
this.validatorLimits.minThreshold = await this.votingToChangeMinThreshold.getBallotLimit(this.web3Instance.eth.defaultAccount);
|
||||
this.validatorLimits.proxy = await this.votingToChangeProxy.getBallotLimit(this.web3Instance.eth.defaultAccount);
|
||||
}
|
||||
}
|
||||
@action
|
||||
async getAllValidatorMetadata() {
|
||||
const keys = await this.poaConsensus.getValidators();
|
||||
keys.forEach(async (key) => {
|
||||
const metadata = await this.validatorMetadata.getValidatorData({miningKey: key})
|
||||
this.validatorsMetadata.push({label: `${key} ${metadata.lastName}`, value: key})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const contractsStore = new ContractsStore();
|
||||
|
|
Loading…
Reference in New Issue