Merge branch 'master' into fallback-provider
# Conflicts: # lib/kredits.js
This commit is contained in:
commit
772071c699
@ -1,65 +1,9 @@
|
|||||||
let contractCalls = {
|
let contractCalls = [
|
||||||
Contributors: {
|
['Contributor', 'add', [{ account: '0x7e8f313c56f809188313aa274fa67ee58c31515d', name: 'bumi', isCore: true, kind: 'preson', url: '', github_username: 'bumi', github_uid: 318, wiki_username: 'bumi' }, {gasLimit: 200000}]],
|
||||||
addContributor: [
|
['Contributor', 'add', [{ account: '0xa502eb4021f3b9ab62f75b57a94e1cfbf81fd827', name: 'raucau', isCore: true, kind: 'person', url: '', github_username: 'skddc', github_uid: 842, wiki_username: 'raucau' }, {gasLimit: 200000}]],
|
||||||
// make sure to use an IPFS hash of one of the objects in ipfsContent
|
['Operator', 'addProposal', [{ contributorId: 2, amount: 42, kind: 'code', description: 'runs the seeds', url: '' }, {gasLimit: 350000}]],
|
||||||
['0x24dd2aedd8a9fe52ac071b3a23b2fc8f225c185e', '0x272bbfc66166f26cae9c9b96b7f9590e095f02edf342ac2dd71e1667a12116ca', 18, 32, true], // QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj
|
['Operator', 'addProposal', [{ contributorId: 3, amount: 23, kind: 'code', description: 'runs the seeds', url: '' }, {gasLimit: 350000}]],
|
||||||
['0xa502eb4021f3b9ab62f75b57a94e1cfbf81fd827', '0x9569ed44826286597982e40bbdff919c6b7752e29d13250efca452644e6b4b25', 18, 32, true] // QmYPu8zvtfDy18ZqHCviVxnKtxycw5UTJLJyk9oAEjWfnL
|
['Operator', 'addProposal', [{contributorId: 3, amount: 100, kind: 'code', description: 'hacks on kredits', url: '' }, {gasLimit: 350000}]],
|
||||||
]
|
['Operator', 'vote', ['1', {gasLimit: 250000}]]
|
||||||
},
|
];
|
||||||
Operator: {
|
module.exports = { contractCalls };
|
||||||
addProposal: [
|
|
||||||
[2, 23, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs"
|
|
||||||
[3, 42, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32], // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs"
|
|
||||||
[3, 100, '0x1e1a168d736fc825213144973a8fd5b3cc9f37ad821a8b3d9c3488034bbf69d8', 18, 32] // QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs"
|
|
||||||
],
|
|
||||||
vote: [
|
|
||||||
[1]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let ipfsContent = [
|
|
||||||
{
|
|
||||||
"@context": "https://schema.kosmos.org",
|
|
||||||
"@type": "Contributor",
|
|
||||||
"kind": "person",
|
|
||||||
"name": "Râu Cao",
|
|
||||||
"url": "https://sebastian.kip.pe",
|
|
||||||
"accounts": [
|
|
||||||
{
|
|
||||||
"site": "github.com",
|
|
||||||
"username": "skddc",
|
|
||||||
"uid": 842,
|
|
||||||
"url": "https://github.com/skddc/"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"@context": "https://schema.kosmos.org",
|
|
||||||
"@type": "Contributor",
|
|
||||||
"kind": "person",
|
|
||||||
"name": "Bumi",
|
|
||||||
"url": "https://michaelbumann.com",
|
|
||||||
"accounts": [
|
|
||||||
{
|
|
||||||
"site": "github.com",
|
|
||||||
"username": "bumi",
|
|
||||||
"uid": 318,
|
|
||||||
"url": "https://github.com/bumi/"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"@context": "https://schema.kosmos.org",
|
|
||||||
"@type": "Contribution",
|
|
||||||
"contributor": {
|
|
||||||
"ipfs": "QmQ2ZZS2bXgneQfKtVTVxe6dV7pcJuXnTeZJQtoVUFsAtJ"
|
|
||||||
},
|
|
||||||
"kind": "dev",
|
|
||||||
"description": "hacking hacking on kredits",
|
|
||||||
"url": "https://github.com/67P/kredits-web/pull/11",
|
|
||||||
"details": {}
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
module.exports = { contractCalls, ipfsContent };
|
|
||||||
|
@ -1 +1 @@
|
|||||||
{"100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"}
|
{"42":"0x205fe1b3dac678b594c5f0535e7d158e38591f93","100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"}
|
@ -1 +1 @@
|
|||||||
{"100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"}
|
{"42":"0x9fd66ee78a5ebe86006f12b37ff59c63f9caa15b","100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"}
|
@ -1 +1 @@
|
|||||||
{"100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"}
|
{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"}
|
@ -1 +1 @@
|
|||||||
{"100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"}
|
{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"}
|
@ -34,7 +34,7 @@ class Contributor extends Base {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add(contributorAttr) {
|
add(contributorAttr, callOptions = {}) {
|
||||||
let json = ContributorSerializer.serialize(contributorAttr);
|
let json = ContributorSerializer.serialize(contributorAttr);
|
||||||
// TODO: validate against schema
|
// TODO: validate against schema
|
||||||
|
|
||||||
@ -42,14 +42,14 @@ class Contributor extends Base {
|
|||||||
.add(json)
|
.add(json)
|
||||||
.then((ipfsHashAttr) => {
|
.then((ipfsHashAttr) => {
|
||||||
let contributor = [
|
let contributor = [
|
||||||
contributorAttr.address,
|
contributorAttr.account,
|
||||||
ipfsHashAttr.hashDigest,
|
ipfsHashAttr.hashDigest,
|
||||||
ipfsHashAttr.hashFunction,
|
ipfsHashAttr.hashFunction,
|
||||||
ipfsHashAttr.hashSize,
|
ipfsHashAttr.hashSize,
|
||||||
contributorAttr.isCore,
|
contributorAttr.isCore,
|
||||||
];
|
];
|
||||||
|
|
||||||
return this.functions.addContributor(...contributor);
|
return this.functions.addContributor(...contributor, callOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
Contributors: require('./contributor'),
|
Contributors: require('./contributor'),
|
||||||
Operator: require('./operator'),
|
Operator: require('./operator'),
|
||||||
Token: require('./token')
|
Token: require('./token'),
|
||||||
}
|
Registry: require('./registry')
|
||||||
|
};
|
||||||
|
@ -34,7 +34,7 @@ class Operator extends Base {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addProposal(proposalAttr) {
|
addProposal(proposalAttr, callOptions = {}) {
|
||||||
let json = ContributionSerializer.serialize(proposalAttr);
|
let json = ContributionSerializer.serialize(proposalAttr);
|
||||||
// TODO: validate against schema
|
// TODO: validate against schema
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class Operator extends Base {
|
|||||||
ipfsHashAttr.hashSize,
|
ipfsHashAttr.hashSize,
|
||||||
];
|
];
|
||||||
|
|
||||||
return this.functions.addProposal(...proposal);
|
return this.functions.addProposal(...proposal, callOptions);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
lib/contracts/registry.js
Normal file
6
lib/contracts/registry.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const Base = require('./base');
|
||||||
|
|
||||||
|
class Registry extends Base {
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Registry;
|
@ -1,17 +1,15 @@
|
|||||||
const ethers = require('ethers');
|
const ethers = require('ethers');
|
||||||
const RSVP = require('rsvp');
|
const RSVP = require('rsvp');
|
||||||
|
|
||||||
const abis = {
|
const ABIS = {
|
||||||
Contributors: require('./abis/Contributors.json'),
|
Contributors: require('./abis/Contributors.json'),
|
||||||
Operator: require('./abis/Operator.json'),
|
Operator: require('./abis/Operator.json'),
|
||||||
Registry: require('./abis/Registry.json'),
|
Registry: require('./abis/Registry.json'),
|
||||||
Token: require('./abis/Token.json')
|
Token: require('./abis/Token.json')
|
||||||
};
|
};
|
||||||
const addresses = {
|
const RegistryAddress = require('./addresses/Registry.json');
|
||||||
Registry: require('./addresses/Registry.json')
|
|
||||||
};
|
|
||||||
|
|
||||||
const contracts = require('./contracts');
|
const Contracts = require('./contracts');
|
||||||
const IPFS = require('./utils/ipfs')
|
const IPFS = require('./utils/ipfs')
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
@ -21,65 +19,50 @@ function capitalize(word) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Kredits {
|
class Kredits {
|
||||||
static get contractNames() {
|
|
||||||
return Object.keys(abis);
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(provider, signer, addresses) {
|
constructor(provider, signer, addresses) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.signer = signer;
|
this.signer = signer;
|
||||||
|
|
||||||
// Initialize our registry contract
|
// by default we only need the registry address.
|
||||||
this.addresses = addresses;
|
// the rest is loaded from there in the init() function
|
||||||
|
this.addresses = addresses || {Registry: RegistryAddress[this.provider.chainId.toString()]}; // chaiID must be a string
|
||||||
|
this.abis = ABIS;
|
||||||
this.contracts = {};
|
this.contracts = {};
|
||||||
this.ipfs = new IPFS();
|
this.ipfs = new IPFS();
|
||||||
}
|
}
|
||||||
|
|
||||||
static setup(provider, signer, ipfsConfig = null) {
|
init(names) {
|
||||||
let ipfsAPI = new IPFS(ipfsConfig);
|
let contractsToLoad = names || Object.keys(ABIS);
|
||||||
|
let addressPromises = contractsToLoad.map((contractName) => {
|
||||||
return ipfsAPI._ipfsAPI.id().catch((error) => {
|
return this.Registry.functions.getProxyFor(contractName).then((address) => {
|
||||||
throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`);
|
this.addresses[contractName] = address;
|
||||||
}).then(() => {
|
}).catch((error) => {
|
||||||
|
throw new Error(`Failed to get address for ${contractName} from registry at ${this.Registry.contract.address}
|
||||||
let registryContract = this.initRegistryContract(provider);
|
|
||||||
|
|
||||||
let addresses = Kredits.contractNames.reduce((mem, name) => {
|
|
||||||
let contractName = capitalize(name);
|
|
||||||
mem[contractName] = registryContract.functions.getProxyFor(contractName).catch((error) => {
|
|
||||||
throw new Error(`Failed to get address for ${contractName} from registry at ${registryContract.address}
|
|
||||||
- correct registry? does it have version entry? - ${error.message}`
|
- correct registry? does it have version entry? - ${error.message}`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return mem;
|
});
|
||||||
}, {});
|
return RSVP.all(addressPromises).then(() => { return this });
|
||||||
|
}
|
||||||
|
|
||||||
return RSVP.hash(addresses)
|
static setup(provider, signer, ipfsConfig = null) {
|
||||||
.then((addresses) => {
|
console.log('Kredits.setup() is deprecated use new Kredits().init() instead');
|
||||||
let kredits = new Kredits(provider, signer, addresses);
|
let ipfs = new IPFS(ipfsConfig);
|
||||||
kredits.ipfs = ipfsAPI;
|
|
||||||
|
return ipfs._ipfsAPI.id().catch((error) => {
|
||||||
|
throw new Error(`IPFS node not available; config: ${JSON.stringify(ipfsConfig)} - ${error.message}`);
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
|
return new Kredits(provider, signer).init().then((kredits) => {
|
||||||
|
kredits.ipfs = ipfs;
|
||||||
return kredits;
|
return kredits;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static initRegistryContract(provider) {
|
get Registry() {
|
||||||
let address = addresses['Registry'][provider.chainId];
|
return this.contractFor('registry');
|
||||||
if (!address) {
|
|
||||||
throw new Error(`Registry address not found; invalid network?
|
|
||||||
requested network: ${provider.chainId}
|
|
||||||
supported networks: ${Object.keys(addresses['Registry'])}
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
provider.getCode(address).then((code) => {
|
|
||||||
// not sure if we always get the same return value of the code is not available
|
|
||||||
// that's why checking if it is < 5 long
|
|
||||||
if (code === '0x00' || code.length < 5) {
|
|
||||||
throw new Error(`Registry not found at ${address} on network ${provider.chainId}`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let abi = abis['Registry'];
|
|
||||||
return new ethers.Contract(address, abi, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get Contributor() {
|
get Contributor() {
|
||||||
@ -101,14 +84,16 @@ class Kredits {
|
|||||||
return this.contracts[name];
|
return this.contracts[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
let contractName = capitalize(name);
|
const contractName = capitalize(name);
|
||||||
let address = this.addresses[contractName];
|
const address = this.addresses[contractName];
|
||||||
if (!address || !abis[contractName]) {
|
const abi = this.abis[contractName];
|
||||||
|
if (!address || !abi) {
|
||||||
throw new Error(`Address or ABI not found for ${contractName}`);
|
throw new Error(`Address or ABI not found for ${contractName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signerOrProvider = this.signer || this.provider;
|
let signerOrProvider = this.signer || this.provider;
|
||||||
let contract = new ethers.Contract(address, abis[contractName], signerOrProvider);
|
let contract = new ethers.Contract(address, abi, signerOrProvider);
|
||||||
this.contracts[name] = new contracts[contractName](contract);
|
this.contracts[name] = new Contracts[contractName](contract);
|
||||||
this.contracts[name].ipfs = this.ipfs;
|
this.contracts[name].ipfs = this.ipfs;
|
||||||
|
|
||||||
return this.contracts[name];
|
return this.contracts[name];
|
||||||
|
@ -41,6 +41,7 @@ class Contribution {
|
|||||||
kind,
|
kind,
|
||||||
description,
|
description,
|
||||||
url,
|
url,
|
||||||
|
details
|
||||||
} = deserialized;
|
} = deserialized;
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
@ -51,7 +52,7 @@ class Contribution {
|
|||||||
},
|
},
|
||||||
kind,
|
kind,
|
||||||
description,
|
description,
|
||||||
"details": {}
|
"details": details || {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
|
@ -35,6 +35,7 @@ class Contributor {
|
|||||||
name,
|
name,
|
||||||
kind,
|
kind,
|
||||||
url,
|
url,
|
||||||
|
accounts,
|
||||||
github_uid,
|
github_uid,
|
||||||
github_username,
|
github_username,
|
||||||
wiki_username,
|
wiki_username,
|
||||||
|
35
package-lock.json
generated
35
package-lock.json
generated
@ -106,10 +106,10 @@
|
|||||||
"integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==",
|
"integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"async": {
|
"async-each-series": {
|
||||||
"version": "1.5.2",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz",
|
||||||
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
|
"integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"babel-code-frame": {
|
"babel-code-frame": {
|
||||||
@ -4230,6 +4230,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/promisify-es6/-/promisify-es6-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/promisify-es6/-/promisify-es6-1.0.3.tgz",
|
||||||
"integrity": "sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA=="
|
"integrity": "sha512-N9iVG+CGJsI4b4ZGazjwLnxErD2d9Pe4DPvvXSxYA9tFNu8ymXME4Qs5HIQ0LMJpNM7zj+m0NlNnNeqFpKzqnA=="
|
||||||
},
|
},
|
||||||
|
"promptly": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/promptly/-/promptly-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"pify": "3.0.0",
|
||||||
|
"read": "1.0.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"protocol-buffers-schema": {
|
"protocol-buffers-schema": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz",
|
||||||
@ -4343,6 +4353,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"read": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
|
||||||
|
"integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"mute-stream": "0.0.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"read-chunk": {
|
"read-chunk": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz",
|
||||||
@ -5401,6 +5420,14 @@
|
|||||||
"recast": "0.12.9",
|
"recast": "0.12.9",
|
||||||
"temp": "0.8.3",
|
"temp": "0.8.3",
|
||||||
"write-file-atomic": "1.3.4"
|
"write-file-atomic": "1.3.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"async": {
|
||||||
|
"version": "1.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
|
||||||
|
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recast": {
|
"recast": {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-json": "truffle compile && node ./scripts/build-json.js",
|
"build-json": "truffle compile && node ./scripts/build-json.js",
|
||||||
"bootstrap": "truffle migrate --reset && truffle exec scripts/seeds.js && npm run build-json",
|
"bootstrap": "truffle migrate --reset && npm run build-json && truffle exec scripts/seeds.js",
|
||||||
"ganache": "ganache-cli -p 7545 -i 100 --db=./.ganache-db -m kredits",
|
"ganache": "ganache-cli -p 7545 -i 100 --db=./.ganache-db -m kredits",
|
||||||
"dev": "truffle migrate && npm run build-json",
|
"dev": "truffle migrate && npm run build-json",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
@ -24,12 +24,14 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/67P/truffle-kredits#readme",
|
"homepage": "https://github.com/67P/truffle-kredits#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"async-each-series": "^1.1.0",
|
||||||
"ganache-cli": "^6.0.3",
|
"ganache-cli": "^6.0.3",
|
||||||
|
"promptly": "^3.0.3",
|
||||||
"truffle": "^4.1.3",
|
"truffle": "^4.1.3",
|
||||||
"zeppelin-solidity": "^1.7.0"
|
"zeppelin-solidity": "^1.7.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ethers": "^3.0.15",
|
"ethers": "3.0.15",
|
||||||
"ipfs-api": "^19.0.0",
|
"ipfs-api": "^19.0.0",
|
||||||
"rsvp": "^4.8.2"
|
"rsvp": "^4.8.2"
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,50 @@
|
|||||||
const Registry = artifacts.require('./Registry.sol');
|
const Registry = artifacts.require('./Registry.sol');
|
||||||
const Operator = artifacts.require('./Operator.sol');
|
const promptly = require('promptly');
|
||||||
const Contributors = artifacts.require('./Contributors.sol');
|
const bs58 = require('bs58');
|
||||||
|
|
||||||
var bs58 = require('bs58');
|
const ethers = require('ethers');
|
||||||
|
const Kredits = require('../lib/kredits');
|
||||||
|
|
||||||
function getBytes32FromMultiash(multihash) {
|
async function prompt(message, options) {
|
||||||
const decoded = bs58.decode(multihash);
|
if (!options) {
|
||||||
|
options = {default: ''}
|
||||||
return {
|
}
|
||||||
digest: `0x${decoded.slice(2).toString('hex')}`,
|
return await promptly.prompt(message, options);
|
||||||
hashFunction: decoded[0],
|
|
||||||
size: decoded[1],
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(callback) {
|
module.exports = function(callback) {
|
||||||
Registry.deployed().then(async (registry) => {
|
Registry.deployed().then(async (registry) => {
|
||||||
var operatorAddress = await registry.getProxyFor('Operator');
|
|
||||||
var contributorsAddress = await registry.getProxyFor('Contributors');
|
|
||||||
|
|
||||||
var operator = await Operator.at(operatorAddress);
|
const networkId = parseInt(web3.version.network);
|
||||||
var contributors = await Contributors.at(contributorsAddress);
|
const provider = new ethers.providers.Web3Provider(
|
||||||
|
web3.currentProvider, { chainId: networkId }
|
||||||
|
);
|
||||||
|
const kredits = await Kredits.setup(provider, provider.getSigner());
|
||||||
|
|
||||||
let contributorToAddAddress = process.argv[4];
|
console.log(`Using contributors at: ${kredits.Contributor.contract.address}`);
|
||||||
if(!contributorToAddAddress) {
|
|
||||||
console.log('please provide an address');
|
|
||||||
proxess.exit();
|
|
||||||
}
|
|
||||||
let ipfsHash = process.argv[5] || 'QmQyZJT9uikzDYTZLhhyVZ5ReZVCoMucYzyvDokDJsijhj';
|
|
||||||
let contributorMultihash = getBytes32FromMultiash(ipfsHash);
|
|
||||||
let isCore = true;
|
|
||||||
let contributorResult = await contributors.addContributor(contributorToAddAddress, contributorMultihash.digest, contributorMultihash.hashFunction, contributorMultihash.size, isCore);
|
|
||||||
console.log('Contributor added, tx: ', contributorResult.tx);
|
|
||||||
|
|
||||||
let contributorId = await contributors.getContributorIdByAddress(contributorToAddAddress);
|
let contributorAttributes = {
|
||||||
let proposalMultihash = getBytes32FromMultiash('QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs');
|
account: await prompt('Contributor address: ', {}),
|
||||||
let proposalResult = await operator.addProposal(contributorId, 23, proposalMultihash.digest, proposalMultihash.hashFunction, proposalMultihash.size);
|
name: await prompt('Name: '),
|
||||||
console.log('Proposal added, tx: ', proposalResult.tx);
|
isCore: await prompt('core? y/n') === 'y',
|
||||||
|
kind: await prompt('Kind (default person): ', {default: 'person'}),
|
||||||
|
url: await prompt('URL: '),
|
||||||
|
github_username: await prompt('GitHub username: '),
|
||||||
|
github_uid: await prompt('GitHub UID: '),
|
||||||
|
wiki_username: await prompt('Wiki username: '),
|
||||||
|
};
|
||||||
|
|
||||||
let proposalId = await operator.proposalsCount();
|
console.log("\nAdding contributor:");
|
||||||
let votingResult = await operator.vote(proposalId.toNumber()-1);
|
console.log(contributorAttributes);
|
||||||
console.log('Voted for proposal', proposalId.toString(), votingResult.tx);
|
|
||||||
|
|
||||||
|
kredits.Contributor.add(contributorAttributes, {gasLimit: 250000}).then((result) => {
|
||||||
|
console.log("\n\nResult:");
|
||||||
|
console.log(result);
|
||||||
callback();
|
callback();
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log('Failed to create contributor');
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
const Registry = artifacts.require('./Registry.sol');
|
const Registry = artifacts.require('./Registry.sol');
|
||||||
const Operator = artifacts.require('./Operator.sol');
|
const Operator = artifacts.require('./Operator.sol');
|
||||||
const Contributors = artifacts.require('./Contributors.sol');
|
const Contributors = artifacts.require('./Contributors.sol');
|
||||||
|
const promptly = require('promptly');
|
||||||
|
|
||||||
var bs58 = require('bs58');
|
const bs58 = require('bs58');
|
||||||
|
|
||||||
function getBytes32FromMultiash(multihash) {
|
function getBytes32FromMultiash(multihash) {
|
||||||
const decoded = bs58.decode(multihash);
|
const decoded = bs58.decode(multihash);
|
||||||
@ -22,12 +23,9 @@ module.exports = function(callback) {
|
|||||||
var operator = await Operator.at(operatorAddress);
|
var operator = await Operator.at(operatorAddress);
|
||||||
var contributors = await Contributors.at(contributorsAddress);
|
var contributors = await Contributors.at(contributorsAddress);
|
||||||
|
|
||||||
let recipientAddress = process.argv[4];
|
let recipientAddress = await promptly.prompt('Contributor address: ');
|
||||||
if(!recipientAddress) {
|
let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' });
|
||||||
console.log('please provide an address');
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
let ipfsHash = process.argv[5] || 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs';
|
|
||||||
let multihash = getBytes32FromMultiash(ipfsHash);
|
let multihash = getBytes32FromMultiash(ipfsHash);
|
||||||
|
|
||||||
let contributorId = await contributors.getContributorIdByAddress(recipientAddress);
|
let contributorId = await contributors.getContributorIdByAddress(recipientAddress);
|
||||||
|
@ -18,6 +18,7 @@ files.forEach((fileName) => {
|
|||||||
let abiFile = path.join(abisPath, `${fileName}.json`);
|
let abiFile = path.join(abisPath, `${fileName}.json`);
|
||||||
fs.writeFileSync(abiFile, JSON.stringify(file.abi));
|
fs.writeFileSync(abiFile, JSON.stringify(file.abi));
|
||||||
|
|
||||||
|
if (fileName === 'Registry') {
|
||||||
let addresseFile = path.join(addressesPath, `${fileName}.json`);
|
let addresseFile = path.join(addressesPath, `${fileName}.json`);
|
||||||
let addresses = Object.keys(file.networks)
|
let addresses = Object.keys(file.networks)
|
||||||
.reduce((addresses, key) => {
|
.reduce((addresses, key) => {
|
||||||
@ -25,7 +26,7 @@ files.forEach((fileName) => {
|
|||||||
return addresses;
|
return addresses;
|
||||||
}, {});
|
}, {});
|
||||||
fs.writeFileSync(addresseFile, JSON.stringify(addresses));
|
fs.writeFileSync(addresseFile, JSON.stringify(addresses));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web");
|
console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web");
|
||||||
|
@ -1,39 +1,45 @@
|
|||||||
const REPL = require('repl');
|
const REPL = require('repl');
|
||||||
|
const promptly = require('promptly');
|
||||||
|
|
||||||
|
const ethers = require('ethers');
|
||||||
|
const Kredits = require('../lib/kredits');
|
||||||
|
|
||||||
module.exports = function(callback) {
|
module.exports = function(callback) {
|
||||||
const Registry = artifacts.require('./Registry.sol');
|
const Registry = artifacts.require('./Registry.sol');
|
||||||
Registry.deployed().then(async (registry) => {
|
Registry.deployed().then(async (registry) => {
|
||||||
let contractName = process.argv[4];
|
let contractName = await promptly.prompt('Contract Name: ');
|
||||||
let method = process.argv[5];
|
let method = await promptly.prompt('Function: ');
|
||||||
let args = process.argv.slice(6);
|
let argumentInput = await promptly.prompt('Arguments (comma separated): ', { default: '' });
|
||||||
|
let args = [];
|
||||||
if (!contractName) {
|
if (argumentInput !== '') {
|
||||||
console.log("Usage:");
|
args = argumentInput.split(',').map(a => a.trim());
|
||||||
console.log(" truffle exec scripts/cli.js <Contract name> <method to call> [<optional> <arguments>]");
|
|
||||||
callback();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let contractAddress = await registry.getProxyFor(contractName);
|
const networkId = parseInt(web3.version.network);
|
||||||
console.log(`Using ${contractName} at ${contractAddress}`);
|
const provider = new ethers.providers.Web3Provider(
|
||||||
let contract = await artifacts.require(`./${contractName}`).at(contractAddress);
|
web3.currentProvider, { chainId: networkId }
|
||||||
|
);
|
||||||
|
const kredits = await Kredits.setup(provider, provider.getSigner());
|
||||||
|
|
||||||
|
const contract = kredits[contractName].contract;
|
||||||
|
console.log(`Using ${contractName} at ${contract.address}`);
|
||||||
|
console.log(`Calling ${method} with ${JSON.stringify(args)}`);
|
||||||
|
|
||||||
if (!contract[method]) {
|
if (!contract[method]) {
|
||||||
callback(new Error(`Method ${method} is not defined on ${contractName}`));
|
callback(new Error(`Method ${method} is not defined on ${contractName}`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(`Calling ${method} with ${JSON.stringify(args)}`);
|
|
||||||
|
|
||||||
contract[method](...args).then((result) => {
|
contract[method](...args).then((result) => {
|
||||||
console.log("\nResult:");
|
console.log("\nResult:");
|
||||||
console.log(result);
|
console.log(result);
|
||||||
|
|
||||||
console.log("\nStartig a REPL. (type .exit to exit)");
|
console.log("\nStartig a REPL. (type .exit to exit)");
|
||||||
console.log(`defined variables: result, ${contractName}, web3`);
|
console.log(`defined variables: result, ${contractName}, kredis`);
|
||||||
let r = REPL.start();
|
let r = REPL.start();
|
||||||
r.context.result = result;
|
r.context.result = result;
|
||||||
r.context[contractName] = contract;
|
r.context[contractName] = contract;
|
||||||
r.context.web3 = web3;
|
r.context.kredits = kredits;
|
||||||
|
|
||||||
r.on('exit', () => {
|
r.on('exit', () => {
|
||||||
console.log('Bye');
|
console.log('Bye');
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
var bs58 = require('bs58');
|
|
||||||
|
|
||||||
function getBytes32FromMultiash(multihash) {
|
|
||||||
const decoded = bs58.decode(multihash);
|
|
||||||
|
|
||||||
return {
|
|
||||||
digest: `0x${decoded.slice(2).toString('hex')}`,
|
|
||||||
hashFunction: decoded[0],
|
|
||||||
size: decoded[1],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getMultihashFromBytes32(multihash) {
|
|
||||||
const { digest, hashFunction, size } = multihash;
|
|
||||||
if (size === 0) return null;
|
|
||||||
|
|
||||||
// cut off leading "0x"
|
|
||||||
const hashBytes = Buffer.from(digest.slice(2), 'hex');
|
|
||||||
|
|
||||||
// prepend hashFunction and digest size
|
|
||||||
//const multihashBytes = new (hashBytes.constructor)(2 + hashBytes.length);
|
|
||||||
const multihashBytes = new Buffer(2 + hashBytes.length);
|
|
||||||
|
|
||||||
console.log(hashBytes.constructor);
|
|
||||||
|
|
||||||
multihashBytes[0] = hashFunction;
|
|
||||||
multihashBytes[1] = size;
|
|
||||||
multihashBytes.set(hashBytes, 2);
|
|
||||||
|
|
||||||
return bs58.encode(multihashBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
var m = getBytes32FromMultiash(process.argv[2]);
|
|
||||||
console.log(m)
|
|
@ -1,34 +1,39 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const seeds = require(path.join(__dirname, '..', '/config/seeds.js'));
|
const seeds = require(path.join(__dirname, '..', '/config/seeds.js'));
|
||||||
const IPFS = require('ipfs-api');
|
|
||||||
|
|
||||||
var ipfs = IPFS({host: 'localhost', port: '5001', protocol: 'http'})
|
const ethers = require('ethers');
|
||||||
|
const Kredits = require('../lib/kredits');
|
||||||
|
|
||||||
|
const each = require('async-each-series');
|
||||||
|
|
||||||
module.exports = function(callback) {
|
module.exports = function(callback) {
|
||||||
const Registry = artifacts.require('./Registry.sol');
|
const Registry = artifacts.require('./Registry.sol');
|
||||||
|
|
||||||
const contracts = {};
|
Registry.deployed().then(async (registry) => {
|
||||||
Registry.deployed().then((registry) => {
|
|
||||||
Object.keys(seeds.contractCalls).forEach(async (contract) => {
|
|
||||||
var address = await registry.getProxyFor(contract);
|
|
||||||
console.log(`Using ${contract} at ${address}`);
|
|
||||||
contracts[contract] = await artifacts.require(contract).at(address);
|
|
||||||
|
|
||||||
Object.keys(seeds.contractCalls[contract]).forEach((method) => {
|
const networkId = parseInt(web3.version.network);
|
||||||
seeds.contractCalls[contract][method].forEach((args) => {
|
const provider = new ethers.providers.Web3Provider(
|
||||||
console.log(`[Sending] ${contract}.#${method}(${JSON.stringify(args)})`);
|
web3.currentProvider, { chainId: networkId }
|
||||||
contracts[contract][method](...args).then((result) => {
|
);
|
||||||
console.log(`[Result] ${contract}.${method}(${JSON.stringify(args)}) => ${result.tx}`);
|
const kredits = await Kredits.setup(provider, provider.getSigner());
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
each(seeds.contractCalls, (call, next) => {
|
||||||
seeds.ipfsContent.forEach((content) => {
|
let [contractName, method, args] = call;
|
||||||
ipfs.add(new ipfs.Buffer(JSON.stringify(content))).then((result) => { console.log(`[IPFS] added ${result[0].hash}`) });
|
let contractWrapper = kredits[contractName];
|
||||||
|
let func;
|
||||||
|
if (contractWrapper[method]) {
|
||||||
|
func = contractWrapper[method];
|
||||||
|
} else {
|
||||||
|
func = contractWrapper.functions[method];
|
||||||
|
}
|
||||||
|
func.apply(contractWrapper, args).then((result) => {
|
||||||
|
console.log(`[OK] kredits.${contractName}.${method}(${JSON.stringify(args)}) => ${result.hash}`);
|
||||||
|
next();
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(`[FAILD] kredits.${contractName}.${method}(${JSON.stringify(args)})`);
|
||||||
|
callback(error)
|
||||||
});
|
});
|
||||||
|
}, () => { console.log("\nDone!") });
|
||||||
|
|
||||||
callback();
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
const promptly = require('promptly');
|
||||||
|
|
||||||
|
module.exports = async function(callback) {
|
||||||
|
let recipient = await promptly.prompt('Recipient address: ');
|
||||||
|
let amount = await promptly.prompt('Amount: ', {default: '1'});
|
||||||
|
amount = parseInt(amount);
|
||||||
|
|
||||||
|
console.log(`sending ${amount} ETH from ${web3.eth.accounts[0]} to ${recipient}`);
|
||||||
|
|
||||||
module.exports = function(callback) {
|
|
||||||
let recipient = process.argv[4];
|
|
||||||
if (!recipient) {
|
|
||||||
console.log('Please provide a recipient address');
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
let amount = parseInt(process.argv[5]) || 1;
|
|
||||||
console.log(recipient);
|
|
||||||
web3.eth.sendTransaction({to: recipient, value: web3.toWei(amount), from: web3.eth.accounts[0]}, console.log);
|
web3.eth.sendTransaction({to: recipient, value: web3.toWei(amount), from: web3.eth.accounts[0]}, console.log);
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
|
@ -5,6 +5,11 @@ module.exports = {
|
|||||||
host: "127.0.0.1",
|
host: "127.0.0.1",
|
||||||
port: 7545,
|
port: 7545,
|
||||||
network_id: "*" // Match any network id
|
network_id: "*" // Match any network id
|
||||||
|
},
|
||||||
|
kovan: {
|
||||||
|
host: "127.0.0.1",
|
||||||
|
port: 8545,
|
||||||
|
network_id: "42"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user