Tokens โ
The GamePlatform's Ledger contains:
- 3 bigmaps related to tokens:
ledger
,token_metadata
andtoken_permissions
.
The two first are those describe in FA2 standard.
Thetoken_permissions
describes specific permissions associated with the token. - FA2 entrypoints +
transfer_and_call
+update_token_permissions
,push_bonds
,mint
,burn
,withdraw
.
Platform tokens should not be confused with bonds. Tokens are stored outside of channels.
Token 0 often corresponds to wrapped XTZ (basically they can be minted by sending xtz and burned so you receive xtz). Other tokens can correspond to FA1.2/FA2 external tokens or internal tokens.
The admin can authorize a model or a specific game to distribute platform tokens (like reputation tokens).
Push bonds โ
See push_bonds.
Mint tokens โ
Native tokens (tokens managed by the ledger) can be minted according to the permissions.
@sp.entrypoint
def mint(self, address, token_id, amount):
sp.set_type(address, sp.TAddress) # Address of the receiver
sp.set_type(token_id, sp.TNat) # Id of the token
sp.set_type(amount) # Amount minted
ledger.mint(
address = player1.address,
token_id = 0,
amount = 100 * 10**6
).run(sender = player1, amount = sp.tez(100))
Burn tokens โ
@sp.entrypoint
def burn(self, address, token_id, amount):
sp.set_type(address, sp.TAddress) # Address of the receiver
sp.set_type(token_id, sp.TNat) # Id of the token
sp.set_type(amount) # Amount minted
ledger.burn(
address = player1.address,
token_id = 0,
amount = 100 * 10**6
).run(sender = player1, amount = sp.tez(100))
Unwrap native tokens โ
Certain native tokens can be unwrapped. In this case they are burned and retransformed.
For example you can unwrap your wXTZ to receive XTZ.
@sp.entrypoint
def withdraw_ledger(self, receiver, tokens):
sp.set_type(receiver, sp.TAddress) # Address of the receiver
# Map of `token_id => amount` you want to withdraw
sp.set_type(tokens, sp.TMap(sp.TNat, sp.TNat))
platform.withdraw_ledger(
receiver = player1.address,
tokens = sp.map({0: 10_000_000})
).run(sender = player1)
Tokens metadata and authorization โ
Token Metadata โ
Set the token metadata.
Token metadata corresponds to those described in TZIP-12 and TZIP-16.
@sp.entrypoint
def set_token_metadata(self, token_id, metadata):
# The id of the token as represented in the platform
sp.set_type(token_id, sp.TNat)
# Metadata of the tokens
sp.set_type(metadata, sp.TMap(sp.TString, sp.TBytes))
c1.set_token_metadata(
token_id = 1,
metadata = {
"name" : sp.utils.bytes_of_string("Wrapped Dummy FA2"),
"decimals" : sp.utils.bytes_of_string("%d" % 0),
"symbol" : sp.utils.bytes_of_string("WDFA2"),
"type" : sp.pack("FA2"),
"max_supply" : sp.pack(100_000_000_000),
"fa2_address" : sp.pack(dummyToken.address),
"fa2_token_id": sp.pack(0),
}
).run(sender = admin)
Set Token Permissions (admin only) โ
Set the token permissions.
The token permissions are pack of the value.
Key | Value Type | Description |
---|---|---|
burn_permissions | sp.TVariant("onlyOwner": Unit, "allow_only: Set(Address)) | Type of permission applied to burn (if not present no burn allowed) "allow_only": only addresses in this set are allowed to burn |
fa_token | Pair(Address, Nat) | Contract address and token_id of the corresponding fa token |
fa2_token_id | Nat | id of the corresponding fa2 token |
mint_cost | Mutez | number of mutez need to mint 1 token |
mint_permissions | sp.TVariant("allow_everyone": Unit, "allow_only: Set(Address)) | Type of permission applied to mint (if not present no mint allowed) "allow_only": only addresses in this set are allowed to mint |
transfer_only_to | Set(Address) | The token can only be transferred to one of those addresses |
transfer_only_from | Set(Address) | The token can only be transferred from one of those addresses |
type* | String {"FA2" , "Native" } | Type of token represented. |
* required
@sp.entrypoint
def update_token_permissions(self, token_id, metadata):
# The id of the token as represented in the platform
sp.set_type(token_id, sp.TNat)
# Permissions of the tokens. If None, the key is deleted.
sp.set_type(metadata, sp.TMap(sp.TString, TOption(bytes)))
lgr = sp.io.import_template("state_channel_games/ledger.py")
c1.update_token_permissions(
token_id = 1,
metadata = lgr.build_token_permissions({
"type" : "NATIVE",
"mint_cost" : sp.mutez(1),
"mint_permissions": sp.variant("allow_everyone", sp.unit)
})
).run(sender = admin)
Game permissions โ
Each running game can have the permission to mint tokens.
The metadata of the game must contain the following key: allowed_mint
.
Its value is a map of bonds and amount.
The game can at most ask the platform to mint this number of tokens when being settled.
Change the game metadata โ
Only admins can change the game metadata.
gameplatform.admin_game_metadata(game_id, "allowed_mint", sp.pack({42: 1000}))
Model permissions โ
The models can have the permission to mint tokens.
The metadata of the model must contain the following key: allowed_mint
.
Its value is a map of bonds and amount.
The model can at most ask the platform to mint this number of tokens.
The value is decreased or left unchanged after each settle of a game held by the model.
Change the model metadata โ
Only admins can change the model metadata.
gameplatform.update_model_metadata(model_id, "allowed_mint", {42: 100_000_000})