Use ethers.js instead of the old web3
the web3 we are using is old and everything will change with web3 1.0 which is currently in beta for ages. ethers.js seems to be a bit more lightweight and implements pretty much the same API so let's give it a try.
This commit is contained in:
@@ -18,8 +18,8 @@ export default Component.extend({
|
||||
inProgress: false,
|
||||
|
||||
isValidAddress: function() {
|
||||
return this.get('kredits.web3')
|
||||
.isAddress(this.get('newContributor.address'));
|
||||
// TODO: add proper address validation
|
||||
return this.get('newContributor.address') !== ''
|
||||
}.property('kredits.web3', 'newContributor.address'),
|
||||
|
||||
isValidName: function() {
|
||||
|
||||
@@ -18,7 +18,8 @@ export default Component.extend({
|
||||
inProgress: false,
|
||||
|
||||
isValidRecipient: computed('proposal.recipientAddress', function() {
|
||||
return this.get('kredits.web3').isAddress(this.get('proposal.recipientAddress'));
|
||||
// TODO: add proper address validation
|
||||
return this.get('proposal.recipientAddress') !== ''
|
||||
}),
|
||||
|
||||
isValidAmount: computed('proposal.amount', function() {
|
||||
|
||||
+20
-37
@@ -50,74 +50,57 @@ export default Ember.Controller.extend({
|
||||
watchContractEvents: function() {
|
||||
this.get('kredits.kreditsContract')
|
||||
.then((contract) => {
|
||||
let events = contract.get('content').allEvents();
|
||||
events.watch((error, data) => {
|
||||
Ember.Logger.debug('[index] Received contract event', data);
|
||||
|
||||
switch (data.event) {
|
||||
case 'ProposalCreated':
|
||||
this._handleProposalCreated(data);
|
||||
break;
|
||||
case 'ProposalExecuted':
|
||||
this._handleProposalExecuted(data);
|
||||
break;
|
||||
case 'ProposalVoted':
|
||||
this._handleProposalVoted(data);
|
||||
break;
|
||||
case 'Transfer':
|
||||
this._handleTransfer(data);
|
||||
break;
|
||||
}
|
||||
});
|
||||
contract.onproposalvoted = this._handleProposalVoted.bind(this); //function(a,b,c) { console.log('voted', a, b, c) }
|
||||
contract.onproposalcreated = this._handleProposalCreated.bind(this);
|
||||
contract.onproposalexecuted = this._handleProposalExecuted.bind(this);
|
||||
// TODO: transfer on the token contract
|
||||
});
|
||||
}.on('init'),
|
||||
|
||||
_handleProposalCreated(data) {
|
||||
_handleProposalCreated(proposalId, creatorAddress, recipientAddress, amount) {
|
||||
if (Ember.isPresent(this.get('model.proposals')
|
||||
.findBy('id', data.args.id.toNumber()))) {
|
||||
.findBy('id', proposalId.toNumber()))) {
|
||||
Ember.Logger.debug('[index] proposal exists, not adding from event');
|
||||
return false;
|
||||
}
|
||||
|
||||
let proposal = Proposal.create({
|
||||
id: data.args.id.toNumber(),
|
||||
creatorAddress: data.args.creator,
|
||||
recipientAddress: data.args.recipient,
|
||||
id: proposalId.toNumber(),
|
||||
creatorAddress: creatorAddress,
|
||||
recipientAddress: recipientAddress,
|
||||
recipientName: null,
|
||||
votesCount: 0,
|
||||
votesNeeded: 2,
|
||||
amount: data.args.amount.toNumber(),
|
||||
executed: false,
|
||||
url: data.args.url,
|
||||
ipfsHash: data.args.ipfsHash
|
||||
amount: amount.toNumber(),
|
||||
executed: false
|
||||
});
|
||||
|
||||
this.get('model.proposals').pushObject(proposal);
|
||||
},
|
||||
|
||||
_handleProposalExecuted(data) {
|
||||
_handleProposalExecuted(proposalId, recipientId, amount) {
|
||||
if (this.get('model.proposals')
|
||||
.findBy('id', data.args.id.toNumber())
|
||||
.findBy('id', recipientId.toNumber())
|
||||
.get('executed')) {
|
||||
Ember.Logger.debug('[index] proposal already executed, not adding from event');
|
||||
return false;
|
||||
}
|
||||
|
||||
this.get('model.proposals')
|
||||
.findBy('id', data.args.id.toNumber())
|
||||
.findBy('id', recipientId.toNumber())
|
||||
.setProperties({
|
||||
'executed': true,
|
||||
'votesCount': 2 // TODO use real count
|
||||
});
|
||||
|
||||
this.get('model.contributors')
|
||||
.findBy('address', data.args.recipient)
|
||||
.incrementProperty('balance', data.args.amount.toNumber());
|
||||
.findBy('id', recipientId)
|
||||
.incrementProperty('kredits', amount.toNumber());
|
||||
},
|
||||
|
||||
_handleProposalVoted(data) {
|
||||
_handleProposalVoted(proposalId, voter, totalVotes) {
|
||||
this.get('model.proposals')
|
||||
.findBy('id', data.args.id.toNumber())
|
||||
.findBy('id', proposalId.toNumber())
|
||||
.incrementProperty('votesCount', 1);
|
||||
},
|
||||
|
||||
@@ -134,8 +117,8 @@ export default Ember.Controller.extend({
|
||||
actions: {
|
||||
|
||||
confirmProposal(proposalId) {
|
||||
this.get('kredits').vote(proposalId).then(transactionId => {
|
||||
window.confirm('Vote submitted to Ethereum blockhain: '+transactionId);
|
||||
this.get('kredits').vote(proposalId).then(transaction => {
|
||||
window.confirm('Vote submitted to Ethereum blockhain: '+transaction.hash);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ export default Ember.Route.extend({
|
||||
const kredits = this.get('kredits');
|
||||
|
||||
if (kredits.get('web3') && kredits.get('web3Provided')) {
|
||||
kredits.get('web3').eth.getAccounts((error, accounts) => {
|
||||
if (error || accounts.length === 0) {
|
||||
kredits.get('listAccounts').then((accounts) => {
|
||||
if (accounts.length === 0) {
|
||||
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
|
||||
transition.retry();
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export default Ember.Route.extend({
|
||||
|
||||
let kredits = this.get('kredits');
|
||||
let totalSupply = kredits.get('tokenContract')
|
||||
.then((contract) => contract.invoke('totalSupply'));
|
||||
.then((contract) => contract.totalSupply());
|
||||
|
||||
return Ember.RSVP.hash({
|
||||
contributors: kredits.getContributors(),
|
||||
|
||||
+39
-64
@@ -1,4 +1,4 @@
|
||||
import Web3 from 'npm:web3';
|
||||
import ethers from 'npm:ethers';
|
||||
import bs58 from 'npm:bs58';
|
||||
import NpmBuffer from 'npm:buffer';
|
||||
|
||||
@@ -24,18 +24,6 @@ const {
|
||||
|
||||
const Buffer = NpmBuffer.Buffer;
|
||||
|
||||
function contractProxy(object) {
|
||||
let proxy = Ember.ObjectProxy.extend({
|
||||
invoke(contractMethod, ...args) {
|
||||
debug('[kredits] invoke', contractMethod, ...args);
|
||||
let contract = this.get('content');
|
||||
return RSVP.denodeify(contract[contractMethod])(...args);
|
||||
}
|
||||
});
|
||||
|
||||
return proxy.create({ content: object });
|
||||
}
|
||||
|
||||
export default Service.extend({
|
||||
|
||||
ipfs: injectService(),
|
||||
@@ -44,41 +32,42 @@ export default Service.extend({
|
||||
web3Provided: false, // Web3 provided (using Mist Browser, Metamask et al.)
|
||||
|
||||
web3: function() {
|
||||
if (this.get('web3Instance')) {
|
||||
return this.get('web3Instance');
|
||||
if (this.get('web3Provider')) {
|
||||
return this.get('web3Provider');
|
||||
}
|
||||
|
||||
let web3Instance;
|
||||
|
||||
let web3Provider;
|
||||
if (typeof window.web3 !== 'undefined') {
|
||||
debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
||||
web3Instance = new Web3(window.web3.currentProvider);
|
||||
let networkId = parseInt(web3.version.network);
|
||||
web3Provider = new ethers.providers.Web3Provider(web3.currentProvider, {chainId: networkId});
|
||||
this.set('web3Provided', true);
|
||||
} else {
|
||||
debug('[kredits] Creating new instance from npm module class');
|
||||
let providerUrl = localStorage.getItem('config:web3ProviderUrl') || config.web3ProviderUrl;
|
||||
let provider = new Web3.providers.HttpProvider(providerUrl);
|
||||
web3Instance = new Web3(provider);
|
||||
let networkId = web3.version.network;
|
||||
web3Provider = new ethers.providers.Web3Provider(web3.currentProvider, {chainId: network});
|
||||
}
|
||||
|
||||
this.set('web3Instance', web3Instance);
|
||||
window.web3 = web3Instance;
|
||||
this.set('web3Provider', web3Provider);
|
||||
return web3Provider;
|
||||
}.property('web3Provider'),
|
||||
|
||||
return web3Instance;
|
||||
}.property('web3Instance'),
|
||||
listAccounts: function() {
|
||||
return this.get('web3').listAccounts();
|
||||
}.property('web3'),
|
||||
|
||||
currentUserAccounts: function() {
|
||||
return (this.get('web3Provided') && this.get('web3').eth.accounts) || [];
|
||||
// TODO: listAccounts returns now a promise
|
||||
return [];
|
||||
return ethers.listAccounts();
|
||||
// return (this.get('web3Provided') && this.get('web3').eth.accounts) || [];
|
||||
}.property('web3Provided', 'web3'),
|
||||
|
||||
registryContract: computed('web3', function() {
|
||||
let networkId = this.get('web3').version.network;
|
||||
let contract = this.get('web3')
|
||||
.eth
|
||||
.contract(abis['Registry'])
|
||||
.at(addresses['Registry'][networkId]);
|
||||
|
||||
return RSVP.resolve(contractProxy(contract));
|
||||
let networkId = this.get('web3').chainId;
|
||||
let registry = new ethers.Contract(addresses['Registry'][networkId], abis['Registry'], this.get('web3'));
|
||||
return registry;
|
||||
}),
|
||||
|
||||
contributorsContract: computed('web3', function() {
|
||||
@@ -94,22 +83,16 @@ export default Service.extend({
|
||||
}),
|
||||
|
||||
contractFor(name) {
|
||||
return this.get('registryContract')
|
||||
.then((contract) => contract.invoke('getProxyFor', name))
|
||||
return this.get('registryContract').functions.getProxyFor(name)
|
||||
.then((address) => {
|
||||
debug('[kredits] get contract', name, address);
|
||||
let contract = this.get('web3')
|
||||
.eth
|
||||
.contract(abis[name])
|
||||
.at(address);
|
||||
|
||||
return contractProxy(contract);
|
||||
return new ethers.Contract(address, abis[name], this.get('web3').getSigner());
|
||||
});
|
||||
},
|
||||
|
||||
getContributorData(id) {
|
||||
return this.get('contributorsContract')
|
||||
.then((contract) => contract.invoke('contributors', id))
|
||||
.then((contract) => contract.contributors(id))
|
||||
.then((data) => {
|
||||
debug('[kredits] contributor', data);
|
||||
|
||||
@@ -120,9 +103,8 @@ export default Service.extend({
|
||||
hashFunction: hashFunction.toNumber(),
|
||||
size: size.toNumber()
|
||||
});
|
||||
|
||||
return this.get('tokenContract')
|
||||
.then((contract) => contract.invoke('balanceOf', address))
|
||||
.then((contract) => contract.balanceOf(address))
|
||||
.then((balance) => {
|
||||
balance = balance.toNumber();
|
||||
|
||||
@@ -144,7 +126,7 @@ export default Service.extend({
|
||||
|
||||
getContributors() {
|
||||
return this.get('contributorsContract')
|
||||
.then((contract) => contract.invoke('contributorsCount'))
|
||||
.then((contract) => contract.contributorsCount())
|
||||
.then(contributorsCount => {
|
||||
debug('[kredits] contributorsCount:', contributorsCount.toNumber());
|
||||
let contributors = [];
|
||||
@@ -159,24 +141,19 @@ export default Service.extend({
|
||||
|
||||
getProposalData(i) {
|
||||
return this.get('kreditsContract')
|
||||
.then((contract) => contract.invoke('proposals', i))
|
||||
.then((contract) => contract.proposals(i))
|
||||
.then(p => {
|
||||
|
||||
let ipfsHash = this.getMultihashFromBytes32({
|
||||
digest: p[6],
|
||||
hashFunction: p[7].toNumber(),
|
||||
size: p[8].toNumber()
|
||||
});
|
||||
let ipfsHash = this.getMultihashFromBytes32({ digest: p.ipfsHash, hashFunction: p.hashFunction, size: p.hashSize });
|
||||
|
||||
let proposal = Proposal.create({
|
||||
id : i,
|
||||
creatorAddress : p[0],
|
||||
recipientId : p[1].toNumber(),
|
||||
votesCount : p[2].toNumber(),
|
||||
votesNeeded : p[3].toNumber(),
|
||||
amount : p[4].toNumber(),
|
||||
executed : p[5],
|
||||
ipfsHash : ipfsHash
|
||||
creatorAddress : p.creator,
|
||||
recipientId : p.recipientId.toNumber(),
|
||||
votesCount : p.votesCount.toNumber(),
|
||||
votesNeeded : p.votesNeeded.toNumber(),
|
||||
amount : p.amount.toNumber(),
|
||||
executed : p.executed,
|
||||
ipfsHash : contributionIpfsHash
|
||||
});
|
||||
|
||||
if (proposal.get('ipfsHash')) {
|
||||
@@ -193,7 +170,7 @@ export default Service.extend({
|
||||
|
||||
getProposals() {
|
||||
return this.get('kreditsContract')
|
||||
.then((contract) => contract.invoke('proposalsCount'))
|
||||
.then((contract) => contract.proposalsCount())
|
||||
.then(proposalsCount => {
|
||||
let proposals = [];
|
||||
|
||||
@@ -209,7 +186,7 @@ export default Service.extend({
|
||||
debug('[kredits] vote for', proposalId);
|
||||
|
||||
return this.get('kreditsContract')
|
||||
.then((contract) => contract.invoke('vote', proposalId))
|
||||
.then((contract) => contract.vote(proposalId))
|
||||
.then((data) => {
|
||||
debug('[kredits] vote response', data);
|
||||
return data;
|
||||
@@ -262,8 +239,7 @@ export default Service.extend({
|
||||
|
||||
return this.get('kreditsContract')
|
||||
.then((contract) => {
|
||||
return contract.invoke(
|
||||
'addContributor',
|
||||
return contract.addContributor(
|
||||
contributor.address,
|
||||
digest,
|
||||
hashFunction,
|
||||
@@ -290,8 +266,7 @@ export default Service.extend({
|
||||
.then(ipfsHash => {
|
||||
return this.get('kreditsContract')
|
||||
.then((contract) => {
|
||||
return contract.invoke(
|
||||
'addProposal',
|
||||
return contract.addProposal(
|
||||
recipientAddress,
|
||||
amount,
|
||||
url,
|
||||
|
||||
Generated
+664
-578
File diff suppressed because it is too large
Load Diff
+4
-3
@@ -55,12 +55,12 @@
|
||||
"ember-parachute": "0.1.0",
|
||||
"ember-resolver": "^2.0.3",
|
||||
"ember-truth-helpers": "1.3.0",
|
||||
"ethers": "^3.0.8",
|
||||
"ipfs-api": "^19.0.0",
|
||||
"kosmos-schemas": "^1.1.2",
|
||||
"kredits-contracts": "github:67P/truffle-kredits#master",
|
||||
"loader.js": "^4.0.10",
|
||||
"tv4": "^1.3.0",
|
||||
"web3": "^0.18.2"
|
||||
"tv4": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12.0"
|
||||
@@ -70,5 +70,6 @@
|
||||
"paths": [
|
||||
"lib/contracts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user