diff --git a/lib/addresses/Contributors.json b/lib/addresses/Contributors.json index 7c8cb62..9b722e1 100644 --- a/lib/addresses/Contributors.json +++ b/lib/addresses/Contributors.json @@ -1 +1 @@ -{"42":"0x205fe1b3dac678b594c5f0535e7d158e38591f93","100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"} \ No newline at end of file +{"42":"0x205fe1b3dac678b594c5f0535e7d158e38591f93","100":"0x6ebe4c6a39216e37f5efafd9ce89e2bed293270e"} \ No newline at end of file diff --git a/lib/addresses/Operator.json b/lib/addresses/Operator.json index b865526..0298bb1 100644 --- a/lib/addresses/Operator.json +++ b/lib/addresses/Operator.json @@ -1 +1 @@ -{"42":"0x9fd66ee78a5ebe86006f12b37ff59c63f9caa15b","100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"} \ No newline at end of file +{"42":"0x9fd66ee78a5ebe86006f12b37ff59c63f9caa15b","100":"0x38062ac7ac5f910471ce490eabf0af1c4ac92c5f"} \ No newline at end of file diff --git a/lib/addresses/Registry.json b/lib/addresses/Registry.json index 8bdcb57..2e23736 100644 --- a/lib/addresses/Registry.json +++ b/lib/addresses/Registry.json @@ -1 +1 @@ -{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x513f8e80a8fbb9fa188320ecf231efcf2f6da9c5"} \ No newline at end of file +{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x2cf47d9c33590ade7261bba063082e5ee1469911"} \ No newline at end of file diff --git a/lib/addresses/Token.json b/lib/addresses/Token.json index 9242b73..ecb7bba 100644 --- a/lib/addresses/Token.json +++ b/lib/addresses/Token.json @@ -1 +1 @@ -{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"} \ No newline at end of file +{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x98547fe20531018a2fd5e4a70be11c4ecbeb0520"} \ No newline at end of file diff --git a/lib/contracts/base.js b/lib/contracts/base.js index de43c19..ba113b5 100644 --- a/lib/contracts/base.js +++ b/lib/contracts/base.js @@ -3,6 +3,10 @@ class Base { this.contract = contract; } + get address() { + return this.contract.address; + } + get functions() { return this.contract.functions; } diff --git a/lib/contracts/contributor.js b/lib/contracts/contributor.js index 127e2dc..a112f2c 100644 --- a/lib/contracts/contributor.js +++ b/lib/contracts/contributor.js @@ -42,13 +42,14 @@ class Contributor extends Base { .add(json) .then((ipfsHashAttr) => { let contributor = [ - contributorAttr.address, + contributorAttr.account, ipfsHashAttr.hashDigest, ipfsHashAttr.hashFunction, ipfsHashAttr.hashSize, contributorAttr.isCore, ]; + console.log(contributor); return this.functions.addContributor(...contributor); }); } diff --git a/lib/contracts/index.js b/lib/contracts/index.js index 9fd06ae..f9f209b 100644 --- a/lib/contracts/index.js +++ b/lib/contracts/index.js @@ -1,5 +1,6 @@ module.exports = { Contributors: require('./contributor'), Operator: require('./operator'), - Token: require('./token') + Token: require('./token'), + Registry: require('./registry') } diff --git a/lib/contracts/registry.js b/lib/contracts/registry.js new file mode 100644 index 0000000..3ff8562 --- /dev/null +++ b/lib/contracts/registry.js @@ -0,0 +1,8 @@ +const Base = require('./base'); + +class Registry extends Base { +} + +module.exports = Registry; + + diff --git a/lib/healthcheck.js b/lib/healthcheck.js new file mode 100644 index 0000000..b440d5e --- /dev/null +++ b/lib/healthcheck.js @@ -0,0 +1,24 @@ +class Healthcheck { + constructor(kredits) { + this.kredits = kredits; + } + + check() { + return this.kredits.ipfs._ipfsAPI.id() + .catch((error) => { + throw new Error(`IPFS node not available; config: ${JSON.stringify(this.kredits.ipfs.config)} - ${error.message}`); + }) + .then(() => { + return Object.keys(this.kredits.contracts).map((name) => { + let contract = this.kredits.contracts[name]; + this.kredits.provider.getCode(contract.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 ${contract.address} on network ${this.kredits.provider.chainId}`); + } + }); + }); + }); + } +} diff --git a/lib/kredits.js b/lib/kredits.js index 8182137..e7eefc5 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -1,13 +1,13 @@ const ethers = require('ethers'); const RSVP = require('rsvp'); -const abis = { +const ABIs = { Contributors: require('./abis/Contributors.json'), Operator: require('./abis/Operator.json'), Registry: require('./abis/Registry.json'), Token: require('./abis/Token.json') }; -const addresses = { +const ADDRESSES = { Registry: require('./addresses/Registry.json') }; @@ -22,7 +22,7 @@ function capitalize(word) { class Kredits { static get contractNames() { - return Object.keys(abis); + return Object.keys(ABIs); } constructor(provider, signer, addresses) { @@ -30,11 +30,26 @@ class Kredits { this.signer = signer; // Initialize our registry contract - this.addresses = addresses; + this.addresses = addresses || ADDRESSES[this.provider.chainId]; + this.abis = ABIs; this.contracts = {}; this.ipfs = new IPFS(); } + init(names) { + let contractsToLoad = names || Kredits.contractNames; + let addressPromises = contractsToLoad.map((contractName) => { + return this.Registry.functions.getProxyFor(contractName).then((address) => { + this.addresses[contractName] = address; + }).catch((error) => { + throw new Error(`Failed to get address for ${contractName} from registry at ${this.Registry.address} + - correct registry? does it have version entry? - ${error.message}` + ); + }); + }); + return RSVP.all(addressPromises).then(() => { return this }); + } + static setup(provider, signer, ipfsConfig = null) { let ipfsAPI = new IPFS(ipfsConfig); @@ -64,11 +79,11 @@ class Kredits { } static initRegistryContract(provider) { - let address = addresses['Registry'][provider.chainId]; + let address = ADDRESSES['Registry'][provider.chainId]; if (!address) { throw new Error(`Registry address not found; invalid network? requested network: ${provider.chainId} - supported networks: ${Object.keys(addresses['Registry'])} + supported networks: ${Object.keys(ADDRESSES['Registry'])} `); } provider.getCode(address).then((code) => { @@ -78,10 +93,14 @@ class Kredits { throw new Error(`Registry not found at ${address} on network ${provider.chainId}`); } }); - let abi = abis['Registry']; + let abi = ABIs['Registry']; return new ethers.Contract(address, abi, provider); } + get Registry() { + return this.contractFor('registry'); + } + get Contributor() { // TODO: rename to contributor return this.contractFor('contributors'); @@ -103,10 +122,11 @@ class Kredits { let contractName = capitalize(name); let address = this.addresses[contractName]; - if (!address || !abis[contractName]) { + let abi = this.abis[contractName]; + if (!address || !abi) { throw new Error(`Address or ABI not found for ${contractName}`); } - let contract = new ethers.Contract(address, abis[contractName], this.signer); + let contract = new ethers.Contract(address, abi, this.signer); this.contracts[name] = new contracts[contractName](contract); this.contracts[name].ipfs = this.ipfs; diff --git a/scripts/add-contributor.js b/scripts/add-contributor.js index 2636c2a..6f5f043 100644 --- a/scripts/add-contributor.js +++ b/scripts/add-contributor.js @@ -3,43 +3,63 @@ const Operator = artifacts.require('./Operator.sol'); const Contributors = artifacts.require('./Contributors.sol'); const promptly = require('promptly'); +const IPFS = require('../lib/utils/ipfs'); +const ipfs = new IPFS(); const bs58 = require('bs58'); -function getBytes32FromMultiash(multihash) { - const decoded = bs58.decode(multihash); +const ethers = require('ethers'); +const Kredits = require('../lib/kredits'); - return { - digest: `0x${decoded.slice(2).toString('hex')}`, - hashFunction: decoded[0], - size: decoded[1], - }; +async function prompt(message, options) { + if (!options) { + options = {default: ''} + } + return await promptly.prompt(message, options); } - module.exports = function(callback) { Registry.deployed().then(async (registry) => { - var operatorAddress = await registry.getProxyFor('Operator'); - var contributorsAddress = await registry.getProxyFor('Contributors'); - var operator = await Operator.at(operatorAddress); - var contributors = await Contributors.at(contributorsAddress); + console.log(`Using registry at: ${registry.address}`); + let networkId = parseInt(web3.version.network); + console.log(web3.currentProvider); + let provider = new ethers.providers.Web3Provider( + web3.currentProvider, + { chainId: networkId } + ) + console.log(provider.getSigner()); + const kredits = await new Kredits(provider, provider.getSigner(), {Registry: registry.address}).init(); + console.log(`Using contributors at: ${kredits.Contributor.address}`); + let contributorAttributes = { + account: await prompt('Contributor address: ', {}), + name: await prompt('Name: '), + 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 contributorToAddAddress = await promptly.prompt('Contributor address: '); - let ipfsHash = await promptly.prompt('IPFS hash (blank for default): ', { default: 'QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs' }); - - 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 proposalMultihash = getBytes32FromMultiash('QmQNA1hhVyL1Vm6HiRxXe9xmc6LUMBDyiNMVgsjThtyevs'); - 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(); - let votingResult = await operator.vote(proposalId.toNumber()-1); - console.log('Voted for proposal', proposalId.toString(), votingResult.tx); - - callback(); + contributorAttributes = { + account: '0x398ac9cdb122e6f526c8bf8dd80eeeb18fce8821', + name: 'bumi', + isCore: '1' + } + console.log("\nCreating new contributor with following attributes:"); + console.log(contributorAttributes); + kredits.Contributor.functions.addContributor('0x398ac9cdb122e6f526c8bf8dd80eeeb18fce8821', + '0x272bbfc66166f26cae9c9b96b7f9590e095f02edf342ac2dd71e1667a12116ca', 18, 32, true).then((r) => { + console.log(r); + process.exit(); + }); + /* + kredits.Contributor.add(contributorAttributes).then((result) => { + console.log(result); + callback(); + }).catch((error) => { + console.log('Failed to create contributor'); + callback(error); + }); + */ }); } diff --git a/truffle.js b/truffle.js index 77e88c5..e7e7beb 100644 --- a/truffle.js +++ b/truffle.js @@ -3,7 +3,7 @@ module.exports = { networks: { development: { host: "127.0.0.1", - port: 7545, + port: 8545, network_id: "*" // Match any network id }, kovan: {