From a8e89a4451e663bde8dc38f5966b3ee94edbe9a1 Mon Sep 17 00:00:00 2001 From: perissology Date: Wed, 20 Sep 2017 17:07:34 +0200 Subject: [PATCH] create a generateClass function --- js/generateClass.js | 95 ++++++++++ js/liquidPledging.js | 408 +++++++++++++++++-------------------------- js/vault.js | 8 +- 3 files changed, 261 insertions(+), 250 deletions(-) create mode 100644 js/generateClass.js diff --git a/js/generateClass.js b/js/generateClass.js new file mode 100644 index 0000000..f6ec76c --- /dev/null +++ b/js/generateClass.js @@ -0,0 +1,95 @@ + +function checkWeb3(web3) { + if (typeof web3.version !== 'string' || !web3.version.startsWith('1.')) { + throw new Error('web3 version 1.x is required'); + } +} + +const estimateGas = (web3, method, opts) => { + if (opts.$noEstimateGas) return Promise.resolve(4700000); + if (opts.$gas || opts.gas) return Promise.resolve(opts.$gas || opts.gas); + + return method.estimateGas(opts) + // eslint-disable-next-line no-confusing-arrow + .then(gas => opts.$extraGas ? gas + opts.$extraGas : Math.floor(gas * 1.1)); +}; + +// if constant method, executes a call, otherwise, estimates gas and executes send +const execute = (web3, txObject, opts, cb) => { + const { _method } = txObject; + + if (_method.constant) return txObject.call(opts); + + // eslint-disable-next-line no-param-reassign + return estimateGas(web3, txObject, opts) + .then((gas) => { + Object.assign(opts, { gas }); + return (cb) ? txObject.send(opts, cb) : txObject.send(opts); + }); +}; + +const methodWrapper = (web3, method, ...args) => { + let cb; + let opts = {}; + + if (typeof args[args.length - 1] === 'function') cb = args.pop(); + if (typeof args[args.length - 1] === 'object') opts = args.pop(); + + const txObject = method(...args); + + return execute(web3, txObject, opts, cb); +}; + + +module.exports = (abi, bytecode) => { + const C = function C(web3, address) { + checkWeb3(web3); + + this.$web3 = web3; + this.$address = address; + this.$contract = new web3.eth.Contract(abi, address); + this.$abi = abi; + this.$byteCode = bytecode; + + + Object.keys(this.$contract.methods) + .filter(key => !key.startsWith('0x')) + .forEach((key) => { + this[key] = (...args) => methodWrapper(web3, this.$contract.methods[key], ...args); + }); + + // set default from address + web3.eth.getAccounts() + .then((accounts) => { + this.$contract.options.from = (accounts.length > 0) ? accounts[0] : undefined; + }); + }; + + C.new = function (web3, ...args) { + let opts = {}; + if (args && args.length > 0 && typeof args[args.length - 1] === 'object') { + opts = args.pop(); + } + + const deploy = new web3.eth.Contract(abi) + .deploy({ + data: bytecode, + arguments: args, + }); + + const getAccount = () => { + if (opts.from) return Promise.resolve(opts.from); + + return web3.eth.getAccounts() + // eslint-disable-next-line no-confusing-arrow + .then(accounts => (accounts.length > 0) ? accounts[0] : undefined); + }; + + return getAccount() + .then(account => Object.assign(opts, { from: account })) + .then(() => execute(web3, deploy, opts)) + .then(contract => new C(web3, contract.options.address)); + }; + + return C; +}; diff --git a/js/liquidPledging.js b/js/liquidPledging.js index df7f490..d0da5a6 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -3,279 +3,195 @@ const LiquidPledgingAbi = require('../build/LiquidPledging.sol').LiquidPledgingA const LiquidPledgingCode = require('../build/LiquidPledging.sol').LiquidPledgingByteCode; const LiquidPledgingMockAbi = require('../build/LiquidPledgingMock.sol').LiquidPledgingMockAbi; const LiquidPledgingMockCode = require('../build/LiquidPledgingMock.sol').LiquidPledgingMockByteCode; - -function checkWeb3(web3) { - if (typeof web3.version !== 'string' || !web3.version.startsWith('1.')) { - throw new Error('web3 version 1.x is required'); - } -} - -const estimateGas = (web3, method, opts) => { - if (opts.$noEstimateGas) return Promise.resolve(4700000); - if (opts.$gas || opts.gas) return Promise.resolve(opts.$gas || opts.gas); - - return method.estimateGas(opts) - // eslint-disable-next-line no-confusing-arrow - .then(gas => opts.$extraGas ? gas + opts.$extraGas : Math.floor(gas * 1.1)); -}; - -// if constant method, executes a call, otherwise, estimates gas and executes send -const execute = (web3, txObject, opts, cb) => { - const { _method } = txObject; - - if (_method.constant) return txObject.call(opts); - - // eslint-disable-next-line no-param-reassign - return estimateGas(web3, txObject, opts) - .then((gas) => { - Object.assign(opts, { gas }); - return (cb) ? txObject.send(opts, cb) : txObject.send(opts); - }); -}; - -const methodWrapper = (web3, method, ...args) => { - let cb; - let opts = {}; - - if (typeof args[args.length - 1] === 'function') cb = args.pop(); - if (typeof args[args.length - 1] === 'object') opts = args.pop(); - - const txObject = method(...args); - - return execute(web3, txObject, opts, cb); -}; - +const generateClass = require('./generateClass'); module.exports = (test) => { const $abi = (test) ? LiquidPledgingMockAbi : LiquidPledgingAbi; const $byteCode = (test) ? LiquidPledgingMockCode : LiquidPledgingCode; + const LiquidPledging = generateClass($abi, $byteCode); - return class LiquidPledging { - constructor(web3, address) { - checkWeb3(web3); + async function $getNote(idNote) { + const note = { + delegates: [], + }; + const res = await this.getNote(idNote); + note.amount = this.$toNumber(res.amount); + note.owner = res.owner; + for (let i = 1; i <= this.$toDecimal(res.nDelegates); i += 1) { + const delegate = {}; + const resd = await this.getNoteDelegate(idNote, i); + delegate.id = this.$toDecimal(resd.idDelegate); + delegate.addr = resd.addr; + delegate.name = resd.name; + note.delegates.push(delegate); + } + if (res.proposedProject) { + note.proposedProject = this.$toDecimal(res.proposedProject); + note.commmitTime = this.$toDecimal(res.commitTime); + } + if (res.oldNote) { + note.oldProject = this.$toDecimal(res.oldNote); + } + if (res.paymentState === '0') { + note.paymentState = 'NotPaid'; + } else if (res.paymentState === '1') { + note.paymentState = 'Paying'; + } else if (res.paymentState === '2') { + note.paymentState = 'Paid'; + } else { + note.paymentState = 'Unknown'; + } + return note; + } - this.$web3 = web3; - this.$address = address; - this.$contract = new web3.eth.Contract($abi, address); - this.$abi = $abi; - this.$byteCode = $byteCode; + LiquidPledging.prototype.$getNote = $getNote; - // helpers - this.$toNumber = web3.utils.toBN; - this.$toDecimal = web3.utils.toDecimal; + async function $getManager(idManager) { + const manager = {}; + const res = await this.getNoteManager(idManager); + if (res.managerType === '0') { + manager.type = 'Donor'; + } else if (res.managerType === '1') { + manager.type = 'Delegate'; + } else if (res.managerType === '2') { + manager.type = 'Project'; + } else { + manager.type = 'Unknown'; + } + manager.addr = res.addr; + manager.name = res.name; + manager.commitTime = this.$toDecimal(res.commitTime); + if (manager.paymentState === 'Project') { + manager.parentProject = res.parentProject; + manager.canceled = res.canceled; + } + return manager; + }; - this.notes = []; - this.managers = []; + LiquidPledging.prototype.$getManager = $getManager; - Object.keys(this.$contract.methods) - .filter(key => !key.startsWith('0x')) - .forEach((key) => { - this[key] = (...args) => methodWrapper(web3, this.$contract.methods[key], ...args); - }); - - // set default from address - web3.eth.getAccounts() - .then((accounts) => { - this.$contract.options.from = (accounts.length > 0) ? accounts[0] : undefined; - }); + async function getState() { + const st = { + notes: [null], + managers: [null], + }; + const nNotes = await this.numberOfNotes(); + for (let i = 1; i <= nNotes; i += 1) { + const note = await this.$getNote(i); + st.notes.push(note); } - async $getNote(idNote) { - const note = { - delegates: [], - }; - const res = await this.getNote(idNote); - note.amount = this.$toNumber(res.amount); - note.owner = res.owner; - for (let i = 1; i <= this.$toDecimal(res.nDelegates); i += 1) { - const delegate = {}; - const resd = await this.getNoteDelegate(idNote, i); - delegate.id = this.$toDecimal(resd.idDelegate); - delegate.addr = resd.addr; - delegate.name = resd.name; - note.delegates.push(delegate); - } - if (res.proposedProject) { - note.proposedProject = this.$toDecimal(res.proposedProject); - note.commmitTime = this.$toDecimal(res.commitTime); - } - if (res.oldNote) { - note.oldProject = this.$toDecimal(res.oldNote); - } - if (res.paymentState === '0') { - note.paymentState = 'NotPaid'; - } else if (res.paymentState === '1') { - note.paymentState = 'Paying'; - } else if (res.paymentState === '2') { - note.paymentState = 'Paid'; - } else { - note.paymentState = 'Unknown'; - } - return note; + const nManagers = await this.numberOfNoteManagers(); + for (let i = 1; i <= nManagers; i += 1) { + const manager = await this.$getManager(i); + st.managers.push(manager); } + return st; + }; - async $getManager(idManager) { - const manager = {}; - const res = await this.getNoteManager(idManager); - if (res.managerType === '0') { - manager.type = 'Donor'; - } else if (res.managerType === '1') { - manager.type = 'Delegate'; - } else if (res.managerType === '2') { - manager.type = 'Project'; - } else { - manager.type = 'Unknown'; - } - manager.addr = res.addr; - manager.name = res.name; - manager.commitTime = this.$toDecimal(res.commitTime); - if (manager.paymentState === 'Project') { - manager.parentProject = res.parentProject; - manager.canceled = res.canceled; - } - return manager; - } + LiquidPledging.prototype.getState = getState; - async getState() { - const st = { - notes: [null], - managers: [null], - }; - const nNotes = await this.numberOfNotes(); - for (let i = 1; i <= nNotes; i += 1) { - const note = await this.$getNote(i); - st.notes.push(note); - } + LiquidPledging.prototype.generateDonorsState = function () { + const donorsState = []; - const nManagers = await this.numberOfNoteManagers(); - for (let i = 1; i <= nManagers; i += 1) { - const manager = await this.$getManager(i); - st.managers.push(manager); - } - return st; - } - - generateDonorsState() { - const donorsState = []; - - const getDonor = (idNote) => { - let note = this.notes[idNote]; - while (note.oldNode) note = this.notes[idNote]; - return note.owner; - }; + const getDonor = (idNote) => { + let note = this.notes[idNote]; + while (note.oldNode) note = this.notes[idNote]; + return note.owner; + }; // Add a donor structure to the list - const addDonor = (_list, idDonor) => { - const list = _list; - if (!list[idDonor]) { - list[idDonor] = { - idDonor, - notAssigned: { - notes: [], - delegates: [], - }, - precommitedProjects: [], - commitedProjects: [], - }; - } - }; + const addDonor = (_list, idDonor) => { + const list = _list; + if (!list[idDonor]) { + list[idDonor] = { + idDonor, + notAssigned: { + notes: [], + delegates: [], + }, + precommitedProjects: [], + commitedProjects: [], + }; + } + }; // Add a delegate structure to the list - const addDelegate = (_list, idDelegate) => { - const list = _list; - if (!list[idDelegate]) { - list[idDelegate] = { - idDelegate, - name: this.managers[idDelegate].name, - notes: [], - delegtes: [], - }; - } - }; + const addDelegate = (_list, idDelegate) => { + const list = _list; + if (!list[idDelegate]) { + list[idDelegate] = { + idDelegate, + name: this.managers[idDelegate].name, + notes: [], + delegtes: [], + }; + } + }; - const addProject = (_list, idProject) => { - const list = _list; - if (!list[idProject]) { - list[idProject] = { - idProject, - notes: [], - commitedProjects: [], - name: this.managers[idProject].name, - commitTime: this.managers[idProject].commitTime, - owner: this.managers[idProject].owner, - parentProject: this.managers[idProject].parentProject, - }; - } - }; + const addProject = (_list, idProject) => { + const list = _list; + if (!list[idProject]) { + list[idProject] = { + idProject, + notes: [], + commitedProjects: [], + name: this.managers[idProject].name, + commitTime: this.managers[idProject].commitTime, + owner: this.managers[idProject].owner, + parentProject: this.managers[idProject].parentProject, + }; + } + }; - const addDelegateNote = (stDonor, idNote) => { - const note = this.notes[idNote]; - stDonor.notAssigned.notes.push(idNote); - let list = stDonor.notAssigned.delegates; - for (let i = 0; i < note.delegationChain.length; i += 1) { - const idDelegate = note.delegationChain[i]; - addDelegate(list, idDelegate); - list = list[idDelegate].delegates; - } - }; + const addDelegateNote = (stDonor, idNote) => { + const note = this.notes[idNote]; + stDonor.notAssigned.notes.push(idNote); + let list = stDonor.notAssigned.delegates; + for (let i = 0; i < note.delegationChain.length; i += 1) { + const idDelegate = note.delegationChain[i]; + addDelegate(list, idDelegate); + list = list[idDelegate].delegates; + } + }; - const addProjectNote = (stDonor, idNote) => { - const note = this.notes[idNote]; + const addProjectNote = (stDonor, idNote) => { + const note = this.notes[idNote]; - const projectList = []; - let n = note; - while (n.oldNode) { - projectList.unshift(n.owner); - n = this.notes[n.oldNode]; - } - - let list = stDonor.commitedProjects; - for (let j = 0; j < projectList.length; j += 1) { - addProject(list, projectList[j]); - list[projectList[j]].notes.push(idNote); - list = list[projectList[j]].commitedProjects; - } - }; - - for (let i = 0; i < this.notes; i += 1) { - const idNote = this.notes[i]; - const idDonor = getDonor(idNote); - addDonor(donorsState, idDonor); - const stDonor = donorsState[idDonor]; - const note = this.notes[idNote]; - if ((note.owner === idDonor) && (note.precommitedProject === 0)) { - addDelegateNote(stDonor, idNote); - } else if ((note.owner === idDonor) && (note.precommitedProject !== 0)) { - addProject(stDonor.precommitedProjects, note.precommitedProject); - stDonor.precommitedProjects[note.precommitedProject].notes.push(idNote); - } else { - addProjectNote(stDonor, idNote); - } + const projectList = []; + let n = note; + while (n.oldNode) { + projectList.unshift(n.owner); + n = this.notes[n.oldNode]; } - this.donorsState = donorsState; + let list = stDonor.commitedProjects; + for (let j = 0; j < projectList.length; j += 1) { + addProject(list, projectList[j]); + list[projectList[j]].notes.push(idNote); + list = list[projectList[j]].commitedProjects; + } + }; + + for (let i = 0; i < this.notes; i += 1) { + const idNote = this.notes[i]; + const idDonor = getDonor(idNote); + addDonor(donorsState, idDonor); + const stDonor = donorsState[idDonor]; + const note = this.notes[idNote]; + if ((note.owner === idDonor) && (note.precommitedProject === 0)) { + addDelegateNote(stDonor, idNote); + } else if ((note.owner === idDonor) && (note.precommitedProject !== 0)) { + addProject(stDonor.precommitedProjects, note.precommitedProject); + stDonor.precommitedProjects[note.precommitedProject].notes.push(idNote); + } else { + addProjectNote(stDonor, idNote); + } } - static new(web3, vault, opts = {}) { - const deploy = new web3.eth.Contract($abi) - .deploy({ - data: $byteCode, - arguments: [vault], - }); - - const getAccount = () => { - if (opts.from) return Promise.resolve(opts.from); - - return web3.eth.getAccounts() - // eslint-disable-next-line no-confusing-arrow - .then(accounts => (accounts.length > 0) ? accounts[0] : undefined); - }; - - return getAccount() - .then(account => Object.assign(opts, { from: account })) - .then(() => execute(web3, deploy, opts)) - .then(contract => new LiquidPledging(web3, contract.options.address)); - } + this.donorsState = donorsState; }; + + return LiquidPledging; }; diff --git a/js/vault.js b/js/vault.js index e4c9a72..c464fed 100644 --- a/js/vault.js +++ b/js/vault.js @@ -1,5 +1,5 @@ -const VaultAbi = require("../build/Vault.sol").VaultAbi; -const VaultByteCode = require("../build/Vault.sol").VaultByteCode; -const runethtx = require("runethtx"); +const VaultAbi = require('../build/Vault.sol').VaultAbi; +const VaultByteCode = require('../build/Vault.sol').VaultByteCode; +const generateClass = require('./generateClass'); -module.exports = runethtx.generateClass(VaultAbi, VaultByteCode); +module.exports = generateClass(VaultAbi, VaultByteCode);