Skip to main content
Version: v1.10

Accounting model

Accounts

Accounts are containers for assets. They can send and receive assets using transactions, the sum of which will determine their balances.

balance(account)=postings(destination)postings(source)balance(account) = \sum postings(destination) - \sum postings(source)

The number of accounts in a ledger is unlimited.

Accounts don't have to represent a real account in your bank; they can represent anything that has meaning to your application. Once you grasp the idiomatic Formance way of building financial applications, you'll start using accounts to represent abstract concepts in your business logic, like a sale, a contract or a payment.

Accounts also do not need to be created prior being used, as submitting a transaction involving it will automatically make it exist in the ledger.

Naming accounts

Accounts are identified by their address, which must match ^[a-zA-Z_0-9]+(:[a-zA-Z_0-9]+){0,}$. It recommended to use colons in addresses to organize them in structured segments, i.e. payments:001:authorization, although this does not trigger any particular behavior on the ledger.

payments:001:authorizations:001
sales:001:contract

Using Metadata

Accounts can bear metadata, which in a key-value format. This metadata can be used to store any information that is relevant to the account, like a reference to an external system, or a description of the account.

tip

Accounts metadata can also be used in Numscript transactions, see metadata in Numscript for more information.

Transactions

An important distinction between ledger solutions is the transaction model they uses underneath.

There are multiple options there, the key distinctions you'll find in the wild being the number of postings per transactions and the number of i/o per postings. Formance uses single i/o postings with multi-postings transactions.

Postings

In Formance and in general, postings model the movement of an amount of an asset from one account to another, e.g. Alice giving 100 coins to Bob:

{
"source": "alice",
"destination": "bob",
"asset": "COIN",
"amount": 100
}

In Formance, transactions model the wrapping of postings with the intent of committing them atomically, e.g. Alice trading coins for gems over the counter:

{
"postings": [
{
"source": "alice",
"destination": "teller",
"amount": 100,
"asset": "COIN"
},
{
"source": "teller",
"destination": "alice",
"amount": 5,
"asset": "GEM"
}
]
}

The rationale behind single i/o postings w/ multi-postings transactions originates from Formance's goal: help developers build sound financial applications, and supported by these observations:

  • Multi-postings transactions allows the ledger to leverage atomicity to reduce the complexity on your side to handle complex transactions, e.g credit this user of X coin by funding the credit from multiple other accounts.

  • While mathematically correct, multi i/o postings are inherently hard to grasp mentally and make auditability a challenge, which goes against our stated goal.

  • In any-case, if needed, multi-postings transactions can be used to model multi i/o postings - by using a transient account, that receives all funds and resends them in a single transaction