From 940439322014cdf70a2a522cb9b31498185c6b2e Mon Sep 17 00:00:00 2001 From: perissology Date: Sat, 16 Sep 2017 06:05:50 +0200 Subject: [PATCH 01/12] replace runethtx with web3 1.0 --- js/liquidPledging.js | 147 ++++++++++++++++++++++++++++++++----------- package.json | 1 - 2 files changed, 109 insertions(+), 39 deletions(-) diff --git a/js/liquidPledging.js b/js/liquidPledging.js index b0369f2..e340b9c 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -3,49 +3,99 @@ 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; -const runethtx = require('runethtx'); + +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)); +}; + +// estimate gas before send if necessary +const sendWithDefaults = (web3, txObject) => { + const origSend = txObject.send; + + // eslint-disable-next-line no-param-reassign + txObject.send = (opts = {}, cb) => estimateGas(web3, txObject, opts) + .then((gas) => { + Object.assign(opts, { gas }); + return (cb) ? origSend(opts, cb) : origSend(opts); + }); + + return txObject; +}; + +const extendMethod = (web3, method) => (...args) => sendWithDefaults(web3, method(...args)); module.exports = (test) => { - const LiquidPladgingContract = test ? - runethtx.generateClass(LiquidPledgingMockAbi, LiquidPledgingMockCode) : - runethtx.generateClass(LiquidPledgingAbi, LiquidPledgingCode); + const $abi = (test) ? LiquidPledgingMockAbi : LiquidPledgingAbi; + const $byteCode = (test) ? LiquidPledgingMockCode : LiquidPledgingCode; - return class LiquidPledging extends LiquidPladgingContract { + + return class LiquidPledging { constructor(web3, address) { - super(web3, address); + checkWeb3(web3); + + this.$web3 = web3; + this.$address = address; + this.$contract = new web3.eth.Contract($abi, address); + this.$abi = $abi; + this.$byteCode = $byteCode; + + // helpers + this.$toNumber = web3.utils.toBN; + this.$toDecimal = web3.utils.toDecimal; + this.notes = []; this.managers = []; - this.b = "xxxxxxx b xxxxxxxx"; + + Object.keys(this.$contract.methods).forEach((key) => { + this[key] = extendMethod(web3, this.$contract.methods[key]); + }); + + // set default from address + web3.eth.getAccounts() + .then((accounts) => { + this.$contract.options.from = (accounts.length > 0) ? accounts[0] : undefined; + }); } async $getNote(idNote) { const note = { delegates: [], }; - const res = await this.getNote(idNote); - note.amount = res[0]; - note.owner = res[1]; - for (let i = 1; i <= res[2].toNumber(); i += 1) { + const res = await this.getNote(idNote).call(); + 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 = resd[0].toNumber(); - delegate.addr = resd[1]; - delegate.name = resd[2]; + const resd = await this.getNoteDelegate(idNote, i).call(); + delegate.id = this.$toDecimal(resd.idDelegate); + delegate.addr = resd.addr; + delegate.name = resd.name; note.delegates.push(delegate); } - if (res[3].toNumber()) { - note.proposedProject = res[3].toNumber(); - note.commmitTime = res[4].toNumber(); + if (res.proposedProject) { + note.proposedProject = this.$toDecimal(res.proposedProject); + note.commmitTime = this.$toDecimal(res.commitTime); } - if (res[5].toNumber()) { - note.oldProject = res[5].toNumber(); + if (res.oldNote) { + note.oldProject = this.$toDecimal(res.oldNote); } - if (res[6].toNumber() === 0) { + if (res.paymentState === '0') { note.paymentState = 'NotPaid'; - } else if (res[6].toNumber() === 1) { + } else if (res.paymentState === '1') { note.paymentState = 'Paying'; - } else if (res[6].toNumber() === 2) { + } else if (res.paymentState === '2') { note.paymentState = 'Paid'; } else { note.paymentState = 'Unknown'; @@ -55,22 +105,22 @@ module.exports = (test) => { async $getManager(idManager) { const manager = {}; - const res = await this.getNoteManager(idManager); - if (res[0].toNumber() === 0) { - manager.paymentState = 'Donor'; - } else if (res[0].toNumber() === 1) { - manager.paymentState = 'Delegate'; - } else if (res[0].toNumber() === 2) { - manager.paymentState = 'Project'; + const res = await this.getNoteManager(idManager).call(); + 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.paymentState = 'Unknown'; + manager.type = 'Unknown'; } - manager.addr = res[1]; - manager.name = res[2]; - manager.commitTime = res[3].toNumber(); + manager.addr = res.addr; + manager.name = res.name; + manager.commitTime = this.$toDecimal(res.commitTime); if (manager.paymentState === 'Project') { - manager.parentProject = res[4]; - manager.canceled = res[5]; + manager.parentProject = res.parentProject; + manager.canceled = res.canceled; } return manager; } @@ -80,13 +130,13 @@ module.exports = (test) => { notes: [null], managers: [null], }; - const nNotes = await this.numberOfNotes(); + const nNotes = await this.numberOfNotes().call(); for (let i = 1; i <= nNotes; i += 1) { const note = await this.$getNote(i); st.notes.push(note); } - const nManagers = await this.numberOfNoteManagers(); + const nManagers = await this.numberOfNoteManagers().call(); for (let i = 1; i <= nManagers; i += 1) { const manager = await this.$getManager(i); st.managers.push(manager); @@ -194,5 +244,26 @@ module.exports = (test) => { this.donorsState = donorsState; } + + 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(() => sendWithDefaults(web3, deploy).send(opts)) + .then(contract => new LiquidPledging(web3, contract.options.address)); + } }; }; diff --git a/package.json b/package.json index f9e6aa4..480293b 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "dependencies": { "async": "^2.4.0", "ethconnector": "0.0.25", - "runethtx": "0.1.1", "chai": "^4.1.0" } } From e993ec27ae6fdc1e490331487c7d00b71c213383 Mon Sep 17 00:00:00 2001 From: perissology Date: Wed, 20 Sep 2017 11:44:34 +0200 Subject: [PATCH 02/12] update liquidpledging wrapper --- js/liquidPledging.js | 60 ++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/js/liquidPledging.js b/js/liquidPledging.js index e340b9c..df7f490 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -19,21 +19,31 @@ const estimateGas = (web3, method, opts) => { .then(gas => opts.$extraGas ? gas + opts.$extraGas : Math.floor(gas * 1.1)); }; -// estimate gas before send if necessary -const sendWithDefaults = (web3, txObject) => { - const origSend = txObject.send; +// if constant method, executes a call, otherwise, estimates gas and executes send +const execute = (web3, txObject, opts, cb) => { + const { _method } = txObject; - // eslint-disable-next-line no-param-reassign - txObject.send = (opts = {}, cb) => estimateGas(web3, txObject, opts) - .then((gas) => { - Object.assign(opts, { gas }); - return (cb) ? origSend(opts, cb) : origSend(opts); - }); + if (_method.constant) return txObject.call(opts); - return txObject; + // 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 extendMethod = (web3, method) => (...args) => sendWithDefaults(web3, method(...args)); +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 = (test) => { @@ -58,9 +68,11 @@ module.exports = (test) => { this.notes = []; this.managers = []; - Object.keys(this.$contract.methods).forEach((key) => { - this[key] = extendMethod(web3, this.$contract.methods[key]); - }); + 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() @@ -73,12 +85,12 @@ module.exports = (test) => { const note = { delegates: [], }; - const res = await this.getNote(idNote).call(); + 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).call(); + const resd = await this.getNoteDelegate(idNote, i); delegate.id = this.$toDecimal(resd.idDelegate); delegate.addr = resd.addr; delegate.name = resd.name; @@ -105,7 +117,7 @@ module.exports = (test) => { async $getManager(idManager) { const manager = {}; - const res = await this.getNoteManager(idManager).call(); + const res = await this.getNoteManager(idManager); if (res.managerType === '0') { manager.type = 'Donor'; } else if (res.managerType === '1') { @@ -130,13 +142,13 @@ module.exports = (test) => { notes: [null], managers: [null], }; - const nNotes = await this.numberOfNotes().call(); + const nNotes = await this.numberOfNotes(); for (let i = 1; i <= nNotes; i += 1) { const note = await this.$getNote(i); st.notes.push(note); } - const nManagers = await this.numberOfNoteManagers().call(); + const nManagers = await this.numberOfNoteManagers(); for (let i = 1; i <= nManagers; i += 1) { const manager = await this.$getManager(i); st.managers.push(manager); @@ -247,10 +259,10 @@ module.exports = (test) => { static new(web3, vault, opts = {}) { const deploy = new web3.eth.Contract($abi) - .deploy({ - data: $byteCode, - arguments: [vault], - }); + .deploy({ + data: $byteCode, + arguments: [vault], + }); const getAccount = () => { if (opts.from) return Promise.resolve(opts.from); @@ -262,7 +274,7 @@ module.exports = (test) => { return getAccount() .then(account => Object.assign(opts, { from: account })) - .then(() => sendWithDefaults(web3, deploy).send(opts)) + .then(() => execute(web3, deploy, opts)) .then(contract => new LiquidPledging(web3, contract.options.address)); } }; From a8e89a4451e663bde8dc38f5966b3ee94edbe9a1 Mon Sep 17 00:00:00 2001 From: perissology Date: Wed, 20 Sep 2017 17:07:34 +0200 Subject: [PATCH 03/12] 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); From ebf53f885a79574a9eabf93037e813dc82a70cd8 Mon Sep 17 00:00:00 2001 From: perissology Date: Thu, 21 Sep 2017 16:53:02 +0200 Subject: [PATCH 04/12] fix a bug in generateClass --- js/generateClass.js | 22 ++++++++++++++++++---- package.json | 3 ++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/js/generateClass.js b/js/generateClass.js index f6ec76c..0ef4d12 100644 --- a/js/generateClass.js +++ b/js/generateClass.js @@ -1,3 +1,4 @@ +const Web3PromiEvent = require('web3-core-promievent'); function checkWeb3(web3) { if (typeof web3.version !== 'string' || !web3.version.startsWith('1.')) { @@ -20,12 +21,25 @@ const execute = (web3, txObject, opts, cb) => { if (_method.constant) return txObject.call(opts); - // eslint-disable-next-line no-param-reassign - return estimateGas(web3, txObject, opts) + // we need to create a new PromiEvent here b/c estimateGas returns a regular promise + // however on a 'send' we want to return a PromiEvent + const defer = new Web3PromiEvent(); + const relayEvent = event => (...args) => defer.eventEmitter.emit(event, ...args); + + estimateGas(web3, txObject, opts) .then((gas) => { Object.assign(opts, { gas }); - return (cb) ? txObject.send(opts, cb) : txObject.send(opts); - }); + return (cb) ? txObject.send(opts, cb) : txObject.send(opts) + // relay all events to our promiEvent + .on('transactionHash', relayEvent('transactionHash')) + .on('confirmation', relayEvent('confirmation')) + .on('receipt', relayEvent('receipt')) + .on('error', relayEvent('error')); + }) + .then(defer.resolve) + .catch(defer.reject); + + return defer.eventEmitter; }; const methodWrapper = (web3, method, ...args) => { diff --git a/package.json b/package.json index 480293b..3354e6a 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "dependencies": { "async": "^2.4.0", "ethconnector": "0.0.25", - "chai": "^4.1.0" + "chai": "^4.1.0", + "web3-core-promievent": "^1.0.0-beta.18" } } From bb14e679f0238cede4e02b128ffd6bca7fbdd6d3 Mon Sep 17 00:00:00 2001 From: perissology Date: Thu, 21 Sep 2017 17:48:56 -0400 Subject: [PATCH 05/12] removed await from liquidPledging.js --- js/generateClass.js | 2 +- js/liquidPledging.js | 159 ++++++++++++++++++++++++------------------- 2 files changed, 90 insertions(+), 71 deletions(-) diff --git a/js/generateClass.js b/js/generateClass.js index 0ef4d12..e91c274 100644 --- a/js/generateClass.js +++ b/js/generateClass.js @@ -72,7 +72,7 @@ module.exports = (abi, bytecode) => { this[key] = (...args) => methodWrapper(web3, this.$contract.methods[key], ...args); }); - // set default from address + // set default from address web3.eth.getAccounts() .then((accounts) => { this.$contract.options.from = (accounts.length > 0) ? accounts[0] : undefined; diff --git a/js/liquidPledging.js b/js/liquidPledging.js index d0da5a6..dc78ecb 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -1,4 +1,3 @@ -/* eslint-disable no-await-in-loop */ const LiquidPledgingAbi = require('../build/LiquidPledging.sol').LiquidPledgingAbi; const LiquidPledgingCode = require('../build/LiquidPledging.sol').LiquidPledgingByteCode; const LiquidPledgingMockAbi = require('../build/LiquidPledgingMock.sol').LiquidPledgingMockAbi; @@ -11,87 +10,107 @@ module.exports = (test) => { const LiquidPledging = generateClass($abi, $byteCode); - async function $getNote(idNote) { + LiquidPledging.prototype.$toDecimal = function (val) { return this.$web3.utils.toDecimal(val); }; + LiquidPledging.prototype.$toNumber = function (val) { this.$web3.utils.toBN(val); }; + + LiquidPledging.prototype.$getNote = function (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; - } - LiquidPledging.prototype.$getNote = $getNote; + return this.getNote(idNote) + .then((res) => { + note.amount = this.$toNumber(res.amount); + note.owner = res.owner; - async function $getManager(idManager) { + 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'; + } + + const promises = []; + for (let i = 1; i <= this.$toDecimal(res.nDelegates); i += 1) { + promises.push( + this.getNoteDelegate(idNote, i) + .then(r => ({ + id: this.$toDecimal(r.idDelegate), + addr: r.addr, + name: r.name, + })), + ); + } + + return Promise.all(promises); + }) + .then((delegates) => { + note.delegates = delegates; + return note; + }); + }; + + LiquidPledging.prototype.$getManager = function (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; + return this.getNoteManager(idManager) + .then((res) => { + 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.$getManager = $getManager; + LiquidPledging.prototype.getState = function () { + const getNotes = () => this.numberOfNotes() + .then((nNotes) => { + const promises = []; + for (let i = 1; i <= nNotes; i += 1) { + promises.push(this.$getNote(i)); + } + return Promise.all(promises); + }); - 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); - } + const getManagers = () => this.numberOfNoteManagers() + .then((nManagers) => { + const promises = []; + for (let i = 1; i <= nManagers; i += 1) { + promises.push(this.$getManager(i)); + } - 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; + return Promise.all(promises); + }); + + return Promise.all([getNotes(), getManagers()]) + .then(([notes, managers]) => ({ + notes: [null, ...notes], + managers: [null, ...managers], + })); }; - LiquidPledging.prototype.getState = getState; - LiquidPledging.prototype.generateDonorsState = function () { const donorsState = []; From a6cd06d6c06aed9902fbe14fc20f5c40f8d2980f Mon Sep 17 00:00:00 2001 From: perissology Date: Fri, 22 Sep 2017 10:38:10 -0700 Subject: [PATCH 06/12] move generateClass.js to seperate package --- js/generateClass.js | 109 ------------------------------------------- js/liquidPledging.js | 2 +- js/vault.js | 2 +- package.json | 4 +- 4 files changed, 4 insertions(+), 113 deletions(-) delete mode 100644 js/generateClass.js diff --git a/js/generateClass.js b/js/generateClass.js deleted file mode 100644 index e91c274..0000000 --- a/js/generateClass.js +++ /dev/null @@ -1,109 +0,0 @@ -const Web3PromiEvent = require('web3-core-promievent'); - -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); - - // we need to create a new PromiEvent here b/c estimateGas returns a regular promise - // however on a 'send' we want to return a PromiEvent - const defer = new Web3PromiEvent(); - const relayEvent = event => (...args) => defer.eventEmitter.emit(event, ...args); - - estimateGas(web3, txObject, opts) - .then((gas) => { - Object.assign(opts, { gas }); - return (cb) ? txObject.send(opts, cb) : txObject.send(opts) - // relay all events to our promiEvent - .on('transactionHash', relayEvent('transactionHash')) - .on('confirmation', relayEvent('confirmation')) - .on('receipt', relayEvent('receipt')) - .on('error', relayEvent('error')); - }) - .then(defer.resolve) - .catch(defer.reject); - - return defer.eventEmitter; -}; - -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 dc78ecb..693ef44 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -2,7 +2,7 @@ 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; -const generateClass = require('./generateClass'); +const generateClass = require('eth-contract-class'); module.exports = (test) => { const $abi = (test) ? LiquidPledgingMockAbi : LiquidPledgingAbi; diff --git a/js/vault.js b/js/vault.js index c464fed..836ff8c 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 generateClass = require('./generateClass'); +const generateClass = require('eth-contract-class'); module.exports = generateClass(VaultAbi, VaultByteCode); diff --git a/package.json b/package.json index 3354e6a..e3ca660 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "homepage": "https://github.com/Giveth/liquidpledging#readme", "dependencies": { "async": "^2.4.0", - "ethconnector": "0.0.25", "chai": "^4.1.0", - "web3-core-promievent": "^1.0.0-beta.18" + "eth-contract-class": "0.0.1", + "ethconnector": "0.0.25" } } From 79a6a6641b02657b451ccb23133ff9f7d2afce75 Mon Sep 17 00:00:00 2001 From: perissology Date: Fri, 22 Sep 2017 11:31:42 -0700 Subject: [PATCH 07/12] fix bug with generateClass import --- js/liquidPledging.js | 2 +- js/vault.js | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/js/liquidPledging.js b/js/liquidPledging.js index 693ef44..74208d4 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -2,7 +2,7 @@ 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; -const generateClass = require('eth-contract-class'); +const generateClass = require('eth-contract-class').default; module.exports = (test) => { const $abi = (test) ? LiquidPledgingMockAbi : LiquidPledgingAbi; diff --git a/js/vault.js b/js/vault.js index 836ff8c..79ca76f 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 generateClass = require('eth-contract-class'); +const generateClass = require('eth-contract-class').default; module.exports = generateClass(VaultAbi, VaultByteCode); diff --git a/package.json b/package.json index e3ca660..4062d2f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "async": "^2.4.0", "chai": "^4.1.0", - "eth-contract-class": "0.0.1", + "eth-contract-class": "0.0.2", "ethconnector": "0.0.25" } } From 5082e0dad11a15b08b1e91049a50b74566506d03 Mon Sep 17 00:00:00 2001 From: perissology Date: Tue, 26 Sep 2017 11:50:57 -0700 Subject: [PATCH 08/12] update eth-contract-class dep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4062d2f..d2dfc6b 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "async": "^2.4.0", "chai": "^4.1.0", - "eth-contract-class": "0.0.2", + "eth-contract-class": "0.0.3", "ethconnector": "0.0.25" } } From 43517ca146cd0e19e2f34ef4fa80054af684f20b Mon Sep 17 00:00:00 2001 From: perissology Date: Tue, 26 Sep 2017 11:59:57 -0700 Subject: [PATCH 09/12] add plugin to noteManager state --- js/liquidPledging.js | 1 + 1 file changed, 1 insertion(+) diff --git a/js/liquidPledging.js b/js/liquidPledging.js index 74208d4..43194af 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -80,6 +80,7 @@ module.exports = (test) => { manager.parentProject = res.parentProject; manager.canceled = res.canceled; } + manager.plugin = res.plugin; return manager; }); }; From 336f25a3bb3d273a79fdbc3c76fb2ffa9849b7de Mon Sep 17 00:00:00 2001 From: perissology Date: Mon, 2 Oct 2017 13:20:56 -0700 Subject: [PATCH 10/12] leave response values as strings in getState call --- js/liquidPledging.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/js/liquidPledging.js b/js/liquidPledging.js index 43194af..4a6dcb2 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -10,9 +10,6 @@ module.exports = (test) => { const LiquidPledging = generateClass($abi, $byteCode); - LiquidPledging.prototype.$toDecimal = function (val) { return this.$web3.utils.toDecimal(val); }; - LiquidPledging.prototype.$toNumber = function (val) { this.$web3.utils.toBN(val); }; - LiquidPledging.prototype.$getNote = function (idNote) { const note = { delegates: [], @@ -20,15 +17,15 @@ module.exports = (test) => { return this.getNote(idNote) .then((res) => { - note.amount = this.$toNumber(res.amount); + note.amount = res.amount; note.owner = res.owner; if (res.proposedProject) { - note.proposedProject = this.$toDecimal(res.proposedProject); - note.commmitTime = this.$toDecimal(res.commitTime); + note.proposedProject = res.proposedProject; + note.commmitTime = res.commitTime; } if (res.oldNote) { - note.oldProject = this.$toDecimal(res.oldNote); + note.oldProject = res.oldNote; } if (res.paymentState === '0') { note.paymentState = 'NotPaid'; @@ -41,11 +38,11 @@ module.exports = (test) => { } const promises = []; - for (let i = 1; i <= this.$toDecimal(res.nDelegates); i += 1) { + for (let i = 1; i <= res.nDelegates; i += 1) { promises.push( this.getNoteDelegate(idNote, i) .then(r => ({ - id: this.$toDecimal(r.idDelegate), + id: r.idDelegate, addr: r.addr, name: r.name, })), @@ -75,12 +72,13 @@ module.exports = (test) => { } manager.addr = res.addr; manager.name = res.name; - manager.commitTime = this.$toDecimal(res.commitTime); + manager.commitTime = res.commitTime; if (manager.paymentState === 'Project') { manager.parentProject = res.parentProject; manager.canceled = res.canceled; } manager.plugin = res.plugin; + manager.canceled = res.canceled; return manager; }); }; From 96d5adc1649d5835d9c9bb06747cb89fcc5db1db Mon Sep 17 00:00:00 2001 From: perissology Date: Tue, 3 Oct 2017 06:06:58 -0700 Subject: [PATCH 11/12] update tests to web3 1.0 syntax --- contracts/Owned.sol | 5 +- js/liquidPledging.js | 2 +- package.json | 9 +- test/NormalOperation.js | 223 +++++++++++++++++++++------------------- 4 files changed, 127 insertions(+), 112 deletions(-) diff --git a/contracts/Owned.sol b/contracts/Owned.sol index 4f1d205..2a16ca2 100644 --- a/contracts/Owned.sol +++ b/contracts/Owned.sol @@ -34,8 +34,7 @@ contract Owned { /// @notice `newOwner` can accept ownership over this contract function acceptOwnership() { - require(msg.sender == newOwner) { - owner = newOwner; - } + require(msg.sender == newOwner); + owner = newOwner; } } diff --git a/js/liquidPledging.js b/js/liquidPledging.js index 4a6dcb2..0ced02a 100644 --- a/js/liquidPledging.js +++ b/js/liquidPledging.js @@ -25,7 +25,7 @@ module.exports = (test) => { note.commmitTime = res.commitTime; } if (res.oldNote) { - note.oldProject = res.oldNote; + note.oldNote = res.oldNote; } if (res.paymentState === '0') { note.paymentState = 'NotPaid'; diff --git a/package.json b/package.json index d2dfc6b..8bc9d87 100644 --- a/package.json +++ b/package.json @@ -34,16 +34,17 @@ "eslint-plugin-import": "^2.6.0", "eslint-plugin-jsx-a11y": "^6.0.2", "eslint-plugin-react": "^7.1.0", - "ethereumjs-testrpc": "^3.0.5", + "ethereumjs-testrpc": "git://github.com/perissology/testrpc.git#81216dbc", + "lerna": "^2.2.0", "random-bytes": "^1.0.0", "mocha": "^3.5.0", - "solcpiler": "0.0.4" + "solcpiler": "0.0.4", + "web3": "git://github.com/perissology/web3.js.git#all_fixes" }, "homepage": "https://github.com/Giveth/liquidpledging#readme", "dependencies": { "async": "^2.4.0", "chai": "^4.1.0", - "eth-contract-class": "0.0.3", - "ethconnector": "0.0.25" + "eth-contract-class": "0.0.4" } } diff --git a/test/NormalOperation.js b/test/NormalOperation.js index 8754b1e..762f3b1 100644 --- a/test/NormalOperation.js +++ b/test/NormalOperation.js @@ -1,31 +1,33 @@ /* eslint-env mocha */ /* eslint-disable no-await-in-loop */ -const ethConnector = require('ethconnector'); +const TestRPC = require('ethereumjs-testrpc'); +const Web3 = require('web3'); const chai = require('chai'); -const getBalance = require('runethtx').getBalance; const liquidpledging = require('../index.js'); const assertFail = require('./helpers/assertFail'); +const { utils } = Web3; + const LiquidPledging = liquidpledging.LiquidPledging(true); const Vault = liquidpledging.Vault; const assert = chai.assert; -const printState = async(liquidPledging) => { +const printState = async (liquidPledging) => { console.log(liquidPledging.b); const st = await liquidPledging.getState(); console.log(JSON.stringify(st, null, 2)); }; -const printBalances = async(liquidPledging) => { +const printBalances = async (liquidPledging) => { const st = await liquidPledging.getState(); assert.equal(st.notes.length, 13); for (let i = 1; i <= 12; i += 1) { - console.log(i, ethConnector.web3.fromWei(st.notes[i].amount).toNumber()); + console.log(i, Web3.utils.fromWei(st.notes[i].amount)); } }; -const readTest = async(liquidPledging) => { +const readTest = async (liquidPledging) => { const t1 = await liquidPledging.test1(); const t2 = await liquidPledging.test2(); const t3 = await liquidPledging.test3(); @@ -36,6 +38,14 @@ const readTest = async(liquidPledging) => { console.log('t4: ', t4.toNumber()); }; +const startTestrpc = opts => new Promise((resolve) => { + const testrpc = TestRPC.server(opts); + + testrpc.listen(8546, '127.0.0.1', (err) => { + resolve(); + }); +}); + describe('LiquidPledging test', () => { let web3; let accounts; @@ -48,19 +58,22 @@ describe('LiquidPledging test', () => { let adminProject2; let adminProject2a; let delegate2; - before((done) => { - ethConnector.init('testrpc', { gasLimit: 5200000 }, () => { - web3 = ethConnector.web3; - accounts = ethConnector.accounts; - donor1 = accounts[1]; - delegate1 = accounts[2]; - adminProject1 = accounts[3]; - adminProject2 = accounts[4]; - adminProject2a = accounts[5]; - delegate2 = accounts[6]; - donor2 = accounts[7]; - done(); + before(async () => { + await startTestrpc({ + ws: true, + gasLimit: 5200000, + total_accounts: 10, }); + + web3 = new Web3('ws://localhost:8546'); + accounts = await web3.eth.getAccounts(); + donor1 = accounts[1]; + delegate1 = accounts[2]; + adminProject1 = accounts[3]; + adminProject2 = accounts[4]; + adminProject2a = accounts[5]; + delegate2 = accounts[6]; + donor2 = accounts[7]; }); it('Should deploy LiquidPledging contract', async () => { vault = await Vault.new(web3); @@ -78,9 +91,9 @@ describe('LiquidPledging test', () => { assert.equal(res[3], 86400); }).timeout(6000); it('Should make a donation', async () => { - await liquidPledging.donate(1, 1, { from: donor1, value: web3.toWei(1) }); + await liquidPledging.donate(1, 1, { from: donor1, value: utils.toWei(1) }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 1); + assert.equal(nNotes, 1); await liquidPledging.getNote(1); }).timeout(6000); it('Should create a delegate', async () => { @@ -93,14 +106,14 @@ describe('LiquidPledging test', () => { assert.equal(res[2], 'Delegate1'); }).timeout(6000); it('Donor should delegate on the delegate', async () => { - await liquidPledging.transfer(1, 1, web3.toWei(0.5), 2, { from: donor1 }); + await liquidPledging.transfer(1, 1, utils.toWei(0.5), 2, { from: donor1 }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 2); + assert.equal(nNotes, 2); const res1 = await liquidPledging.getNote(1); - assert.equal(res1[0].toNumber(), web3.toWei(0.5)); + assert.equal(res1[0], utils.toWei(0.5)); const res2 = await liquidPledging.getNote(2); - assert.equal(res2[0].toNumber(), web3.toWei(0.5)); - assert.equal(res2[1].toNumber(), 1); // One delegate + assert.equal(res2[0], utils.toWei(0.5)); + assert.equal(res2[1], 1); // One delegate const d = await liquidPledging.getNoteDelegate(2, 1); assert.equal(d[0], 2); @@ -134,75 +147,75 @@ describe('LiquidPledging test', () => { }).timeout(6000); it('Delegate should assign to project1', async () => { const n = Math.floor(new Date().getTime() / 1000); - await liquidPledging.transfer(2, 2, web3.toWei(0.2), 3, { from: delegate1 }); + await liquidPledging.transfer(2, 2, utils.toWei(0.2), 3, { from: delegate1 }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 3); + assert.equal(nNotes, 3); const res3 = await liquidPledging.getNote(3); - assert.equal(res3[0].toNumber(), web3.toWei(0.2)); - assert.equal(res3[1].toNumber(), 1); // Owner - assert.equal(res3[2].toNumber(), 1); // Delegates - assert.equal(res3[3].toNumber(), 3); // Proposed Project - assert.isAbove(res3[4].toNumber(), n + 86000); - assert.equal(res3[5].toNumber(), 0); // Old Node - assert.equal(res3[6].toNumber(), 0); // Not Paid + assert.equal(res3[0], utils.toWei(0.2)); + assert.equal(res3[1], 1); // Owner + assert.equal(res3[2], 1); // Delegates + assert.equal(res3[3], 3); // Proposed Project + assert.isAbove(utils.toDecimal(res3[4]), n + 86000); + assert.equal(res3[5], 0); // Old Node + assert.equal(res3[6], 0); // Not Paid }).timeout(6000); it('Donor should change his mind and assign half of it to project2', async () => { - await liquidPledging.transfer(1, 3, web3.toWei(0.1), 4, { from: donor1 }); + await liquidPledging.transfer(1, 3, utils.toWei(0.1), 4, { from: donor1 }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 4); + assert.equal(nNotes, 4); const res3 = await liquidPledging.getNote(3); - assert.equal(res3[0].toNumber(), web3.toWei(0.1)); + assert.equal(res3[0], utils.toWei(0.1)); const res4 = await liquidPledging.getNote(4); - assert.equal(res4[1].toNumber(), 4); // Owner - assert.equal(res4[2].toNumber(), 0); // Delegates - assert.equal(res4[3].toNumber(), 0); // Proposed Project + assert.equal(res4[1], 4); // Owner + assert.equal(res4[2], 0); // Delegates + assert.equal(res4[3], 0); // Proposed Project assert.equal(res4[4], 0); - assert.equal(res4[5].toNumber(), 2); // Old Node - assert.equal(res4[6].toNumber(), 0); // Not Paid + assert.equal(res4[5], 2); // Old Node + assert.equal(res4[6], 0); // Not Paid }).timeout(6000); it('After the time, the project1 should be able to spend part of it', async () => { const n = Math.floor(new Date().getTime() / 1000); await liquidPledging.setMockedTime(n + 86401); - await liquidPledging.withdraw(3, web3.toWei(0.05), { from: adminProject1 }); + await liquidPledging.withdraw(3, utils.toWei(0.05), { from: adminProject1 }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 6); + assert.equal(nNotes, 6); const res5 = await liquidPledging.getNote(5); - assert.equal(res5[0].toNumber(), web3.toWei(0.05)); - assert.equal(res5[1].toNumber(), 3); // Owner - assert.equal(res5[2].toNumber(), 0); // Delegates - assert.equal(res5[3].toNumber(), 0); // Proposed Project + assert.equal(res5[0], utils.toWei(0.05)); + assert.equal(res5[1], 3); // Owner + assert.equal(res5[2], 0); // Delegates + assert.equal(res5[3], 0); // Proposed Project assert.equal(res5[4], 0); // commit time - assert.equal(res5[5].toNumber(), 2); // Old Node - assert.equal(res5[6].toNumber(), 0); // Not Paid + assert.equal(res5[5], 2); // Old Node + assert.equal(res5[6], 0); // Not Paid const res6 = await liquidPledging.getNote(6); - assert.equal(res6[0].toNumber(), web3.toWei(0.05)); - assert.equal(res6[1].toNumber(), 3); // Owner - assert.equal(res6[2].toNumber(), 0); // Delegates - assert.equal(res6[3].toNumber(), 0); // Proposed Project + assert.equal(res6[0], utils.toWei(0.05)); + assert.equal(res6[1], 3); // Owner + assert.equal(res6[2], 0); // Delegates + assert.equal(res6[3], 0); // Proposed Project assert.equal(res6[4], 0); // commit time - assert.equal(res6[5].toNumber(), 2); // Old Node - assert.equal(res6[6].toNumber(), 1); // Peinding paid Paid + assert.equal(res6[5], 2); // Old Node + assert.equal(res6[6], 1); // Peinding paid Paid }).timeout(6000); it('Should collect the Ether', async () => { - const initialBalance = await getBalance(web3, adminProject1); + const initialBalance = await web3.eth.getBalance(adminProject1); await vault.confirmPayment(0); - const finalBalance = await getBalance(web3, adminProject1); + const finalBalance = await web3.eth.getBalance(adminProject1); - const collected = web3.fromWei(finalBalance.sub(initialBalance)).toNumber(); + const collected = utils.fromWei(utils.toBN(finalBalance).sub(utils.toBN(initialBalance))); assert.equal(collected, 0.05); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), 7); + assert.equal(nNotes, 7); const res7 = await liquidPledging.getNote(7); - assert.equal(res7[0].toNumber(), web3.toWei(0.05)); - assert.equal(res7[1].toNumber(), 3); // Owner - assert.equal(res7[2].toNumber(), 0); // Delegates - assert.equal(res7[3].toNumber(), 0); // Proposed Project + assert.equal(res7[0], utils.toWei(0.05)); + assert.equal(res7[1], 3); // Owner + assert.equal(res7[2], 0); // Delegates + assert.equal(res7[3], 0); // Proposed Project assert.equal(res7[4], 0); // commit time - assert.equal(res7[5].toNumber(), 2); // Old Node - assert.equal(res7[6].toNumber(), 2); // Peinding paid Paid + assert.equal(res7[5], 2); // Old Node + assert.equal(res7[6], 2); // Peinding paid Paid }).timeout(6000); it('Admin of the project1 should be able to cancel project1', async () => { await liquidPledging.cancelProject(3, { from: adminProject1 }); @@ -211,29 +224,30 @@ describe('LiquidPledging test', () => { }).timeout(6000); it('Should not allow to withdraw from a canceled project', async () => { const st = await liquidPledging.getState(liquidPledging); - assert.equal(web3.fromWei(st.notes[5].amount).toNumber(), 0.05); + assert.equal(utils.fromWei(st.notes[5].amount), 0.05); await assertFail(async () => { - await liquidPledging.withdraw(5, web3.toWei(0.01), { from: adminProject1 }); + await liquidPledging.withdraw(5, utils.toWei(0.01), { from: adminProject1 }); }); }).timeout(6000); it('Delegate should send part of this ETH to project2', async () => { - await liquidPledging.transfer(2, 5, web3.toWei(0.03), 4, - { $extraGas: 100000 }, - { from: delegate1 }); + await liquidPledging.transfer(2, 5, utils.toWei(0.03), 4, { + $extraGas: 100000, + from: delegate1, + }); const st = await liquidPledging.getState(liquidPledging); assert.equal(st.notes.length, 9); - assert.equal(web3.fromWei(st.notes[8].amount).toNumber(), 0.03); + assert.equal(utils.fromWei(st.notes[8].amount), 0.03); assert.equal(st.notes[8].owner, 1); assert.equal(st.notes[8].delegates.length, 1); assert.equal(st.notes[8].delegates[0].id, 2); assert.equal(st.notes[8].proposedProject, 4); }).timeout(6000); it('Donor should be able to send the remaining to project2', async () => { - await liquidPledging.transfer(1, 5, web3.toWei(0.02), 4, { from: donor1 }); + await liquidPledging.transfer(1, 5, utils.toWei(0.02), 4, { from: donor1, $extraGas: 100000 }); const st = await liquidPledging.getState(liquidPledging); assert.equal(st.notes.length, 9); - assert.equal(web3.fromWei(st.notes[5].amount).toNumber(), 0); - assert.equal(web3.fromWei(st.notes[4].amount).toNumber(), 0.12); + assert.equal(utils.fromWei(st.notes[5].amount), 0); + assert.equal(utils.fromWei(st.notes[4].amount), 0.12); }).timeout(6000); it('A subproject 2a and a delegate2 is created', async () => { await liquidPledging.addProject('Project2a', adminProject2a, 4, 86400, 0, { from: adminProject2 }); @@ -242,28 +256,28 @@ describe('LiquidPledging test', () => { assert.equal(nManagers, 6); }).timeout(6000); it('Project 2 delegate in delegate2', async () => { - await liquidPledging.transfer(4, 4, web3.toWei(0.02), 6, { from: adminProject2 }); + await liquidPledging.transfer(4, 4, utils.toWei(0.02), 6, { from: adminProject2 }); const st = await liquidPledging.getState(liquidPledging); assert.equal(st.notes.length, 10); - assert.equal(web3.fromWei(st.notes[9].amount).toNumber(), 0.02); - assert.equal(web3.fromWei(st.notes[4].amount).toNumber(), 0.1); + assert.equal(utils.fromWei(st.notes[9].amount), 0.02); + assert.equal(utils.fromWei(st.notes[4].amount), 0.1); }).timeout(6000); it('delegate2 assigns to projec2a', async () => { - await liquidPledging.transfer(6, 9, web3.toWei(0.01), 5, { from: delegate2 }); + await liquidPledging.transfer(6, 9, utils.toWei(0.01), 5, { from: delegate2 }); const st = await liquidPledging.getState(liquidPledging); assert.equal(st.notes.length, 11); - assert.equal(web3.fromWei(st.notes[9].amount).toNumber(), 0.01); - assert.equal(web3.fromWei(st.notes[10].amount).toNumber(), 0.01); + assert.equal(utils.fromWei(st.notes[9].amount), 0.01); + assert.equal(utils.fromWei(st.notes[10].amount), 0.01); }).timeout(4000); it('project2a authorize to spend a litle', async () => { const n = Math.floor(new Date().getTime() / 1000); await liquidPledging.setMockedTime(n + (86401 * 3)); - await liquidPledging.withdraw(10, web3.toWei(0.005), { from: adminProject2a }); + await liquidPledging.withdraw(10, utils.toWei(0.005), { from: adminProject2a }); const st = await liquidPledging.getState(liquidPledging); assert.equal(st.notes.length, 13); - assert.equal(web3.fromWei(st.notes[10].amount).toNumber(), 0); - assert.equal(web3.fromWei(st.notes[11].amount).toNumber(), 0.005); - assert.equal(web3.fromWei(st.notes[12].amount).toNumber(), 0.005); + assert.equal(utils.fromWei(st.notes[10].amount), 0); + assert.equal(utils.fromWei(st.notes[11].amount), 0.005); + assert.equal(utils.fromWei(st.notes[12].amount), 0.005); }).timeout(4000); it('project2 is canceled', async () => { await liquidPledging.cancelProject(4, { from: adminProject2 }); @@ -275,41 +289,42 @@ describe('LiquidPledging test', () => { }).timeout(6000); it('Should not be able to withdraw it', async () => { await assertFail(async () => { - await liquidPledging.withdraw(12, web3.toWei(0.005), { from: donor1 }); + await liquidPledging.withdraw(12, utils.toWei(0.005), { from: donor1 }); }); }).timeout(6000); - it('Should not be able to cancel payment', async () => { - await vault.cancelPayment(1); - const st = await liquidPledging.getState(liquidPledging); + it('Should be able to cancel payment', async () => { + // bug somewhere which will throw invalid op_code if we don't provide gas or extraGas + await vault.cancelPayment(1, { $extraGas: 100000 }); + const st = await liquidPledging.getState(); assert.equal(st.notes.length, 13); - assert.equal(web3.fromWei(st.notes[2].amount).toNumber(), 0.31); - assert.equal(web3.fromWei(st.notes[11].amount).toNumber(), 0); - assert.equal(web3.fromWei(st.notes[12].amount).toNumber(), 0); + assert.equal(utils.fromWei(st.notes[2].amount), 0.31); + assert.equal(utils.fromWei(st.notes[11].amount), 0); + assert.equal(utils.fromWei(st.notes[12].amount), 0); }).timeout(6000); it('original owner should recover the remaining funds', async () => { - await liquidPledging.withdraw(1, web3.toWei(0.5), { from: donor1 }); - await liquidPledging.withdraw(2, web3.toWei(0.31), { from: donor1 }); - await liquidPledging.withdraw(4, web3.toWei(0.1), { from: donor1 }); + await liquidPledging.withdraw(1, utils.toWei(0.5), { from: donor1 }); + await liquidPledging.withdraw(2, utils.toWei(0.31), { from: donor1 }); + await liquidPledging.withdraw(4, utils.toWei(0.1), { $extraGas: 100000, from: donor1 }); - await liquidPledging.withdraw(8, web3.toWei(0.03), { $extraGas: 100000 }, { from: donor1 }); - await liquidPledging.withdraw(9, web3.toWei(0.01), { from: donor1 }); + await liquidPledging.withdraw(8, utils.toWei(0.03), { $extraGas: 100000, from: donor1 }); + await liquidPledging.withdraw(9, utils.toWei(0.01), { $extraGas: 100000, from: donor1 }); - const initialBalance = await getBalance(web3, donor1); + const initialBalance = await web3.eth.getBalance(donor1); await vault.multiConfirm([2, 3, 4, 5, 6]); - const finalBalance = await getBalance(web3, donor1); - const collected = web3.fromWei(finalBalance.sub(initialBalance)).toNumber(); + const finalBalance = await web3.eth.getBalance(donor1); + const collected = utils.fromWei(utils.toBN(finalBalance).sub(utils.toBN(initialBalance))); assert.equal(collected, 0.95); - }).timeout(8000); + }).timeout(10000); it('Should make a donation and create donor', async () => { const oldNNotes = await liquidPledging.numberOfNotes(); const oldNManagers = await liquidPledging.numberOfNoteManagers(); - await liquidPledging.donate(0, 1, { from: donor2, value: web3.toWei(1) }); + await liquidPledging.donate(0, 1, { from: donor2, value: utils.toWei(1) }); const nNotes = await liquidPledging.numberOfNotes(); - assert.equal(nNotes.toNumber(), oldNNotes.toNumber() + 1); + assert.equal(utils.toDecimal(nNotes), utils.toDecimal(oldNNotes) + 1); const nManagers = await liquidPledging.numberOfNoteManagers(); - assert.equal(nManagers.toNumber(), oldNManagers.toNumber() + 1); + assert.equal(utils.toDecimal(nManagers), utils.toDecimal(oldNManagers) + 1); const res = await liquidPledging.getNoteManager(nManagers); assert.equal(res[0], 0); // Donor assert.equal(res[1], donor2); From 5f3a73b5c1e27cdc28cc9a8998d4a99cf24d0583 Mon Sep 17 00:00:00 2001 From: perissology Date: Tue, 3 Oct 2017 06:19:28 -0700 Subject: [PATCH 12/12] inline starting testrpc --- test/NormalOperation.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/NormalOperation.js b/test/NormalOperation.js index 79f499c..60fe8e8 100644 --- a/test/NormalOperation.js +++ b/test/NormalOperation.js @@ -38,14 +38,6 @@ const readTest = async (liquidPledging) => { console.log('t4: ', t4.toNumber()); }; -const startTestrpc = opts => new Promise((resolve) => { - const testrpc = TestRPC.server(opts); - - testrpc.listen(8546, '127.0.0.1', (err) => { - resolve(); - }); -}); - describe('LiquidPledging test', () => { let web3; let accounts; @@ -59,11 +51,13 @@ describe('LiquidPledging test', () => { let adminCampaign2a; let delegate2; before(async () => { - await startTestrpc({ + const testrpc = TestRPC.server({ ws: true, gasLimit: 5200000, total_accounts: 10, }); + + testrpc.listen(8546, '127.0.0.1'); web3 = new Web3('ws://localhost:8546'); accounts = await web3.eth.getAccounts();