About
========


This is an ethereum-based implementation of the [fathom
protocol](http://fathom.network/whitepaper/), which defines a peer assessment
protocol based on a participatory token economy: You get tokens through
assessment, you pay them to get assessed. This system is an abstracted
assessment framework capable of assessing anything: Anyone can create a
credential, anyone to get assessed in it and anyone who passes can assess
others. For more documentation see our
[documentation](http://docs.fathom.network/).

Contract Structure
==============

Fathom credentials (or: concepts) are are ordered hierarchically from most
general to most specific. For example, if you wanted to be assessed in creating
a Hello World program in Python you would create that assessment on the Hello
World concept, which would be a child of the Python concept, which would be a
child of the Programming concept, et cetera. This allows us to assemble
knowledgable assessors for new or young concepts by drawing them from their
parents.

At the heart of the contract-system is the `conceptRegistry`-contract. Upon
deployment, it creates the MEW-concept - a special concept at the root of the
concept-ontology that has no parent and is associated to no particular skill or
assessable quality. The conceptRegistry also manages the creation of new
concepts and serves as a central point-of-reference for the other system
contracts:

- `FathomToken`: Manages account balances and, together with the 'Minter'
  periodically creates new tokens that are distributed in a lottery mechanism to
  successfull assessors.
- 'ProxyFactory': A factory-contract to create proxies for the many concepts and
  assessments. By changing the template of the proxy, it can also be used to
  introduce updates to the system, such as changing the assessment-rules.
- 'Distributor': A contract designed to be used for deploy-time only. It is used
  to directly add the initial members to the MEW-concept bypassing the need to
  complete an assessment, but will only do so a predefined number of times.
  
Then there are the two central contracts that define credentials and how they
are issued:
- 'Concept': Defines what a credential is about, stores information about
  the credential-holders (aka concept-members) and creates new assessments.
- 'Assessment': Calls assessors, runs the assessment game and, upon a positive
  outcome, adds the assessee as a new member to the concept.
  
Dependencies
========

Install all dependencies by running 

> npm i

This will install 
- [ganache-cli](https://github.com/trufflesuite/ganache-cli) (formerly named testrpc), to run your private testnet,
- [truffle-hd-walletprovider](https://github.com/trufflesuite/truffle-hdwallet-provider) to manage keys when deploying to rinkeby and
- [ethjs-abi](https://github.com/ethjs/ethjs-abi) and [ethereumjs-abi](https://github.com/ethereumjs/ethereumjs-abi), to be able to run all our tests.

Deployment
========

Deploying a fathom-network-instance will lead the following contracts being on-chain:

- ConceptRegistry.sol, to manage creation of new concepts
- FathomToken.sol, to manage payments
- One instance of Concept.sol, being the root of the concept-tree (the _MEW-concept_)
- Math.sol, a library to do scoring and clustering

### Local Testnet 

Open a console and run your private testnet with 30 accounts.
> ganache-cli -a 30

In another console, run the migration: 
>'truffle migrate'

All address in the testnet will be funded with AHAs and the first six will be
added to the Mew Concept.

### Public Network

To deploy to a public network you need to supply a funded account. You can do
this by creating a file called `secrets.json` in the root folder
('./'), containing seed words that have ETH on the network you want to deploy
to. 

Your secrets.json-file should look like this: 
>"baseball poet vague session shrimp humus embrace glare monkey donkey balony bread"

#### 1) Specify the initial accounts

You need to provide at least one address for the initial accounts to the system.
These will have tokens distributed them and will be entered into the mew
concept. To do so, create a file `./initialMembers.json` in the root-folder of
the project.

Its content should look like this

>'["0xaccount1...", "0xaccount2...", ... ]'

To modify the amount addresses are funded with , open
`/migrations/2_deploy_contracts.js` and set the variable `initialAmount` to the
desired value.

_*NOTE*: If you *DON'T* want to the MEW-concept to have any initial members nor
distribute tokens to them, remove the third and fourth migration-file and
continue at step 3). (Be aware that this you'll have to manually call the
distributor and add the first member to the MEW-concept before any assessment
can be run in your system.)_

If you *DO* want to seed the network with some initial users in the mew-concept
add them to the list of initial accounts.

#### 2) Configure token & member distribution

By default, all tokens will be distributed amongst all addresses in the
initial-member list and all addresses will be added to MEW. If you want to
change that play around with the parameters in [getAccounts.js](js/getAccounts.js).

#### 3) Deploy

Lastly, run 
>'truffle migrate --network rinkeby' 

or 

>'truffle migrate --network kovan 

#### 4) Troubleshooting

- If you encounter an error-message saying 'Unknown number of arguments to
  solidity-function' it sometimes helps to recompile everything: 
  > rm -rf ./build

- If you get any other issues feel free to open an issue or add to an existing
one.


Tests
============
Most functionnalities are tested in the test files inside the 'test' folder. 
To run them, try: 
> truffle test

Also, there is a script 'create2concepts2assessmnets.js' that creates two new
concepts and initiates an assessment on each. When deploying to a
non-development testnet, supply the name of the net as argument: 
> node create2concepts2assessments.js rinkeby

For further tests, there also is a script that runs an assessment until a given stage, e.g.:

> node completeAssessment.js -s commit 100,100,90,90,90,90

, which will create a concept, create an assessment of size 6 in it and will
complete the stage commit (assessors logging in the given scores). More examples
of how this script can be used are to be found in the comments inside of it.
Note that this ONLY works on your local testnet, because you can not send the 
_evmIncreaseTime_-command to an actual testnet.

Coverage
===========

We use [solidity-coverage](https://github.com/sc-forks/solidity-coverage):

> npm run coverage

You can find the current coverage [here](https://fathom.gitlab.io/fathom-contracts)

Contributing
=========

To contribute to this project...
- check out our [contribution guide](https://gitlab.com/fathom/org) to see how
  you we work together,
- talk to us on [gitter](https://gitter.im/fathom-network/Lobby) or
- send an email to <contact@fathom.network> if you would like to get in contact.

This repo has two relevant branches: master and development. master holds
the version of our protocol which will eventually be deployed on the main-net.
On the development-branch, the protocol is modified to make testing and
developing for it much easier. Therefore, several constants (e.g. minimum number
of assessors) have been factored out into an extra-contract, so that it becomes
possible to create and complete assessments without having to wait and whithout
controlling many accounts.

Styleguide
==========

#### Solidity

We follow the [solidity-style
guide](https://solidity.readthedocs.io/en/develop/style-guide.html) and have
recently committed to using the
[solhint](https://protofire.github.io/solhint/rules.html)-linter to enforce it.

After installing it, simply run 
> solhint ./contracts/xxx.sol

until your code does not generate any errors or warnings.


#### Javascript

We follow Standard JS style guide.

[![JavaScript Style Guide](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)

To use its linter, run the following command:
```
npm run lint-js
```
This will check all JavaScript files in the current working directory and call attention to any code that needs fixing. 


Troubleshooting
==========

If the tests fail even though you think they shouldn't, sometimes it helps to do clean the build folder and run them anew:
```
rm -rf build
```
