Skip to content

How to implement a Freicoin exchange

Jorge Timón edited this page Feb 3, 2014 · 1 revision

It is possible to implement a Freicoin exchange which results in stable trading with minimal overhead. I will assume that the exchange uses the demurrage-adjusted running balance approach to demurrage accounting, as this results in less complicated code and the smallest overhead, and exchanges need not do their accounting in the blockchain directly anyway.

The essence of the exchange is a collection of bid and a collection of ask orders (the orderbook), which are then matched into a sequential series of order fulfillment transactions, which themselves actually move balances around. Let's take each step in turn:

A bid/ask order is an open request by the user to trade XXX number of freicoins for YYY number of bitcoins, dollars, euros, beerbucks, or whatever. In our example Alice wants to trade 1,000frc for 0.5btc, and Bob has an open order giving bitcoins for freicoins at that price, although at the time they entered their bid/ask orders neither one cared when precisely it would occur. This is what the internal state of the exchange looks like:

Alice: <1,500frc, #19500>
       <   10btc>
Bob:   <  100frc, #20000>
       <   50btc>

Bids:  [<5,000frc, 2.5btc, Bob>]
Asks:  [<0.5btc, 1,000frc, Alice>]

Log:   []

This is the simplest model, but it should be obvious how it can be extended to support orders with expiry times, fill-or-kill status or other conditions.

The exchange continuously matches bids to asks, generating fulfillment transactions at the current block height. In this case the exchange creates a multi-chain transaction sending 1,000frc from Alice to Bob with a reference height equal to the current block height, and transferring 0.5btc back from Bob to Alice. Here's the state of the exchange after the fulfillment transaction is created:

Alice: <1,500frc, #19500>
       <   10btc>
Bob:   <  100frc, #20000>
       <   50btc>

Bids:  [<4,000frc, 2btc, Bob>]
Asks:  []

Log:   [<1,000frc Alice -> Bob, 0.5btc Bob -> Alice, #21000>]

An accounting process then replays the fulfillment transaction log, with each order fulfillment setting the reference height for the affected balances to the block height the transaction was fulfilled at (applying demurrage as described here):

Alice: <1,497.85576581frc, #21000>
       <   10btc>
Bob:   <   99.90467798frc, #21000>
       <   50btc>

Bids:  [<4,000frc, 2btc, Bob>]
Asks:  []

Log:   [...]

It then applies the recorded balance transfer (this and the demurrage adjustment should really be an atomic operation, otherwise the log is in an indeterminate state):

Alice: <  497.85576581frc, #21000>
       <   10.5btc>
Bob:   <1,099.90467798frc, #21000>
       <   49.5btc>

Bids:  [<4,000frc, 2btc, Bob>]
Asks:  []

Log:   []

Although it has been illustrative to consider these three steps as distinct from each other and occurring in parallel, the simplest application combines them all into a single sequential program which scans the orderbook and executes trades at the current block height. But I'll leave the implementation details as an exercise for the interested reader.

The only other notes worth making are that 1) since account balances decay, it's possible for naked bid/ask orders to exist at the time of fulfillment; make sure you check for this, and 2) the user-interface needs to perform demurrage calculations to show available balances based on the current block height rather than the reference-height of the latest fulfillment, which is what the database stores. Ideally this is done client-side in JavaScript (similar to the many web applications turn dates into localized text like "five minutes ago"), but it could be done server-side as well at the cost of making the user refresh to check their available balance.