Melon Protocol

Melon ([méllō], μέλλω; Greek for "destined to be") is blockchain software that seeks to enable participants to set up, manage and invest in technology regulated investment funds in a way that reduces barriers to entry, while minimizing the requirements for trust.

It does so by leveraging the fact that digital assets on distributed quasi-Turing Complete machines can be held solely by smart-contract code, and spent only according to preprogrammed rules within this code. The Melon protocol is a set of rules for how digital assets can be spent once held in a Melon smart-contract, or a Melon investment fund. These rules are meant to protect the investor and fund manager from malevolent behaviour of each other, even when both parties remain private.

Melon is to investment funds as Bitcoin is to accounting: a set of rules, enforced by blockchain technology, legitimized by the consent of its participants.

This repository contains a reference implementation of the Melon protocol written in Solidity, as specified in our paper.

Append the README.md in deployments/configs/[chain]-[track]/ with your change.

Change the addresses of the factory that you want to redeploy and of the version to "DEPLOY". This will redeploy the factory, and redeploy the version with the new factory and all old factories registered. Remove exchangeConfigs anyways, this is just for information.

Development Tips

Using the logger

To help debug the system, the test environment has loggers that log into ./logs/. This keeps the terminal clean but also a great possibility to inspect the logs in detail. Here is how it works:

Inside a function that has the environment, the environment.logger is a curried function with the following signature:

(namespace: string, level: LogLevels, ...messages: any): void;

This currying gives a high level of flexibility, but basically we just use this pattern:

const log = environment.logger('melon:protocol:module');
// and then use debug as you would console.log:
log(
LogLevels.DEBUG,
'Something happened',
interestingObject,
' ... and more ...',
whatever,
);

Basically, LogLevels.DEBUG just logs into the log files and does not output to the screen. LogLevels.INFO logs to the console for deployment but not during tests. So INFO logs should be concise whereas DEBUG logs should be verbose. LogLevels.WARN and LogLevels.ERROR log always to the console.

A consumer can obviously inject its own logger.

Deconstruct a transaction from the transactionFactory

Generally, transactions have a shortcut method called execute, which is renamed to the actual transaction name:

Skip gas estimation preflight/guards

Sometimes during development, one wants to check if a transaction actually fails without the guards. To do so, there are options inside of the transaction factory. The simplest example would be transfer. So here is the minimalistic usage of transfer with skipped guards and transactions:

Events

Main principle: Every smart contract should be seen as an event-sourced entity:

It has one current state. We can query the current state through calls.

This current state is the result of an initial state and a list of transactions that altered that state. When the state of a smart contract changes, it should emit events in a fashion that an external observer can reproduce the state of the smart contract from every point in history only by observing the emitted events.

In other words: Events should transport as much information as needed so that an observer can sync for example a database.

How to do this:

Define the shape of the state of a smart contract

Define possible changes to that state

Emit events when that state changes.

Example ERC20

Shape of state:

mapping (address => uint256) balances;

Possible changes:

Someone sends somebody an amount: Transfer

Emit events: It is obvious for that example, but lets see what an observer can see the following events and reproduce every step in history.

For the sake of simplicity, lets assume that: 0x0: is the null address 0x1: user 1 0x2: user 2 ...and so on

Spec json is invalid when running Parity Devchain

Stuck at deploy step

Deploying contracts may stuck indefinitely in case your parity node is not unlocked for some reason. Locked node requires you to enter password for each transaciton manually.

Contributing

As an open-source project, we welcome any kind of community involvement, whether that is by contributing code, reporting issues or engaging in insightful discussions. Please see our contributing instructions for information on the code style we use.

Security Issues

If you find a vulnerability that may affect live or testnet deployments please send your report privately to security@melonport.com. Please DO NOT file a public issue.

Protocol Design

When considering protocol design proposals, we are looking for:

A description of the problem this design proposal solves

Discussion of the tradeoffs involved

Review of other existing solutions

Links to relevant literature (RFCs, papers, etc)

Discussion of the proposed solution

Please note that protocol design is hard, and meticulous work. You may need to review existing literature and think through generalized use cases.

Implementation Design

When considering design proposals for implementations, we are looking for: