From 69cec002f9a58ec9402cbb314c7fb1bcee6a7e8a Mon Sep 17 00:00:00 2001 From: viktor Date: Mon, 25 Dec 2017 10:46:35 +0300 Subject: [PATCH] Ballot creator fullname from metadacontract ia added, relates to #15 --- src/components/BallotKeysCard.jsx | 26 +- src/components/BallotMinThresholdCard.jsx | 26 +- src/components/BallotProxyCard.jsx | 26 +- src/contracts/ValidatorMetadata.contract.js | 57 +++ src/contracts/addresses.js | 3 +- src/contracts/validatorMetadata.abi.json | 461 ++++++++++++++++++++ src/helpers.js | 18 + src/index.js | 1 + src/stores/ContractsStore.js | 9 + 9 files changed, 623 insertions(+), 4 deletions(-) create mode 100644 src/contracts/ValidatorMetadata.contract.js create mode 100644 src/contracts/validatorMetadata.abi.json create mode 100644 src/helpers.js diff --git a/src/components/BallotKeysCard.jsx b/src/components/BallotKeysCard.jsx index 3ec0dea..0ae3865 100644 --- a/src/components/BallotKeysCard.jsx +++ b/src/components/BallotKeysCard.jsx @@ -2,6 +2,7 @@ import React from 'react'; import moment from 'moment'; import { observable, action, computed } from "mobx"; import { inject, observer } from "mobx-react"; +import { toAscii } from "../helpers" @inject("contractsStore", "ballotStore") @observer @@ -14,6 +15,7 @@ export class BallotKeysCard extends React.Component { @observable affectedKeyTypeDisplayName; @observable ballotType; @observable ballotTypeDisplayName; + @observable creator; @action("Get ballotTypeDisplayName") getBallotTypeDisplayName(ballotType) { @@ -109,6 +111,27 @@ export class BallotKeysCard extends React.Component { this.affectedKey = affectedKey; } + @action("Get creator") + getCreator = async (_id) => { + const { contractsStore } = this.props; + let votingState = await contractsStore.votingToChangeKeys.votingToChangeKeysInstance.methods.votingState(_id).call() + console.log("votingState:", votingState); + this.getValidatorFullname(votingState.creator); + } + + @action("Get validator full name") + getValidatorFullname = async (_miningKey) => { + const { contractsStore } = this.props; + let validator = await contractsStore.validatorMetadata.metadataInstance.methods.validators(_miningKey).call(); + console.log(validator) + console.log(validator.firstName) + console.log(validator.firstName.length) + let firstName = toAscii(validator.firstName); + let lastName = toAscii(validator.lastName); + let fullName = `${firstName} ${lastName}` + this.creator = fullName ? fullName : _miningKey; + } + constructor(props) { super(props); this.getStartTime(this.props.id); @@ -116,6 +139,7 @@ export class BallotKeysCard extends React.Component { this.getAffectedKey(this.props.id); this.getAffectedKeyType(this.props.id); this.getBallotType(this.props.id); + this.getCreator(this.props.id); this.calcTimeToFinish(this.props.id); } @@ -128,7 +152,7 @@ export class BallotKeysCard extends React.Component {

Name

-

Suleyman Duyar

+

{this.creator}

{this.startTime}

