Anatomy of an Asset
Each Bantu asset has two characteristics: the asset code and the issuer. When you look up or interact with an asset on Bantu, you always use both to identify it.
Many Bantu tokens represent credits that can be redeemed for something outside the network—often fiat currency, but also bonds, carbon credits, gold, etc.—and since more than one organization can issue a credit representing the same underlying asset, asset codes often overlap. More than one company offers a USD token on Bantu, for instance.
However, the combination of asset code and issuer allows each asset to be uniquely identified: each USD token is offered by, and redeemable with, one specific issuer.
When you issue an asset, the first thing you do is choose an identifying code. Currently, there are two supported formats.
- Alphanumeric 4-character maximum: Any characters from the set [a-z][A-Z][0-9] are allowed. The code can be shorter than 4 characters, but the trailing characters must all be empty.
- Alphanumeric 12-character maximum: Any characters from the set [a-z][A-Z][0-9] are allowed. The code can be any number of characters from 5 to 12, but the trailing characters must all be empty.
Provided it falls into one of those two buckets, you can choose any asset code you like. That said, if you’re issuing a currency, you should use the appropriate ISO 4217 code, and if you’re issuing a stock or bond, the appropriate ISIN number. Doing so makes it easier for Bantu interfaces to properly display and sort your token in their listings, and allows potential token holders to understand, at a glance, what your token represents.
There is no dedicated operation to create an asset on Bantu. Instead, assets are created with a payment operation: an issuing account makes a payment using the asset it’s issuing, and that payment actually creates the asset on the network.
The public key of the issuing account is linked on the ledger to the asset itself. Responsibility for and control over an asset resides with the issuing account, and since settings are stored at the account level on the ledger, the issuing account is where you use
set_optionsoperations to link to meta-information about an asset and set authorization flags.
Before an account can hold an asset another account issues, it has to establish something called a trustline, which is a persistent account-level ledger entry created with a
A trustline is an explicit opt-in to hold a particular token, so it specifies both asset code and issuer. Each trustline increases an account’s minimum lumen balance by one base reserve — currently 0.5 XLM — and tracks the balance of the asset the account holds. Trustlines can also limit the amount of an asset an account can hold, though more often than not, account holders don’t set that limit: they simply turn the trustline on, which by default allows the maximum.
A trustline also tracks liabilities. Buying liabilities equal the total amount of the asset offered to buy aggregated over all offers owned by an account, and selling liabilities equal the total amount of the asset offered to sell aggregated over all offers owned by an account. A trustline must always have balance sufficiently large to satisfy its selling liabilities, and a balance sufficiently below its limit to accommodate its buying liabilities.
In Expansion, assets are represented in a JSON object:
// `asset_type` is used to determine how asset data is stored.
// It can be `native` (XBN), `credit_alphanum4`, or `credit_alphanum12`.
In the Bantu SDKs, they’re represented with the
var astroDollar = new StellarSdk.Asset(
Each asset amount is encoded as a signed 64-bit integer in the XDR structures that Bantu uses to encode transactions. The asset amount unit seen by end users is scaled down by a factor of ten million (10,000,000) to arrive at the native 64-bit integer representation.
For example, the integer amount value
2.5123456units of the asset. This scaling allows for seven decimal places of precision in human-friendly amount units.
The smallest non-zero amount unit is
0.0000001(one ten-millionth) represented as an integer value of one. The largest amount unit possible is
((2^63)-1)/(10^7)(derived from max int64 scaled down) which is
The numbers are represented as
int64s. Amount values are stored as only signed integers to avoid bugs that arise from mixing signed and unsigned integers.
In Expansion and client-side libraries such as