Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ce100e819 | |||
| 7216522d83 | |||
| 956f858620 | |||
| 8a7abba486 | |||
| c6c48f49d2 | |||
| db2e12c750 | |||
| 7dc75a19b5 | |||
| 926913da50 | |||
| a045702937 |
@@ -1,6 +1,11 @@
|
||||
# Kredits
|
||||
[](https://www.npmjs.com/package/kredits-contracts)
|
||||
|
||||
This repository contains all the contracts for Kredits as a [truffle framework](http://truffleframework.com/) project.
|
||||
# Kredits Contracts
|
||||
|
||||
This repository contains the Solidity smart contracts and JavaScript API
|
||||
wrapper for [Kosmos Kredits](https://wiki.kosmos.org/Kredits).
|
||||
|
||||
It uses the [Truffle framework](http://truffleframework.com/) for some things.
|
||||
|
||||
## Development
|
||||
|
||||
@@ -12,19 +17,24 @@ This repository contains all the contracts for Kredits as a [truffle framework](
|
||||
|
||||
All requirements are defined in `package.json`.
|
||||
|
||||
Those can be installed globally for convenience:
|
||||
Those can be installed globally for convenience:
|
||||
|
||||
* [truffle framework](http://truffleframework.com): `npm install -g truffle`
|
||||
* [ganache](http://truffleframework.com/ganache): `npm install -g ganache-cli`
|
||||
|
||||
We use following solidity contract libraries:
|
||||
|
||||
* [Open Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity)
|
||||
|
||||
For local development it is recommended to use [ganache-cli](https://github.com/trufflesuite/ganache-cli) (or the [ganache GUI](http://truffleframework.com/ganache/) to run a local development chain.
|
||||
For local development it is recommended to use
|
||||
[ganache-cli](https://github.com/trufflesuite/ganache-cli) (or the [ganache
|
||||
GUI](http://truffleframework.com/ganache/) to run a local development chain.
|
||||
Using the ganache simulator no full Ethereum node is required.
|
||||
|
||||
We default to:
|
||||
We default to:
|
||||
|
||||
* port 7545 for development to not get in conflict with the default Ethereum RPC port.
|
||||
* port 7545 for development to not get in conflict with the default Ethereum
|
||||
RPC port.
|
||||
* network ID 100 to stay on the same network id
|
||||
* store ganache data in .ganache-db to presist the chain data across restarts
|
||||
* use a fixed Mnemonic code to get the same accounts across restarts
|
||||
@@ -37,116 +47,137 @@ Run your ganache simulator before using Kredits locally:
|
||||
|
||||
### Truffle console
|
||||
|
||||
Truffle comes with a simple REPL to interact with the Smart Contracts. Have a look at the [documentation here](http://truffleframework.com/docs/getting_started/console)
|
||||
Truffle comes with a simple REPL to interact with the Smart Contracts. Have a
|
||||
look at the [documentation
|
||||
here](http://truffleframework.com/docs/getting_started/console)
|
||||
|
||||
NOTE: There are promisses, have a look at the examples:
|
||||
NOTE: There are promisses, have a look at the examples:
|
||||
|
||||
```javascript
|
||||
Token.deployed().then(function(token) {
|
||||
Token.deployed().then(function(token) {
|
||||
token.totalSupply.call().then(function(value) {
|
||||
console.log(value.toString());
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
Also please be aware of the differences between web3.js 0.2x.x and [1.x.x](https://web3js.readthedocs.io/en/1.0/) - [web3 repo](https://github.com/ethereum/web3.js/)
|
||||
|
||||
Also please be aware of the differences between web3.js 0.2x.x and
|
||||
[1.x.x](https://web3js.readthedocs.io/en/1.0/) - [web3
|
||||
repo](https://github.com/ethereum/web3.js/)
|
||||
|
||||
## Contract Deployment
|
||||
|
||||
Truffle uses migration scripts to deploy contract to various networks. Have a look at the `migrations` folder for those.
|
||||
The Ethereum nodes for the different networks need to be configured in `truffle.js`.
|
||||
Truffle uses migration scripts to deploy contract to various networks. Have a
|
||||
look at the `migrations` folder for those. The Ethereum nodes for the
|
||||
different networks need to be configured in `truffle.js`.
|
||||
|
||||
Run the truffle migration scripts:
|
||||
Run the truffle migration scripts:
|
||||
|
||||
$ truffle deploy
|
||||
$ truffle deploy
|
||||
$ truffle deploy --network=<network config from truffle.js>
|
||||
|
||||
Truffle keeps track of already executed migration scripts. To reset the migration use the `--reset` option
|
||||
Truffle keeps track of already executed migration scripts. To reset the
|
||||
migration use the `--reset` option
|
||||
|
||||
$ truffle migrate --reset
|
||||
|
||||
Migration scripts can also be run from within `truffle console` or `truffle develop`
|
||||
Migration scripts can also be run from within `truffle console` or `truffle
|
||||
develop`
|
||||
|
||||
To initially bootstrap a local development chain in ganache you can use the bootstrap script:
|
||||
|
||||
$ npm run bootstrap (= `truffle migrate --reset && truffle exec scripts/seeds.js && npm run build-json`)
|
||||
To initially bootstrap a local development chain in ganache you can use the
|
||||
bootstrap script:
|
||||
|
||||
$ npm run bootstrap
|
||||
|
||||
## Helper scripts
|
||||
|
||||
`scripts/` contains some helper scripts to interact with the contracts from the CLI.
|
||||
At some point these should be moved into a real nice CLI.
|
||||
`scripts/` contains some helper scripts to interact with the contracts from the
|
||||
CLI. _At some point these should be moved into a real nice CLI._
|
||||
|
||||
To run these scripts use `truffle exec`. For example: `truffle exec scripts/add-proposal.js`
|
||||
To run these scripts use `truffle exec`. For example: `truffle exec
|
||||
scripts/add-proposal.js`.
|
||||
|
||||
### cli.js
|
||||
|
||||
Call any function on any contract:
|
||||
|
||||
$ truffle exec scripts/cli.js
|
||||
|
||||
### repl.js
|
||||
Similar to cli.js but only provides a REPL with an initialized `kredits` instance.
|
||||
|
||||
Similar to cli.js but only provides a REPL with an initialized `kredits`
|
||||
instance.
|
||||
|
||||
$ truffle exec scripts/repl.js
|
||||
|
||||
### add-contributor.js
|
||||
Adds a new core contributor, creates a proposal for the new contributor and votes for that one.
|
||||
|
||||
$ truffle exec scripts/add-contributor.js
|
||||
Adds a new core contributor, creates a proposal for the new contributor and
|
||||
votes for that one.
|
||||
|
||||
$ truffle exec scripts/add-contributor.js
|
||||
|
||||
### add-proposal.js
|
||||
|
||||
Adds a new proposal for an existing contributor
|
||||
|
||||
$ truffle exec scripts/add-proposal.js
|
||||
|
||||
### send-funds.js
|
||||
Sends funds to an address. Helpful in development mode to for example fund a metamask account.
|
||||
|
||||
$ truffle exec scripts/send-funds.js
|
||||
Sends funds to an address. Helpful in development mode to for example fund a
|
||||
metamask account.
|
||||
|
||||
$ truffle exec scripts/send-funds.js
|
||||
|
||||
### seeds.js
|
||||
Run seeds defined in `config/seeds.js`.
|
||||
Run seeds defined in `config/seeds.js`.
|
||||
|
||||
$ truffle exec scripts/seeds.js
|
||||
or
|
||||
$ truffle exec scripts/seeds.js
|
||||
or
|
||||
$ npm run seeds
|
||||
|
||||
|
||||
## Upgradeable contracts
|
||||
|
||||
Some of the contracts use upgradability ideas from [zeppelinos](https://github.com/zeppelinos/labs) (see `contracts/upgradable`).
|
||||
Some of the contracts use upgradability ideas from
|
||||
[zeppelinos](https://github.com/zeppelinos/labs) (see `contracts/upgradable`).
|
||||
|
||||
The basic idea is to have a Registry contract that knows about the current implementations and a Proxy contract that uses `delegatecall` to call the current implementation.
|
||||
That means the Proxy contract holds the storage and the address of that one does not change but the actuall implemenation is managed through the Registry.
|
||||
The basic idea is to have a Registry contract that knows about the current
|
||||
implementations and a Proxy contract that uses `delegatecall` to call the
|
||||
current implementation. That means the Proxy contract holds the storage and
|
||||
the address of that one does not change but the actuall implemenation is
|
||||
managed through the Registry.
|
||||
|
||||
To deploy a new version a new contract is deployed then the version is registered (`addVersion()`) in the Registry and on the Proxy contract is "upgraded" (`upgrade()`) to the new version.
|
||||
To deploy a new version a new contract is deployed then the version is
|
||||
registered (`addVersion()`) in the Registry and on the Proxy contract is
|
||||
"upgraded" (`upgrade()`) to the new version.
|
||||
|
||||
The Registry knows about all the different contracts and implementations. Versions are stored as uint and automatically incremented for every added implementation.
|
||||
The Registry knows about all the different contracts and implementations.
|
||||
Versions are stored as uint and automatically incremented for every added
|
||||
implementation.
|
||||
|
||||
### Example
|
||||
|
||||
### Example:
|
||||
|
||||
Deployment is best done using the [truffle deployer]()
|
||||
Deployment is best done using the truffle deployer.
|
||||
|
||||
1. Setup
|
||||
1. deploy the Registry
|
||||
2. deploy the contract
|
||||
3. register the contract at the Registry:
|
||||
1. Deploy the Registry
|
||||
2. Deploy the contract
|
||||
3. Register the contract at the Registry:
|
||||
`registry.addVersion('Token', Token.address)`
|
||||
4. create the Proxy:
|
||||
4. Create the Proxy:
|
||||
`registry.createProxy('Token', 1)`
|
||||
2. Update
|
||||
1. deploy a new Version of the contract
|
||||
2. register the new version at the Registry:
|
||||
1. Deploy a new Version of the contract
|
||||
2. Register the new version at the Registry:
|
||||
`registry.addVersion('Token', NewToken.address)`
|
||||
3. set the new implementation address on the Proxy contract:
|
||||
3. Set the new implementation address on the Proxy contract:
|
||||
`registry.upgrade('Token', 2)`
|
||||
|
||||
|
||||
## Known Issues
|
||||
|
||||
When resetting ganache Metamask might have an invalid transaction nonce and transactions get rejected.
|
||||
Nonces in Ethereum must be incrementing and have no gap.
|
||||
When resetting ganache Metamask might have an invalid transaction nonce and
|
||||
transactions get rejected. Nonces in Ethereum must be incrementing and have no
|
||||
gap.
|
||||
|
||||
To solve this reset the metamask account (Account -> Settings -> Reset Account)
|
||||
@@ -1 +1 @@
|
||||
[{"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":"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":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":"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,7 +1,7 @@
|
||||
const ethers = require('ethers');
|
||||
const RSVP = require('rsvp');
|
||||
|
||||
const Healthcheck = require('./utils/healthcheck');
|
||||
const Preflight = require('./utils/preflight');
|
||||
|
||||
const ABIS = {
|
||||
Contributors: require('./abis/Contributors.json'),
|
||||
@@ -97,8 +97,8 @@ class Kredits {
|
||||
return this.contracts[name];
|
||||
}
|
||||
|
||||
healthcheck() {
|
||||
return new Healthcheck(this).check();
|
||||
preflightChecks() {
|
||||
return new Preflight(this).check();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class Healthcheck {
|
||||
class Preflight {
|
||||
constructor(kredits) {
|
||||
this.kredits = kredits;
|
||||
}
|
||||
@@ -25,4 +25,4 @@ class Healthcheck {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Healthcheck;
|
||||
module.exports = Preflight;
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "kredits-contracts",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "kredits-contracts",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.2",
|
||||
"description": "Ethereum contracts and npm wrapper for Kredits",
|
||||
"main": "./lib/kredits.js",
|
||||
"directories": {
|
||||
@@ -34,5 +34,9 @@
|
||||
"ethers": "3.0.15",
|
||||
"ipfs-api": "^19.0.0",
|
||||
"rsvp": "^4.8.2"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"kosmos",
|
||||
"kredits"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user