Build on aragonOS #62

Merged
bumi merged 51 commits from aragonos into master 2019-04-02 19:36:36 +00:00
97 changed files with 85411 additions and 1155 deletions
Showing only changes of commit 6c569239de - Show all commits

2
.gitignore vendored
View File

@ -1,4 +1,6 @@
build
flattened_contracts
node_modules
**/node_modules
.ganache-db
.tm_properties

4
apps/contribution/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
build
.cache
dist

View File

@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test

162
apps/contribution/README.md Normal file
View File

@ -0,0 +1,162 @@
# Aragon React Boilerplate
> 🕵️ [Find more boilerplates using GitHub](https://github.com/search?q=topic:aragon-boilerplate) |
> ✨ [Official boilerplates](https://github.com/search?q=topic:aragon-boilerplate+org:aragon)
React boilerplate for Aragon applications.
This boilerplate also includes a fully working example app, complete with a background worker and a front-end in React (with Aragon UI).
## Usage
```sh
aragon init app.aragonpm.eth react
```
## Running your app
### Using HTTP
Running your app using HTTP will allow for a faster development process of your app's front-end, as it can be hot-reloaded without the need to execute `aragon run` every time a change is made.
- First start your app's development server running `npm run start:app`, and keep that process running. By default it will rebuild the app and reload the server when changes to the source are made.
- After that, you can run `npm run start:aragon:http` which will compile your app's contracts, publish the app locally and create a DAO. You will need to stop it and run it again after making changes to your smart contracts.
Changes to the app's background script (`app/script.js`) cannot be hot-reloaded, after making changes to the script, you will need to either restart the development server (`npm run start:app`) or rebuild the script `npm run build:script`.
### Using IPFS
Running your app using IPFS will mimic the production environment that will be used for running your app. `npm run start:aragon:ipfs` will run your app using IPFS. Whenever a change is made to any file in your front-end, a new version of the app needs to be published, so the command needs to be restarted.
## What's in the box?
### npm Scripts
- **start** or **start:aragon:ipfs**: Runs your app inside a DAO served from IPFS
- **start:aragon:http**: Runs your app inside a DAO served with HTTP (hot reloading)
- **start:app**: Starts a development server for your app
- **compile**: Compile the smart contracts
- **build**: Builds the front-end and background script
- **build:app**: Builds the front-end
- **build:script**: Builds the background script
- **test**: Runs tests for the contracts
- **publish:patch**: Release a patch version to aragonPM (only frontend/content changes allowed)
- **publish:minor**: Release a minor version to aragonPM (only frontend/content changes allowed)
- **publish:major**: Release a major version to aragonPM (frontend **and** contract changes)
- **versions**: Check the currently installed versions of the app
### Libraries
- [**@aragon/os**](https://github.com/aragon/aragonos): Aragon interfaces
- [**@aragon/client**](https://github.com/aragon/aragon.js/tree/master/packages/aragon-client): Wrapper for Aragon application RPC
- [**@aragon/ui**](https://github.com/aragon/aragon-ui): Aragon UI components (in React)
## Publish
This app has 3 environments defined in `arapp.json`:
| Environment | Network |
|--- |--- |
| default | localhost |
| staging | rinkeby |
| production | mainnet |
Prerequisites:
- ENS Registry address
Note: the `default` environment which points to `localhost` does not have an ENS Registry address specified because the `@aragon/cli` will default the value to `0xB9462EF3441346dBc6E49236Edbb0dF207db09B7` (the ENS Registry pre-deployed on the local development chain).
### Introduction to environments
Environments are defined in `arapp.json`, for example `staging` points to:
- an ENS registry (`0x314159265dd8dbb310642f98f50c066173c1259b`)
- an APM registry (`open.aragonpm.eth`)
- an APM repository (`app`)
- an Ethereum network (`rinkeby`)
- an Ethereum websockets provider (`wss://rinkeby.eth.aragon.network/ws` - to **read** from the blockchain)
The `rinkeby` network is further defined in `truffle.js`, and has:
- an Ethereum provider (to **write** to the blockchain):
- an address (`https://rinkeby.infura.io`)
- an Ethereum Account (`0xb4124cEB3451635DAcedd11767f004d8a28c6eE7`)
(which is the first account generated from the `DEFAULT_MNEMONIC` variable, to use a different account see [here](#Using-a-different-Ethereum-account))
### Major version: content + contract
Command:
```
npm run publish:major -- --environment staging
```
This will:
1. _build_ the app's frontend (the output lives in `dist`)
2. _compile_ the app's contract (the output lives in `build`)
3. publish the app to the **staging** environment.
Sample output:
```
> aragon apm publish major "--environment" "staging"
✔ Successfully published app.open.aragonpm.eth v1.0.0:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
Transaction hash: 0x3d752db29cc106e9ff98b260a90615921eb32471425a29ead8cbb830fb224d8
```
Note: the contract location is defined in `arapp.json` under `path`.
Note: you can also deploy a major version with only frontend changes by passing `--only-content`.
### Minor/patch version: content only
Command:
```
npm run publish:patch -- --environment staging
```
This will:
1. _build_ the app's frontend (which lives in `dist`)
2. publish the app to the **staging** environment.
Sample output:
```
✔ Successfully published app.open.aragonpm.eth v1.1.1:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
Transaction hash: 0x57864d8efd8d439008621b494b19a3e8f876a8a46b38475f9626802f0a1403c2
```
### Check published versions
Command:
```
npm run versions -- --environment staging
```
Sample output:
```
app.open.aragonpm.eth has 4 published versions
✔ 1.0.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
✔ 1.1.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmSwjUZFpv2c2e9fLoxtgFrAsAmBN4DyQGJp4RcqQcW3z3
✔ 1.1.1: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
✔ 2.0.0: 0x74CBbbC932d7C344FCd789Eba24BfD40e52980c9 ipfs:Qmadb3hzwLDKtb93fF367Vg1epkdsLZF4dhpapNYynjgZF
```
### Using a different Ethereum account
To deploy from a different account, you can:
- define a `~/.aragon/mnemonic.json` file
```
{
"mnemonic": "explain tackle mirror kit ..."
}
```
or
- define a `~/.aragon/${network_name}_key.json` file, for example: `~/.aragon/rinkeby_key.json`
```
{
"keys": [
"a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
]
}
```

View File

@ -0,0 +1,33 @@
{
"roles": [
{
"name": "Add contributions",
"id": "ADD_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Manage token contract",
"id": "MANAGE_TOKEN_CONTRACT_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "contribution.aragonpm.eth"
},
"staging": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "contribution.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "contribution.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Contribution.sol"
}

View File

@ -0,0 +1,139 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/IKernel.sol";
interface IToken {
//function mintFor(address contributorAccount, uint256 amount, uint256 proposalId) external;
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public;
}
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 = 0xe04a882e7a6adf5603207d545ea49aec17e6b936c4d9eae3d74dbe482264991a;
struct ContributionData {
address contributor;
uint256 amount;
bool claimed;
bytes32 hashDigest;
uint8 hashFunction;
uint8 hashSize;
string tokenMetadataURL;
uint claimAfterBlock;
bool exists;
}
string internal name_;
string internal symbol_;
address public tokenContract;
mapping(uint256 => address) contributionOwner;
mapping(address => uint256[]) ownedContributions;
mapping(uint256 => ContributionData) public contributions;
uint256 public contributionsCount;
uint256 public blocksToWait = 0;
event ContributionAdded(uint256 id, address indexed contributor, uint256 amount);
event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount);
function initialize() public onlyInit {
initialized();
}
function name() external view returns (string) {
return name_;
}
function symbol() external view returns (string) {
return symbol_;
}
function balanceOf(address owner) public view returns (uint256) {
require(owner != address(0));
return ownedContributions[owner].length;
}
function ownerOf(uint256 contributionId) public view returns (address) {
require(exists(contributionId));
return contributions[contributionId].contributor;
}
function tokenOfOwnerByIndex(address contributor, uint256 index) public view returns (uint256) {
return ownedContributions[contributor][index];
}
function tokenMetadata(uint256 contributionId) public view returns (string) {
return contributions[contributionId].tokenMetadataURL;
}
function getContribution(uint256 contributionId) public view returns (uint256 id, address contributor, uint256 amount, bool claimed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint claimAfterBlock, bool exists) {
id = contributionId;
ContributionData storage c = contributions[id];
return (
id,
c.contributor,
c.amount,
c.claimed,
c.hashDigest,
c.hashFunction,
c.hashSize,
c.claimAfterBlock,
c.exists
);
}
function add(uint256 amount, address contributorAccount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_CONTRIBUTION_ROLE) {
//require(canPerform(msg.sender, ADD_CONTRIBUTION_ROLE, new uint256[](0)), 'nope');
uint256 contributionId = contributionsCount + 1;
ContributionData storage c = contributions[contributionId];
c.exists = true;
c.amount = amount;
c.claimed = false;
c.contributor = contributorAccount;
c.hashDigest = hashDigest;
c.hashFunction = hashFunction;
c.hashSize = hashSize;
c.claimAfterBlock = block.number; // + blocksToWait;
contributionsCount++;
contributionOwner[contributionId] = contributorAccount;
ownedContributions[contributorAccount].push(contributionId);
emit ContributionAdded(contributionId, contributorAccount, amount);
}
function claim(uint256 contributionId) public isInitialized {
ContributionData storage c = contributions[contributionId];
require(c.exists, 'NOT_FOUND');
require(!c.claimed, 'ALREADY_CLAIMED');
require(block.number > c.claimAfterBlock, 'NOT_CLAIMABLE');
//c.claimed = true;
//IToken(getTokenContract()).mintFor(c.contributor, c.amount, contributionId); // somehow this does not work
bytes4 sig = bytes4(keccak256("mintFor()"));
address token = getTokenContract();
//IToken token = IToken(getTokenContract());
//token.call(sig);
//IToken(token).mintFor(c.contributor, c.amount, contributionId);
IToken(token).mintFor(c.contributor, c.amount, contributionId);
//emit ContributionClaimed(contributionId, c.contributor, c.amount);
}
function getTokenContract() public view returns (address) {
return 0x8779fc70eeea01d00efa9044c29d3c930fdb874a;
//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;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.17;
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
@ -8,15 +8,15 @@ contract Migrations {
if (msg.sender == owner) _;
}
function Migrations() public {
function Migrations() {
owner = msg.sender;
}
function setCompleted(uint completed) public restricted {
function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) public restricted {
function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}

View File

@ -0,0 +1,4 @@
{
"name": "Contribution",
"description": "Kredits contribution app"
}

View File

@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}

View File

@ -0,0 +1,5 @@
var Contribution = artifacts.require('Contribution.sol')
module.exports = function (deployer) {
deployer.deploy(Contribution)
}

21093
apps/contribution/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
{
"name": "app-name",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.1.0",
"@aragon/cli": "^5.5.0"
},
"devDependencies": {
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "npm run sync-assets && npm run build:script -- --no-minify && parcel serve app/index.html -p 8001 --out-dir dist/ --no-cache",
"test": "aragon contracts test",
"compile": "aragon contracts compile",
"sync-assets": "copy-aragon-ui-assets -n aragon-ui ./dist",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions"
},
"keywords": []
}

View File

@ -0,0 +1,5 @@
const CounterApp = artifacts.require('Contribution.sol')
contract('Contribution', (accounts) => {
it('should be tested')
})

View File

@ -0,0 +1,63 @@
/**
* https://github.com/aragon/aragonOS/blob/v4.0.0/truffle-config.js
*/
const homedir = require('homedir')
const path = require('path')
const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')
const DEFAULT_MNEMONIC = 'explain tackle mirror kit van hammer degree position ginger unfair soup bonus'
const defaultRPC = (network) =>
`https://${network}.infura.io`
const configFilePath = (filename) =>
path.join(homedir(), `.aragon/${filename}`)
const mnemonic = () => {
try {
return require(configFilePath('mnemonic.json')).mnemonic
} catch (e) {
return DEFAULT_MNEMONIC
}
}
const settingsForNetwork = (network) => {
try {
return require(configFilePath(`${network}_key.json`))
} catch (e) {
return { }
}
}
// Lazily loaded provider
const providerForNetwork = (network) => (
() => {
let { rpc, keys } = settingsForNetwork(network)
rpc = rpc || defaultRPC(network)
if (!keys || keys.length == 0) {
return new HDWalletProvider(mnemonic(), rpc)
}
return new HDWalletProviderPrivkey(keys, rpc)
}
)
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*'
},
mainnet: {
network_id: 1,
provider: providerForNetwork('mainnet')
},
rinkeby: {
network_id: 4,
provider: providerForNetwork('rinkeby')
}
}
}

4
apps/contributor/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
build
.cache
dist

View File

@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test

162
apps/contributor/README.md Normal file
View File

@ -0,0 +1,162 @@
# Aragon React Boilerplate
> 🕵️ [Find more boilerplates using GitHub](https://github.com/search?q=topic:aragon-boilerplate) |
> ✨ [Official boilerplates](https://github.com/search?q=topic:aragon-boilerplate+org:aragon)
React boilerplate for Aragon applications.
This boilerplate also includes a fully working example app, complete with a background worker and a front-end in React (with Aragon UI).
## Usage
```sh
aragon init app.aragonpm.eth react
```
## Running your app
### Using HTTP
Running your app using HTTP will allow for a faster development process of your app's front-end, as it can be hot-reloaded without the need to execute `aragon run` every time a change is made.
- First start your app's development server running `npm run start:app`, and keep that process running. By default it will rebuild the app and reload the server when changes to the source are made.
- After that, you can run `npm run start:aragon:http` which will compile your app's contracts, publish the app locally and create a DAO. You will need to stop it and run it again after making changes to your smart contracts.
Changes to the app's background script (`app/script.js`) cannot be hot-reloaded, after making changes to the script, you will need to either restart the development server (`npm run start:app`) or rebuild the script `npm run build:script`.
### Using IPFS
Running your app using IPFS will mimic the production environment that will be used for running your app. `npm run start:aragon:ipfs` will run your app using IPFS. Whenever a change is made to any file in your front-end, a new version of the app needs to be published, so the command needs to be restarted.
## What's in the box?
### npm Scripts
- **start** or **start:aragon:ipfs**: Runs your app inside a DAO served from IPFS
- **start:aragon:http**: Runs your app inside a DAO served with HTTP (hot reloading)
- **start:app**: Starts a development server for your app
- **compile**: Compile the smart contracts
- **build**: Builds the front-end and background script
- **build:app**: Builds the front-end
- **build:script**: Builds the background script
- **test**: Runs tests for the contracts
- **publish:patch**: Release a patch version to aragonPM (only frontend/content changes allowed)
- **publish:minor**: Release a minor version to aragonPM (only frontend/content changes allowed)
- **publish:major**: Release a major version to aragonPM (frontend **and** contract changes)
- **versions**: Check the currently installed versions of the app
### Libraries
- [**@aragon/os**](https://github.com/aragon/aragonos): Aragon interfaces
- [**@aragon/client**](https://github.com/aragon/aragon.js/tree/master/packages/aragon-client): Wrapper for Aragon application RPC
- [**@aragon/ui**](https://github.com/aragon/aragon-ui): Aragon UI components (in React)
## Publish
This app has 3 environments defined in `arapp.json`:
| Environment | Network |
|--- |--- |
| default | localhost |
| staging | rinkeby |
| production | mainnet |
Prerequisites:
- ENS Registry address
Note: the `default` environment which points to `localhost` does not have an ENS Registry address specified because the `@aragon/cli` will default the value to `0xB9462EF3441346dBc6E49236Edbb0dF207db09B7` (the ENS Registry pre-deployed on the local development chain).
### Introduction to environments
Environments are defined in `arapp.json`, for example `staging` points to:
- an ENS registry (`0x314159265dd8dbb310642f98f50c066173c1259b`)
- an APM registry (`open.aragonpm.eth`)
- an APM repository (`app`)
- an Ethereum network (`rinkeby`)
- an Ethereum websockets provider (`wss://rinkeby.eth.aragon.network/ws` - to **read** from the blockchain)
The `rinkeby` network is further defined in `truffle.js`, and has:
- an Ethereum provider (to **write** to the blockchain):
- an address (`https://rinkeby.infura.io`)
- an Ethereum Account (`0xb4124cEB3451635DAcedd11767f004d8a28c6eE7`)
(which is the first account generated from the `DEFAULT_MNEMONIC` variable, to use a different account see [here](#Using-a-different-Ethereum-account))
### Major version: content + contract
Command:
```
npm run publish:major -- --environment staging
```
This will:
1. _build_ the app's frontend (the output lives in `dist`)
2. _compile_ the app's contract (the output lives in `build`)
3. publish the app to the **staging** environment.
Sample output:
```
> aragon apm publish major "--environment" "staging"
✔ Successfully published app.open.aragonpm.eth v1.0.0:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
Transaction hash: 0x3d752db29cc106e9ff98b260a90615921eb32471425a29ead8cbb830fb224d8
```
Note: the contract location is defined in `arapp.json` under `path`.
Note: you can also deploy a major version with only frontend changes by passing `--only-content`.
### Minor/patch version: content only
Command:
```
npm run publish:patch -- --environment staging
```
This will:
1. _build_ the app's frontend (which lives in `dist`)
2. publish the app to the **staging** environment.
Sample output:
```
✔ Successfully published app.open.aragonpm.eth v1.1.1:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
Transaction hash: 0x57864d8efd8d439008621b494b19a3e8f876a8a46b38475f9626802f0a1403c2
```
### Check published versions
Command:
```
npm run versions -- --environment staging
```
Sample output:
```
app.open.aragonpm.eth has 4 published versions
✔ 1.0.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
✔ 1.1.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmSwjUZFpv2c2e9fLoxtgFrAsAmBN4DyQGJp4RcqQcW3z3
✔ 1.1.1: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
✔ 2.0.0: 0x74CBbbC932d7C344FCd789Eba24BfD40e52980c9 ipfs:Qmadb3hzwLDKtb93fF367Vg1epkdsLZF4dhpapNYynjgZF
```
### Using a different Ethereum account
To deploy from a different account, you can:
- define a `~/.aragon/mnemonic.json` file
```
{
"mnemonic": "explain tackle mirror kit ..."
}
```
or
- define a `~/.aragon/${network_name}_key.json` file, for example: `~/.aragon/rinkeby_key.json`
```
{
"keys": [
"a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
]
}
```

View File

@ -0,0 +1,28 @@
{
"roles": [
{
"name": "Manage contributors",
"id": "MANAGE_CONTRIBUTORS_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "contributor.aragonpm.eth"
},
"staging": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "contributor.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "contributor.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Contributor.sol"
}

View File

@ -1,10 +1,9 @@
pragma solidity ^0.4.18;
pragma solidity ^0.4.24;
// import basic ERC20 details to be able to call balanceOf
import 'zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol';
import './upgradeable/Upgradeable.sol';
import "@aragon/os/contracts/apps/AragonApp.sol";
contract Contributors is Upgradeable {
contract Contributor is AragonApp {
bytes32 public constant MANAGE_CONTRIBUTORS_ROLE = keccak256("MANAGE_CONTRIBUTORS_ROLE");
struct Contributor {
address account;
@ -23,20 +22,16 @@ contract Contributors is Upgradeable {
event ContributorAccountUpdated(uint id, address oldAccount, address newAccount);
event ContributorAdded(uint id, address account);
modifier onlyCoreOrOperator() {
require(msg.sender == registry.getProxyFor('Operator') || addressIsCore(msg.sender));
_;
}
function initialize(address sender) public payable {
require(msg.sender == address(registry));
uint _id = 1;
function initialize(address root) public onlyInit {
uint _id = contributorsCount + 1;
Contributor storage c = contributors[_id];
c.exists = true;
c.isCore = true;
c.account = sender;
contributorIds[sender] = _id;
c.account = root;
contributorIds[root] = _id;
contributorsCount += 1;
initialized();
}
function coreContributorsCount() view public returns (uint) {
@ -49,14 +44,14 @@ contract Contributors is Upgradeable {
return count;
}
function updateContributorAccount(uint id, address oldAccount, address newAccount) public onlyCoreOrOperator {
function updateContributorAccount(uint id, address oldAccount, address newAccount) public auth(MANAGE_CONTRIBUTORS_ROLE) {
contributorIds[oldAccount] = 0;
contributorIds[newAccount] = id;
contributors[id].account = newAccount;
ContributorAccountUpdated(id, oldAccount, newAccount);
}
function updateContributorIpfsHash(uint id, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public onlyCoreOrOperator {
function updateContributorIpfsHash(uint id, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
Contributor storage c = contributors[id];
bytes32 oldIpfsHash = c.ipfsHash;
c.ipfsHash = ipfsHash;
@ -66,7 +61,7 @@ contract Contributors is Upgradeable {
ContributorProfileUpdated(id, oldIpfsHash, c.ipfsHash);
}
function addContributor(address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore) public onlyCoreOrOperator {
function addContributor(address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore) public isInitialized auth(MANAGE_CONTRIBUTORS_ROLE) {
require(!addressExists(account));
uint _id = contributorsCount + 1;
assert(!contributors[_id].exists); // this can not be acually
@ -80,7 +75,7 @@ contract Contributors is Upgradeable {
contributorIds[account] = _id;
contributorsCount += 1;
ContributorAdded(_id, account);
emit ContributorAdded(_id, account);
}
function isCore(uint id) view public returns (bool) {
@ -112,7 +107,7 @@ contract Contributors is Upgradeable {
return contributors[id];
}
function getContributorById(uint _id) public view returns (uint id, address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore, uint balance, bool exists ) {
function getContributorById(uint _id) public view returns (uint id, address account, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, bool isCore, bool exists ) {
id = _id;
Contributor storage c = contributors[_id];
account = c.account;
@ -121,8 +116,9 @@ contract Contributors is Upgradeable {
hashSize = c.hashSize;
isCore = c.isCore;
exists = c.exists;
ERC20Basic token = ERC20Basic(registry.getProxyFor('Token'));
balance = token.balanceOf(account);
}
function canPerform(address _who, address _where, bytes32 _what, uint256[] _how) public view returns (bool) {
return addressExists(_who);
}
}

View File

@ -0,0 +1,23 @@
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migrations() {
owner = msg.sender;
}
function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

View File

@ -0,0 +1,4 @@
{
"name": "Contributor",
"description": "Kredits Contributor app"
}

View File

@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}

View File

@ -0,0 +1,5 @@
var Contributor = artifacts.require('Contributor.sol')
module.exports = function (deployer) {
deployer.deploy(Contributor)
}

13527
apps/contributor/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
{
"name": "kredits-contributor",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.1.0",
"@aragon/cli": "^5.5.0"
},
"devDependencies": {},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"test": "aragon contracts test",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions"
},
"keywords": []
}

View File

@ -0,0 +1,5 @@
const CounterApp = artifacts.require('CounterApp.sol')
contract('CounterApp', (accounts) => {
it('should be tested')
})

View File

@ -0,0 +1,63 @@
/**
* https://github.com/aragon/aragonOS/blob/v4.0.0/truffle-config.js
*/
const homedir = require('homedir')
const path = require('path')
const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')
const DEFAULT_MNEMONIC = 'explain tackle mirror kit van hammer degree position ginger unfair soup bonus'
const defaultRPC = (network) =>
`https://${network}.infura.io`
const configFilePath = (filename) =>
path.join(homedir(), `.aragon/${filename}`)
const mnemonic = () => {
try {
return require(configFilePath('mnemonic.json')).mnemonic
} catch (e) {
return DEFAULT_MNEMONIC
}
}
const settingsForNetwork = (network) => {
try {
return require(configFilePath(`${network}_key.json`))
} catch (e) {
return { }
}
}
// Lazily loaded provider
const providerForNetwork = (network) => (
() => {
let { rpc, keys } = settingsForNetwork(network)
rpc = rpc || defaultRPC(network)
if (!keys || keys.length == 0) {
return new HDWalletProvider(mnemonic(), rpc)
}
return new HDWalletProviderPrivkey(keys, rpc)
}
)
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*'
},
mainnet: {
network_id: 1,
provider: providerForNetwork('mainnet')
},
rinkeby: {
network_id: 4,
provider: providerForNetwork('rinkeby')
}
}
}

162
apps/proposal/README.md Normal file
View File

@ -0,0 +1,162 @@
# Aragon React Boilerplate
> 🕵️ [Find more boilerplates using GitHub](https://github.com/search?q=topic:aragon-boilerplate) |
> ✨ [Official boilerplates](https://github.com/search?q=topic:aragon-boilerplate+org:aragon)
React boilerplate for Aragon applications.
This boilerplate also includes a fully working example app, complete with a background worker and a front-end in React (with Aragon UI).
## Usage
```sh
aragon init app.aragonpm.eth react
```
## Running your app
### Using HTTP
Running your app using HTTP will allow for a faster development process of your app's front-end, as it can be hot-reloaded without the need to execute `aragon run` every time a change is made.
- First start your app's development server running `npm run start:app`, and keep that process running. By default it will rebuild the app and reload the server when changes to the source are made.
- After that, you can run `npm run start:aragon:http` which will compile your app's contracts, publish the app locally and create a DAO. You will need to stop it and run it again after making changes to your smart contracts.
Changes to the app's background script (`app/script.js`) cannot be hot-reloaded, after making changes to the script, you will need to either restart the development server (`npm run start:app`) or rebuild the script `npm run build:script`.
### Using IPFS
Running your app using IPFS will mimic the production environment that will be used for running your app. `npm run start:aragon:ipfs` will run your app using IPFS. Whenever a change is made to any file in your front-end, a new version of the app needs to be published, so the command needs to be restarted.
## What's in the box?
### npm Scripts
- **start** or **start:aragon:ipfs**: Runs your app inside a DAO served from IPFS
- **start:aragon:http**: Runs your app inside a DAO served with HTTP (hot reloading)
- **start:app**: Starts a development server for your app
- **compile**: Compile the smart contracts
- **build**: Builds the front-end and background script
- **build:app**: Builds the front-end
- **build:script**: Builds the background script
- **test**: Runs tests for the contracts
- **publish:patch**: Release a patch version to aragonPM (only frontend/content changes allowed)
- **publish:minor**: Release a minor version to aragonPM (only frontend/content changes allowed)
- **publish:major**: Release a major version to aragonPM (frontend **and** contract changes)
- **versions**: Check the currently installed versions of the app
### Libraries
- [**@aragon/os**](https://github.com/aragon/aragonos): Aragon interfaces
- [**@aragon/client**](https://github.com/aragon/aragon.js/tree/master/packages/aragon-client): Wrapper for Aragon application RPC
- [**@aragon/ui**](https://github.com/aragon/aragon-ui): Aragon UI components (in React)
## Publish
This app has 3 environments defined in `arapp.json`:
| Environment | Network |
|--- |--- |
| default | localhost |
| staging | rinkeby |
| production | mainnet |
Prerequisites:
- ENS Registry address
Note: the `default` environment which points to `localhost` does not have an ENS Registry address specified because the `@aragon/cli` will default the value to `0xB9462EF3441346dBc6E49236Edbb0dF207db09B7` (the ENS Registry pre-deployed on the local development chain).
### Introduction to environments
Environments are defined in `arapp.json`, for example `staging` points to:
- an ENS registry (`0x314159265dd8dbb310642f98f50c066173c1259b`)
- an APM registry (`open.aragonpm.eth`)
- an APM repository (`app`)
- an Ethereum network (`rinkeby`)
- an Ethereum websockets provider (`wss://rinkeby.eth.aragon.network/ws` - to **read** from the blockchain)
The `rinkeby` network is further defined in `truffle.js`, and has:
- an Ethereum provider (to **write** to the blockchain):
- an address (`https://rinkeby.infura.io`)
- an Ethereum Account (`0xb4124cEB3451635DAcedd11767f004d8a28c6eE7`)
(which is the first account generated from the `DEFAULT_MNEMONIC` variable, to use a different account see [here](#Using-a-different-Ethereum-account))
### Major version: content + contract
Command:
```
npm run publish:major -- --environment staging
```
This will:
1. _build_ the app's frontend (the output lives in `dist`)
2. _compile_ the app's contract (the output lives in `build`)
3. publish the app to the **staging** environment.
Sample output:
```
> aragon apm publish major "--environment" "staging"
✔ Successfully published app.open.aragonpm.eth v1.0.0:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
Transaction hash: 0x3d752db29cc106e9ff98b260a90615921eb32471425a29ead8cbb830fb224d8
```
Note: the contract location is defined in `arapp.json` under `path`.
Note: you can also deploy a major version with only frontend changes by passing `--only-content`.
### Minor/patch version: content only
Command:
```
npm run publish:patch -- --environment staging
```
This will:
1. _build_ the app's frontend (which lives in `dist`)
2. publish the app to the **staging** environment.
Sample output:
```
✔ Successfully published app.open.aragonpm.eth v1.1.1:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
Transaction hash: 0x57864d8efd8d439008621b494b19a3e8f876a8a46b38475f9626802f0a1403c2
```
### Check published versions
Command:
```
npm run versions -- --environment staging
```
Sample output:
```
app.open.aragonpm.eth has 4 published versions
✔ 1.0.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
✔ 1.1.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmSwjUZFpv2c2e9fLoxtgFrAsAmBN4DyQGJp4RcqQcW3z3
✔ 1.1.1: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
✔ 2.0.0: 0x74CBbbC932d7C344FCd789Eba24BfD40e52980c9 ipfs:Qmadb3hzwLDKtb93fF367Vg1epkdsLZF4dhpapNYynjgZF
```
### Using a different Ethereum account
To deploy from a different account, you can:
- define a `~/.aragon/mnemonic.json` file
```
{
"mnemonic": "explain tackle mirror kit ..."
}
```
or
- define a `~/.aragon/${network_name}_key.json` file, for example: `~/.aragon/rinkeby_key.json`
```
{
"keys": [
"a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
]
}
```

43
apps/proposal/arapp.json Normal file
View File

@ -0,0 +1,43 @@
{
"roles": [
{
"name": "Add proposal",
"id": "ADD_PROPOSAL_ROLE",
"params": []
},
{
"name": "Vote proposals",
"id": "VOTE_PROPOSAL_ROLE",
"params": []
},
{
"name": "Add contribution",
"id": "ADD_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Manage contributors",
"id": "MANAGE_CONTRIBUTORS_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "proposal.aragonpm.eth"
},
"staging": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "proposal.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "proposal.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Proposal.sol"
}

View File

@ -0,0 +1,132 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/IKernel.sol";
interface IContributor {
function getContributorAddressById(uint256 contributorId) public view returns (address);
function getContributorIdByAddress(address contributorAccount) public view returns (uint256);
function exists(uint256 contributorId) public view returns (bool);
}
interface IContribution {
function add(uint256 amount, address contributor, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public;
}
contract Proposal is AragonApp {
bytes32 public constant ADD_PROPOSAL_ROLE = keccak256("ADD_PROPOSAL_ROLE");
bytes32 public constant VOTE_PROPOSAL_ROLE = keccak256("VOTE_PROPOSAL_ROLE");
bytes32 public constant KERNEL_APP_ADDR_NAMESPACE = 0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb;
bytes32 public constant CONTRIBUTOR_APP_ID = 0xe9140f1e39c8a1d04167c3b710688a3eecea2976f34735c8eb98956f4764635b;
bytes32 public constant CONTRIBUTION_APP_ID = 0x7fcf91283b719b30c2fa954ff0da021e1b91aed09d7aa13df5e8078a4a1007eb;
struct Proposal {
address creatorAccount;
uint contributorId;
uint votesCount;
uint votesNeeded;
uint256 amount;
bool executed;
bytes32 hashDigest;
uint8 hashFunction;
uint8 hashSize;
uint256[] voterIds;
mapping (uint256 => bool) votes;
bool exists;
}
mapping(uint256 => Proposal) public proposals;
uint256 public proposalsCount;
event ProposalCreated(uint256 id, address creatorAccount, uint256 contributorId, uint256 amount);
event ProposalVoted(uint256 id, uint256 voterId, uint256 totalVotes);
event ProposalExecuted(uint256 id, uint256 contributorId, uint256 amount);
function initialize() public onlyInit {
initialized();
}
function getContributorContract() public view returns (address) {
return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, CONTRIBUTOR_APP_ID);
}
function getContributionContract() public view returns (address) {
return IKernel(kernel()).getApp(KERNEL_APP_ADDR_NAMESPACE, CONTRIBUTION_APP_ID);
}
function addProposal(uint contributorId, uint256 amount, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize) public isInitialized auth(ADD_PROPOSAL_ROLE) {
require(IContributor(getContributorContract()).exists(contributorId), 'CONTRIBUTOR_NOT_FOUND');
uint256 proposalId = proposalsCount + 1;
uint256 _votesNeeded = 1; //contributorsContract().coreContributorsCount() / 100 * 75;
Proposal storage p = proposals[proposalId];
p.creatorAccount = msg.sender;
p.contributorId = contributorId;
p.amount = amount;
p.hashDigest = hashDigest;
p.hashFunction = hashFunction;
p.hashSize = hashSize;
p.votesCount = 0;
p.votesNeeded = _votesNeeded;
p.exists = true;
proposalsCount++;
emit ProposalCreated(proposalId, msg.sender, p.contributorId, p.amount);
}
function getProposal(uint proposalId) public view returns (uint256 id, address creatorAccount, uint256 contributorId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) {
id = proposalId;
Proposal storage p = proposals[id];
return (
id,
p.creatorAccount,
p.contributorId,
p.votesCount,
p.votesNeeded,
p.amount,
p.executed,
p.hashDigest,
p.hashFunction,
p.hashSize,
p.voterIds,
p.exists
);
}
function vote(uint256 proposalId) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
Proposal storage p = proposals[proposalId];
require(!p.executed, 'ALREADY_EXECUTED');
uint256 voterId = IContributor(getContributorContract()).getContributorIdByAddress(msg.sender);
require(p.votes[voterId] != true, 'ALREADY_VOTED');
p.voterIds.push(voterId);
p.votes[voterId] = true;
p.votesCount++;
if (p.votesCount >= p.votesNeeded) {
executeProposal(proposalId);
}
emit ProposalVoted(proposalId, voterId, p.votesCount);
}
function batchVote(uint256[] _proposalIds) public isInitialized auth(VOTE_PROPOSAL_ROLE) {
for (uint256 i = 0; i < _proposalIds.length; i++) {
vote(_proposalIds[i]);
}
}
function executeProposal(uint proposalId) private {
Proposal storage p = proposals[proposalId];
require(!p.executed, 'ALREADY_EXECUTED');
require(p.votesCount >= p.votesNeeded, 'MISSING_VOTES');
address contributorAccount = IContributor(getContributorContract()).getContributorAddressById(p.contributorId);
IContribution(getContributionContract()).add(p.amount, contributorAccount, p.hashDigest, p.hashFunction, p.hashSize);
p.executed = true;
emit ProposalExecuted(proposalId, p.contributorId, p.amount);
}
}

View File

@ -0,0 +1,4 @@
{
"name": "Proposal",
"description": "Kredits proposal app"
}

View File

@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}

21093
apps/proposal/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
{
"name": "kredits-proposal",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.1.0",
"@aragon/cli": "^5.5.0"
},
"devDependencies": {
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"test": "aragon contracts test",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions"
},
"keywords": []
}

63
apps/proposal/truffle.js Normal file
View File

@ -0,0 +1,63 @@
/**
* https://github.com/aragon/aragonOS/blob/v4.0.0/truffle-config.js
*/
const homedir = require('homedir')
const path = require('path')
const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')
const DEFAULT_MNEMONIC = 'explain tackle mirror kit van hammer degree position ginger unfair soup bonus'
const defaultRPC = (network) =>
`https://${network}.infura.io`
const configFilePath = (filename) =>
path.join(homedir(), `.aragon/${filename}`)
const mnemonic = () => {
try {
return require(configFilePath('mnemonic.json')).mnemonic
} catch (e) {
return DEFAULT_MNEMONIC
}
}
const settingsForNetwork = (network) => {
try {
return require(configFilePath(`${network}_key.json`))
} catch (e) {
return { }
}
}
// Lazily loaded provider
const providerForNetwork = (network) => (
() => {
let { rpc, keys } = settingsForNetwork(network)
rpc = rpc || defaultRPC(network)
if (!keys || keys.length == 0) {
return new HDWalletProvider(mnemonic(), rpc)
}
return new HDWalletProviderPrivkey(keys, rpc)
}
)
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*'
},
mainnet: {
network_id: 1,
provider: providerForNetwork('mainnet')
},
rinkeby: {
network_id: 4,
provider: providerForNetwork('rinkeby')
}
}
}

4
apps/token/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
node_modules
build
.cache
dist

14
apps/token/.ipfsignore Normal file
View File

@ -0,0 +1,14 @@
# Git files
.gitignore
# Build files
.cache
node_modules
build
# Lock files
package-lock.json
yarn.lock
# Others
test

162
apps/token/README.md Normal file
View File

@ -0,0 +1,162 @@
# Aragon React Boilerplate
> 🕵️ [Find more boilerplates using GitHub](https://github.com/search?q=topic:aragon-boilerplate) |
> ✨ [Official boilerplates](https://github.com/search?q=topic:aragon-boilerplate+org:aragon)
React boilerplate for Aragon applications.
This boilerplate also includes a fully working example app, complete with a background worker and a front-end in React (with Aragon UI).
## Usage
```sh
aragon init app.aragonpm.eth react
```
## Running your app
### Using HTTP
Running your app using HTTP will allow for a faster development process of your app's front-end, as it can be hot-reloaded without the need to execute `aragon run` every time a change is made.
- First start your app's development server running `npm run start:app`, and keep that process running. By default it will rebuild the app and reload the server when changes to the source are made.
- After that, you can run `npm run start:aragon:http` which will compile your app's contracts, publish the app locally and create a DAO. You will need to stop it and run it again after making changes to your smart contracts.
Changes to the app's background script (`app/script.js`) cannot be hot-reloaded, after making changes to the script, you will need to either restart the development server (`npm run start:app`) or rebuild the script `npm run build:script`.
### Using IPFS
Running your app using IPFS will mimic the production environment that will be used for running your app. `npm run start:aragon:ipfs` will run your app using IPFS. Whenever a change is made to any file in your front-end, a new version of the app needs to be published, so the command needs to be restarted.
## What's in the box?
### npm Scripts
- **start** or **start:aragon:ipfs**: Runs your app inside a DAO served from IPFS
- **start:aragon:http**: Runs your app inside a DAO served with HTTP (hot reloading)
- **start:app**: Starts a development server for your app
- **compile**: Compile the smart contracts
- **build**: Builds the front-end and background script
- **build:app**: Builds the front-end
- **build:script**: Builds the background script
- **test**: Runs tests for the contracts
- **publish:patch**: Release a patch version to aragonPM (only frontend/content changes allowed)
- **publish:minor**: Release a minor version to aragonPM (only frontend/content changes allowed)
- **publish:major**: Release a major version to aragonPM (frontend **and** contract changes)
- **versions**: Check the currently installed versions of the app
### Libraries
- [**@aragon/os**](https://github.com/aragon/aragonos): Aragon interfaces
- [**@aragon/client**](https://github.com/aragon/aragon.js/tree/master/packages/aragon-client): Wrapper for Aragon application RPC
- [**@aragon/ui**](https://github.com/aragon/aragon-ui): Aragon UI components (in React)
## Publish
This app has 3 environments defined in `arapp.json`:
| Environment | Network |
|--- |--- |
| default | localhost |
| staging | rinkeby |
| production | mainnet |
Prerequisites:
- ENS Registry address
Note: the `default` environment which points to `localhost` does not have an ENS Registry address specified because the `@aragon/cli` will default the value to `0xB9462EF3441346dBc6E49236Edbb0dF207db09B7` (the ENS Registry pre-deployed on the local development chain).
### Introduction to environments
Environments are defined in `arapp.json`, for example `staging` points to:
- an ENS registry (`0x314159265dd8dbb310642f98f50c066173c1259b`)
- an APM registry (`open.aragonpm.eth`)
- an APM repository (`app`)
- an Ethereum network (`rinkeby`)
- an Ethereum websockets provider (`wss://rinkeby.eth.aragon.network/ws` - to **read** from the blockchain)
The `rinkeby` network is further defined in `truffle.js`, and has:
- an Ethereum provider (to **write** to the blockchain):
- an address (`https://rinkeby.infura.io`)
- an Ethereum Account (`0xb4124cEB3451635DAcedd11767f004d8a28c6eE7`)
(which is the first account generated from the `DEFAULT_MNEMONIC` variable, to use a different account see [here](#Using-a-different-Ethereum-account))
### Major version: content + contract
Command:
```
npm run publish:major -- --environment staging
```
This will:
1. _build_ the app's frontend (the output lives in `dist`)
2. _compile_ the app's contract (the output lives in `build`)
3. publish the app to the **staging** environment.
Sample output:
```
> aragon apm publish major "--environment" "staging"
✔ Successfully published app.open.aragonpm.eth v1.0.0:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
Transaction hash: 0x3d752db29cc106e9ff98b260a90615921eb32471425a29ead8cbb830fb224d8
```
Note: the contract location is defined in `arapp.json` under `path`.
Note: you can also deploy a major version with only frontend changes by passing `--only-content`.
### Minor/patch version: content only
Command:
```
npm run publish:patch -- --environment staging
```
This will:
1. _build_ the app's frontend (which lives in `dist`)
2. publish the app to the **staging** environment.
Sample output:
```
✔ Successfully published app.open.aragonpm.eth v1.1.1:
Contract address: 0xE636bcA5B95e94F749F63E322a04DB59362299F1
Content (ipfs): QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
Transaction hash: 0x57864d8efd8d439008621b494b19a3e8f876a8a46b38475f9626802f0a1403c2
```
### Check published versions
Command:
```
npm run versions -- --environment staging
```
Sample output:
```
app.open.aragonpm.eth has 4 published versions
✔ 1.0.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmR695Wu5KrHNec7pRP3kPvwYihABDAyVYdX5D5vwLgxCn
✔ 1.1.0: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmSwjUZFpv2c2e9fLoxtgFrAsAmBN4DyQGJp4RcqQcW3z3
✔ 1.1.1: 0xE636bcA5B95e94F749F63E322a04DB59362299F1 ipfs:QmUYv9cjyNVxCyAJGK2YXjkbzh6u4iW2ak81Z9obdefM1q
✔ 2.0.0: 0x74CBbbC932d7C344FCd789Eba24BfD40e52980c9 ipfs:Qmadb3hzwLDKtb93fF367Vg1epkdsLZF4dhpapNYynjgZF
```
### Using a different Ethereum account
To deploy from a different account, you can:
- define a `~/.aragon/mnemonic.json` file
```
{
"mnemonic": "explain tackle mirror kit ..."
}
```
or
- define a `~/.aragon/${network_name}_key.json` file, for example: `~/.aragon/rinkeby_key.json`
```
{
"keys": [
"a8a54b2d8197bc0b19bb8a084031be71835580a01e70a45a13babd16c9bc1563"
]
}
```

28
apps/token/arapp.json Normal file
View File

@ -0,0 +1,28 @@
{
"roles": [
{
"name": "Mint token",
"id": "MINT_TOKEN_ROLE",
"params": []
}
],
"environments": {
"default": {
"network": "development",
"appName": "token.aragonpm.eth"
},
"staging": {
"registry": "0x98df287b6c145399aaa709692c8d308357bc085d",
"appName": "token.open.aragonpm.eth",
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"network": "rinkeby"
},
"production": {
"registry": "0x314159265dd8dbb310642f98f50c066173c1259b",
"appName": "token.open.aragonpm.eth",
"wsRPC": "wss://mainnet.eth.aragon.network/ws",
"network": "mainnet"
}
},
"path": "contracts/Token.sol"
}

View File

@ -0,0 +1,173 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/lib/math/SafeMath.sol";
/**
* beause ERC20.sol conflicts with the aragon ERC20.sol this is copied and modified from:
* https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20.sol
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://eips.ethereum.org/EIPS/eip-20
* Originally based on code by FirstBlood:
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*
* This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
* all accounts just by listening to said events. Note that this isn't required by the specification, and other
* compliant implementations may not do it.
*/
contract ERC20Token {
using SafeMath for uint256;
mapping (address => uint256) public _balances;
mapping (address => mapping (address => uint256)) private _allowed;
uint256 public _totalSupply;
string public name;
string public symbol;
uint8 public decimals;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev Gets the balance of the specified address.
* @param owner The address to query the balance of.
* @return A uint256 representing the amount owned by the passed address.
*/
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param owner address The address which owns the funds.
* @param spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowed[owner][spender];
}
/**
* @dev Transfer token to a specified address
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
/**
* @dev Transfer tokens from one address to another.
* Note that while this function emits an Approval event, this is not required as per the specification,
* and other compliant implementations may not emit the event.
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 the amount of tokens to be transferred
*/
function transferFrom(address from, address to, uint256 value) public returns (bool) {
_transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
return true;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param addedValue The amount of tokens to increase the allowance by.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
return true;
}
/**
* @dev Transfer token for a specified addresses
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function _transfer(address from, address to, uint256 value) internal {
require(to != address(0));
_balances[from] = _balances[from].sub(value);
_balances[to] = _balances[to].add(value);
emit Transfer(from, to, value);
}
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param account The account that will receive the created tokens.
* @param value The amount that will be created.
*/
function _mint(address account, uint256 value) internal {
require(account != address(0), 'invalid address');
_totalSupply = _totalSupply.add(value);
_balances[account] = _balances[account].add(value);
emit Transfer(address(0), account, value);
}
/**
* @dev Approve an address to spend another addresses' tokens.
* @param owner The address that owns the tokens.
* @param spender The address that will spend the tokens.
* @param value The number of tokens that can be spent.
*/
function _approve(address owner, address spender, uint256 value) internal {
require(spender != address(0));
require(owner != address(0));
_allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
}

View File

@ -0,0 +1,20 @@
pragma solidity ^0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "./ERC20Token.sol";
contract Token is ERC20Token, AragonApp {
bytes32 public constant MINT_TOKEN_ROLE = keccak256("MINT_TOKEN_ROLE");
event LogMint(address indexed recipient, uint256 amount, uint256 contributionId);
function initialize() public onlyInit {
initialized();
}
function mintFor(address contributorAccount, uint256 amount, uint256 contributionId) public isInitialized auth(MINT_TOKEN_ROLE) {
_mint(contributorAccount, amount);
emit LogMint(contributorAccount, amount, contributionId);
}
}

View File

@ -0,0 +1,23 @@
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migrations() {
owner = msg.sender;
}
function setCompleted(uint completed) restricted {
last_completed_migration = completed;
}
function upgrade(address new_address) restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}

4
apps/token/manifest.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "Token",
"description": "Kredits token app"
}

View File

@ -0,0 +1,5 @@
var Migrations = artifacts.require('./Migrations.sol')
module.exports = function (deployer) {
deployer.deploy(Migrations)
}

View File

@ -0,0 +1,5 @@
var Token = artifacts.require('Token.sol')
module.exports = function (deployer) {
deployer.deploy(Token)
}

13482
apps/token/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

28
apps/token/package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "kredits-token",
"version": "1.0.0",
"description": "",
"dependencies": {
"@aragon/os": "^4.1.0",
"@aragon/cli": "^5.5.0"
},
"devDependencies": {
},
"scripts": {
"start": "npm run start:aragon:ipfs",
"start:aragon:ipfs": "aragon run",
"start:aragon:http": "aragon run --http localhost:8001 --http-served-from ./dist",
"start:app": "",
"test": "aragon contracts test",
"compile": "aragon contracts compile",
"sync-assets": "",
"build:app": "",
"build:script": "",
"build": "",
"publish:patch": "aragon apm publish patch",
"publish:minor": "aragon apm publish minor",
"publish:major": "aragon apm publish major",
"versions": "aragon apm versions"
},
"keywords": []
}

5
apps/token/test/app.js Normal file
View File

@ -0,0 +1,5 @@
const CounterApp = artifacts.require('CounterApp.sol')
contract('CounterApp', (accounts) => {
it('should be tested')
})

63
apps/token/truffle.js Normal file
View File

@ -0,0 +1,63 @@
/**
* https://github.com/aragon/aragonOS/blob/v4.0.0/truffle-config.js
*/
const homedir = require('homedir')
const path = require('path')
const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')
const DEFAULT_MNEMONIC = 'explain tackle mirror kit van hammer degree position ginger unfair soup bonus'
const defaultRPC = (network) =>
`https://${network}.infura.io`
const configFilePath = (filename) =>
path.join(homedir(), `.aragon/${filename}`)
const mnemonic = () => {
try {
return require(configFilePath('mnemonic.json')).mnemonic
} catch (e) {
return DEFAULT_MNEMONIC
}
}
const settingsForNetwork = (network) => {
try {
return require(configFilePath(`${network}_key.json`))
} catch (e) {
return { }
}
}
// Lazily loaded provider
const providerForNetwork = (network) => (
() => {
let { rpc, keys } = settingsForNetwork(network)
rpc = rpc || defaultRPC(network)
if (!keys || keys.length == 0) {
return new HDWalletProvider(mnemonic(), rpc)
}
return new HDWalletProviderPrivkey(keys, rpc)
}
)
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*'
},
mainnet: {
network_id: 1,
provider: providerForNetwork('mainnet')
},
rinkeby: {
network_id: 4,
provider: providerForNetwork('rinkeby')
}
}
}

46
arapp.json Normal file
View File

@ -0,0 +1,46 @@
{
"roles": [
{
"name": "Add contributions",
"id": "ADD_CONTRIBUTION_ROLE",
"params": []
},
{
"name": "Manage contributors",
"id": "MANAGE_CONTRIBUTORS_ROLE",
"params": []
},
{
"name": "Mint token",
"id": "MINT_TOKEN_ROLE",
"params": []
},
{
"name": "Add proposal",
"id": "ADD_PROPOSAL_ROLE",
"params": []
},
{
"name": "Vote proposal",
"id": "VOTE_PROPOSAL_ROLE",
"params": []
}
],
"environments": {
"rinkeby": {
"wsRPC": "wss://rinkeby.eth.aragon.network/ws",
"registry": "0x98Df287B6C145399Aaa709692c8D308357bC085D",
"appName": "dummy.open.aragonpm.eth",
"network": "rinkeby"
},
"rpc": {
"network": "rpc",
"appName": "dummy.aragonpm.eth"
},
"default": {
"network": "rpc",
"appName": "dummy.aragonpm.eth"
}
},
"path": "contracts/misc/DummyApp.sol"
}

View File

@ -1,126 +0,0 @@
pragma solidity ^0.4.19;
import "zeppelin-solidity/contracts/token/ERC721/ERC721Token.sol";
import './upgradeable/Upgradeable.sol';
// ToDo: only load interfaces
import './Token.sol';
import './Contributors.sol';
contract Contribution is Upgradeable, ERC721Token {
struct ContributionData {
address contributor;
uint amount;
bool claimed;
bytes32 hashDigest;
uint8 hashFunction;
uint8 hashSize;
string tokenMetadataURL;
uint claimAfterBlock;
bool exists;
}
string internal name_;
string internal symbol_;
mapping(uint256 => address) contributionOwner;
mapping(address => uint256[]) ownedContributions;
mapping(uint256 => ContributionData) public contributions;
uint256 public contributionsCount;
event ContributionAdded(uint256 id, address indexed contributor, uint256 amount);
event ContributionClaimed(uint256 id, address indexed contributor, uint256 amount);
modifier coreOnly() {
require(contributorsContract().addressIsCore(msg.sender));
_;
}
modifier contributorOnly() {
require(contributorsContract().addressExists(msg.sender));
_;
}
function contributorsContract() view public returns (Contributors) {
return Contributors(registry.getProxyFor('Contributors'));
}
function tokenContract() view public returns (Token) {
return Token(registry.getProxyFor('Token'));
}
function name() external view returns (string) {
return name_;
}
function symbol() external view returns (string) {
return symbol_;
}
function ownerOf(uint256 contributionId) public view returns (address) {
require(exists(contributionId));
return contributions[contributionId].contributor;
}
function balanceOf(address contributor) public view returns (uint) {
return ownedContributions[contributor].length;
}
function tokenOfOwnerByIndex(address contributor, uint index) public view returns (uint) {
return ownedContributions[contributor][index];
}
function tokenMetadata(uint contributionId) public view returns (string) {
return contributions[contributionId].tokenMetadataURL;
}
function getContribution(uint contributionId) public view returns (uint256 id, address contributor, uint256 amount, bool claimed, bytes32 hashDigest, uint8 hashFunction, uint8 hashSize, uint claimAfterBlock, bool exists) {
id = contributionId;
ContributionData storage c = contributions[id];
return (
id,
c.contributor,
c.amount,
c.claimed,
c.hashDigest,
c.hashFunction,
c.hashSize,
c.claimAfterBlock,
c.exists
);
}
function add(uint256 amount, address contributor, uint256 blocksToWait) public coreOnly {
uint contributionId = contributionsCount + 1;
ContributionData storage c = contributions[contributionId];
c.exists = true;
c.amount = amount;
c.claimed = false;
c.contributor = contributor;
c.claimAfterBlock = block.number + blocksToWait;
contributionsCount++;
contributionOwner[contributionId] = contributor;
ownedContributions[contributor].push(contributionId);
ContributionAdded(contributionId, contributor, amount);
}
function claim(uint256 contributionId) public {
ContributionData storage c = contributions[contributionId];
require(c.exists);
require(!c.claimed);
require(block.number > c.claimAfterBlock);
c.claimed = true;
tokenContract().mintFor(c.contributor, c.amount, contributionId);
ContributionClaimed(contributionId, c.contributor, c.amount);
}
function exists(uint256 contributionId) view public returns (bool) {
return contributions[contributionId].exists;
}
}

85
contracts/KreditsKit.sol Normal file
View File

@ -0,0 +1,85 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
import "@aragon/os/contracts/kernel/Kernel.sol";
import "@aragon/os/contracts/acl/ACL.sol";
import "@aragon/os/contracts/acl/ACLSyntaxSugar.sol";
import "@aragon/kits-base/contracts/KitBase.sol";
import "./misc/APMNamehashOpen.sol";
import "../apps/contribution/contracts/Contribution.sol";
import "../apps/contributor/contracts/Contributor.sol";
import "../apps/token/contracts/Token.sol";
import "../apps/proposal/contracts/Proposal.sol";
contract KreditsKit is KitBase, APMNamehashOpen, ACLSyntaxSugar {
bytes32 public contributorAppId = apmNamehash("contributor"); // 0xe9140f1e39c8a1d04167c3b710688a3eecea2976f34735c8eb98956f4764635b
bytes32 public contributionAppId = apmNamehash("contribution"); // 0x7fcf91283b719b30c2fa954ff0da021e1b91aed09d7aa13df5e8078a4a1007eb
bytes32 public tokenAppId = apmNamehash("token"); // 0xe04a882e7a6adf5603207d545ea49aec17e6b936c4d9eae3d74dbe482264991a
fsmanuel commented 2019-03-27 11:06:51 +00:00 (Migrated from github.com)
Review

❤️

❤️
bytes32 public proposalAppId = apmNamehash("proposal"); // 0xaf5fe5c3b0d9581ee88974bbc8699e6fa71efd1b321e44b2227103c9ef21dbdb
event DeployInstance(address dao);
event InstalledApp(address dao, address appProxy, bytes32 appId);
constructor (DAOFactory _fac, ENS _ens) public KitBase(_fac, _ens) {}
function newInstance() public returns (Kernel dao, ERCProxy proxy) {
address root = msg.sender;
dao = fac.newDAO(this);
ACL acl = ACL(dao.acl());
acl.createPermission(this, dao, dao.APP_MANAGER_ROLE(), this);
Contributor contributor = Contributor(_installApp(dao, contributorAppId));
contributor.initialize(root);
acl.createPermission(root, contributor, contributor.MANAGE_CONTRIBUTORS_ROLE(), root);
Token token = Token(_installApp(dao, tokenAppId));
token.initialize();
Contribution contribution = Contribution(_installApp(dao, contributionAppId));
contribution.initialize();
Proposal proposal = Proposal(_installApp(dao, proposalAppId));
proposal.initialize();
acl.createPermission(root, contribution, contribution.ADD_CONTRIBUTION_ROLE(), this);
acl.grantPermission(proposal, contribution, contribution.ADD_CONTRIBUTION_ROLE());
uint256[] memory params = new uint256[](1);
params[0] = uint256(203) << 248 | uint256(1) << 240 | uint240(contributor);
acl.grantPermissionP(root, contribution, contribution.ADD_CONTRIBUTION_ROLE(), params);
//acl.setPermissionManager(this, proposal, proposal.VOTE_PROPOSAL_ROLE();
acl.createPermission(root, proposal, proposal.VOTE_PROPOSAL_ROLE(), this);
acl.grantPermissionP(root, proposal, proposal.VOTE_PROPOSAL_ROLE(), params);
acl.createPermission(root, proposal, proposal.ADD_PROPOSAL_ROLE(), this);
acl.grantPermissionP(root, proposal, proposal.ADD_PROPOSAL_ROLE(), params);
acl.setPermissionManager(root, proposal, proposal.VOTE_PROPOSAL_ROLE());
acl.setPermissionManager(root, proposal, proposal.ADD_PROPOSAL_ROLE());
acl.setPermissionManager(root, contribution, contribution.ADD_CONTRIBUTION_ROLE());
acl.createPermission(root, token, token.MINT_TOKEN_ROLE(), this);
acl.grantPermission(contribution, token, token.MINT_TOKEN_ROLE());
acl.setPermissionManager(root, token, token.MINT_TOKEN_ROLE());
cleanupDAOPermissions(dao, acl, root);
emit DeployInstance(dao);
//return dao;
}
function _installApp(Kernel _dao, bytes32 _appId) internal returns (AragonApp) {
address baseAppAddress = latestVersionAppBase(_appId);
require(baseAppAddress != address(0), "App should be deployed");
AragonApp appProxy = AragonApp(_dao.newAppInstance(_appId, baseAppAddress, new bytes(0), true));
emit InstalledApp(_dao, appProxy, _appId);
return appProxy;
}
}

View File

@ -1,133 +0,0 @@
pragma solidity ^0.4.18;
// ToDo: only load interfaces
import './Token.sol';
import './Contributors.sol';
import './Contribution.sol';
contract Operator is Upgradeable {
struct Proposal {
address creatorAccount;
uint contributorId;
uint votesCount;
uint votesNeeded;
uint256 amount;
bool executed;
bytes32 ipfsHash;
uint8 hashFunction;
uint8 hashSize;
uint256[] voterIds;
mapping (uint256 => bool) votes;
bool exists;
}
mapping(uint256 => Proposal) public proposals;
uint256 public proposalsCount;
event ProposalCreated(uint256 id, address creatorAccount, uint256 contributorId, uint256 amount);
event ProposalVoted(uint256 id, uint256 voterId, uint256 totalVotes);
event ProposalExecuted(uint256 id, uint256 contributorId, uint256 amount);
modifier coreOnly() {
require(contributorsContract().addressIsCore(msg.sender));
_;
}
modifier contributorOnly() {
require(contributorsContract().addressExists(msg.sender));
_;
}
modifier noEther() {
require(msg.value == 0);
_;
}
function contributorsContract() view public returns (Contributors) {
return Contributors(registry.getProxyFor('Contributors'));
}
function tokenContract() view public returns (Token) {
return Token(registry.getProxyFor('Token'));
}
function contributionContract() view public returns (Contribution) {
return Contribution(registry.getProxyFor('Contribution'));
}
function contributorsCount() view public returns (uint) {
return contributorsContract().contributorsCount();
}
function coreContributorsCount() view public returns (uint) {
return contributorsContract().coreContributorsCount();
}
function addProposal(uint contributorId, uint256 amount, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize) public {
require(contributorsContract().exists(contributorId));
uint256 proposalId = proposalsCount + 1;
uint256 _votesNeeded = contributorsContract().coreContributorsCount() / 100 * 75;
var p = proposals[proposalId];
p.creatorAccount = msg.sender;
p.contributorId = contributorId;
p.amount = amount;
p.ipfsHash = ipfsHash;
p.hashFunction = hashFunction;
p.hashSize = hashSize;
p.votesCount = 0;
p.votesNeeded = _votesNeeded;
p.exists = true;
proposalsCount++;
ProposalCreated(proposalId, msg.sender, p.contributorId, p.amount);
}
function getProposal(uint proposalId) public view returns (uint256 id, address creatorAccount, uint256 contributorId, uint256 votesCount, uint256 votesNeeded, uint256 amount, bool executed, bytes32 ipfsHash, uint8 hashFunction, uint8 hashSize, uint256[] voterIds, bool exists) {
id = proposalId;
Proposal storage p = proposals[id];
return (
id,
p.creatorAccount,
p.contributorId,
p.votesCount,
p.votesNeeded,
p.amount,
p.executed,
p.ipfsHash,
p.hashFunction,
p.hashSize,
p.voterIds,
p.exists
);
}
function vote(uint256 proposalId) public coreOnly {
var p = proposals[proposalId];
require(!p.executed);
uint256 voterId = contributorsContract().getContributorIdByAddress(msg.sender);
require(p.votes[voterId] != true);
p.voterIds.push(voterId);
p.votes[voterId] = true;
p.votesCount++;
if (p.votesCount >= p.votesNeeded) {
executeProposal(proposalId);
}
ProposalVoted(proposalId, voterId, p.votesCount);
}
function batchVote(uint256[] _proposalIds) public coreOnly {
for (uint256 i = 0; i < _proposalIds.length; i++) {
vote(_proposalIds[i]);
}
}
function executeProposal(uint proposalId) private {
var p = proposals[proposalId];
require(!p.executed);
require(p.votesCount >= p.votesNeeded);
address recipientAddress = contributorsContract().getContributorAddressById(p.contributorId);
contributionContract().add(p.amount, recipientAddress, 0);
p.executed = true;
ProposalExecuted(proposalId, p.contributorId, p.amount);
}
}

View File

@ -1,27 +0,0 @@
pragma solidity ^0.4.18;
import 'zeppelin-solidity/contracts/token/ERC20/BasicToken.sol';
import './upgradeable/Upgradeable.sol';
contract Token is Upgradeable, BasicToken {
string public name;
string public symbol;
uint8 public decimals;
event LogMint(address indexed recipient, uint256 amount, uint256 proposalId);
function initialize(address sender) public payable {
require(msg.sender == address(registry));
name = 'Kredits';
symbol = 'K';
decimals = 18;
}
function mintFor(address contributorAccount, uint256 amount, uint proposalId) onlyRegistryContractFor('Contribution') public {
totalSupply_ = totalSupply_.add(amount);
balances[contributorAccount] = balances[contributorAccount].add(amount);
LogMint(contributorAccount, amount, proposalId);
}
}

View File

@ -0,0 +1,13 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apm/APMNamehash.sol";
contract APMNamehashOpen is APMNamehash {
bytes32 public constant OPEN_TITLE = keccak256("open");
bytes32 public constant OPEN_APM_NODE = keccak256(abi.encodePacked(APM_NODE, OPEN_TITLE));
function apmNamehashOpen(string name) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(OPEN_APM_NODE, keccak256(name)));
}
}

View File

@ -0,0 +1,16 @@
pragma solidity 0.4.24;
import "@aragon/os/contracts/apps/AragonApp.sol";
// This is a "Dummy" app which's only purpose to exist is because
// Aragon's CLI still doesn't support running a Kit inside a project
// which isn't considered to be a "valid" Aragon project.
// It requires us to have an arrap.json file pointing to the contract
// and a manifest.json file which describes the front-end structure.
contract DummyApp is AragonApp {
function initialize() public onlyInit {
initialized();
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.17;
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
@ -8,7 +8,7 @@ contract Migrations {
if (msg.sender == owner) _;
}
function Migrations() public {
function constructor() public {
owner = msg.sender;
}

View File

@ -1,53 +0,0 @@
pragma solidity ^0.4.18;
/**
* @title IRegistry
* @dev This contract represents the interface of a registry contract
*/
interface IRegistry {
/**
* @dev This event will be emitted every time a new proxy is created
* @param name of the contract, as specified in the registry
* @param proxy representing the address of the proxy created
*/
event ProxyCreated(string name, address proxy);
/**
* @dev This event will be emitted every time a new implementation is registered
* @param name of the contract, as specified in the registry
* @param version representing the version name of the registered implementation
* @param implementation representing the address of the registered implementation
*/
event VersionAdded(string name, uint version, address implementation);
/**
* @dev This event will be emitted every time a proxy is upgraded to a new version
* @param name of the contract, as specified in the registry
* @param version representing the version name of the registered implementation
*/
event ProxyImplementationUpgraded(string name, uint version);
/**
* @dev Registers a new version with its implementation address
* @param name of the contract, as specified in the registry
* @param implementation representing the address of the new implementation to be registered
*/
function addVersion(string name, address implementation) public;
/**
* @dev Tells the address of the implementation for a given version
* @param name of the contract, as specified in the registry
* @param version to query the implementation of
* @return address of the implementation registered for the given version
*/
function getVersion(string name, uint version) public view returns (address);
/**
* @dev Tells the latest address of the implementation
* @param name of the contract, as specified in the registry
* @return address of the implementation registered for the latest version
*/
function getLatestVersion(string name) public view returns (address);
function getProxyFor(string name) public view returns (address);
}

View File

@ -1,36 +0,0 @@
pragma solidity ^0.4.18;
/**
* @title Proxy
* @dev Gives the possibility to delegate any call to a foreign implementation.
*/
contract Proxy {
/**
* @dev Tells the address of the implementation where every call will be delegated.
* @return address of the implementation to which it will be delegated
*/
function implementation() public view returns (address);
/**
* @dev Fallback function allowing to perform a delegatecall to the given implementation.
* This function will return whatever the implementation call returns
*/
function () payable public {
address _impl = implementation();
require(_impl != address(0));
bytes memory data = msg.data;
assembly {
let result := delegatecall(gas, _impl, add(data, 0x20), mload(data), 0, 0)
let size := returndatasize
let ptr := mload(0x40)
returndatacopy(ptr, 0, size)
switch result
case 0 { revert(ptr, size) }
default { return(ptr, size) }
}
}
}

View File

@ -1,86 +0,0 @@
pragma solidity ^0.4.18;
import './IRegistry.sol';
import './Upgradeable.sol';
import './UpgradeabilityProxy.sol';
/**
* @title Registry
* @dev This contract works as a registry of versions, it holds the implementations for the registered versions.
*/
contract Registry is IRegistry {
// mapping of contract names to versions to implementation
// "Token" => "1.0.0" => "0x123"
mapping(bytes32 => mapping(uint => address)) public versions;
// current version for a certain contract
mapping(bytes32 => uint) public currentVersions;
// mapping of the contract names to the proxy addresses
mapping(bytes32 => address) public proxies;
/**
* @dev Registers a new version with its implementation address
* @param name of the contract
* @param implementation representing the address of the new implementation to be registered
*/
function addVersion(string name, address implementation) public {
bytes32 key = keccak256(name);
currentVersions[key] = currentVersions[key] + 1;
uint version = currentVersions[key];
require(versions[key][version] == 0x0);
versions[key][version] = implementation;
VersionAdded(name, version, implementation);
}
/**
* @dev Tells the address of the implementation for a given version
* @param name of the contract
* @param version to query the implementation of
* @return address of the implementation registered for the given version
*/
function getVersion(string name, uint version) public view returns (address) {
bytes32 key = keccak256(name);
return versions[key][version];
}
function getLatestVersion(string name) public view returns (address) {
bytes32 key = keccak256(name);
uint current = currentVersions[key];
return getVersion(name, current);
}
function getProxyFor(string name) public view returns (address) {
bytes32 key = keccak256(name);
return proxies[key];
}
function upgrade(string name, uint version) public {
bytes32 key = keccak256(name);
UpgradeabilityProxy(proxies[key]).upgradeTo(version);
ProxyImplementationUpgraded(name, version);
}
function upgradeToLatest(string name) public {
bytes32 key = keccak256(name);
uint current = currentVersions[key];
upgrade(name, current);
}
/**
* @dev Creates an upgradeable proxy
* @param name of the contract
* @param version representing the first version to be set for the proxy
* @return address of the new proxy created
*/
function createProxy(string name, uint version) public payable returns (UpgradeabilityProxy) {
bytes32 key = keccak256(name);
require(proxies[key] == 0x0);
UpgradeabilityProxy proxy = new UpgradeabilityProxy(name, version);
proxies[key] = address(proxy);
Upgradeable(proxy).initialize.value(msg.value)(msg.sender);
ProxyCreated(name, proxy);
return proxy;
}
}

View File

@ -1,28 +0,0 @@
pragma solidity ^0.4.18;
import './Proxy.sol';
import './IRegistry.sol';
import './UpgradeabilityStorage.sol';
/**
* @title UpgradeabilityProxy
* @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
*/
contract UpgradeabilityProxy is Proxy, UpgradeabilityStorage {
function UpgradeabilityProxy(string _name, uint _version) public {
_proxiedContractName = _name;
registry = IRegistry(msg.sender);
upgradeTo(_version);
}
/**
* @dev Upgrades the implementation to the requested version
* @param _version representing the version name of the new implementation to be set
*/
function upgradeTo(uint _version) public {
require(msg.sender == address(registry));
_implementation = registry.getVersion(_proxiedContractName, _version);
}
}

View File

@ -1,37 +0,0 @@
pragma solidity ^0.4.18;
import './IRegistry.sol';
/**
* @title UpgradeabilityStorage
* @dev This contract holds all the necessary state variables to support the upgrade functionality
*/
contract UpgradeabilityStorage {
// Versions registry
IRegistry internal registry;
// Address of the current implementation
address internal _implementation;
// contract name
string public _proxiedContractName;
modifier requireRegistry() {
require(address(registry) != 0x0);
_;
}
modifier onlyRegistryContractFor(string name) {
require(address(registry) != 0x0);
require(msg.sender == registry.getProxyFor(name));
_;
}
/**
* @dev Tells the address of the current implementation
* @return address of the current implementation
*/
function implementation() public view returns (address) {
return _implementation;
}
}

View File

@ -1,19 +0,0 @@
pragma solidity ^0.4.18;
import './UpgradeabilityStorage.sol';
/**
* @title Upgradeable
* @dev This contract holds all the minimum required functionality for a behavior to be upgradeable.
* This means, required state variables for owned upgradeability purpose and simple initialization validation.
*/
contract Upgradeable is UpgradeabilityStorage {
/**
* @dev Validates the caller is the versions registry.
* THIS FUNCTION SHOULD BE OVERRIDDEN CALLING SUPER
* @param sender representing the address deploying the initial behavior of the contract
*/
function initialize(address sender) public payable {
require(msg.sender == address(registry));
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"contributors","outputs":[{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"contributorIds","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldIpfsHash","type":"bytes32"},{"indexed":false,"name":"newIpfsHash","type":"bytes32"}],"name":"ContributorProfileUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"oldAccount","type":"address"},{"indexed":false,"name":"newAccount","type":"address"}],"name":"ContributorAccountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"account","type":"address"}],"name":"ContributorAdded","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"oldAccount","type":"address"},{"name":"newAccount","type":"address"}],"name":"updateContributorAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"}],"name":"updateContributorIpfsHash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"}],"name":"addContributor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"isCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"addressIsCore","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"addressExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"getContributorAddressById","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getContributorById","outputs":[{"name":"id","type":"uint256"},{"name":"account","type":"address"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"isCore","type":"bool"},{"name":"balance","type":"uint256"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]

1
lib/abis/Kernel.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"creatorAccount","type":"address"},{"name":"contributorId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"proposalsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"creatorAccount","type":"address"},{"indexed":false,"name":"contributorId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"voterId","type":"uint256"},{"indexed":false,"name":"totalVotes","type":"uint256"}],"name":"ProposalVoted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"contributorId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"constant":true,"inputs":[],"name":"contributorsContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributionContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"coreContributorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"contributorId","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"}],"name":"addProposal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"proposalId","type":"uint256"}],"name":"getProposal","outputs":[{"name":"id","type":"uint256"},{"name":"creatorAccount","type":"address"},{"name":"contributorId","type":"uint256"},{"name":"votesCount","type":"uint256"},{"name":"votesNeeded","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"executed","type":"bool"},{"name":"ipfsHash","type":"bytes32"},{"name":"hashFunction","type":"uint8"},{"name":"hashSize","type":"uint8"},{"name":"voterIds","type":"uint256[]"},{"name":"exists","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proposalId","type":"uint256"}],"name":"vote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposalIds","type":"uint256[]"}],"name":"batchVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

1
lib/abis/Proposal.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
[{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"currentVersions","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"proxies","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"},{"name":"","type":"uint256"}],"name":"versions","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"proxy","type":"address"}],"name":"ProxyCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"version","type":"uint256"},{"indexed":false,"name":"implementation","type":"address"}],"name":"VersionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"version","type":"uint256"}],"name":"ProxyImplementationUpgraded","type":"event"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"implementation","type":"address"}],"name":"addVersion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"},{"name":"version","type":"uint256"}],"name":"getVersion","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"getLatestVersion","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"name","type":"string"}],"name":"getProxyFor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"version","type":"uint256"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"}],"name":"upgradeToLatest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"name","type":"string"},{"name":"version","type":"uint256"}],"name":"createProxy","outputs":[{"name":"","type":"address"}],"payable":true,"stateMutability":"payable","type":"function"}]

View File

@ -1 +1 @@
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_proxiedContractName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"proposalId","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"contributorAccount","type":"address"},{"name":"amount","type":"uint256"},{"name":"proposalId","type":"uint256"}],"name":"mintFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
[{"constant":true,"inputs":[],"name":"hasInitialized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"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":"_foo","outputs":[{"name":"","type":"uint256"}],"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":"MINT_TOKEN_ROLE","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":"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"},{"anonymous":false,"inputs":[{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"contributionId","type":"uint256"}],"name":"LogMint","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":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"foo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"mintFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

View File

@ -1 +0,0 @@
{"42":"0x205fe1b3dac678b594c5f0535e7d158e38591f93","100":"0xa7fc9b1f678c41396b53904f94f50a42ff44d826"}

View File

@ -1 +0,0 @@
{"42":"0x9fd66ee78a5ebe86006f12b37ff59c63f9caa15b","100":"0x95d3bd7d136bb0b7ac9988097e964236f8a9976e"}

View File

@ -1 +0,0 @@
{"42":"0xc270e6ea4fe303df9f1a3d4a132ac425264082e7","100":"0x7458dea485d9d8301e3ce43e8a1ec1456be5ba83"}

View File

@ -1 +0,0 @@
{"42":"0xf71ccf7ab48044ef9ae0b5e6983dbd3266b78b36","100":"0x3fc29fbe40c2d0ca78c7e81342f00226650fe2ad"}

1
lib/addresses/dao.json Normal file
View File

@ -0,0 +1 @@
bumi commented 2019-03-27 21:12:17 +00:00 (Migrated from github.com)
Review

I am wondering how I can prevent that those local address details get commited.
Those "14945560" network IDs are devchain IDs.
so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?

I am wondering how I can prevent that those local address details get commited. Those "14945560" network IDs are devchain IDs. so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?
bumi commented 2019-03-27 21:12:17 +00:00 (Migrated from github.com)
Review

I am wondering how I can prevent that those local address details get commited.
Those "14945560" network IDs are devchain IDs.
so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?

I am wondering how I can prevent that those local address details get commited. Those "14945560" network IDs are devchain IDs. so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?
fsmanuel commented 2019-03-28 17:16:51 +00:00 (Migrated from github.com)
Review

Maybe a git pre commit hook would work. I have never worked with git hooks...

Maybe a git pre commit hook would work. I have never worked with git hooks...
fsmanuel commented 2019-03-28 17:16:51 +00:00 (Migrated from github.com)
Review

Maybe a git pre commit hook would work. I have never worked with git hooks...

Maybe a git pre commit hook would work. I have never worked with git hooks...
raucao commented 2019-03-28 21:43:54 +00:00 (Migrated from github.com)
Review

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.
raucao commented 2019-03-28 21:43:54 +00:00 (Migrated from github.com)
Review

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.
bumi commented 2019-03-28 23:03:39 +00:00 (Migrated from github.com)
Review

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones.
so what would the hook do?

then it probably does not change that often...

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones. so what would the hook do? then it probably does not change that often...
bumi commented 2019-03-28 23:03:39 +00:00 (Migrated from github.com)
Review

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones.
so what would the hook do?

then it probably does not change that often...

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones. so what would the hook do? then it probably does not change that often...
{"23827572":"0xe4e0e7fe54d9189df29a80c07ab733fc9a212761","65047207":"0xdbe26ae4a434472a7474db60cc3e3c97a57bbf38"}
bumi commented 2019-03-27 21:12:17 +00:00 (Migrated from github.com)
Review

I am wondering how I can prevent that those local address details get commited.
Those "14945560" network IDs are devchain IDs.
so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?

I am wondering how I can prevent that those local address details get commited. Those "14945560" network IDs are devchain IDs. so far I don't think it is worth to write code for that and maybe simply try to ignore commiting those changes, but if somebody has an idea...?
fsmanuel commented 2019-03-28 17:16:51 +00:00 (Migrated from github.com)
Review

Maybe a git pre commit hook would work. I have never worked with git hooks...

Maybe a git pre commit hook would work. I have never worked with git hooks...
raucao commented 2019-03-28 21:43:54 +00:00 (Migrated from github.com)
Review

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.

Yes, I think that could be a good solution. Git hooks are pretty easy to work with actually.
bumi commented 2019-03-28 23:03:39 +00:00 (Migrated from github.com)
Review

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones.
so what would the hook do?

then it probably does not change that often...

hmm. the issue is locally you need those addresses in the file but in the repo we only need the commonly used ones. so what would the hook do? then it probably does not change that often...

View File

@ -46,6 +46,26 @@ class Contribution extends Base {
return RSVP.all(contributions);
});
}
addContribution(contributionAttr, callOptions = {}) {
let json = ContributionSerializer.serialize(contributionAttr);
// TODO: validate against schema
return this.ipfs
.add(json)
.then((ipfsHashAttr) => {
let contribution = [
contributionAttr.amount,
contributionAttr.contributorAccount,
ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize,
];
console.log(contribution);
return this.functions.add(...contribution, callOptions);
});
}
}
module.exports = Contribution;

View File

@ -1,7 +1,7 @@
module.exports = {
Contributors: require('./contributor'),
Contributor: require('./contributor'),
Contribution: require('./contribution'),
Operator: require('./operator'),
Proposal: require('./proposal'),
Token: require('./token'),
Registry: require('./registry')
Kernel: require('./kernel')
};

21
lib/contracts/kernel.js Normal file
View File

@ -0,0 +1,21 @@
const Base = require('./base');
KERNEL_APP_ADDR_NAMESPACE = '0xd6f028ca0e8edb4a8c9757ca4fdccab25fa1e0317da1188108f7d2dee14902fb';
class Kernel extends Base {
getApp(appName) {
return this.functions.getApp(KERNEL_APP_ADDR_NAMESPACE, this.appNamehash(appName));
}
appNamehash(appName) {
return {
Contributor: '0xe9140f1e39c8a1d04167c3b710688a3eecea2976f34735c8eb98956f4764635b',
Contribution: '0x7fcf91283b719b30c2fa954ff0da021e1b91aed09d7aa13df5e8078a4a1007eb',
Token: '0xe04a882e7a6adf5603207d545ea49aec17e6b936c4d9eae3d74dbe482264991a',
Proposal: '0xaf5fe5c3b0d9581ee88974bbc8699e6fa71efd1b321e44b2227103c9ef21dbdb'
}[appName];
}
}
module.exports = Kernel;

View File

@ -1,6 +0,0 @@
const Base = require('./base');
class Registry extends Base {
}
module.exports = Registry;

View File

@ -4,13 +4,19 @@ const RSVP = require('rsvp');
const Preflight = require('./utils/preflight');
const ABIS = {
Contributors: require('./abis/Contributors.json'),
Contributor: require('./abis/Contributor.json'),
Contribution: require('./abis/Contribution.json'),
Operator: require('./abis/Operator.json'),
Registry: require('./abis/Registry.json'),
Token: require('./abis/Token.json')
Token: require('./abis/Token.json'),
Proposal: require('./abis/Proposal.json'),
Kernel: require('./abis/Kernel.json')
};
const RegistryAddress = require('./addresses/Registry.json');
const APP_CONTRACTS = [
'Contributor',
'Contribution',
'Token',
'Proposal'
];
const DaoAddresses = require('./addresses/dao.json');
const Contracts = require('./contracts');
const IPFS = require('./utils/ipfs')
@ -28,18 +34,18 @@ class Kredits {
this.provider = provider;
this.signer = signer;
// by default we only need the registry address.
// by default we only need the DAO/Kernel address.
// the rest is loaded from there in the init() function
this.addresses = addresses || { Registry: RegistryAddress[this.provider.chainId.toString()] }; // chainID must be a string
this.addresses = addresses || { Kernel: DaoAddresses[this.provider.chainId.toString()] }; // chainID must be a string
this.abis = abis || ABIS;
this.ipfs = new IPFS(ipfsConfig);
this.contracts = {};
}
init(names) {
let contractsToLoad = names || Object.keys(ABIS);
let contractsToLoad = names || APP_CONTRACTS;
let addressPromises = contractsToLoad.map((contractName) => {
return this.Registry.functions.getProxyFor(contractName).then((address) => {
return this.Kernel.getApp(contractName).then((address) => {
this.addresses[contractName] = address;
}).catch((error) => {
throw new Error(`Failed to get address for ${contractName} from registry at ${this.Registry.contract.address}
@ -55,13 +61,13 @@ class Kredits {
return new Kredits(provider, signer, { ipfsConfig: ipfsConfig }).init();
}
get Registry() {
return this.contractFor('registry');
get Kernel() {
return this.contractFor('Kernel');
}
get Contributor() {
// TODO: rename to contributor
return this.contractFor('contributors');
return this.contractFor('Contributor');
}
get Contributors() {
@ -69,16 +75,16 @@ class Kredits {
return this.Contributor;
}
get Operator() {
return this.contractFor('operator');
get Proposal() {
return this.contractFor('Proposal');
}
fsmanuel commented 2019-03-29 14:43:41 +00:00 (Migrated from github.com)
Review

You don't need the () see get Contributors()

You don't need the `()` see `get Contributors()`
bumi commented 2019-03-29 17:15:55 +00:00 (Migrated from github.com)
Review

ah ja... thx.

ah ja... thx.
get Token() {
return this.contractFor('token');
return this.contractFor('Token');
}
get Contribution() {
return this.contractFor('contribution');
return this.contractFor('Contribution');
}
// Should be private

View File

@ -1,5 +0,0 @@
var Registry = artifacts.require('./upgradeable/Registry.sol');
module.exports = function(deployer) {
deployer.deploy(Registry);
};

View File

@ -1,15 +0,0 @@
var Registry = artifacts.require('./Registry.sol');
var Token = artifacts.require('./Token.sol');
module.exports = function(deployer) {
deployer.deploy(Token).then(function(token) {
console.log('Registry address: ', Registry.address);
console.log('Token address: ', Token.address);
Registry.deployed().then(function(registry) {
registry.addVersion('Token', Token.address);
registry.createProxy('Token', 1);
});
});
};

View File

@ -1,13 +0,0 @@
var Registry = artifacts.require('./Registry.sol');
var Contributors = artifacts.require('./Contributors.sol');
module.exports = function(deployer) {
deployer.deploy(Contributors).then(function(contributors) {
console.log('Registry address: ', Registry.address);
console.log('Contributors address: ', Contributors.address);
Registry.deployed().then(function(registry) {
registry.addVersion('Contributors', Contributors.address);
registry.createProxy('Contributors', 1);
});
});
};

View File

@ -1,13 +0,0 @@
var Registry = artifacts.require('./Registry.sol');
var Operator = artifacts.require('./Operator.sol');
module.exports = function(deployer) {
deployer.deploy(Operator).then(function(operator) {
console.log('Registry address: ', Registry.address);
console.log('Operator address: ', Operator.address);
Registry.deployed().then(function(registry) {
registry.addVersion('Operator', Operator.address);
registry.createProxy('Operator', 1);
});
});
};

View File

@ -1,13 +0,0 @@
var Registry = artifacts.require('./Registry.sol');
var Contribution = artifacts.require('./Contribution.sol');
module.exports = function(deployer) {
deployer.deploy(Contribution).then(function(contribution) {
console.log('Registry address: ', Registry.address);
console.log('Contribution address: ', Contribution.address);
Registry.deployed().then(function(registry) {
registry.addVersion('Contribution', Contribution.address);
registry.createProxy('Contribution', 1);
});
});
};

14329
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
"test": "test"
},
"scripts": {
"build-json": "truffle compile && node ./scripts/build-json.js",
"build-json": "aragon contracts compile --all && node ./scripts/build-json.js",
"reset": "truffle migrate --reset && npm run build-json",
"bootstrap": "npm run reset && truffle exec scripts/seeds.js",
"ganache": "ganache-cli -p 7545 -i 100 --db=./.ganache-db -m kredits",
@ -25,11 +25,13 @@
},
"homepage": "https://github.com/67P/truffle-kredits#readme",
"devDependencies": {
"@aragon/cli": "^5.5.0",
"@aragon/kits-base": "^1.0.0",
"@aragon/os": "^4.1.0",
"async-each-series": "^1.1.0",
"ganache-cli": "^6.1.8",
"openzeppelin-solidity": "^2.2.0",
"promptly": "^3.0.3",
"truffle": "^4.1.14",
"zeppelin-solidity": "^1.7.0"
"solc": "^0.4.25"
},
"dependencies": {
"ethers": "3.0.15",

View File

@ -0,0 +1,43 @@
const promptly = require('promptly');
const ethers = require('ethers');
fsmanuel commented 2019-03-29 14:39:10 +00:00 (Migrated from github.com)
Review

❤️

❤️
bumi commented 2019-03-29 17:16:27 +00:00 (Migrated from github.com)
Review

is it actually init_kredits.js or initKredits.js` as file name?

is it actually `init_kredits.js` or initKredits.js` as file name?
fsmanuel commented 2019-03-30 13:32:30 +00:00 (Migrated from github.com)
Review

I think JS folks use require('./helpers/init-kredits'); You don't need the .js

I think JS folks use `require('./helpers/init-kredits');` You don't need the `.js`
const Kredits = require('../lib/kredits');
module.exports = async function(callback) {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await new Kredits(provider, provider.getSigner()).init();
console.log(`Using Contributions at: ${kredits.Contribution.contract.address}`);
let contributor = await promptly.prompt('Contributor (address or id): ');
let contributorId;
if (contributor.length < 5) {
contributorAccount = await kredits.Contributor.functions.getContributorAddressById(contributor);
} else {
contributorAccount = contributor;
}
console.log(`Creating a contribution for contributor Account #${contributorAccount}`);
let contributionAttributes = {
contributorAccount,
amount: await promptly.prompt('Amount: '),
description: await promptly.prompt('Description: '),
kind: await promptly.prompt('Kind: ', { default: 'dev' }),
url: await promptly.prompt('URL: ', { default: '' })
}
console.log("\nAdding contribution:");
console.log(contributionAttributes);
kredits.Contribution.addContribution(contributionAttributes, { gasLimit: 300000 }).then((result) => {
console.log("\n\nResult:");
console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create contribution');
callback(error);
});
}

View File

@ -1,4 +1,3 @@
const Registry = artifacts.require('./Registry.sol');
const promptly = require('promptly');
const ethers = require('ethers');
@ -11,39 +10,35 @@ async function prompt(message, options) {
return await promptly.prompt(message, options);
}
module.exports = function(callback) {
Registry.deployed().then(async (registry) => {
module.exports = async function(callback) {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await new Kredits(provider, provider.getSigner()).init();
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await Kredits.setup(provider, provider.getSigner());
console.log(`Using contributors at: ${kredits.Contributor.contract.address}`);
console.log(`Using contributors at: ${kredits.Contributor.contract.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 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: '),
};
console.log("\nAdding contributor:");
console.log(contributorAttributes);
kredits.Contributor.add(contributorAttributes, { gasLimit: 250000 }).then((result) => {
console.log("\n\nResult:");
console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create contributor');
callback(error);
});
console.log("\nAdding contributor:");
console.log(contributorAttributes);
kredits.Contributor.add(contributorAttributes, { gasLimit: 250000 }).then((result) => {
console.log("\n\nResult:");
console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create contributor');
callback(error);
});
}

View File

@ -1,46 +1,43 @@
const Registry = artifacts.require('./Registry.sol');
const promptly = require('promptly');
const ethers = require('ethers');
const Kredits = require('../lib/kredits');
module.exports = function(callback) {
Registry.deployed().then(async (registry) => {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await Kredits.setup(provider, provider.getSigner());
module.exports = async function(callback) {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await new Kredits(provider, provider.getSigner()).init();
console.log(`Using operator at: ${kredits.Operator.contract.address}`);
console.log(`Using Proposal at: ${kredits.Proposal.contract.address}`);
let contributor = await promptly.prompt('Contributor (address or id): ');
let contributorId;
if (contributor.length < 5) {
contributorId = contributor;
} else {
contributorId = await kredits.Contributor.functions.getContributorIdByAddress(contributor);
}
console.log(`Creating a proposal for contributor ID #${contributorId}`);
let contributor = await promptly.prompt('Contributor (address or id): ');
let contributorId;
if (contributor.length < 5) {
contributorId = contributor;
} else {
contributorId = await kredits.Contributor.functions.getContributorIdByAddress(contributor);
}
console.log(`Creating a proposal for contributor ID #${contributorId}`);
let contributionAttributes = {
contributorId,
amount: await promptly.prompt('Amount: '),
description: await promptly.prompt('Description: '),
kind: await promptly.prompt('Kind: ', { default: 'dev' }),
url: await promptly.prompt('URL: ', { default: '' })
}
let contributionAttributes = {
contributorId,
amount: await promptly.prompt('Amount: '),
description: await promptly.prompt('Description: '),
kind: await promptly.prompt('Kind: ', { default: 'dev' }),
url: await promptly.prompt('URL: ', { default: '' })
}
console.log("\nAdding proposal:");
console.log(contributionAttributes);
console.log("\nAdding proposal:");
console.log(contributionAttributes);
kredits.Operator.addProposal(contributionAttributes, { gasLimit: 300000 }).then((result) => {
console.log("\n\nResult:");
console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create proposal');
console.log(error);
});
kredits.Proposal.addProposal(contributionAttributes, { gasLimit: 300000 }).then((result) => {
console.log("\n\nResult:");
console.log(result);
callback();
}).catch((error) => {
console.log('Failed to create proposal');
callback(error);
});
}

View File

@ -4,13 +4,12 @@ const path = require('path');
const contractsPath = path.join(__dirname, '..', 'build', 'contracts');
const libPath = path.join(__dirname, '..', 'lib');
const abisPath = path.join(libPath, 'abis');
const addressesPath = path.join(libPath, 'addresses');
const files = [
'Contributors',
'Contributor',
'Contribution',
'Operator',
'Registry',
'Kernel',
'Proposal',
'Token'
];
@ -18,17 +17,6 @@ files.forEach((fileName) => {
let file = require(`${contractsPath}/${fileName}.json`);
let abiFile = path.join(abisPath, `${fileName}.json`);
fs.writeFileSync(abiFile, JSON.stringify(file.abi));
if (fileName === 'Registry') {
let addresseFile = path.join(addressesPath, `${fileName}.json`);
let content = fs.readFileSync(addresseFile);
let addresses = Object.keys(file.networks)
.reduce((addresses, key) => {
addresses[key] = file.networks[key].address;
return addresses;
}, JSON.parse(content));
fs.writeFileSync(addresseFile, JSON.stringify(addresses));
}
});
console.log("Don't forget to reaload the JSON files from your application; i.e. restart kredits-web");

View File

@ -5,14 +5,12 @@ const ethers = require('ethers');
const Kredits = require('../lib/kredits');
module.exports = function(callback) {
const Registry = artifacts.require('./Registry.sol');
Registry.deployed().then(async (registry) => {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await Kredits.setup(provider, provider.getSigner());
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
new Kredits(provider, provider.getSigner()).init().then(async function(kredits) {
let contractName = await promptly.prompt('Contract Name: ');
const contractWrapper = kredits[contractName];

49
scripts/deploy-kit.js Normal file
View File

@ -0,0 +1,49 @@
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const deployDAOFactory = require('@aragon/os/scripts/deploy-daofactory.js')
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const KreditsKit = artifacts.require('KreditsKit')
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const fs = require('fs');
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const path = require('path');
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const libPath = path.join(__dirname, '..', 'lib');
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const addressesPath = path.join(libPath, 'addresses');
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const ensAddr = process.env.ENS
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
module.exports = async (callback) => {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
if (!ensAddr) {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
callback(new Error("ENS address not found in environment variable ENS"))
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
}
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
deployDAOFactory(null, { artifacts, verbose: false })
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
.catch(console.log)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
.then((result) => {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const daoFactory = result.daoFactory
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
KreditsKit.new(daoFactory.address, ensAddr)
fsmanuel commented 2019-03-24 22:16:51 +00:00 (Migrated from github.com)
Review

Are you a javascript pro, now?

Are you a javascript pro, now?
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
bumi commented 2019-03-26 23:43:10 +00:00 (Migrated from github.com)
Review

a pro in being desperate :)
those scripts are executed in some truffle context and debugging sometimes is a pain because truffle swallows the errors and traces... so I sometimes threw everything on it :D

a pro in being desperate :) those scripts are executed in some truffle context and debugging sometimes is a pain because truffle swallows the errors and traces... so I sometimes threw everything on it :D
fsmanuel commented 2019-03-27 11:10:41 +00:00 (Migrated from github.com)
Review

Much better with a normal function!

Much better with a normal function!
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
.catch(console.log)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
.then((kreditsKit) => {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
console.log(kreditsKit.address)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
kreditsKit.newInstance().then((ret) => {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
console.log(ret.logs);
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const installedEvents = ret.logs.filter(log => log.event === 'InstalledApp').map(log => log.args)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const deployEvents = ret.logs.filter(log => log.event === 'DeployInstance').map(log => log.args)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
if (deployEvents.length > 1) {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
callback(new Error("More than one DAO was deployed. Something is wrong"))
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
}
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const daoAddress = deployEvents[0].dao;
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
const networkId = parseInt(web3.version.network);
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
let addresseFile = path.join(addressesPath, `dao.json`);
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
let addresses = JSON.parse(fs.readFileSync(addresseFile));
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
addresses[networkId] = daoAddress;
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fs.writeFileSync(addresseFile, JSON.stringify(addresses));
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
callback();
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
}).catch((e) => {
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
console.log(e);
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
})
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
})
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
})
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)
}
fsmanuel commented 2019-03-24 22:23:01 +00:00 (Migrated from github.com)
Review

What about:

const KreditsKit = artifacts.require('KreditsKit')
const kreditsKitFile = 'KreditsKit.json'
// ...
let addresseFile = path.join(addressesPath, kreditsKitFile);
What about: ```js const KreditsKit = artifacts.require('KreditsKit') const kreditsKitFile = 'KreditsKit.json' // ... let addresseFile = path.join(addressesPath, kreditsKitFile); ```
fsmanuel commented 2019-03-27 11:38:31 +00:00 (Migrated from github.com)
Review

const networkId = await getNetworkId(web3);

`const networkId = await getNetworkId(web3);`
raucao commented 2019-03-27 11:39:55 +00:00 (Migrated from github.com)
Review

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

Have you tried the new suggestion feature in these comments? It's pretty useful! (And you'll be credited in the commit.)

View File

@ -1,18 +1,16 @@
const REPL = require('repl');
const promptly = require('promptly');
const ethers = require('ethers');
const Kredits = require('../lib/kredits');
module.exports = function(callback) {
const Registry = artifacts.require('./Registry.sol');
Registry.deployed().then(async (registry) => {
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
const kredits = await Kredits.setup(provider, provider.getSigner());
console.log(`defined variables: kredits, web3`);
const networkId = parseInt(web3.version.network);
const provider = new ethers.providers.Web3Provider(
web3.currentProvider, { chainId: networkId }
);
new Kredits(provider, provider.getSigner()).init().then((kredits) => {
console.log(`Defined variables: kredits, web3`);
let r = REPL.start();
r.context.kredits = kredits;
r.context.web3 = web3;

View File

@ -1,15 +1,68 @@
/**
* https://github.com/aragon/aragonOS/blob/v4.0.0/truffle-config.js
*/
const homedir = require('homedir')
const path = require('path')
const HDWalletProvider = require('truffle-hdwallet-provider')
const HDWalletProviderPrivkey = require('truffle-hdwallet-provider-privkey')
const DEFAULT_MNEMONIC = 'explain tackle mirror kit van hammer degree position ginger unfair soup bonus'
const defaultRPC = (network) =>
`https://${network}.infura.io`
const configFilePath = (filename) =>
path.join(homedir(), `.aragon/${filename}`)
const mnemonic = () => {
try {
return require(configFilePath('mnemonic.json')).mnemonic
} catch (e) {
return DEFAULT_MNEMONIC
}
}
const settingsForNetwork = (network) => {
try {
return require(configFilePath(`${network}_key.json`))
} catch (e) {
return { }
}
}
// Lazily loaded provider
const providerForNetwork = (network) => (
() => {
let { rpc, keys } = settingsForNetwork(network)
rpc = rpc || defaultRPC(network)
if (!keys || keys.length == 0) {
return new HDWalletProvider(mnemonic(), rpc)
}
return new HDWalletProviderPrivkey(keys, rpc)
}
)
module.exports = {
// See <http://truffleframework.com/docs/advanced/configuration>
networks: {
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*" // Match any network id
},
kovan: {
host: "127.0.0.1",
rpc: {
host: 'localhost',
port: 8545,
network_id: "42"
network_id: '*'
},
development: {
host: 'localhost',
port: 8545,
network_id: '*'
},
mainnet: {
network_id: 1,
provider: providerForNetwork('mainnet')
},
rinkeby: {
network_id: 4,
provider: providerForNetwork('rinkeby')
}
}
};
}