From f5973756c890feec9d7d5cf1fb903f233bb591ed Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Wed, 27 Mar 2019 00:21:06 +0100 Subject: [PATCH] Dynamically set AppIds AppIds are used to lookup the actual contract addresses of each app. Because of different registry names (open.aragonpm.eth vs. aragonpm.eth) we have to use different ids in the local dev chain and in the testnet/mainnet. To allow this we need to set the appids dynamically. There is an open aragon issue to solve this and also allow to use open.aragonpm.eth in the devchain by default. https://github.com/aragon/aragen/issues/10 --- apps/contribution/arapp.json | 2 +- apps/contribution/contracts/Contribution.sol | 19 +++++++++++-------- apps/contributor/arapp.json | 2 +- apps/contributor/contracts/Contributor.sol | 8 +++++++- apps/proposal/arapp.json | 2 +- apps/proposal/contracts/Proposal.sol | 12 +++++++----- apps/token/arapp.json | 2 +- apps/token/contracts/Token.sol | 7 ++++++- contracts/KreditsKit.sol | 8 ++++---- lib/addresses/KreditsKit.json | 2 +- lib/addresses/dao.json | 2 +- lib/app_ids.json | 1 + lib/contracts/kernel.js | 9 ++------- scripts/deploy-kit.js | 19 ++++++++++--------- scripts/helpers/file_inject.js | 8 ++++++++ scripts/helpers/networkid.js | 11 +++++++++++ scripts/new-dao.js | 12 +++++------- 17 files changed, 78 insertions(+), 48 deletions(-) create mode 100644 lib/app_ids.json create mode 100644 scripts/helpers/file_inject.js create mode 100644 scripts/helpers/networkid.js diff --git a/apps/contribution/arapp.json b/apps/contribution/arapp.json index 5a63ec5..01d78af 100644 --- a/apps/contribution/arapp.json +++ b/apps/contribution/arapp.json @@ -14,7 +14,7 @@ "environments": { "default": { "network": "development", - "appName": "kredits-contribution.open.aragonpm.eth" + "appName": "kredits-contribution.aragonpm.eth" }, "rinkeby": { "registry": "0x98df287b6c145399aaa709692c8d308357bc085d", diff --git a/apps/contribution/contracts/Contribution.sol b/apps/contribution/contracts/Contribution.sol index 094d51c..a439f61 100644 --- a/apps/contribution/contracts/Contribution.sol +++ b/apps/contribution/contracts/Contribution.sol @@ -11,7 +11,9 @@ contract Contribution is AragonApp { bytes32 public constant ADD_CONTRIBUTION_ROLE = keccak256("ADD_CONTRIBUTION_ROLE"); bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb; - bytes32 public constant TOKEN_APP_ID = 0x82c0e483537d703bb6f0fc799d2cc60d8f62edcb0f6d26d5571a92be8485b112; + // ensure alphabetic order + enum Apps { Contribution, Contributor, Proposal, Token } + bytes32[4] public appIds; struct ContributionData { address contributor; @@ -38,10 +40,17 @@ contract Contribution is AragonApp { event ContributionAdded(uint256 id, address indexed contributor, uint256 amount); event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount); - function initialize() public onlyInit { + function initialize(bytes32[4] _appIds) public onlyInit { + appIds = _appIds; initialized(); } + function getTokenContract() public view returns (address) { + IKernel k = IKernel(kernel()); + + return k.getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Token)]); + } + function name() external view returns (string) { return name_; } @@ -116,12 +125,6 @@ contract Contribution is AragonApp { IToken(token).mintFor(c.contributor, c.amount, contributionId); emit ContributionClaimed(contributionId, c.contributor, c.amount); } - - function getTokenContract() public view returns (address) { - IKernel k = IKernel(kernel()); - - return k.getApp(KERNEL_APP_ADDR_NAMESPACE, TOKEN_APP_ID); - } function exists(uint256 contributionId) view public returns (bool) { return contributions[contributionId].exists; diff --git a/apps/contributor/arapp.json b/apps/contributor/arapp.json index e26fa44..58c090e 100644 --- a/apps/contributor/arapp.json +++ b/apps/contributor/arapp.json @@ -9,7 +9,7 @@ "environments": { "default": { "network": "development", - "appName": "kredits-contributor.open.aragonpm.eth" + "appName": "kredits-contributor.aragonpm.eth" }, "rinkeby": { "registry": "0x98df287b6c145399aaa709692c8d308357bc085d", diff --git a/apps/contributor/contracts/Contributor.sol b/apps/contributor/contracts/Contributor.sol index 41ef319..4e92d4e 100644 --- a/apps/contributor/contracts/Contributor.sol +++ b/apps/contributor/contracts/Contributor.sol @@ -18,11 +18,15 @@ contract Contributor is AragonApp { mapping (uint => Contributor) public contributors; uint256 public contributorsCount; + // ensure alphabetic order + enum Apps { Contribution, Contributor, Proposal, Token } + bytes32[4] public appIds; + event ContributorProfileUpdated(uint id, bytes32 oldIpfsHash, bytes32 newIpfsHash); event ContributorAccountUpdated(uint id, address oldAccount, address newAccount); event ContributorAdded(uint id, address account); - function initialize(address root) public onlyInit { + function initialize(address root,bytes32[4] _appIds) public onlyInit { uint _id = contributorsCount + 1; Contributor storage c = contributors[_id]; c.exists = true; @@ -31,6 +35,8 @@ contract Contributor is AragonApp { contributorIds[root] = _id; contributorsCount += 1; + appIds = _appIds; + initialized(); } diff --git a/apps/proposal/arapp.json b/apps/proposal/arapp.json index 255d894..71172d5 100644 --- a/apps/proposal/arapp.json +++ b/apps/proposal/arapp.json @@ -14,7 +14,7 @@ "environments": { "default": { "network": "development", - "appName": "kredits-proposal.open.aragonpm.eth" + "appName": "kredits-proposal.aragonpm.eth" }, "rinkeby": { "registry": "0x98df287b6c145399aaa709692c8d308357bc085d", diff --git a/apps/proposal/contracts/Proposal.sol b/apps/proposal/contracts/Proposal.sol index ac5a3e9..a0d808f 100644 --- a/apps/proposal/contracts/Proposal.sol +++ b/apps/proposal/contracts/Proposal.sol @@ -19,8 +19,9 @@ contract Proposal is AragonApp { bytes32 public constant VOTE_PROPOSAL_ROLE = keccak256("VOTE_PROPOSAL_ROLE"); bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb; - bytes32 public constant CONTRIBUTOR_APP_ID = 0x8e50972b062e83b48dbb2a68d8a058f2a07227ca183c144dc974e6da3186d7e9; - bytes32 public constant CONTRIBUTION_APP_ID = 0x09f5274cba299b46c5be722ef672d10eef7a2ef980b612aef529d74fb9da7643; + // ensure alphabetic order + enum Apps { Contribution, Contributor, Proposal, Token } + bytes32[4] public appIds; struct Proposal { address creatorAccount; @@ -45,16 +46,17 @@ contract Proposal is AragonApp { event ProposalVoted(uint256 id, uint256 voterId, uint256 totalVotes); event ProposalExecuted(uint256 id, uint256 contributorId, uint256 amount); - function initialize() public onlyInit { + function initialize(bytes32[4] _appIds) public onlyInit { + appIds = _appIds; initialized(); } function getContributorContract() public view returns (address) { - return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, CONTRIBUTOR_APP_ID); + return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contributor)]); } function getContributionContract() public view returns (address) { - return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, CONTRIBUTION_APP_ID); + return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, appIds[uint8(Apps.Contribution)]); } function addProposal(uint contributorId, uint256 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_PROPOSAL_ROLE) { diff --git a/apps/token/arapp.json b/apps/token/arapp.json index 2197661..d3918ae 100644 --- a/apps/token/arapp.json +++ b/apps/token/arapp.json @@ -9,7 +9,7 @@ "environments": { "default": { "network": "development", - "appName": "kredits-token.open.aragonpm.eth" + "appName": "kredits-token.aragonpm.eth" }, "rinkeby": { "registry": "0x98df287b6c145399aaa709692c8d308357bc085d", diff --git a/apps/token/contracts/Token.sol b/apps/token/contracts/Token.sol index 128b763..2096d9c 100644 --- a/apps/token/contracts/Token.sol +++ b/apps/token/contracts/Token.sol @@ -6,9 +6,14 @@ import "./ERC20Token.sol"; contract Token is ERC20Token, AragonApp { bytes32 public constant MINT_TOKEN_ROLE = keccak256("MINT_TOKEN_ROLE"); + // ensure alphabetic order + enum Apps { Contribution, Contributor, Proposal, Token } + bytes32[4] public appIds; + event LogMint(address indexed recipient, uint256 amount, uint256 contributionId); - function initialize() public onlyInit { + function initialize(bytes32[4] _appIds) public onlyInit { + appIds = _appIds; initialized(); } diff --git a/contracts/KreditsKit.sol b/contracts/KreditsKit.sol index 7333f9a..9336e0d 100644 --- a/contracts/KreditsKit.sol +++ b/contracts/KreditsKit.sol @@ -32,17 +32,17 @@ contract KreditsKit is KitBase { acl.createPermission(this, dao, dao.APP_MANAGER_ROLE(), this); Contributor contributor = Contributor(_installApp(dao, appIds[uint8(Apps.Contributor)])); - contributor.initialize(root); + contributor.initialize(root, appIds); acl.createPermission(root, contributor, contributor.MANAGE_CONTRIBUTORS_ROLE(), root); Token token = Token(_installApp(dao, appIds[uint8(Apps.Token)])); - token.initialize(); + token.initialize(appIds); Contribution contribution = Contribution(_installApp(dao, appIds[uint8(Apps.Contribution)])); - contribution.initialize(); + contribution.initialize(appIds); Proposal proposal = Proposal(_installApp(dao, appIds[uint8(Apps.Proposal)])); - proposal.initialize(); + proposal.initialize(appIds); acl.createPermission(root, contribution, contribution.ADD_CONTRIBUTION_ROLE(), this); acl.grantPermission(proposal, contribution, contribution.ADD_CONTRIBUTION_ROLE()); diff --git a/lib/addresses/KreditsKit.json b/lib/addresses/KreditsKit.json index 28639dd..df24761 100644 --- a/lib/addresses/KreditsKit.json +++ b/lib/addresses/KreditsKit.json @@ -1 +1 @@ -{"4":"0xf4f3963718e5c2b426dd5c3ef0ab4b31ffb7a318","14945560":"0x6e0745b6b18d0233708554049eeaab0cb81c4ab0","42097210":"0x15d7adc7d6283d57d45017512567985e3a768b83","51657314":"0x053e2ebaf79eb0ccc5139a40b2a3ddca79409cdc","55632786":"0x4d97bd8efacf46b33c4438ed0b7b6aabfa2359fb","84923523":"0x48c2eac33521070509f9819a824a3d5686ba5ce8"} \ No newline at end of file +{"4":"0x948b9e124f1648d75862a5b7f2a72f58440cf242","14945560":"0x6e0745b6b18d0233708554049eeaab0cb81c4ab0","42097210":"0x15d7adc7d6283d57d45017512567985e3a768b83","51657314":"0x053e2ebaf79eb0ccc5139a40b2a3ddca79409cdc","55632786":"0x4d97bd8efacf46b33c4438ed0b7b6aabfa2359fb","74971415":"0xa35aacdfccac54d3d96e0d29050c773b251c2c83","84923523":"0x48c2eac33521070509f9819a824a3d5686ba5ce8","85406806":"0xe47c45da69763807897f446d087d84fe572b04c4"} \ No newline at end of file diff --git a/lib/addresses/dao.json b/lib/addresses/dao.json index 2da7b0c..ff2dc39 100644 --- a/lib/addresses/dao.json +++ b/lib/addresses/dao.json @@ -1 +1 @@ -{"4":"0x8b7c0bec9476ce08d9769a87d272b03b350712e2","14945560":"0x183af3950364390a266edff2a0e7c4c2f95c0691","23827572":"0xe4e0e7fe54d9189df29a80c07ab733fc9a212761","42097210":"0x183af3950364390a266edff2a0e7c4c2f95c0691","51657314":"0xad3a80686847d55d7b14b930bc6db53681ae1b1e","55632786":"0x4fde16c57ddf6d4870d5edd599074bb50dc96f88","65047207":"0xb67567175ac213f6f622b23d3d972d5b877c4813"} \ No newline at end of file +{"4":"0x8b7c0bec9476ce08d9769a87d272b03b350712e2","14945560":"0x183af3950364390a266edff2a0e7c4c2f95c0691","23827572":"0xe4e0e7fe54d9189df29a80c07ab733fc9a212761","42097210":"0x183af3950364390a266edff2a0e7c4c2f95c0691","51657314":"0xad3a80686847d55d7b14b930bc6db53681ae1b1e","55632786":"0x4fde16c57ddf6d4870d5edd599074bb50dc96f88","65047207":"0xb67567175ac213f6f622b23d3d972d5b877c4813","74971415":"0x183af3950364390a266edff2a0e7c4c2f95c0691","85406806":"0x192db9a1f757c7c2afd03cb5afe883b27d0d3937"} \ No newline at end of file diff --git a/lib/app_ids.json b/lib/app_ids.json new file mode 100644 index 0000000..dadb4dd --- /dev/null +++ b/lib/app_ids.json @@ -0,0 +1 @@ +{"74971415":{"Contribution":"0xe401b988b8af39119004de5c7691a60391d69d873b3120682a8c61306a4883ce","Contributor":"0x7829d33291d6e118d115ce321de9341894a2da120bd35505fc03b98f715c606d","Proposal":"0x15d03d435b24a74317868c24fda4646302076b59272241a122a3868eb5c745da","Token":"0x85b0f626cecde6188d11940904fedeb16a4d49b0e8c878b9d109b23d38062ca7"},"85406806":{"Contribution":"0xe401b988b8af39119004de5c7691a60391d69d873b3120682a8c61306a4883ce","Contributor":"0x7829d33291d6e118d115ce321de9341894a2da120bd35505fc03b98f715c606d","Proposal":"0x15d03d435b24a74317868c24fda4646302076b59272241a122a3868eb5c745da","Token":"0x85b0f626cecde6188d11940904fedeb16a4d49b0e8c878b9d109b23d38062ca7"}} \ No newline at end of file diff --git a/lib/contracts/kernel.js b/lib/contracts/kernel.js index b8c5f87..8f063ae 100644 --- a/lib/contracts/kernel.js +++ b/lib/contracts/kernel.js @@ -1,5 +1,5 @@ +const AppIds = require('../app_ids.json'); const Base = require('./base'); - KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb'; class Kernel extends Base { @@ -9,12 +9,7 @@ class Kernel extends Base { } appNamehash(appName) { - return { - Contributor: '0x8e50972b062e83b48dbb2a68d8a058f2a07227ca183c144dc974e6da3186d7e9', - Contribution: '0x09f5274cba299b46c5be722ef672d10eef7a2ef980b612aef529d74fb9da7643', - Token: '0x82c0e483537d703bb6f0fc799d2cc60d8f62edcb0f6d26d5571a92be8485b112', - Proposal: '0xb48bc8b4e539823f3be98d67f4130c07b5d29cc998993debcdea15c6faf4cf8a' - }[appName]; + return AppIds[this.contract.provider.chainId.toString()][appName]; } } diff --git a/scripts/deploy-kit.js b/scripts/deploy-kit.js index 35ed9f8..045ccdd 100644 --- a/scripts/deploy-kit.js +++ b/scripts/deploy-kit.js @@ -5,8 +5,7 @@ const path = require('path'); const argv = require('yargs').argv const namehash = require('eth-ens-namehash').hash -const libPath = path.join(__dirname, '..', 'lib'); -const addressesPath = path.join(libPath, 'addresses'); +const fileInject = require('./helpers/file_inject.js') const DAOFactory = artifacts.require('DAOFactory') const KreditsKit = artifacts.require('KreditsKit') @@ -48,16 +47,18 @@ module.exports = async function(callback) { const apps = fs.readdirSync('./apps') console.log(`Found apps: [${apps}].${apm}`) - const appIds = apps.map(app => namehash(`kredits-${app}.${apm}`)) + let appIds = {} + apps.sort().forEach((app) => { + let [first, ...rest] = app; + let contractName = `${first.toUpperCase()}${rest.join('')}` + appIds[contractName] = namehash(`kredits-${app}.${apm}`) + }) - KreditsKit.new(daoFactory.address, ensAddr, appIds).then((kreditsKit) => { + KreditsKit.new(daoFactory.address, ensAddr, Object.values(appIds)).then((kreditsKit) => { console.log(`Deployed KreditsKit at: ${kreditsKit.address}`); - let addresseFile = path.join(addressesPath, `KreditsKit.json`); - let addresses = JSON.parse(fs.readFileSync(addresseFile)); - - addresses[networkId] = kreditsKit.address; - fs.writeFileSync(addresseFile, JSON.stringify(addresses)); + fileInject(path.join(__dirname, '..', 'lib/addresses/KreditsKit.json'), networkId, kreditsKit.address); + fileInject(path.join(__dirname, '..', 'lib/app_ids.json'), networkId, appIds); callback(); }).catch((e) => { diff --git a/scripts/helpers/file_inject.js b/scripts/helpers/file_inject.js new file mode 100644 index 0000000..abc0c80 --- /dev/null +++ b/scripts/helpers/file_inject.js @@ -0,0 +1,8 @@ +// help, give me a better name + +const fs = require('fs'); +module.exports = function (file, networkId, data) { + let content = JSON.parse(fs.readFileSync(file)); + content[networkId] = data; + fs.writeFileSync(file, JSON.stringify(content)); +} diff --git a/scripts/helpers/networkid.js b/scripts/helpers/networkid.js new file mode 100644 index 0000000..92c12e7 --- /dev/null +++ b/scripts/helpers/networkid.js @@ -0,0 +1,11 @@ +module.exports = function(web3) { + return new Promise((resolve, reject) => { + web3.version.getNetwork((err, network) => { + if (err) { + reject(err); + } else { + resolve(network); + } + }) + }) +} diff --git a/scripts/new-dao.js b/scripts/new-dao.js index 4685ee0..ad37e39 100644 --- a/scripts/new-dao.js +++ b/scripts/new-dao.js @@ -1,7 +1,9 @@ const fs = require('fs'); const path = require('path'); -const libPath = path.join(__dirname, '..', 'lib'); -const addressesPath = path.join(libPath, 'addresses'); + +const fileInject = require('./helpers/file_inject.js'); + +const addressesPath = path.join(__dirname, '..', 'lib/addresses'); const KreditsKit = artifacts.require('KreditsKit') @@ -39,11 +41,7 @@ module.exports = async function(callback) { } const daoAddress = deployEvents[0].dao; - let addresseFile = path.join(addressesPath, `dao.json`); - let addresses = JSON.parse(fs.readFileSync(addresseFile)); - - addresses[networkId] = daoAddress; - fs.writeFileSync(addresseFile, JSON.stringify(addresses)); + fileInject(path.join(addressesPath, 'dao.json'), networkId, daoAddress) console.log(`\n\nCreated new DAO at: ${daoAddress}`)