Fair Minting is a process whereby users are able to “mint” tokens in a decentralized manner. One user initiates the mint (either with or without a “premint”), and then other users are able to trigger it to create tokens for themselves. Fair Minting was likely inspired by the original Counterparty Proof-of-Burn mechanism, by which users sent BTC to an unspendable address and XCP tokens were generate for them automatically.
More recently, BRC-20 introduced a variant of the Fair Mint model that has been adopted by many fungible token protocols recently, including SRC-20 on Bitcoin Stamps. In this system, users are able to mint "for free" by paying only a miner fee: the term “fair mint” refers to the fact that the creator of the minting system is not enriched in the process, and that the minting process is decentralized
In 2023, Joe Looney introduced the ”XCP-20” Fair Mint model by setting up a dispenser on a burn address; its name is a tongue-in-cheek reference to BRC-20. Buyers, largely unaware that Counterparty existed—and this was not new in any way—sent massive amounts of Bitcoin to the burn address and received tokens in return. In this way, tokens got distributed, but the deployer was not directly enriched.
Additional functionality may be added as well:
- A “soft cap” mechanism, establishing a minimum amount of the token to be issued, optionally by a particular block height. (Before
soft_cap_deadline_block
payment will be escrowed trustlessly.) - A commission in the new token sent to the creator of the mint for each mint operation (proportional to the quantity minted)
- A “Start Block” and “End Block”
Implementation Notes:
- Fair Mints will be possible by issuers of extant assets as long as those assets do not have locked quantities.
- The
premint
quantity will be credited to the issuer at thestart_block
. - If an asset can be reset it can also be Fair Minted, but fair minting itself would not first effect an asset reset.
- If, after
end_block
the total quantity issued of the asset is less thanhard_cap
, then the future issuances or fair mints may be done on the asset until the the quantity issued equalshard_cap
. - For the duration of the mint period, the state of description lock and quantity lock cannot be changed.
It would be possible, to use the issuances.py
contract and add the fair minting implementation to it. However, this contract is already 1000 lines long and it is preferable not to add complexity to it. New contracts will therefore be implemented but, to ensure maximum compatibility with other assets, the issuances
and assets
tables will be used: the creation of a fair minting will result in the creation of a line in the assets
and issuances
tables and then each fair mining will result in the creation of a line in the issuances
table.
There will be two new contracts: fairminter.py
and fairmint.py
. These two contracts will respect the usual interface of all other contracts, that is to say the functions initialise()
, validate()
, compose()
, unpack()
and parse()
. The first will allow the creation of a "mintable" asset and the second will allow users to "mint" this asset. After the minting period, a minted asset functions just like a locked issuance asset.
-
fairminter.compose()
- db: Database connection
- asset: Asset to be minted
- price: Price in XCP of each unit of asset, by default, 0
- max_mint_per_tx: Amount minted if price is equal to 0; otherwise, maximum amount of asset that can be minted in a single transaction. If None, there is no limit.
- description: Description of the asset
- hard_cap: Maximum amount of asset to be minted, if None, no limit
- burn_payment: If True, the payment asset is burned, otherwise it is sent to the source
- premint_quantity: Amount of asset to be minted when the sale starts, if 0, no premint; preminted assets are sent to the source of the transaction
- start_block: Block at which the sale starts, if None, the sale starts immediately
- end_block: Block at which the sale ends, if None, the sale never ends
- soft_cap: Minimum amount of asset to be minted, if None, no minimum; if the soft cap is not reached by the
soft_cap_deadline_block
, the sale is canceled, asset is revoked from all minters and all payments are refunded - soft_cap_deadline_block: Block at which the soft cap must be reached, required if soft_cap is not None
- asset_parent: Asset to be used as parent for the new asset. If provided, the issued asset will be numeric with an
asset_longname
equal to<asset_parent>.<asset>
. The source of the transaction must be the issuer of the parent asset - lock_description: If True, the description of the asset cannot be changed
- lock_quantity:
- minted_asset_commission: Commission to be paid in minted asset, a fraction of 1 (i.e., 0.05 is five percent); the commission is deducted from the asset received by the minter and sent to the Fair Minter owner
-
fairmint.compose()
- db: Database connection
- asset: Asset to be minted
- quantity: Quantity of asset to be minted, by default
mint_per_tx
from the correspondingfairminter
- New Routes
- Get All Fair Minters:
/v2/fairminters
- Get Fair Minter By Tx Hash:
/v2/fairminters/<tx_hash>
- Get Fair Minter By Asset:
/v2/assets/<asset>/fairminter
- Get Fair Minters By Address:
/v2/addresses/<address>/fairminters
- Get Mints By Fair Minter:
/v2/fairminters/<tx_hash>/mints
- Get Mints By Asset:
/v2/assets/<asset>/mints
- Get Mints By Address:
/v2/addresses/<address>/mints
- Get All Fair Minters:
- A
fair_minted
field will be added to theissuances
table. This is the field that will be checked to prevent token issuance other than through fair minting. - A new table
fairminters
will be created with the following fields:- tx_hash (Fair Minter identifier)
- block_index
- source (source of the transaction)
- asset
- parent_asset
- description
- price
- payment_asset
- hard_cap
- burn_payment
- max_mint_per_tx
- premint_quantity
- start_block
- end_block
- payment_asset_commission
- minted_asset_commission
- soft_cap
- soft_cap_deadline_block
- status (
open
,closed
,cancelled
,invalid: <reasons>
)
- A new table
fairmints
will be created with the following fields:- tx_hash (Mint identifier)
- block_index
- fair_minter_tx_hash
- asset
- quantity
- payment_asset
- payment_quantity
- status (
valid
,invalid: <reasons>
)
For each row in the fairminters
and fairmints
table a row will be added to the issuances
table.
- Ouziel Slama
- Adam Krellenstein
- mikeinspace
Initial thoughts...
Eliminate burn payment parameter by just setting commissions to zero.On further review, this doesn't make sense as burn/source option is independent of commission