🎛️Modules
Overview
Cronos PoS Chain utilizes Cosmos SDK and the Tendermint Core consensus engine underneath. Specifically, the Cosmos SDK is a framework that facilitates the development of secure state-machines on top of Tendermint. In particular, we utilize different SDK modules to facilitate the special features of the Cronos PoS Chain.
In this documentation, we will be focusing on some of the important modules we used, for example:
Authz - Facilitates authorizations granted to one account to perform actions on behalf of another account;
Bank - Token transfer functionalities and query support for the total supply of all assets;
Distribution - Fee distribution, and staking rewards to the validators and delegator;
Governance - On-chain proposals and voting;
Mint - Creation of new units of staking token;
Nft - Non-Fungible Token management;
Slashing - Validator punishment mechanisms;
Staking - Proof-of-Stake layer for public blockchains;
Supply - Retrieve total and liquid supply.
authz
authz
Introduction
The authz
module facilitates granting authorizations to perform actions, such as spending tokens, on behalf of one account to other accounts.
Overview
An authorization is an allowance to execute an action by the grantee on behalf of the authorization granter, e.g. to send tokens to an account from the granter, or to delegate tokens to a validator from the granter. There are 3 major built-in authorization types:
SendAuthorization
StakeAuthorization
GenericAuthorization
SendAuthorization
SendAuthorization
implements an authorization to the grantee to perform, on behalf of the granter, a basic send
action defined in the bank module. It takes a SpendLimit
that is greater than 0 to specify the maximum amount of tokens the grantee can spend. The SpendLimit
keeps track of how many tokens allowed are left in the authorization and is updated as the tokens are spent until the SendAuthorization
get cleared when the SpendLimit
reach 0. Sending an amount greater than the SpendLimit
is not allowed.
StakeAuthorization
StakeAuthorization
implements an authorization to the grantee to perform, on behalf of the granter, delegate
, unbond
(undelegate), or redelegate
actions defined in the staking module. Each of the above actions need to be authorized separately, with which either an AllowList
or a DenyList
must be specified to restrict which validators to or not to perform a staking action with. Optionally, MaxTokens
can also be specified in the authorization that keeps track of a limit to the amount of tokens to be delegated/undelegated/redelegated. If left unspecified, the amount is unlimited. Similar to the SpendLimit
in SendAuthorization
, MaxTokens
gets updated after each valid authorized staking action. An authorized staking action that uses tokens beyond the MaxTokens
is not allowed.
GenericAuthorization
GenericAuthorization
implements an authorization to the grantee to perform, on behalf of the granter, a generic action. In other words, GenericAuthorization
facilitates an arbitrary action grant, where a MsgTypeURL
must be specified to correspond to an action defined in the modules. A GenericAuthorization
is currently unrestricted beyond the MsgTypeURL
. For example, when granting someone to send tokens, the SpendLimit
in SendAuthorization
will not be enforced. Therefore, a SendAuthorization
without a spend limit may in fact be implemented as a GenericAuthorization
with the MsgTypeURL
been set to /cosmos.bank.v1beta1.MsgSend
. The following are some common MsgTypeURLs
:
Send:
/cosmos.bank.v1beta1.MsgSend
Delegate:
/cosmos.staking.v1beta1.MsgDelegate
Unbond/Undelegate:
/cosmos.staking.v1beta1.MsgUndelegate
Redelegate:
/cosmos.staking.v1beta1.MsgBeginRedelegate
Withdraw delegator reward:
/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward
Mint NFT:
/chainmain.nft.v1.MsgMintNFT
Burn NFT:
/chainmain.nft.v1.MsgBurnNFT
Transfer NFT:
/chainmain.nft.v1.MsgTransferNFT
Edit NFT:
/chainmain.nft.v1.MsgEditNFT
::: tip NOTE Expiration of Grant: The granter can optionally set an Expiration
time in form of a UNIX Timestamp for any authorization grant. The Expiration
time should be later than current UNIX Timestamp and is defaulted to be one year from current time if unspecified. An authorization may be executed only if the grant has not yet expired. Setting an Expiration
time for an authorization grant is generally encouraged. :::
Transactions and Queries
Transactions
In general, a granter can grant
an authorization to a grantee or revoke
an existing authorization already granted to the grantee. A grantee can execute
an authorization already granted by the granter.
grant
:
grant
:An authorization starts from the granter granting the grantee.
under
SendAuthorization
tx authz grant [grantee_address] send --spend-limit [amount] --from [granter_address]
- Grant to send with a spend limit
tx authz grant [grantee_address] send --spend-limit [amount] --from [granter_address]
- Grant to send with a spend limitExample: Grant to send with a spend limit and an expiration time The granter may grant a grantee to send tokens on the granter's behalf, where a spend limit should be provided through the --spend-limit
flag. For example, granter may authorize grantee to spend up to 10 CRO
, and sets an expiration time at the end of the year 2022 (i.e. 1672531199
in Unix timestamp) by running
under
StakeAuthorization
tx authz grant [grantee_address] delegate --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to delegate to validators on a specified list
tx authz grant [grantee_address] delegate --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to delegate to validators on a specified listExample: Grant to delegate to validators on a specified list with a spend limit The granter may grant a grantee to delegate tokens on the granter's behalf, where either a list of allowed validators (through the --allowed-validators
flag) or denied validators (through the --deny-validators
flag) should be provided. For example, granter may authorize grantee to delegate on the granter's behalf up to 10 CRO
towards a specified list of validators by running
On the contrary, the granter may choose to exclude a list of validators the grantee can delegate to on the granter's behalf:
tx authz grant [grantee_address] delegate --spend-limit [amount] --deny-validators [list_of_deny_validators_separated_by_,] --from [granter_address]
- Grant to delegate to validators excluding a specified list
tx authz grant [grantee_address] delegate --spend-limit [amount] --deny-validators [list_of_deny_validators_separated_by_,] --from [granter_address]
- Grant to delegate to validators excluding a specified listGranting to redelegate or undelegate (unbond) is very similar by just replacing the delegate
with redelegate
or unbond
:
tx authz grant [grantee_address] redelegate --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to redelegate to validators on a specified list
tx authz grant [grantee_address] redelegate --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to redelegate to validators on a specified listtx authz grant [grantee_address] unbond --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to unbond from validators on a specified list
tx authz grant [grantee_address] unbond --spend-limit [amount] --allowed-validators [list_of_allowed_validators_separated_by_,] --from [granter_address]
- Grant to unbond from validators on a specified listNOTE Spend Limit for StakeAuthorization
: A spend limit for a grant to delegate/redelegate/unbond is not necessary but generally recommended.
under
GenericAuthorization
Other than the above grants under SendAuthorization
or StakeAuthorization
, one may authorize other grants through GenericAuthorization
:
tx authz grant [grantee_address] generic --msg-type [msg_type_url] --from [granter_address]
- Grant for generic authorization with a specified Message Type URL
tx authz grant [grantee_address] generic --msg-type [msg_type_url] --from [granter_address]
- Grant for generic authorization with a specified Message Type URLExample: Grant to withdraw delegator reward
Similarly:
tx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgMintNFT --from [granter_address]
- Grant to mint NFT
tx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgMintNFT --from [granter_address]
- Grant to mint NFTtx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgTransferNFT --from [granter_address]
- Grant to transfer NFT
tx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgTransferNFT --from [granter_address]
- Grant to transfer NFTtx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgEditNFT --from [granter_address]
- Grant to edit NFT
tx authz grant [grantee_address] generic --msg-type /chainmain.nft.v1.MsgEditNFT --from [granter_address]
- Grant to edit NFTso on and so forth.
NOTE Message Type URL & Updating an Existing Grant: At any time, there is up to one grant allowed for each Message Type URL over a unique granter-grantee pair. To update an existing grant, the granter will need to re-grant the grantee and the new grant will overwrite the old grant.
exec
:
exec
:The exec
transaction composes of 2 transactions:
the
authorized transaction
: the transaction to be executed on behalf of the granter; andthe
execution transaction
: the transaction that contains and executes the aboveauthorized transaction
.
After a valid grant is set up, the grantee needs to first prepare the authorized transaction
, in JSON format, on behalf of the granter. For instance, when the grantee wants to execute a SendAuthorization
to send 10 CRO
from the granter to a recipient
, one easy way to generate such authorized transaction
and saves it to a file named tx.json
is to use the --generate-only
flag by running:
NOTE The authorized transaction
here does not need to be signed and the address after the --from
flag is the granter_address
instead of the grantee_address
. In other words, this authorized transaction
is created by the grantee but prepared as if he/she were the granter.
After the authorized transaction
is properly prepared, the grantee needs to issue an execution transaction
to execute the authorized transaction
:
tx authz exec [tx_json] --from [grantee_address]
- Execute an authorization
tx authz exec [tx_json] --from [grantee_address]
- Execute an authorizationLikewise, all valid authorized grants can be executed with proper authorized transaction
and execution transaction
.
revoke
:
revoke
:The granter may choose to revoke
an existing authorization already granted to the grantee by running:
tx authz revoke [grantee_address] [msg_type_url] --from [granter_address]
- Revoke an authorization with a specified Message Type URL
tx authz revoke [grantee_address] [msg_type_url] --from [granter_address]
- Revoke an authorization with a specified Message Type URLExample: Revoke an existing SendAuthorization
Queries
query authz grants [granter_address] [grantee_address]
- Query all existing grants between a granter-grantee pair
query authz grants [granter_address] [grantee_address]
- Query all existing grants between a granter-grantee pairExample: Query all existing grants between the specified granter and grantee
We may also specify a MsgTypeURL
for the query:
query authz grants [granter_address] [grantee_address] [msg_type_url]
- Query the grant with a specified Message Type URL between a granter-grantee pair
query authz grants [granter_address] [grantee_address] [msg_type_url]
- Query the grant with a specified Message Type URL between a granter-grantee pairExample: Query the grant to withdraw delegator reward between the specified granter and grantee
bank
bank
Introduction
The bank
module maintains the state of two primary objects:
Account balances by address;
Total supply of tokens of the chain
bank
module tracks and provides query support for the total supply of all assets used in the application. It also supports token transfer functionalities. Specifically, the total supply is updated whenever a token is:
Minted, e.g. Token created by the mint module; or
Burned, e.g. Token distorted by the slashing module.
Transactions and Queries
Transactions
tx bank send [from_key_or_address] [to_address] [amount] [network_id]
- Send Funds
tx bank send [from_key_or_address] [to_address] [amount] [network_id]
- Send FundsYou can transfer tokens to a designated address by the tx bank send
command. For example, we can send 10 CRO from address_a
to address_b
by
Queries
query bank balances [address]
- Check the balance of a specified account
query bank balances [address]
- Check the balance of a specified accountOne can check the current balance of a specified account by:
query bank total
- Check the total supply of the token
query bank total
- Check the total supply of the tokenYou can also check the current total supply of the token by:
Appendix
bank
module: Network Parameters and configuration
bank
module: Network Parameters and configurationKey | Type | Example |
---|---|---|
| []SendEnabled | [{denom: "basecro", enabled: true }] |
| bool | true |
distribution
distribution
Introduction
The distribution
module is responsible for the distribution of rewards to the validators and delegators.
Overview
Network Parameters
Below are all the network parameters for the distribution
module:
community_tax
- The rate of community tax;base_proposer_reward
- Base bonus on transaction fees collected in a valid block;bonus_proposer_reward
- Maximum bonus on transaction fees collected in a valid block;withdraw_addr_enabled
- Whether delegators can set a different address to withdraw their rewards.
Rewards
There are two main types of rewards
Block rewards, governed by the mint module; and
Block reward
Block rewards are distributed proportionally to all validators relative to their voting power. This means that even though each validator gains CRO with each reward, all validators will maintain equal weight over time.
For the validator operator, the distribution information is updated if:
the amount of delegation to a validator is updated (delegation, unbond, slashing, etc.);
a validator successfully proposes a block and receives the reward;
any delegator withdraws from a validator, or
the validator withdraws it's commission.
For delegators, once they have delegated to a validator, they will be entitled to a portion of the total reward obtained by the validators. The reward is proportional to their delegated amount, and the commission charged by the validator operator (if any).
Transaction Fees Bonus
When a validator is selected to propose the next block, they must include at least 66% precommits of the previous block. To incentivise validators to include more than 66% precommits, the module provide a bonus reward (portion of the transaction fee in the block) to the proposer.
This bonus reward is dependent linearly on the precommits from the other validators. Starting from 66% of the precommits, the basic bonus will be base_proposer_reward
and increase linearly to bonus_proposer_reward
when the validator includes 100% of the precommits.
This mechanism aims to incentivize non-empty block proposals, better networking between validators as well as to mitigate censorship. For further example, kindly refer to this link.
Community tax
The community_tax
is the tax rate of the reward obtained by the validator. Specifically, part of the reward will be taxed and sent to the community pool. The funds in the community pool can be withdrawn by submitting a community pool spend proposal with the gov module.
Even if the community_tax
is set to be zero, the balance of the community pool could be non-zero. For example, the truncated remainder in some accounting edge cases will be sent to the community pool as well. Besides that, users can fund the community pool voluntarily, and there could be funds allocated to the community pool in the genesis.
Transactions and Queries
Transactions
tx distribution withdraw-all-rewards
- Withdraw all delegations rewards for a delegator
tx distribution withdraw-all-rewards
- Withdraw all delegations rewards for a delegatorDelegator can withdraw their reward(s) from the validator(s) that they have delegated to all at once.
tx distribution withdraw-rewards [validator-addr]
- Withdraw rewards from a given validator address
tx distribution withdraw-rewards [validator-addr]
- Withdraw rewards from a given validator addressDelegator can withdraw their reward(s) from a specific validator.
Remark: Validator operation can withdraw the commission in addition to the rewards by adding the commission flag --commission
.
tx distribution set-withdraw-addr [withdraw-addr]
- Change the default withdraw address for rewards associated with an address
tx distribution set-withdraw-addr [withdraw-addr]
- Change the default withdraw address for rewards associated with an addressDelegator can set a different address to withdraw their rewards.
tx distribution fund-community-pool [amount]
- Funds the community pool with the specified amount
tx distribution fund-community-pool [amount]
- Funds the community pool with the specified amountUsers can make a contribution to the community pool with a specific amount.
Queries
query distribution commission [validator]
- Query distribution validator commission
query distribution commission [validator]
- Query distribution validator commissionWe can check the commission of a specific validator.
query distribution community-pool
- Query the amount of coins in the community pool
query distribution community-pool
- Query the amount of coins in the community poolWe can check the balance of the community pool.
query distribution rewards [delegator-addr] [validator-addr]
- Query all distribution delegator rewards or rewards from a particular validator
query distribution rewards [delegator-addr] [validator-addr]
- Query all distribution delegator rewards or rewards from a particular validatorwe can check the current rewards for a delegation on a specific validator.
query distribution slashes [validator] [start-height] [end-height]
- Query distribution validator slashes
query distribution slashes [validator] [start-height] [end-height]
- Query distribution validator slashesWe can check the history of slashing events of a validator.
query distribution validator-outstanding-rewards [validator]
- Query distribution outstanding rewards for a validator and all their delegations
query distribution validator-outstanding-rewards [validator]
- Query distribution outstanding rewards for a validator and all their delegationsWe can check distribution outstanding (un-withdrawn) rewards for a validator and all of their delegations.
query distribution params
- Query the current distribution parameters
query distribution params
- Query the current distribution parametersWe can query the current distribution parameters by
Appendix
distribution
module: Network Parameters and configuration
distribution
module: Network Parameters and configurationThe following tables show the overall effects of the distribution related network parameters on different configurations:
|
|
| |
Type | string (dec) | string (dec) | string (dec) |
Higher | More reward will goes into the community pool | Higher basic transaction fees bonus for the proposer | Easier for a proposal to be passed |
Lower | Less reward will goes into the community pool | Lower basic transaction fees bonus for the proposer | Harder for a proposal to be passed |
Constraints | Value has to be less or equal to | Value has to be less or equal to | Value has to be less or equal to |
Sample configuration |
|
|
|
gov
gov
Introduction
The gov
module enables on-chain governance which allows Cronos PoS Chain token holders to participate in the decision-making processes. For example, users can:
Form an idea and seek feedback;
Create the proposal and adjust according to feedback as needed;
Submit a proposal along with an initial deposit;
Deposit tokens and fund an active proposal;
Vote for an active proposal.
The details about the governance proposal process are available on The Proposal Process page.
Overview
Network parameters
Below are all the network parameters for the gov
module:
deposit_params
- Deposit related parameters:min_deposit
: Minimum deposit for a proposal to enter voting period; andmax_deposit_period
: Maximum period for CRO holders to deposit on a proposal.
voting_params
- Voting related parametersvoting_period
: The length of the voting period.
tally_params
- Tally related parametersquorum
: The minimum percentage of voting power that needs to be casted on a proposal for the result to be valid;threshold
: Minimum proportion ofYes
votes (excludingAbstain
votes) for the proposal to be accepted; andveto
: Minimum proportion ofVeto
votes to total votes ratio for proposal to be vetoed.
The Governance Procedure
Phase 0 - Submit a proposal along with an initial deposit:
Users can submit a proposal with an initial deposit. The proposal will then become "active" and enter the deposit period.
Phase 1 - Deposit period
During the deposit period, users can deposit and support an active proposal. Once the deposit of the proposal reaches min_deposit
, it will enter the voting period. Otherwise, if the proposal is not successfully funded within max_deposit_period
, it will become inactive and the entire deposit will be refunded.
Phase 2 - Voting period
During the voting period, staked (bonded) tokens will be able to participate in the voting. Users can choose one of the following option: "yes"
, "no"
, "no_with_veto"
and "abstain"
After the voting_period
has passed, there are several scenarios where a proposal will be considered to be "Rejected", for example, if
No one votes (everyone
"abstain"
);Votes did not reach the
quorum
;More than
veto
of voters vote for"no_with_veto"
;More than
threshold
of non-abstaining voters vote"no"
.
Otherwise, the proposal will be accepted and changes will be implemented according to the proposal.
Transactions and Queries
Transactions
tx gov submit-proposal
- Submit a proposal along with an initial deposit
tx gov submit-proposal
- Submit a proposal along with an initial depositSubmit a parameter change proposal -
param-change [proposal-file]
Users can submit a proposal to modify network parameters during runtime. Here is a demo proposal if we would like to change the parameter
MaxValidators
(maximum number of validators) in thestaking
module,Submit a community pool spend proposal -
community-pool-spend [proposal-file]
Users can submit a proposal and request funds from the community pool to support their projects or other usages.
Submit a software upgrade proposal-
software-upgrade [name] (--upgrade-height [height] | --upgrade-time [time]) (--upgrade-info [info])
Users can submit an upgrade proposal and suggest a software upgrade at a specific block height.
Cancel the current software upgrade proposal -
cancel-software-upgrade
On the other hand, users can submit a proposal to cancel the planned software upgrade.
tx gov deposit [proposal-id] [deposit]
- Deposit tokens for an active proposal
tx gov deposit [proposal-id] [deposit]
- Deposit tokens for an active proposalUsers can submit a deposit transaction to fund and support an active proposal.
tx gov vote [proposal-id] [option]
- Vote for an active proposal
tx gov vote [proposal-id] [option]
- Vote for an active proposalUsers can vote for an active proposal. Valid value of "option"
field can be "yes"
, "no"
, "no_with_veto"
and "abstain"
.
Queries
query gov proposals [proposal-id]
- Query proposals with optional filters
query gov proposals [proposal-id]
- Query proposals with optional filtersWe can check the proposal with optional filters by:
In the above example, there is only one proposal with "proposal_id": "1"
, with the title: "Staking Param Change"
that change the MaxValidators
parameter of the staking
module to 151
. We can also see that the status of the proposal is "PROPOSAL_STATUS_PASSED"
, which means that this proposal has been passed.
query gov proposal [proposal-id]
Query details of a single proposal
query gov proposal [proposal-id]
Query details of a single proposalSimilarly, we can check the details of a proposal with a given "proposal_id"
.
query gov tally [proposal-id]
Get the tally of a proposal vote
query gov tally [proposal-id]
Get the tally of a proposal voteWe can also check the tally of a proposal with a given "proposal_id"
.
query gov params
- Query the current gov parameters
query gov params
- Query the current gov parametersWe can query the current gov parameters by
Appendix
gov
module: Network Parameters and configuration
gov
module: Network Parameters and configurationThe following tables show the overall effects of the gov related network parameters on different configurations:
|
|
| |
Type | array (coins) | string (time ns) | string (time ns) |
Higher | Larger window for calculating the downtime | Longer deposit period | Longer voting period |
Lower | Smaller window for calculating the downtime | Shorter deposit period | Shorter voting period |
Constraints | Value has to be a positive integer | Value has to be positive | Value has to be positive |
Sample configuration |
|
|
|
|
|
| |
Type | string (dec) | string (dec) | string (dec) |
Higher | Easier for a proposal to be passed | Easier for a proposal to be passed | Easier for a proposal to be passed |
Lower | Harder for a proposal to be passed | Harder for a proposal to be passed | Harder for a proposal to be passed |
Constraints | Value has to be less than or equal to | Value has to be less than or equal to | Value has to be less than or equal to |
Sample configuration |
|
|
|
mint
mint
Introduction
The mint
module is responsible for creating tokens in a flexible way to reward the validators who participate in the proof of stake consensus process (see also the distribution module). It is also designed in a way to bring a balance between market liquidity and staked supply.
Overview
Network parameters
Below are all the network parameters for the mint
module:
"blocks_per_year"
- The expected number of blocks being produced per year;"goal_bonded"
- Goal of bonded tokens in percentage;"inflation_max"
- Maximum annual inflation rate;"inflation_min"
- Minimum annual inflation rate;"inflation_rate_change"
- Maximum annual change in inflation rate;"mint_denom"
- Type of the token being minted.
The target annual inflation rate is recalculated for each previsions cycle. The inflation is also subject to a rate change (positive or negative) depending on the distance from the desired ratio ("goal_bonded"
). The maximum rate change possible is defined to be "inflation_rate_change"
per year, where the annual inflation is capped between "inflation_min"
and "inflation_max"
.
mint
module: Queries
mint
module: QueriesQueries
query mint params
- Query the current minting annual provisions value
query mint params
- Query the current minting annual provisions valueWe can query the current minting annual provisions value, for example:
implies that the current minting annual provisions will be 109573801550200370
basecro ( i.e. 1,095,738,015
CRO)
query mint inflation
- Query the current minting inflation value
query mint inflation
- Query the current minting inflation valueWe can query the current minting inflation value, for example:
implies that the current minting annual provisions will be 0.013687008526984104
( i.e. 1.368%
)
query mint annual-provisions
- Query the current minting parameters
query mint annual-provisions
- Query the current minting parametersWe can query the current query parameters by
Appendix
gov
module: Network Parameters and configuration
gov
module: Network Parameters and configurationThe following tables show the overall effects of the mint related network parameters on different configurations:
|
|
| |
Type | array (coins) | string (dec) | string |
Higher | More expected blocks per year | Higher target bonding ratio | N/A |
Lower | Less expected blocks per year | Lower target bonding ratio | N/A |
Constraints | Value has to be a positive integer | Value has to be less than or equal to | N/A |
Sample configuration |
|
|
|
|
|
| |
Type | string (dec) | string (dec) | string (dec) (dec) |
Higher | Higher ceiling for the inflation rate | Higher floor for the inflation rate | Higher yearly rate of change for the inflation |
Lower | Lower ceiling for the inflation rate | Lower floor for the inflation rate | Lower yearly rate of change for the inflation |
Constraints | Value has to be less than or equal to | Value has to be less than or equal to | Value has to be less than or equal to |
Sample configuration |
|
|
|
nft
nft
Introduction
Fungible tokens are mutually interchangeable, and one most common example of fungible tokens is fiat currencies. Specifically, the $100.50 US dollars in my bank account is equally valuable as the $100.50 US dollars in someone else's bank account. Another example of fungible tokens would be the native cryptocurrency of Ethereum, one of the most popular blockchain networks, i.e. Ether. Ethers are totally fungible, meaning that one ether is equal to one ether, and it's equal to any other ether as well. Particularly, ethers are also highly divisible up to one wei, or 0.000000000000000001 (10-18) ether.
In contrast, non-fungible tokens (NFTs) are special tokens that are unique in the sense that they cannot be split or equally interchanged for other NFTs of the same type. CryptoKitties on Ethereum or Loaded Lions on Cronos PoS Chain are both examples of NFTs: each CryptoKitty or Loaded Lion are unique and non-divisible, unlike Bitcoin. Generally speaking, NFTs are unique, non-interchangeable, and non-divisible.
On-chain NFT standards were first developed on Ethereum within the ERC-721 standard and its subsequent Ethereum Improvement Proposals. The subsequent ERC-1155 standard aims to address some restrictions of Ethereum such as storage costs and semi-fungible assets. NFTs on application specific blockchains share some but not all features as their Ethereum brethren, since application specific blockchains are more flexible in how their resources are utilized, such as the ability to use strings as IDs.
The nft
module here facilitates managing non-fungible tokens that represent individual assets with unique features on Cronos PoS Chain.
Overview
There are two key concepts for NFTs on Cronos PoS Chain, namely, denom and token:
denom
A denom represents a collection of NFTs. For example, I could issue a denom named "CryptoPuppies" under which my collection of 100 CryptoPuppies NFTs get minted. Each denom has a
denom ID
and adenom name
, both are unique on chain. Adenom schema
should generally be set when a denom gets issued, which indicates the format of NFT metadata under this denom.token
An NFT, or simply "token", is a specific instance of NFT minted under a denom. Each token has a
token ID
, which is unique under a specific denom. Generally, a token also has itstoken name
(name of the NFT),token URI
(off-chain information or storage location of the NFT), andtoken metadata
(on-chain data that provides information about the NFT).
Specifications denom ID
: a string of lowercase alphanumeric characters with length between 3 and 64 that begins with a letter, unique over the chain;
denom name
: a non-empty string, unique over the chain;
denom schema
: a JSON metadata format for NFTs under this denom;
token ID
: a string that is unique under the denom;
token name
: a string;
token URI
: a string that directs to the off-chain information or storage location of the NFT;
token metadata
: a JSON object that matches the denom schema and represents the on-chain data that provides information about the NFT.
Just as each user is uniquely identified by its address, each NFT is uniquely identified by the combination of its denom ID and its token ID (like a UID for the NFT), showing its uniqueness, non-interchangeability, and non-divisibility.
Transactions and Queries
Transactions
In general,
any user may
issue
a denom as long as neither the denom ID nor the denom name has been taken;the creator of a denom, also know as the owner of the denom, is the only user who may
mint
an NFT under such denom;a user may
edit
orburn
an NFT only if he/she is both the creator and the owner of that NFT;a user may
transfer
an NFT as long as he/she is the owner of that NFT.
issue
:
issue
:Every NFT needs to "live" under a denom: an NFT collection. Therefore, the first step is to issue a denom before one can mint NFTs:
tx nft issue [denom_id] --name [denom_name] --schema [denom_schema] --from [user_address]
- Issue a denom
tx nft issue [denom_id] --name [denom_name] --schema [denom_schema] --from [user_address]
- Issue a denomExample: Issue a new denom with specified name and schema
NOTE Even though the denom schema is not a compulsory field, it is generally recommended to illustrate the format of NFT metadata as an informative summary of such denom. Moreover, a denom is non-transferable, non-editable, and non-deletable, so be mindful when issuing a denom.
mint
:
mint
:When a denom has been issued, the denom owner (the creator) may mint an NFT under such denom.
tx nft mint [denom_id] [token_id] --name [token_name] --uri [token_uri] --data [token_metadata] --recipient [recipient_address] --from [user_address]
- Mint an NFT
tx nft mint [denom_id] [token_id] --name [token_name] --uri [token_uri] --data [token_metadata] --recipient [recipient_address] --from [user_address]
- Mint an NFTExample: Mint an NFT with specified name, URI, data, and recipient
NOTE The token name, URI, and metadata fields are optional but highly recommended fields during the minting process, even though they might also be edited later through edit
. In addition, the minter may specify a recipient of the new NFT, where it defaults to be just the minter if not specified.
edit
:
edit
:Unlike NFTs minted on Ethereum, an NFT minted on Cronos PoS Chain may easily be edited, provided that the user editing it is both the owner and creator of such NFT.
tx nft edit [denom_id] [token_id] --name [new_name] --uri [new_uri] --data [new_metadata] --from [user_address]
- Edit an NFT
tx nft edit [denom_id] [token_id] --name [new_name] --uri [new_uri] --data [new_metadata] --from [user_address]
- Edit an NFTExample: Edit an NFT to change its URI
NOTE There are 3 fields available for NFT editing: name, URI, and the metadata. Any field that is not specified will remain unchanged.
burn
:
burn
:A user may burn an existing NFT as long as he/she is both the owner and creator of such NFT, similar to editing the NFT.
tx nft burn [denom_id] [token_id] --from [user_address]
- Burn an NFT
tx nft burn [denom_id] [token_id] --from [user_address]
- Burn an NFTExample: Burn an NFT
NOTE A token ID is unique under a specific denom, meaning no two existing NFTs can share the same token ID under the same denom. However, when an NFT gets burnt, its token ID is freed and is available for mint again.
transfer
:
transfer
:Transferring an NFT is easy: one only needs to be the owner of the NFT.
tx nft transfer [recipient_address] [denom_id] [token_id] --from [granter_address]
- Transfer an NFT
tx nft transfer [recipient_address] [denom_id] [token_id] --from [granter_address]
- Transfer an NFTExample: Transfer an NFT to a recipient
Queries
In the NFT module, queries can be divided into 3 main categories:
denom information;
token information;
owner information.
query denom information:
query nft denom [denom_id]
- Query information of a denom by its denom ID
query nft denom [denom_id]
- Query information of a denom by its denom IDExample: Query information of a denom by its denom ID
Effectively, one may also query information of a denom by its denom name instead of denom id:
query nft denom-by-name [denom_name]
- Query information of a denom by its denom name
query nft denom-by-name [denom_name]
- Query information of a denom by its denom nameTo check the number of existing NFTs in a denom:
query nft supply [denom_id]
- Query the number of existing NFTs in a denom
query nft supply [denom_id]
- Query the number of existing NFTs in a denomExample: Query the number of existing NFTs in a denom
In addition, one may query the number of existing NFTs in a denom of a specific owner through the --owner
flag:
query nft supply [denom_id] --owner [owner_address]
- Query the number of existing NFTs in a denom of a specific owner
query nft supply [denom_id] --owner [owner_address]
- Query the number of existing NFTs in a denom of a specific ownerExample: Query the number of existing NFTs in a denom of a specific owner
query token information:
One may query information of a specific NFT with its UID (denom ID and token ID):
query nft token [denom_id] [token_id]
- Query information of an NFT
query nft token [denom_id] [token_id]
- Query information of an NFTExample: Query information of an NFT
One may also query information of all NFTs under a specific denom:
query nft collection [denom_id]
- Query information of all NFTs under a specific denom
query nft collection [denom_id]
- Query information of all NFTs under a specific denomExample: Query information of all NFTs under a specific denom
query owner information:
Last but not least, information of a specific NFT owner may also be queried.
query nft owner [owner_address]
- Query information of all NFTs owned by a specific owner
query nft owner [owner_address]
- Query information of all NFTs owned by a specific ownerExample: Query information of all NFTs owned by a specific owner
One may also use the --denom-id
flag to query owner NFT information under a specific denom:
query nft owner [owner_address] --denom-id [denom_id]
- Query information of all NFTs owned by a specific owner under specified denom
query nft owner [owner_address] --denom-id [denom_id]
- Query information of all NFTs owned by a specific owner under specified denomExample: Query information of all NFTs owned by a specific owner under specified denom
slashing
slashing
Introduction
Validators are responsible for signing or proposing a block at each consensus round. A penalty should be imposed on validators' misbehaviour to reinforce this.
Specifically, slashing
functionality that aims to disincentivize network-observable actions, such as faulty validations. The penalties may include losing some amount of their stake, losing their ability to perform the network functionality for a period of time, collect rewards, etc.
Overview
Network parameters
Below are all the network parameters used to configure the behavior of validator punishments. Details of all these parameters and their effect on behavior of validator punishments is discussed later in this document.
signed_blocks_window
: Number of blocks for which the liveness is calculated for uptime tracking;min_signed_per_window
: Maximum percentage of blocks with faulty/missed validations allowed for an account in last;signed_blocks_window
blocks before it gets deactivated;downtime_jail_duration
: Duration for jailing;slash_fraction_double_sign
: Percentage of funds being slashed when validator makes a byzantine fault; andslash_fraction_downtime
: Percentage of funds being slashed when a validator is non-live.
Slashing mechanism
Punishments for a validator are triggered when they either make a byzantine fault or become non-live:
Liveness Faults (Low availability)
A validator is said to be non-live when they fail to successfully sign at least
min_signed_per_window
blocks (in percentage) in the lastsigned_blocks_window
blocks.signed_blocks_window
andmin_signed_per_window
are network parameters and can be configured during genesis and can be updated during runtime by the governance module.
Example: For example, if block_signing_window
is 2000
blocks and min_signed_per_window
is 0.5
, a validator will be marked as non-live and jailed if they fail to successfully sign at least 2000*0.5=1000
blocks in the last 2000
blocks.
Byzantine Faults
A validator is said to make a byzantine fault when they sign conflicting messages/blocks at the same height and round. Tendermint has mechanisms to publish evidence of validators that signed conflicting votes so they can be punished by the slashing module. For example:
Validator who votes for two different blocks within a single round ("Equivocation validator"/ "Double signing");
Validator who signs commit messages for arbitrary application state ( "Lunatic validator").
Remark: The evidence of a set of validators attempting to mislead a light client can also be detected and captured. However, even the Amnesia attack can be detected, punishment can not be applied at this stage, as we can not deduce the malicious validators.
Implementation note: Tendermint passes Evidence
of a byzantine validator in BeginBlock
request. Before jailing any account due to byzantine fault, that evidence should be verified. Also, it should be checked that evidence provided by tendermint is not older than max_age
in tendermint.
Inactivity Slashing
It is important that the validators maintain excellent availability and network connectivity to perform their tasks. A penalty should be imposed on validators' misbehaviour to reinforce this.
When a validator fails to successfully sign missed_block_threshold
blocks in the last block_signing_window
blocks, it is immediately jailed and punished by deducting funds from their bonded and unbonded amount and removing them from the active validator set. The funds to be deducted are calculated based on slash_fraction_downtime
. Kindly refer to this link on the logic of the liveness tracking.
Jailing
A validator is jailed when they make liveness or Byzantine fault. When a validator is jailed, it will no longer be considered as an active validator until they are un-jailed. Futhermore, it cannot be un-jailed before downtime_jail_duration
. This downtime_jail_duration
is a network parameter which can be configured during genesis.
Important: When a validator is jailed because of a byzantine fault, their validator public key is added to a list of permanently banned validators and cannot re-join the network as a validator with the same public key, see staking tombstone.
Un-jailing
When a jailed validator wishes to resume normal operations (after downtime_jail_duration
has passed), they can create a unjail
transaction which marks them as un-jailed. Validator will then rejoin the validator set once it has been successful un-jailed.
Slashing for Byzantine Fault
When there is byzantine fault detected, they are immediately slashed other than jailed. The funds to be deducted are calculated based on slash_fraction_double_sign
. Furthermore, validators who commit this double-signing fault will also be put into the "tombstone state", which means it will be blacklisted and jailed forever.
Transactions and Queries
Transactions
tx slashing unjail
- Unjailing a validator
tx slashing unjail
- Unjailing a validatorValidators could be punished and jailed due to network misbehaviour, for example if we check the validator set:
After the jailing period has passed, one can broadcast an unjail
transaction to unjail the validator and resume its normal operations by
Queries
query slashing params
- Query the current slashing parameters
query slashing params
- Query the current slashing parametersWe can query the current slashing parameters by
Appendix
slashing
module: Network Parameters and configuration
slashing
module: Network Parameters and configurationThe following tables show overall effects on different configurations of the slashing related network parameters:
|
|
| |
Type | string (int64) | string (dec) | string (int64) |
Higher | Larger window for calculating the downtime | Higher availability is required | Longer jailing duration |
Lower | Smaller window for calculating the downtime | Lower availability is required | Longer jailing duration |
Constraints | Value has to be a positive integer | Value has to be positive | Value has to be a positive integer |
Sample configuration |
|
|
|
|
| |
Type | string (dec) | string (dec) |
Higher | Heavier penalty on byzantine faults | Heavier penalty on liveness faults |
Lower | Lighter penalty on byzantine faults | Lighter penalty on liveness faults |
Constraints | Value has to be less than or equal to | Value has to be less than or equal to |
Sample configuration |
|
|
staking
staking
Introduction
The staking
module handles Proof-of-Stake related logics, which plays a very important part to the underneath consensus protocol.
Overview
Cronos PoS Chain is based on Tendermint Core's consensus engine, it relies on a set of validators to participate in the proof of stake (PoS) consensus protocol, and they are responsible for committing new blocks to the blockchain.
unbonding_time
: The time duration of unbonding;max_validators
: The maximum number of validators;max_entries
: The max entries for either unbonding delegation or redelegation;historical_entries
: The number of historical entries to persist; andbond_denom
: Coin denomination for staking.
Validator
Validators are responsible for signing or proposing a block at each consensus round. It is important that the validators maintain excellent availability and network connectivity to perform their tasks. To incentivise the validator nodes to run the network, rewards are distributed to the validators according to their performance and amount of staked tokens (see distribution and mint). On the other hand, a penalty should be imposed on validators' misbehaviour (see slashing).
Delegator
The staking
module enables CRO owners to delegate their tokens to active validators and share part of the reward obtained by the validator during the proof of stake protocol(see distribution module). Specifically, it allows token owners to take part in the consensus process without running a validator themselves.
It is important to point out that the delegator and the validator are on the same boat: they share the reward and the risk. In particular, part of their delegated token could be slashed due to validator's misbehaviour (see slashing). Therefore, it is very important to choose a reliable validator to delegate to. Kindly refer to this link for detailed specification and state transitions of delegation.
Transactions and Queries
Transactions
tx staking create-validator
- Create new validator initialized with a self-delegation
tx staking create-validator
- Create new validator initialized with a self-delegationFirst of all, we can create a validator with the create-validator
transaction, for example:
tx staking delegate [validator-addr] [amount]
- Delegate liquid tokens to a validator
tx staking delegate [validator-addr] [amount]
- Delegate liquid tokens to a validatorAs discussed in the delegator section, one can delegate their tokens to an active validator by:
tx staking unbond [validator-addr] [amount]
- Unbond shares from a validator
tx staking unbond [validator-addr] [amount]
- Unbond shares from a validatorDelegators can unbond their staked tokens by
Remark: Note that funds will only be available after the unbonding_time
has passed.
tx staking redelegate [src-validator-addr] [dst-validator-addr] [amount]
- Redelegate illiquid tokens from one validator to another
tx staking redelegate [src-validator-addr] [dst-validator-addr] [amount]
- Redelegate illiquid tokens from one validator to anotherWe can also move our staked tokens from one validator to another by:
Queries
We will be covering most of the commonly used queries here. Meanwhile, you can use
to check all the supported sub-commands.
query staking delegation [delegator-addr] [validator-addr]
- Query a delegation based on address and validator address
query staking delegation [delegator-addr] [validator-addr]
- Query a delegation based on address and validator addressWith a given delegator address and the validator account that it is associated with, we can check the delegation by:
query staking delegations-to [validator-addr]
- Query all delegations made to one validator
query staking delegations-to [validator-addr]
- Query all delegations made to one validatorWe can check all the delegations made to a specific validator:
query staking pool
- Query the current staking pool values
query staking pool
- Query the current staking pool valuesWe can check the amount of bonded and unbonded amount in the staking pool:
query staking unbonding-delegation [delegator-addr] [validator-addr]
- Query an unbonding-delegation record based on delegator and validator address
query staking unbonding-delegation [delegator-addr] [validator-addr]
- Query an unbonding-delegation record based on delegator and validator addressquery staking validator [validator-addr]
- Query a specific validator
query staking validator [validator-addr]
- Query a specific validatorWe can query the details of a specific validator with its validator address (crocncl...) by:
query staking validators
- Query all validators
query staking validators
- Query all validatorsA full list of validators and their details can be found by this query.
query staking params
- Query the current staking parameters
query staking params
- Query the current staking parametersFinally, we can query the current staking parameters by
Appendix
staking
module: Network Parameters Configuration
staking
module: Network Parameters ConfigurationThe following tables show the overall effects of the staking related network parameters on different configurations:
|
|
| |
Type | string | uint16 | uint16 |
Higher | N/A | More historical entries to persist | More entries for either unbonding delegation or redelegation |
Lower | N/A | Less historical entries to persist | Fewer entries for either unbonding delegation or redelegation |
Constraints | N/A | Value has to be positive | Value has to be positive |
Sample configuration |
|
|
|
|
| |
Type | uint16 | string |
Higher | More active validators | Longer waiting period for unbonding |
Lower | Fewer active validators | Shorter waiting period for unbonding |
Constraints | Value has to be less than or equal to | Positive value in seconds |
Sample configuration |
|
|
supply
supply
Introduction
The supply
module is responsible for retrieving the total and liquid supply.
Queries
query supply liquid
- Check the total supply of coins on the chain
query supply liquid
- Check the total supply of coins on the chainWe can also use the query
command of the supply
module to check the current total supply:
query supply liquid
- Check the liquid supply of coins on the chain
query supply liquid
- Check the liquid supply of coins on the chainWe can also query the liquid supply, which is the total supply bonded subtracted by the non-circulating supply such as bonded amounts, unvested amounts, uncollected rewards, etc.
Last updated