Refactor helper scripts to use kredits module

This reuses the kredits library functions in the helper scripts and
seeds. We no longer need to add IPFS hashes manually but simply can
provider contributor/proposal data.
This commit is contained in:
bumi 2018-04-20 12:56:09 +02:00
parent d4ca8d7c25
commit 2503ac7c73
7 changed files with 98 additions and 162 deletions

View File

@ -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 };

16
package-lock.json generated
View File

@ -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": {
@ -5420,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": {

View File

@ -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,6 +24,7 @@
}, },
"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", "promptly": "^3.0.3",
"truffle": "^4.1.3", "truffle": "^4.1.3",

View File

@ -1,45 +1,50 @@
const Registry = artifacts.require('./Registry.sol'); const Registry = artifacts.require('./Registry.sol');
const Operator = artifacts.require('./Operator.sol');
const Contributors = artifacts.require('./Contributors.sol');
const promptly = require('promptly'); const promptly = require('promptly');
const bs58 = require('bs58'); const bs58 = require('bs58');
function getBytes32FromMultiash(multihash) { const ethers = require('ethers');
const decoded = bs58.decode(multihash); const Kredits = require('../lib/kredits');
return { async function prompt(message, options) {
digest: `0x${decoded.slice(2).toString('hex')}`, if (!options) {
hashFunction: decoded[0], options = {default: ''}
size: decoded[1], }
}; return await promptly.prompt(message, options);
} }
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 = await promptly.prompt('Contributor address: '); console.log(`Using contributors at: ${kredits.Contributor.contract.address}`);
let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' });
let contributorMultihash = getBytes32FromMultiash(ipfsHash); let contributorAttributes = {
let isCore = true; account: await prompt('Contributor address: ', {}),
let contributorResult = await contributors.addContributor(contributorToAddAddress, contributorMultihash.digest, contributorMultihash.hashFunction, contributorMultihash.size, isCore); name: await prompt('Name: '),
console.log('Contributor added, tx: ', contributorResult.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 contributorId = await contributors.getContributorIdByAddress(contributorToAddAddress); console.log("\nAdding contributor:");
let proposalMultihash = getBytes32FromMultiash('QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'); console.log(contributorAttributes);
let proposalResult = await operator.addProposal(contributorId, 23, proposalMultihash.digest, proposalMultihash.hashFunction, proposalMultihash.size);
console.log('Proposal added, tx: ', proposalResult.tx);
let proposalId = await operator.proposalsCount(); kredits.Contributor.add(contributorAttributes, {gasLimit: 250000}).then((result) => {
let votingResult = await operator.vote(proposalId.toNumber()-1); console.log("\n\nResult:");
console.log('Voted for proposal', proposalId.toString(), votingResult.tx); console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create contributor');
callback(error);
});
callback();
}); });
} }

View File

@ -1,6 +1,9 @@
const REPL = require('repl'); const REPL = require('repl');
const promptly = require('promptly'); 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) => {
@ -12,26 +15,31 @@ module.exports = function(callback) {
args = argumentInput.split(',').map(a => a.trim()); args = argumentInput.split(',').map(a => a.trim());
} }
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');

View File

@ -1,35 +0,0 @@
const 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)

View File

@ -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) => {
let [contractName, method, args] = call;
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!") });
}); });
seeds.ipfsContent.forEach((content) => {
ipfs.add(new ipfs.Buffer(JSON.stringify(content))).then((result) => { console.log(`[IPFS] added ${result[0].hash}`) });
});
callback();
} }