The core blockchain part for the ANATHA Blockchain will be secured using the Tendermint Protocol and built by leveraging the Cosmos ecosystem to develop our own ANATHA SDK. The Tendermint Core handles executing the consensus engine and managing the P2P connectivity layer. As such, Tendermint doesn’t know anything about the transactions that are being executed. The transaction validity checks and transaction execution is conducted at the ANATHA network layer in separate functionality based state machines called modules.
This module contains all of the logic linking an ANATHA address to one or more decentralized human-readable addresses (DeHRAs) and their metadata, which could include multi-currency wallets and other crypto addresses. Every user can have multiple DeHRAs. Every one of those DeHRAs point to their native ANATHA Address. Every ANATHA Address holds a mapping of addresses for multiple cryptocurrencies grouped by the cryptocurrency and the order of the addresses within the same cryptocurrency.
Users have the ability to add multiple addresses from multiple cryptocurrencies. The first registered addresses of known cryptocurrencies within the ANATHA Platform have a decreased registration fee. Every following registered address has an increased fee. The fee mechanism is set in place to reduce malicious transactions overloading the network.
The ANATHA network uses the Bech32 address format wherever users must handle binary data. Bech32 encoding provides robust integrity checks on data and the human readable part (HRP) provides contextual hints that can assist UI developers with providing informative error messages. In the ANATHA network, keys and addresses may refer to a number of different roles in the network like accounts, validators etc.
In this chapter, we will discuss the modules needed to execute the ANATHA business logic defined by the Product document. We will also discuss efforts for reusing existing open-source modules and building them from scratch.
We will present all modules within a Module Definition Framework consisting of the following parts:
- Abstract - defines high-level module purpose
- Concepts - describe specialized concepts and definitions used throughout the spec
- State - specification of which data is stored and in what kind of data structures
- Messages - transactions that the module state machine can process
- Begin Block - specify any begin-block operations
- End Block - specify any end-block operations
- Hooks - describe available hooks to be called by/from this module
- Keepers - logical division for module functions. Keeper methods are invoked from handler functions only
- Events - emitted for indexing. The events include a type and a key and value that are being emitted from the module
- Parameters - configuration points for each module
The list is nonbinding and all parts are optional.
The auth module is responsible for specifying the base transaction and account types for an application. It contains the ante handler, where all basic transaction validity checks (signatures, nonces, auxiliary fields) are performed, and exposes the account keeper, which allows other modules to read, write, and modify accounts.
Accounts contain authentication information for a uniquely identified external user of an SDK blockchain, including public key, address, and account number/sequence number for replay protection. For efficiency, since account balances must also be fetched to pay fees, account structs also store the balance of a user.
The auth module won’t have transaction handlers of its own but does expose a special handler called AnteHandler, used for performing basic validity checks on a transaction, such that it could be thrown out of the mempool. Note that the ante handler is called on CheckTx, but also on DeliverTx.
The AnteHandler is configurable and additional check middleware can be added to it. Initially, the AnteHandler would perform the following checks:
- Transaction type - only allow known transaction types
- Transaction signature checks
- Fee amount checks
The auth module only exposes one keeper, the AccountKeeper, which can be used to read and write accounts. It would also provide utility functions for reply attack protection. The keeper would expose the following methods:
- Generate an account object with a specified address
- Generate an account object with a consecutive account number
- Retrieve account from the store
- Persist an account to the store
- Remove an account from the store
- Iteration through all accounts
- Retrieve accounts public key based on its address
- Retrieve the sequence of an account based on its address
- Get the next global account number
The auth module will provide the following configurations:
- The maximal amount of data that can be attached to a transaction as a memo. Memos can be used to invoke off-chain processing
- The limit of signatures that can be included in a single transaction
- Transaction fee mechanics that are determined by the size and the cost of signature verifications.
The Tx module is responsible for handling coin transfers between accounts and tracking special case pseudo-transfers which must work differently with particular kinds of accounts (notably bonding/unbonding for savings accounts). It exposes several interfaces with varying capabilities for secure interaction with other modules which must alter user balances.
Presently, the Tx module has no inherent state — it simply reads and writes accounts using the AccountKeeper from the auth module. This implementation choice is intended to minimize necessary state reads/writes since we expect most transactions to involve coin amounts (for fees), so storing coin data in the account saves reading it separately.
The Tx module provides three different exported keeper interfaces which can be passed to other modules which need to read or update account balances:
- BaseKeeper - provides full-permission access: the ability to arbitrary modify any account's balance and mint or burn coins.
- setCoins - fetches an account by address, sets the coins on the account, and saves the account
- addCoins/subtractCoins - fetches the coins of an account, adds/subtracts the provided amount, and saves the account. This increases/decreases the total supply
- SendKeeper - provides access to account balances and the ability to transfer coins between accounts, but not to alter the total supply:
- sendCoins - transfers coins from one account to another
- ViewKeeper - provides read-only access to account balances but no balance alteration functionality. All balance lookups are conducted in constant time and space complexity:
- getCoins - returns the coins associated with an account
- hasCoins - returns whether or not an account has at least the provided amount of coins
The Tx module processes only one transaction of type MsgSend which supports transferring multiple sending balances to multiple receiving accounts.
The following events are emitted from the bank module:
- Type: transfer, Key: recipient, Value: <address>
- Type: transfer, Key: amount, Value: <amount>
- Type: message, Key: module, Value: bank
- Type: message, Key: action, Value: send
- Type: message, Key: sender, Value: <address>
The Tx module will provide the following configurations:
- Whether the token transfer function is enabled. This is used for the consensus protocol testing phase where all transfers would be locked
This Distribution module implements a functional way to passively distribute rewards between network participants. For computation optimization, this mechanism does not distribute funds proactively, but rather allows the users to claim their rewards.
The Distribution module consists of several pools that can either be modules or module accounts. The overall distribution mechanism is shown in a diagram below and consists of:
- Inflation Distribution - 1% annual inflation that is generated every block is transferred from the Mint module and allocated to the ANATHA Master Module and to the Network Validator Reward Pool
- The Network Validation Reward Pool locks a calculated amount of rewards in the Savings Account module and distributes the rest in the following block for rewards gained in the previous block. The outbound distribution to the savings pool is calculated as follows:
- The Savings Accounts Module activates distributions once every 24 hours to all savers that had collateral locked up for at least 24 hours
- The ANATHA Master Modules’ distribution function is triggered once daily and distributes the funds in the following way:
- 50% of the distribution gets split between HRA holders that have been an HRA owner in the last 24h. Only one HRA per account is eligible for the reward
- 25% of the distribution fees get transferred to the ANATHA Development Fund Account
- 25% of the distribution gets split between the Security Token Holders proportional to the amount of security tokens they are holding
All mentioned coin distributions aren’t done proactively but are reserved until the point when the user decides to send a transaction that would invoke withdrawals for his/her account.
The ANATHA Master Module blocks award withdrawals for the first 365 days of the blockchain running.
The Distribution module handles the following messages:
- MsgWithdrawValidatorRewardsAll - when a validator wishes to withdraw their rewards it must send MsgWithdrawValidatorRewardsAll. This transaction withdraws the validators rewards, as well as any rewards earning on their self-stake. Note that parts of this transaction logic are also triggered each with any change in individual delegations, such as an unbond.
The crisis module halts the blockchain under the circumstance that a blockchain invariant is broken.
Invariants can be registered with the application during the application initialization process. Each module can expose invariants to the crisis module including their route. Invariants can be checked one at a time and require a transaction fee payment.
Due to the anticipated large gas cost required to verify an invariant (and potential to exceed the maximum allowable block gas limit) a constant fee is used instead of the standard gas consumption method. The constant fee is intended to be larger than the anticipated gas cost of running the invariant with the standard gas consumption method.
Blockchain invariants can be checked using the MsgVerifyInvariant message which specifies the exact invariant to be checked. This message is expected to fail if the sender does not have enough coins for the constant fee or the invariant route is not registered. This message checks the invariant provided, and if the invariant is broken it panics, halting the blockchain. If the invariant is broken, the constant fee is never deducted as the transaction is never committed to a block (equivalent to being refunded). However, if the invariant is not broken, the constant fee will not be refunded.
The following events are emitted from the crisis module:
- Type: invariant, Key: route, Value: <route>
- Type: message, Key: module, Value: crisis
- Type: message, Key: action, Value: verify_invariant
- Type: message, Key: sender, Value: <address>
The ConstantFee param is held in the global params store.
The Governance module enables the blockchain to support an on-chain governance system. Before evolving to a decentralized governance system, this module will implement governance procedures based on a threshold on-chain multi-signature model, meaning that only participants that are registered in the genesis block would be able to create governance proposals and vote. Utilizing the mechanism of the Upgrade module, the Governance module can be self-updated to decentralized governance. (Note that, while this governance module is built, it will become functional following the first global distribution from the ANATHA Master Contract (12 months into soft launch) and will be accomplished via network upgrade which requires the compliance of node operators. During the 12 months of soft launch, governance will do two things: Assign control of the treasury account and propose node software updates.)
The governance process is divided in a few steps that are outlined below:
- Proposal submission: Proposal is submitted to the blockchain by one of the predefined governance managers.
- Vote: Once Proposal is submitted, the voting opens. Other predefined governance managers can then send TxGovVote transactions to vote on the proposal.
- If the proposal involves a software upgrade:
- Signal: Validators start signalling that they are ready to switch to the new version.
- Switch: Once more than 75% of validators have signalled that they are ready to switch, their software automatically flips to the new version.
In the initial version of the governance module, there are two types of proposal:
- PlainTextProposal - All the proposals that do not involve a modification of the source code go under this type. For example, an opinion poll would use a proposal of type PlainTextProposal.
- SoftwareUpgradeProposal - Is accepted, validators are expected to update their software in accordance with the proposal. This mechanism is explained in the Upgrade module
- Proposal handlers and types exposed in other modules
Other modules may expand upon the governance module by implementing their own proposal types and handlers. These types are registered and processed through the governance module (eg. ParamChangeProposal, TreasuryProposal, SofwareUpgradeProposal), which then execute the respective module's proposal handler when a proposal passes. This custom handler may perform arbitrary state changes.
The initial option set includes the following options: Yes, No, NoWithVeto, Abstain. NoWithVeto counts as No but also adds a Veto vote. Abstain option allows voters to signal that they do not intend to vote in favour or against the proposal but accept the result of the vote.
Quorum is defined as the minimum percentage of voting power that needs to be cast on a proposal for the result to be valid. Threshold is defined as the minimum proportion of Yes votes (excluding Abstain votes) for the proposal to be accepted.
Initially, the threshold is set at 50% with a possibility to veto if more than 1/3rd of votes (excluding Abstain votes) are NoWithVeto votes. This means that proposals are accepted if the proportion of Yes votes (excluding Abstain votes) at the end of the voting period is superior to 50% and if the proportion of NoWithVeto votes is inferior to 1/3 (excluding Abstain votes).
The main data structures that the Governance module uses are:
- A mapping map[proposalID] -> Proposal. The Proposal type stores basic information about the proposal like Content, ID, Status, Result and different timestamps
- A mapping map[proposalID][address] to Vote. This mapping allows us to query all addresses that voted on the proposal along with their vote
The messages that the Governance module processes are:
- TxGovSubmitProposal - submitting a proposal
- TxGovVote - voting transaction
The minting mechanism was designed to generate an inflation rate in the system. The inflation rate is initially set at 1% annually and calculated daily (or per block). The module supports having a dynamic inflation rate based on several parameters but starts off with a fixed 1% annual inflation rate which can be changed through governance proposals or network upgrade procedures.
The minting module state consists of two different stores:
- Module-level store - keeps the current annual inflation rate and the current annual expected provisions. These values are updated on every block for the previous block that has been accepted by the network
- Global parameter store - parameters that can be changed via governance proposals. Explained in the Parameters section
Minting parameters are recalculated and inflation paid at the beginning of each block for the previously processed block.
The target annual inflation rate is recalculated each block. If configured, the inflation is also subject to a rate change (positive or negative) depending on the distance from the desired staking/savings ratio. The maximum annual inflation rate change can be set independently, as well as the maximum and minimum values for annual inflation.
The annual provisions are calculated on each block based on current total supply and inflation rate with the formula:
Block provisions are generated for each block based on current annual provisions. The provisions are then minted by the mint module's ModuleMinterAccount and then transferred to the auth's FeeCollector module account. Block provisions are calculated by the following formula:
The configurable parameters for the Minting module that are stored in the global parameter store:
- MintDenom - the type of coin to mint
- InflationRateChange - maximum annual change in the inflation rate
- InflationMax - maximum inflation rate
- InflationMin - minimum inflation rate
- GoalBonded - the goal of the percentage of bonded assets
- BlocksPerYear - an estimate of blocks per year. Not used for time-based calculations on the blockchain but only to calculate estimated block provisions
Note: To achieve a constant 1% annual inflation rate the parameters InflationMax and InflationMin both need to be set at 1%.
The following events are emitted from the crisis module:
- Type: mint, Key: bonded_ratio, Value: <bonded_ratio>
- Type: mint, Key: inflation, Value: <inflation>
- Type: mint, Key: annual_provisions, Value: <annual_provisions>
- Type: mint, Key: amount, Value: <amount>
The params module provides a globally available parameter store which can be used to configure different modules. It can support permissioned parameter store access.
There are two main types of parameter stores:
- Keeper Parameter Store - has permission to access all existing spaces. For it to be used by a module, it needs to be injected during the initialization of that module
- Subspace - isolated namespace for parameter storage, where keys are prefixed by preconfigured space names. Subspaces can be used by other modules which need a private parameter store that other keepers cannot modify.
The module enables the blockchain to support a Proof-of-Stake system. In this system, holders of the native staking token of the chain can become validators and stake tokens to ultimately determine the effective validator set for the system. The specific difference between other PoS networks is that in this system all validators will have the same voting power that equals their stake. This mechanism is only available to HRA holders.
The Rewards module allows users to lock up their collateral and receive interest on it in 24 hour periods. The Rewards module will save a list of accounts that have deposited their funds. It will store data structures to execute the on-chain fee distribution module proposed by Dev Ojha. The rewards funds will be transferred from the Network Validator Reward Pool explained in the Distribution module.
An ANATHA validator can be in one of the following three states:
- Unbonded - The validator is not in the active set. They cannot sign blocks and do not earn rewards
- Bonded - Once the validator stakes sufficient bonded tokens they automatically join the active set during EndBlock and their status is updated to Bonded. They are signing blocks and receiving rewards. They can be slashed for misbehaviour. If a Validator wants to stop Validating they will have to announce that and must wait for the duration of the UnbondingTime, a chain-specific param. during which time they are still slashable for offences if those offences were committed during the period of time that the tokens were bonded
- Unbonding - When a validator leaves the active set, either by choice or due to slashing or tombstoning, an unbonding of their stake begins and lasts the specified UnboundingTime before their tokens are transferred from the BondedPool
In the current implementation of staking, there are the following important concepts:
- Operator - a keypair representing entity who runs a validator and has tokens staked
- Validator - a keypair that participates in the consensus. One operator can decide to change its validator keys. This is what Tendermint sees
The validator set will be formed from top MaxValidators that will be sorted by the amount of time they have been in the validating set. Since this set wouldn’t change often, to provide an incentive for waiting validators.
The staking module processes the following messages:
- MsgCreateValidator - Notifying the blockchain of a new potential validator, the message must contain a predefined amount of MinSelfDelegation coins that are going to be staked
- MsgEditValidator - Enables changing validator information as: address, description
- MsgBeginUnbonding - Notifies the network that the validator no longer wants to participate in the consensus algorithm. The validator needs to wait for UnbondingTime before can claim their stake back
On an End Block event several important changes happen:
- The staking validator set is updated during this process. As a part of this process, any updated validators are also returned back to Tendermint for inclusion in the Tendermint validator set which is responsible for validating Tendermint messages at the consensus layer. The new validator set consists of the top MaxValidators sorted by power. That validator set is compared with the previous one and all the missing validators begin unbounding their tokens, while the new validators are instantly bonded. All the token transfers are conducted between the NotBondedPool and BondedPool
- When a validator is leaving the bonded validator set (either through being jailed, or not having sufficient bonded tokens) it begins the unbonding process. At this point, the validator is said to be an unbonding validator, whereby it will mature to become an "unbonded validator" after the UnbondingTime period has passed. Each block the validator queue is to be checked for mature unbonding validators. At this point, any mature validators are deleted from state.
The staking module provides the following parameters:
- MinSelfDelegation - the amount of stake all validators have to put in, it has to be the exact number
- UnbondingTime - the amount of time needed to unlock validators’ collateral after deciding to stop validating
- MaxValidators - the maximum number of validators allowed in a single consensus round
- BondDenom - Denomination of the global staking currency
The slashing module disincentivizes any attributable action by a protocol-recognized actor with value at stake by penalizing them ("slashing"). Penalties include:
- Burning some amount of their stake
- Removing their ability to vote on future blocks for a period of time
At any given time, there are any number of validators registered in the state machine. Each block, the top MaxValidators validators who are not jailed become bonded, meaning that they may propose and vote on blocks. Validators who are bonded are at stake, meaning that part or all of their stake is at risk if they commit a protocol fault.
The protocol faults that are handled by the slashing module are:
- Double block signs (Equivocation)
- Liveness faults - Validators are penalized for failing to be included in the list of precommits for some number of blocks by being automatically jailed, potentially slashed, and unbonded
The slashing module keeps a global store of all slashing offence punishments but handles only Liveness faults as they are lighter offences, while the more serious consensus offences are handled in the Evidence module.
Liveness slashing is detected immediately as soon as the infraction occurs, and therefore no slashing period is needed to receive further offence proofs. A validator is immediately put into jail period, and they cannot commit another liveness fault until they send an unjailing transaction.
Every block includes a set of precommits by the validators for the previous block, known as the LastCommitInfo provided by Tendermint. A LastCommitInfo is valid so long as it contains precommits from +2/3 of the total voting power.
Information about validator's liveness activity is tracked through ValidatorSigningInfo. It is indexed in the store as follows:
- ValidatorSigningInfo is stored in a map with the key being the consensus address
- MissedBlocksBitArray is stored in a map with the key being the consensus address and the value representing a bit array where each bit represents if the validator missed the block for a given index in the bit-array
The ValidatorSigningInfo structure keeps track of:
- Address - The validator's consensus address.
- StartHeight - The height that the candidate became an active validator (with non-zero voting power).
- IndexOffset - Index which is incremented each time the validator was bonded in a block and may have signed a precommit or not
- JailedUntil - Time for which the validator is jailed until due to liveness downtime
- Tombstoned: Describes if the validator is tombstoned or not. It is set once the validator commits an equivocation or for any other configured misbehaviour.
- MissedBlocksCounter: A counter kept to avoid unnecessary array reads. Note that Sum(MissedBlocksBitArray) equals MissedBlocksCounter always.
The Slashing module handles the following messages:
- Unjail - If a validator was automatically unbonded due to downtime and wishes to come back online & possibly rejoin the bonded set. If the validator has enough stake to be in the top MaximumBondedValidators, they will be automatically rebonded and begin to again collect rewards
At the beginning of each block, we update the ValidatorSigningInfo for each validator and check if they've crossed below the liveness threshold over a sliding window. This sliding window is defined by SignedBlocksWindow and the index in this window is determined by IndexOffset found in the validator's ValidatorSigningInfo. For each block processed, the IndexOffset is incremented regardless if the validator signed or not. Once the index is determined, the MissedBlocksBitArray and MissedBlocksCounter are updated accordingly.
Finally, in order to determine if a validator crosses below the liveness threshold, we fetch the maximum number of blocks missed:
and the minimum height at which we can determine liveness, minHeight. If the current block is greater than minHeight and the validator's MissedBlocksCounter is greater than MaxMissed, they will be slashed by SlashFractionDowntime, will be jailed for DowntimeJailDuration, and have the following values reset: MissedBlocksBitArray, MissedBlocksCounter, and IndexOffset.
The Slashing module provides the following configurable parameters:
Note: Parameters without explanation have been documented in the Begin Block chapter
The Evidence module allows the submission and handling of arbitrary evidence of misbehaviour such as equivocation and counterfactual signing.
The module provides an API for other modules to register their evidence checking logic similar to the Crisis module. Submitted Evidence is first routed through the evidence module's Router in which it attempts to find a corresponding registered Handler for that specific Evidence type. Each Evidence type must have a Handler registered with the evidence module's keeper in order for it to be successfully routed and executed. The Handler for a given Evidence type can perform any arbitrary state transitions such as slashing, jailing, and tombstoning.
Currently the Evidence module only stores a list of valid submitted Evidence in the state.
Evidence is submitted through a MsgSubmitEvidence message. The supplied Evidence in the message must have a corresponding Handler registered with the Evidence module's Router in order to be processed and routed correctly.
Apart from the generalized framework for application-level evidence handling, the Evidence module provides a built-in evidence handler for the underlying consensus engine which is automatically submitted if found. The relevant information is forwarded to the application as ABCI Evidence in abci.RequestBeginBlock so that the validator can be accordingly punished.
Currently, the evidence module only handles evidence of type Equivocation (double signing) which is derived from Tendermint's ABCIEvidenceTypeDuplicateVote during BeginBlock.
If valid Equivocation evidence is included in a block, the validator's stake is slashed by SlashFractionDoubleSign, which is defined by the slashing module, of what their stake was when the infraction occurred (rather than when the evidence was discovered).IIn addition, the validator is permanently jailed and tombstoned making it impossible for that validator to ever re-enter the validator set. Only Evidence that is not older than the specified MaxEvidenceAge will be considered.
The Evidence module contains the following parameters:
- MaxEvidenceAge - evidence older than the parameter is not considered
The supply module passively tracks the total supply of coins within a chain, provides a pattern for other modules to hold/interact with coins and introduces a security invariant check to verify a chain's total supply.
The total supply of the network is equal to the sum of all coins from all accounts. The total supply is updated every time a coin is minted or burned.
The supply module introduces a new type of account (ModuleAccount) which can be used by modules to allocate tokens and in special cases mint or burn tokens. At a base level, these module accounts are capable of sending/receiving tokens to and from accounts and other module accounts.
Each ModuleAccount has a different set of permissions that provide different object capabilities to perform certain actions. Permissions need to be registered upon the creation of the SupplyKeeper so that every time a ModuleAccount calls the allowed functions, the keeper can lookup the permissions to that specific account and perform or not the action.
The supply module store only keeps track of the total supply of the chain.
The supply keeper provides wrapper functions for the AuthKeeper and the BankKeeper that are related to ModuleAccounts in order to be able to:
- Get and set ModuleAccounts by providing its name
- Send coins from and to other ModuleAccounts or standard accounts by passing its name
- Mint or burn coins from ModuleAccounts
The Upgrade module facilitates smoothly upgrading a live chain to a new (breaking) software version. It accomplishes this by providing a BeginBlocker hook that prevents the blockchain state machine from proceeding once a pre-defined upgrade block time or height has been reached The module does not assume anything regarding how governance decides to do an upgrade, but just the mechanism for coordinating the upgrade safely. Without software support for upgrades, upgrading a live chain is risky because all of the validators need to pause their state machines at exactly the same point in the process. If this is not done correctly, there can be state inconsistencies which are hard to recover from.
The Upgrade module defines a Plan type in which a live upgrade is scheduled to occur. A Plan can be scheduled at a specific block height or time, but not both. A Plan is created once a (frozen) release candidate along with an appropriate upgrade Handler is agreed upon, where the Name of a Plan corresponds to a specific Handler. Typically, a Plan is created through a SoftwareUpgradeProposal governance proposal process, where if voted upon and passed, will be scheduled. The Info of a Plan may contain various metadata about the upgrade, typically application-specific upgrade info to be included on-chain such as a git commit that validators could automatically upgrade to. The upgrade process can be fully automated for node operators. By populating the Info field with the necessary information, binaries can automatically be downloaded.
The internal state of the Upgrade module is relatively minimal and simple. The state only contains the currently active upgrade Plan (if one exists) by key 0x0 and if a Plan is marked as "done" by key 0x1.
Routes that relay messages to this module would only be passed to the Governance module which is the only way to initiate an Upgrade plan.
The following messages are available to the Governance module:
The Savings module allows users to lock up their collateral and receive interest on it in 24 hour periods.
The Savings module will save a list of accounts that have deposited their funds. It will store data structures to execute the on-chain fee distribution module proposed by Dev Ojha in https://drops.dagstuhl.de/opus/volltexte/2019/11400/. The savings funds will be transferred from the Network Validator Reward Pool explained in the Distribution module.
The Savings module will handle the following messages:
- MsgDeposit - allows the user to deposit any funds available on their account
- MsgWithdraw - allows the user to withdraw a specified amount from the savings account. This action resets the savings block time and interest accumulation will start in the interest payment period where the given savings account hasn’t been touched for 24 or more hours
- MsgWithdrawInterest - allows the user to withdraw interest to their account
The savings module will contain a configurable interest rate which can be changed by governance.
This module contains all of the logic linking an ANATHA address to one or more human-readable addresses (HRAs) and their metadata, which could include multi-currency wallets and other crypto addresses.
Every user can have multiple HRAs. Every one of those HRAs point to their native ANATHA Address. Every ANATHA Address holds a mapping of addresses for multiple cryptocurrencies grouped by the cryptocurrency and the order of the addresses within the same cryptocurrency. User have the ability to add multiple addresses from multiple cryptocurrencies. The first registered address of known cryptocurrencies within the ANATHA Platform have a decreased registration fee. Every following registered address has an increased fee. The fee mechanism is set in place to reduce malicious transactions overloading the network.
For the internal HRA storage following structures will be allocated:
- map[AnathaAddress] -> HRA - mapping from an ANATHA address to the list of HRA-s owned by the address holder.
- map[HRA] -> AnathaAddress - mapping from the hashed value of the HRA to the address of the owner
- map[HRA] -> HraInfo - mapping from the hashed value of the HRA to the structure describing specifics of given HRA
- map[AnathaAddress][CryptocurrencyId][Index] -> Address - mapping that maps an ANATHA address to multiple addresses of multiple cryptocurrencies
Each HraInfo structure consists of the following fields:
- ExpiryTime - the expiry timestamp of the HRA
- Price - the price at which the HRA can be sold in uANATHA. 0 if not for sale
The HRA module would support handling the following messages:
- RegisterHRA - message that has a parametrized cost that will tie the signers' address to the registered HRA. As additional data to this transaction, the user can pass the initial cryptocurrency wallet addresses that they want to be tied to their ANATHA. If this is the first registration of an HRA, addresses generated in the ANATHA Wallet would be automatically connected to the owners, address
- RenewHRA - message that would increase the ownership over an HRA for 1 year costing a parametrized fee
- SetSellingPrice - message that sets the price for the given HRA
- BuyHRA - message, when sent with the supplied price that matches with the selling price of the HRA transfers the HRA, to the buyer
- DeleteHRA - message that removes the AnathaAddress -> HRA association. If this is the last of the users’ HRA all his cryptocurrency address mappings would be deleted
- TransferHRA - message that transfers the HRA to another user
- RegisterAddress - allows the user to tie an external cryptocurrency address to their ANATHA Address that can be accessed through the HRA
- DeregisterAddress - allows the user to remove the previously registered external cryptocurrency address
The HRA module would expose the main keeper which would be accessible by other modules that require translating addresses. The rough list of functions provided by the keeper would be:
- GetHRAInfo - returns HRA basic information
- GetHRAByAddress - returns all HRAs owned by supplied address
- GetAddressByHRA - returns the ANATHA address
- PersistHRAInfo - stores modified HRA related data
At the beginning of every block maintenance procedures which include pruning expired HRA information and mappings would be executed.
- HRADenomination - default uANATHA
- HRAAnnualPrice - in combination with the previous parameter the total price of annual registration is calculated. Default 100000000 = 1 ANATHA
The Treasury module is in charge of holding the initial supply of ANATHA generating the treasury public sale price based on the amount of ANATHA transferred out of the treasury and receive ANATHA that had been bought back by the external Treasury System. The Treasury module will be controlled by an on-chain multi-signature wallet with its threshold requirements specified in the genesis file. To fulfil the objectives from the Product document, this on-chain module requires a complementing off-chain module which is described in the Backend Services section.
The Treasury module will expose routes to the Governance module through which this module's methods can be invoked through.
The Treasury module will have a BuyBack queue, where ANATHA holders would send their ANATHA as Orders and specify the cryptocurrency they want to get in exchange. If the liquidity of the Treasury Backend allows, it will execute the transfer and claim the ANATHA.
The Treasury module keeps a queryable current price in USD based on in-flow and out-flow of the initial supply of ANATHA. Starting at $0.01, the ANATHA token price increases by $0.01 for every 10,000,000 (10 million) ANATHA sold.
0 - 10,000,000 tokens sold: $0.01
10,000,001 - 20,000,000 tokens sold: $0.02
20,000,001 - 30,000,000 tokens sold: $0.03
30,000,001 - 40,000,000 tokens sold: $0.04
7,690,000,001 - 7,700,000,000 tokens sold: $7.70
The Treasury will hold a queue of BuyBack Orders waiting to be executed:
- Orders per user map[address] -> Order
- Global list of orders -> Order
The Treasury module keeper will provide the following functionalities:
- Update sale price
- Expose sale price
- Manage Orders from the queue
- TransferFunds - governance proposal based transfer funds from the Treasury to the specified address
- DepositFunds - return of bought back ANATHA and readjusting the sale price
- SellBack - deposits attached ANATHA to the Treasury fund and the message metadata would include the cryptocurrency identifier the ANATHA holder would like to get
- DeleteOrder - would allow the user to remove the order
- FulfillOrder - message that can be sent only by the Treasury backend after fulfilling the SellBack order. This would release the locked funds back in to the Treasury fund
The Governance module enables the blockchain to support an on-chain governance system. Before evolving to a decentralized governance system, this module will implement governance procedures based on a threshold on-chain multi-signature model, meaning that only participants that are registered in the genesis block would be able to create governance proposals and vote. Utilizing the mechanism of the Upgrade module, the Governance module can be self-updated to decentralized governance.
A web dashboard that allows ANATHA administrators to access a variety of private network data and monitor network activities. ANATHA administrators can also edit certain system-wide settings from a control panel within the admin dashboard.
The Treasury Backend is intended to work in parallel with the Treasury blockchain module and will be in charge of:
- Managing ANATHA that have been transferred to the account controlled by the treasury backend
- Handling various payment methods and disbursing ANATHA to buyers conveying to the USD selling price specified by the on-chain module
- In an advanced implementation, the system would scan the market if it can fulfil the purchase order cheaper. If it can, the profits are kept by ANATHA.
A standard explorer that provides API connectivity and a web interface for access to transactional and overall network data. The explorer provides generic information about the network (blocks, transactions, addresses, balances), HRA registry (HRA lookup, HRAmappings), and validators (number active, performance).
A program that allows qualified individuals onboard themselves as a validator and validate blocks of the ANATHA blockchain. Validator security and general parameters are defined based on standards set forth by the ANATHA network. Minimum validator requirements include owning an active HRA, owning 500,000 ANATHA available to stake, 99% or greater server up-time.
- Max number of nodes to begin with - 30
- Max number of nodes ultimately - 100
- Max number of nodes in the waiting list - unlimited
- Total number of nodes ANATHA is running - 3
- Leaderboard for waiting list
The indexing service indexes transactions by wallet addresses and by transaction hashes which makes it easier to filter out transactions associated with a certain address and it makes it easy to query a single transaction by its unique hash (SHA256 hash of the whole transaction object).
The indexing service is constantly subscribed to new transactions from existing blockchain nodes and it stores indexed data in a Redis datastore. If, for whatever reason, the indexing service would stop working it would not lose existing data and it would continue the synchronization process from the last saved block. As a part of the indexing process, invalid transactions are also saved, but they’re flagged with an invalid flag.
The Indexing service provides a highly available API which serves information that can’t be queried directly from the blockchain. These APIs would be used by various frontends like a blockchain explorer, wallet, etc.
To list a few items that the Indexer would index:
- HRA by expiry date
- Transactions by address
- Initializing an ANATHA wallet (keypair)
- By generating a keypair
- By importing a raw private key
- Checking the balance of an address
- Signing and transacting of ANATHA coins
- WebSocket event listeners that happen on each block and each transaction
- Module Query and Transaction related functionality:
- Query status of connected node
- Block - Get verified data for a block at a given height
- Transactions - Search for all transactions that match the given tags (Events) or hash
- Account balance
- State exposed in every module (Governance, Distribution, Staking, Slashing, HRA, Savings, Treasury, ...)
- Create and relay a signed transaction
- Broadcast offline generated signatures
- Messages exposed in every module (Governance, Distribution, Staking, Slashing, HRA, Savings, Treasury, ...)
One of the main interfaces for an application is the command-line interface. This entry point adds commands from the application's modules to let end-users create messages and queries.
Transactions are created by users to wrap messages that trigger state changes when they get included in a valid block. Transaction commands are typically exposed in each module tx.go file.
Queries allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own query.go file.
The CLI Tool will be called anathacli and will be a compiled Golang binary executable.
Each Message from the listed modules can be crafted by the CLI.