Use ethers.js instead of the old web3 #29

Merged
bumi merged 8 commits from ethers into master 2018-04-04 12:20:55 +00:00
7 changed files with 733 additions and 687 deletions
Showing only changes of commit 3f0b1ccbcd - Show all commits
+2 -2
View File
@@ -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() {
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.)
fsmanuel commented 2018-04-04 10:59:28 +00:00 (Migrated from github.com)
Review

❤️

❤️
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,
+663 -577
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -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": {}
}