Intent/Audience
This document is for developers aspiring to improve Complementary Currencies for Drupal or to build something similar for another platform.
Introduction
This architecture supports mutual credit systems such as LETS, SEL, Tauschring and Timebanks. These systems are characterised by the sum and mean of all user balances always being zero. There is no central authority issuing the currency, managing liquidity or inflation. There is no possibility of forgery because the system calculates the balances from the sum total of transactions, and every transaction has a description, a payer and a payee.
The story of a transaction
Ben did some Gardening for Ann. She logs on to her community web site to pay him. On his profile she fills in a form entitled 'transact with Ben' She simply completes the transaction direction (that she is paying him), the number of credits, and a description of what he did. The system infers that she is starting the transaction and that Ben is completing it. Then the system checks that both are within their balance limits before showing a confirmation page which asks her to rate Ben's work. When she submits this she can see her cleared balance has changed and has an opportunity to edit or delete the transaction before Ben signs it.
Ben receives an email and clicks on it. He sees the transaction waiting to be completed on his 'money' page. He clicks to sign it and the transaction is complete and can only be edited by an administrator.
Transaction Form
Another important component is the transaction form, which needs to be context sensitive to save users filling in unneccessary fields. The form has three modes.
- INIT, for when only one or two fields are provided. This will typically show the starter/completer selectors
- EDIT, for a user to edit their transaction before the completer signs it. This doesn't allow changing of the participants or the direction because it would be too complex
- FULLEDIT, for an administrator to have full access. This form allows for contradictory data in the payer/payee/starter/completer selectors.
The transaction object
At the heart of the system is the transaction object. It contains the following properties:
- Transaction ID: auto-increment integer (Key)
- Title: string
- Quantity: integer or float
- Currency ID: currency ID
- Quality rating: float
- Payer ID: user ID
- Payee ID: user ID
- Starter ID: user ID
- Completer ID: user ID
- Transaction type: enum
- Depends On: transaction ID
- Currency: currency data
- Starter: information about the starter user
- Completer: information about the completer user
- State: enum.
There are four possible transaction types, namely:
- incoming_direct
- incoming_confirmed
- outgoing_direct
- outgoing_confirmed.
There are three transaction states so far:
- completed
- pending
- deleted with room for another
- contested
Whenever the transaction form is processed, or a transaction loaded from the database, it must first be converted to a transaction object. In this format it can be passed around the system. The form will sometimes contain only partial information, such as starter, completer and direction, so the payee and payer need to be derived, or inferred from the other data.
Permissions
These need to be a little more elaborate than many frameworks probably provide. Transactions can always be viewed by an accountant, and either of the participants. But systems will want to decide for themselves whether transactions can be seen by all members or even by non-members. And of course the ability to 'edit' or 'sign' a transaction depends on who it's starter and completer are.
Transaction actions
When a transaction is viewed in a list or on a page of it's own, some buttons are provided, depending on the user's permissions. The buttons are Sign, Edit, Delete. These are nothing to do with the transaction form.
API
This is not well developed, but the most useful function will create a transaction in one
function generate_transaction_node($title, $payer_uid, $payee_uid, $quantity, $options=array(), $cid=0){}
In the Complementary Currencies module for Drupal, this is used to create the transaction from the form, but also for mass payments and generating example data. It has also been used for auto-payments such as demurrage, and will shortly be used to imprint transactions from offers and wants.
Balances
The system retains it's integrity by deriving the balances from the sum of a user's transactions. So for performance reasons there is a cache table which contains a row for each currency for each user:
- User ID
- Currency ID
- Current balance
- Cleared balance
- Pending difference
- Gross income
- Average rating
Displays
There are many ways to do this but the suggested displays are:
- User balances
- User transactions by month, incoming and outgoing
- Recent user transactions, showing the running balance
- A history of the account balance as a google chart
- A list of all pending transactions
Most of the displays depend on a function which will get all the transactions a user was involved in, and optionally add the running balance, and return the ones for a given time period. I call this
function get_transactions_for_user($uid, $options=array(), $running_balance = FALSE){}
Transaction ratings
A configuration text field invites administrators to determine the scale on which transactions are rated. This is actually asking for numeric keys and textual values for the rating dropdown selector. Ratings are averaged out and presented alongside balances, per currency.
Accounts
There isn't always a 1:1 relationship between users and accounts. Currently the system assumes account 1 (like user 1 in Drupal) is special. But there is a need for more non-member accounts. Taking this idea further, the trading account numbers could be decoupled from the user IDs and users would have permissions to manage certain accounts, rather than identifying with those accounts.
Stats
There is one basic function which loads all recent transactions and analyses them into a data structure. This can also be cached before being handed to a display function
Currencies and multiple currencies
So the transaction object, form and many of the displays all carry with them a currency ID. In a single currency system, this value is set at zero and the default currency properties stored in a system variable. For systems with more currencies, a database table is needed. Each currency has the following values:
- name - textfield
- icon - small image
- purpose - textfield
- default max credit - positive integer
- default max debit - negative integer
- relative value - that's relative to other currencies within a larger schema. this would be used
- for trading between currencies and transactions between systems
- division i.e. integers, hundredths or quarters of an hour
- zero offset - By offsetting zero you can work to counter any stigma which might be attached to keeping a debit balance.
In a large system in which anyone has permission to create a currency, there is a need to restrict the currencies visible to a given user so as not overwhelm them. Marketplace is experimenting with 'universal' and 'meme' currencies. Universal currencies can be seen by all, but meme currencies can only be seen by people who have traded with them. So meme currencies spread around the system as people use it.
In the future we might build multiple currencies per transaction. This will involve rebuilding the transaction object to include an array of currency ids and quantities to summarise several transactions with the same id.
Reporting.
Because of the lack of coordination in the CC movement, this function does a little data gathering. Right now it just collects the domain name, site name, number of active members and number of transactions in the last 30 days.
Classified ads, (Offers and wants)
This is a simple content type which can be edited by its creator and admin only. It has the following properties:
- title
- body (optional)
- price (version 1.1 only)
- currency ID - integer (version 1.1 only)
- unit - one off, per hour, per day (version 1.1 only)
Volunteer recognition system
Some would view it as a currency, but there is a kind of volunteering recognition system (currently at version 0.5). The idea is that a committee member will post a volunteer request to do a specific task. A member will pledge to do it, and a committee member will mark it completed. Whereupon the volunteer 'owns' that task and a kudos counter in his profile is incremented.
Comments