diff --git a/src/components/BallotMinThresholdCard.jsx b/src/components/BallotMinThresholdCard.jsx index d238392..3308218 100644 --- a/src/components/BallotMinThresholdCard.jsx +++ b/src/components/BallotMinThresholdCard.jsx @@ -2,6 +2,7 @@ import React from 'react'; import moment from 'moment'; import { observable, action } from "mobx"; import { inject, observer } from "mobx-react"; +import { toAscii } from "../helpers" @inject("contractsStore") @observer @@ -10,6 +11,7 @@ export class BallotMinThresholdCard extends React.Component { @observable endTime; @observable timeToFinish; @observable proposedValue; + @observable creator; @action("Get start time of min threshold ballot") getStartTime = async (_id) => { @@ -48,11 +50,33 @@ export class BallotMinThresholdCard extends React.Component { this.proposedValue = proposedValue; } + @action("Get creator") + getCreator = async (_id) => { + const { contractsStore } = this.props; + let votingState = await contractsStore.votingToChangeKeys.votingToChangeKeysInstance.methods.votingState(_id).call() + console.log("votingState:", votingState); + this.getValidatorFullname(votingState.creator); + } + + @action("Get validator full name") + getValidatorFullname = async (_miningKey) => { + const { contractsStore } = this.props; + let validator = await contractsStore.validatorMetadata.metadataInstance.methods.validators(_miningKey).call(); + console.log(validator) + console.log(validator.firstName) + console.log(validator.firstName.length) + let firstName = toAscii(validator.firstName); + let lastName = toAscii(validator.lastName); + let fullName = `${firstName} ${lastName}` + this.creator = fullName ? fullName : _miningKey; + } + constructor(props) { super(props); this.getStartTime(this.props.id); this.getEndTime(this.props.id); this.getProposedValue(this.props.id); + this.getCreator(this.props.id); this.calcTimeToFinish(this.props.id); } @@ -65,7 +89,7 @@ export class BallotMinThresholdCard extends React.Component {

Name

-

Suleyman Duyar

+

{this.creator}

{this.startTime}

diff --git a/src/components/BallotProxyCard.jsx b/src/components/BallotProxyCard.jsx index 1cad423..cea5df5 100644 --- a/src/components/BallotProxyCard.jsx +++ b/src/components/BallotProxyCard.jsx @@ -2,6 +2,7 @@ import React from 'react'; import moment from 'moment'; import { observable, action, computed } from "mobx"; import { inject, observer } from "mobx-react"; +import { toAscii } from "../helpers" @inject("contractsStore", "ballotStore") @observer @@ -11,6 +12,7 @@ export class BallotProxyCard extends React.Component { @observable timeToFinish; @observable proposedAddress; @observable contractType; + @observable creator; @action("Calculate time to finish") calcTimeToFinish = (_id) => { @@ -57,12 +59,34 @@ export class BallotProxyCard extends React.Component { this.contractType = contractType; } + @action("Get creator") + getCreator = async (_id) => { + const { contractsStore } = this.props; + let votingState = await contractsStore.votingToChangeKeys.votingToChangeKeysInstance.methods.votingState(_id).call() + console.log("votingState:", votingState); + this.getValidatorFullname(votingState.creator); + } + + @action("Get validator full name") + getValidatorFullname = async (_miningKey) => { + const { contractsStore } = this.props; + let validator = await contractsStore.validatorMetadata.metadataInstance.methods.validators(_miningKey).call(); + console.log(validator) + console.log(validator.firstName) + console.log(validator.firstName.length) + let firstName = toAscii(validator.firstName); + let lastName = toAscii(validator.lastName); + let fullName = `${firstName} ${lastName}` + this.creator = fullName ? fullName : _miningKey; + } + constructor(props) { super(props); this.getStartTime(this.props.id); this.getEndTime(this.props.id); this.getProposedAddress(this.props.id); this.getContractType(this.props.id); + this.getCreator(this.props.id); this.calcTimeToFinish(this.props.id); } @@ -76,7 +100,7 @@ export class BallotProxyCard extends React.Component {

Name

-

Suleyman Duyar

+

{this.creator}

{this.startTime}

diff --git a/src/contracts/ValidatorMetadata.contract.js b/src/contracts/ValidatorMetadata.contract.js new file mode 100644 index 0000000..94c9a60 --- /dev/null +++ b/src/contracts/ValidatorMetadata.contract.js @@ -0,0 +1,57 @@ +import MetadataAbi from './validatorMetadata.abi.json' +import Web3 from 'web3'; +import moment from 'moment'; +import {METADATA_ADDRESS} from './addresses'; +var toAscii = function(hex) { + var str = '', + i = 0, + l = hex.length; + if (hex.substring(0, 2) === '0x') { + i = 2; + } + for (; i < l; i+=2) { + var code = parseInt(hex.substr(i, 2), 16); + if (code === 0) continue; // this is added + str += String.fromCharCode(code); + } + 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); + this.metadataInstance = new this.web3_10.eth.Contract(MetadataAbi, METADATA_ADDRESS); + } + } + + async getValidatorData({votingKey, miningKey}){ + miningKey = miningKey || await this.getMiningByVoting(votingKey); + let validatorData = await this.metadataInstance.methods.validators(miningKey).call(); + let createdDate = validatorData.createdDate > 0 ? moment.unix(validatorData.createdDate).format('YYYY-MM-DD') : '' + let updatedDate = validatorData.updatedDate > 0 ? moment.unix(validatorData.updatedDate).format('YYYY-MM-DD') : '' + let expirationDate = validatorData.expirationDate > 0 ? moment.unix(validatorData.expirationDate).format('YYYY-MM-DD') : '' + let postal_code = Number(validatorData.zipcode) || '' + return { + firstName: toAscii(validatorData.firstName), + lastName: toAscii(validatorData.lastName), + fullAddress: validatorData.fullAddress, + createdDate, + updatedDate, + expirationDate, + licenseId: toAscii(validatorData.licenseId), + us_state: toAscii(validatorData.state), + postal_code, + } + } + + async getMiningByVoting(votingKey){ + return await this.metadataInstance.methods.getMiningByVotingKey(votingKey).call(); + } + + async getMinThreshold({miningKey}) { + let validatorData = await this.metadataInstance.methods.validators(miningKey).call(); + return validatorData.minThreshold; + } +} diff --git a/src/contracts/addresses.js b/src/contracts/addresses.js index 69fad07..5961350 100644 --- a/src/contracts/addresses.js +++ b/src/contracts/addresses.js @@ -2,5 +2,6 @@ module.exports = { KEYS_MANAGER_ADDRESS: '0x0e4a78ba651fcf2058e1326e16fc9160553ca467', VOTING_TO_CHANGE_KEYS_ADDRESS: '0x534165101c5eec16c4a18102b98b8a903644e513', VOTING_TO_CHANGE_MIN_THRESHOLD: '0xf7ee04d7e85ecf98ad62f96b0a40ab82de1eb0e3', - VOTING_TO_CHANGE_PROXY: '0x13d3c35d9947d77c677a648b9916998c4393622f' + VOTING_TO_CHANGE_PROXY: '0x13d3c35d9947d77c677a648b9916998c4393622f', + METADATA_ADDRESS: '0x1ada723e24f414a72bac6a127f4b2a8d91dfec38' } \ No newline at end of file diff --git a/src/contracts/validatorMetadata.abi.json b/src/contracts/validatorMetadata.abi.json new file mode 100644 index 0000000..3d354df --- /dev/null +++ b/src/contracts/validatorMetadata.abi.json @@ -0,0 +1,461 @@ +[ + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "pendingChanges", + "outputs": [ + { + "name": "firstName", + "type": "bytes32" + }, + { + "name": "lastName", + "type": "bytes32" + }, + { + "name": "licenseId", + "type": "bytes32" + }, + { + "name": "fullAddress", + "type": "string" + }, + { + "name": "state", + "type": "bytes32" + }, + { + "name": "zipcode", + "type": "uint256" + }, + { + "name": "expirationDate", + "type": "uint256" + }, + { + "name": "createdDate", + "type": "uint256" + }, + { + "name": "updatedDate", + "type": "uint256" + }, + { + "name": "minThreshold", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getBallotsStorage", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "confirmations", + "outputs": [ + { + "name": "count", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_miningKey", + "type": "address" + } + ], + "name": "finalize", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getTime", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_votingKey", + "type": "address" + } + ], + "name": "getMiningByVotingKey", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_firstName", + "type": "bytes32" + }, + { + "name": "_lastName", + "type": "bytes32" + }, + { + "name": "_licenseId", + "type": "bytes32" + }, + { + "name": "_fullAddress", + "type": "string" + }, + { + "name": "_state", + "type": "bytes32" + }, + { + "name": "_zipcode", + "type": "uint256" + }, + { + "name": "_expirationDate", + "type": "uint256" + } + ], + "name": "changeRequest", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getKeysManager", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_miningKey", + "type": "address" + } + ], + "name": "confirmPendingChange", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "proxyStorage", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_miningKey", + "type": "address" + } + ], + "name": "onlyIfChangeExist", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getMinThreshold", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_miningKey", + "type": "address" + }, + { + "name": "_voter", + "type": "address" + } + ], + "name": "isAddressAlreadyVoted", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_firstName", + "type": "bytes32" + }, + { + "name": "_lastName", + "type": "bytes32" + }, + { + "name": "_licenseId", + "type": "bytes32" + }, + { + "name": "_fullAddress", + "type": "string" + }, + { + "name": "_state", + "type": "bytes32" + }, + { + "name": "_zipcode", + "type": "uint256" + }, + { + "name": "_expirationDate", + "type": "uint256" + } + ], + "name": "createMetadata", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "cancelPendingChange", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "validators", + "outputs": [ + { + "name": "firstName", + "type": "bytes32" + }, + { + "name": "lastName", + "type": "bytes32" + }, + { + "name": "licenseId", + "type": "bytes32" + }, + { + "name": "fullAddress", + "type": "string" + }, + { + "name": "state", + "type": "bytes32" + }, + { + "name": "zipcode", + "type": "uint256" + }, + { + "name": "expirationDate", + "type": "uint256" + }, + { + "name": "createdDate", + "type": "uint256" + }, + { + "name": "updatedDate", + "type": "uint256" + }, + { + "name": "minThreshold", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_proxyStorage", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "miningKey", + "type": "address" + } + ], + "name": "MetadataCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "miningKey", + "type": "address" + } + ], + "name": "ChangeRequestInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "miningKey", + "type": "address" + } + ], + "name": "CancelledRequest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "miningKey", + "type": "address" + }, + { + "indexed": false, + "name": "votingSender", + "type": "address" + } + ], + "name": "Confirmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "miningKey", + "type": "address" + } + ], + "name": "FinalizedChange", + "type": "event" + } +] diff --git a/src/helpers.js b/src/helpers.js new file mode 100644 index 0000000..caa3b89 --- /dev/null +++ b/src/helpers.js @@ -0,0 +1,18 @@ +var toAscii = function(hex) { + var str = '', + i = 0, + l = hex.length; + if (hex.substring(0, 2) === '0x') { + i = 2; + } + for (; i < l; i+=2) { + var code = parseInt(hex.substr(i, 2), 16); + if (code === 0) continue; // this is added + str += String.fromCharCode(code); + } + return str; +}; + +module.exports = { + toAscii: toAscii +} diff --git a/src/index.js b/src/index.js index d6baaa9..f572937 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,7 @@ class AppMainRouter extends Component { contractsStore.setVotingToChangeKeys(web3Config); contractsStore.setVotingToChangeMinThreshold(web3Config); contractsStore.setVotingToChangeProxy(web3Config); + contractsStore.setValidatorMetadata(web3Config); contractsStore.setVotingKey(web3Config); contractsStore.getAllKeysBallots(); contractsStore.getAllProxyBallots(); diff --git a/src/stores/ContractsStore.js b/src/stores/ContractsStore.js index a28755a..6935e7c 100644 --- a/src/stores/ContractsStore.js +++ b/src/stores/ContractsStore.js @@ -4,6 +4,7 @@ import React from 'react'; import VotingToChangeKeys from '../contracts/VotingToChangeKeys.contract' import VotingToChangeMinThreshold from '../contracts/VotingToChangeMinThreshold.contract' import VotingToChangeProxy from '../contracts/VotingToChangeProxy.contract' +import ValidatorMetadata from '../contracts/ValidatorMetadata.contract' import ballotStore from './BallotStore' import ballotsStore from './BallotsStore' import getWeb3 from '../getWeb3'; @@ -19,6 +20,7 @@ class ContractsStore { @observable votingToChangeKeys; @observable votingToChangeMinThreshold; @observable votingToChangeProxy; + @observable validatorMetadata; @observable votingKey; @observable miningKey; @observable web3Instance; @@ -67,6 +69,13 @@ class ContractsStore { }); } + @action("Set ValidatorMetadata contract") + setValidatorMetadata = (web3Config) => { + this.validatorMetadata = new ValidatorMetadata({ + web3: web3Config.web3Instance + }); + } + @action("Set voting key") setVotingKey = (web3Config) => { this.votingKey = web3Config.defaultAccount;