From 94832d4d0774ecf3f53502e4f1a2aca43387e21a Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Thu, 28 Mar 2019 12:39:04 +0100 Subject: [PATCH] Add ACL contract wrapper this mainly allows us to check if an account has a certain role and thus if the account can call specific contract functions. At some point we might want to extend that to support the check if an account can call the function. For that we would need to have a mapping between function names and roles, which we have not right now. --- lib/abis/ACL.json | 1 + lib/contracts/acl.js | 13 +++++++++++++ lib/contracts/index.js | 3 ++- lib/contracts/kernel.js | 3 +++ lib/kredits.js | 10 ++++++++-- scripts/build-json.js | 3 ++- 6 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 lib/abis/ACL.json create mode 100644 lib/contracts/acl.js diff --git a/lib/abis/ACL.json b/lib/abis/ACL.json new file mode 100644 index 0000000..0e17161 --- /dev/null +++ b/lib/abis/ACL.json @@ -0,0 +1 @@ +[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"NO_PERMISSION","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_script","type":"bytes"}],"name":"getEVMScriptExecutor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getRecoveryVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CREATE_PERMISSIONS_ROLE","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"token","type":"address"}],"name":"allowRecoverability","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"appId","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitializationBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"}],"name":"transferToVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_sender","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"canPerform","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEVMScriptRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ANY_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EMPTY_PARAM_HASH","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"kernel","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPetrified","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BURN_ENTITY","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"allowed","type":"bool"}],"name":"SetPermission","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"entity","type":"address"},{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":false,"name":"paramsHash","type":"bytes32"}],"name":"SetPermissionParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"app","type":"address"},{"indexed":true,"name":"role","type":"bytes32"},{"indexed":true,"name":"manager","type":"address"}],"name":"ChangePermissionManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"executor","type":"address"},{"indexed":false,"name":"script","type":"bytes"},{"indexed":false,"name":"input","type":"bytes"},{"indexed":false,"name":"returnData","type":"bytes"}],"name":"ScriptResult","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"vault","type":"address"},{"indexed":true,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"RecoverToVault","type":"event"},{"constant":false,"inputs":[{"name":"_permissionsCreator","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_manager","type":"address"}],"name":"createPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"grantPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_params","type":"uint256[]"}],"name":"grantPermissionP","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"revokePermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newManager","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"setPermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"removePermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"createBurnedPermission","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"burnPermissionManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"getPermissionParamsLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_entity","type":"address"},{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"},{"name":"_index","type":"uint256"}],"name":"getPermissionParam","outputs":[{"name":"","type":"uint8"},{"name":"","type":"uint8"},{"name":"","type":"uint240"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_app","type":"address"},{"name":"_role","type":"bytes32"}],"name":"getPermissionManager","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"uint256[]"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"bytes"}],"name":"hasPermission","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_paramsHash","type":"bytes32"},{"name":"_who","type":"address"},{"name":"_where","type":"address"},{"name":"_what","type":"bytes32"},{"name":"_how","type":"uint256[]"}],"name":"evalParams","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}] \ No newline at end of file diff --git a/lib/contracts/acl.js b/lib/contracts/acl.js new file mode 100644 index 0000000..0b30500 --- /dev/null +++ b/lib/contracts/acl.js @@ -0,0 +1,13 @@ +const Base = require('./base'); +const EthersUtils = require('ethers').utils; + +class Acl extends Base { + + hasPermission(fromAddress, contractAddress, roleID, params = null) { + let roleHash = EthersUtils.keccak256(EthersUtils.toUtf8Bytes(roleID)); + console.log(roleHash) + return this.functions.hasPermission(fromAddress, contractAddress, roleHash, params); + } +} + +module.exports = Acl; diff --git a/lib/contracts/index.js b/lib/contracts/index.js index b5ba754..d28e44d 100644 --- a/lib/contracts/index.js +++ b/lib/contracts/index.js @@ -3,5 +3,6 @@ module.exports = { Contribution: require('./contribution'), Proposal: require('./proposal'), Token: require('./token'), - Kernel: require('./kernel') + Kernel: require('./kernel'), + Acl: require('./acl') }; diff --git a/lib/contracts/kernel.js b/lib/contracts/kernel.js index 8f063ae..bf01704 100644 --- a/lib/contracts/kernel.js +++ b/lib/contracts/kernel.js @@ -5,6 +5,9 @@ KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da118810 class Kernel extends Base { getApp(appName) { + if (appName === 'Acl') { + return this.functions.acl(); + } return this.functions.getApp(KERNEL_APP_ADDR_NAMESPACE, this.appNamehash(appName)); } diff --git a/lib/kredits.js b/lib/kredits.js index e0cf00c..692841e 100644 --- a/lib/kredits.js +++ b/lib/kredits.js @@ -8,13 +8,15 @@ const ABIS = { Contribution: require('./abis/Contribution.json'), Token: require('./abis/Token.json'), Proposal: require('./abis/Proposal.json'), - Kernel: require('./abis/Kernel.json') + Kernel: require('./abis/Kernel.json'), + Acl: require('./abis/ACL.json') }; const APP_CONTRACTS = [ 'Contributor', 'Contribution', 'Token', - 'Proposal' + 'Proposal', + 'Acl' ]; const DaoAddresses = require('./addresses/dao.json'); @@ -86,6 +88,10 @@ class Kredits { return this.contractFor('Contribution'); } + get Acl() { + return this.contractFor('Acl'); + } + // Should be private contractFor(name) { if (this.contracts[name]) { diff --git a/scripts/build-json.js b/scripts/build-json.js index 760f3fc..4235926 100644 --- a/scripts/build-json.js +++ b/scripts/build-json.js @@ -10,7 +10,8 @@ const files = [ 'Contribution', 'Kernel', 'Proposal', - 'Token' + 'Token', + 'ACL' ]; files.forEach((fileName) => {