Cost: Free to use with 100,000 credits to use their API endpoints
|
| **Numia** | Indexes both EVM and Cosmos transactions on HyperPaxeer. Also indexes other chains on the Cosmos ecosystem. The service runs on Google BigQuery and requires users to sign up for their own accounts. | `cosmos` `evm` |
[Get started with GCP instruction](https://docs.numia.xyz/using-numia/getting-started-with-gcp)
[Pulling Numia Data Image](https://docs.numia.xyz/using-numia/querying-numia-datasets)
[Google Cloud](https://cloud.google.com/) provides free trial with ample credits (\$300) to run many queries for at least a few months
|
| **[SubQuery](https://subquery.network/)** | A fast, reliable, and decentralised indexer empowering developers to build customised APIs for their web3 projects. Supporting over 100+ networks, get started with our SDK, managed service & decentralised network. | `cosmos` + `evm` |
|
| **[Envio](https://envio.dev/)** | Envio is a full-featured data indexing solution that provides application developers with a seamless and efficient way to index and aggregate real-time and historical blockchain data for any EVM. Designed to optimize the user experience, Envio offers automatic code generation, flexible language support, multi-chain data aggregation, and a reliable cost-effective hosted service. | `evm` |
|
# Develop
Source: https://sidiorresearchlabs.mintlify.app/develop/index
Build on HyperPaxeer.
# Getting Started
Looking to build a dApp on HyperPaxeer? Following this documentation and our academy
you can learn how and become part of the rich ecosystem of EVM builders on
Cosmos. Whether you are building new use cases on HyperPaxeer or porting an existing
dApp from another chain, you'll want to check out the sections on
1. Building and deploying [EVM Smart Contracts](./develop/smart-contracts)
2. Integrating [wallets](./develop/wallet-integration) (e.g. Keplr and MetaMask) into your Frontend
3. Available developer [Tools](./tools/index.md)
## Why develop dApps on HyperPaxeer?
The HyperPaxeer Core Development Team is on a mission to provide the foundational tools necessary for building the cross-chain
applications of the future, freeing developers from the confines of todayβs siloed blockchains.
HyperPaxeer focuses on cross-chain **innovation** so that developers can build entirely new dApp experiences for their users.
Deploying smart contracts on HyperPaxeer is **easy**, as the HyperPaxeer blockchain is fully compatible with Ethereum and its rich
ecosystem of robust tooling, wallets, explorers, a surplus of assets, and intelligent end-users. At the same time,
HyperPaxeer allows developers to build **scalable** EVM dApp chains with the upcoming HyperPaxeer SDK and it hosts one of the
most active community governance that seeks **fairness** across all key actors (users, builders, and validators).
HyperPaxeer does this by leveraging the interoperability of the Cosmos Ecosystem and the market-dominating support for EVM
development. This allows dApp developers to use Ethereum smart contracts to implement the business logic on-chain
while having access to Cosmos chain functionalities, such as exchanging value with the rest of the Cosmos Ecosystem
through the Inter Blockchain Communication Protocol (IBC).
## Contributors
You can also contribute to the HyperPaxeer ecosystem without building a dApp. Head over to [tools](./tools/index.md) to learn
how to contribute as a full-stack developer by building new dev tools or [protocol](../protocol) to help
out building the core protocol.
# Mainnet
Source: https://sidiorresearchlabs.mintlify.app/develop/mainnet
# Mainnet
Before real users transact with actual funds on your dApp, account for security, deployment, monitoring, and support requirements. HyperPaxeer currently operates mainnet only, so test contracts locally or on private development networks before production deployment.
## Deployment
You can deploy your contracts on mainnet using the [JSON-RPC](../develop/smart-contracts#deploy-with-ethereum-json-rpc) and the [mainnet network endpoints](./../develop/api/networks). Before you do so, review the following considerations.
### Security
Thoroughly test your smart contracts in local and private environments before deploying to HyperPaxeer mainnet. Comprehensive tests should cover all functions, error handling, and edge cases.
Whenever possible, perform a comprehensive security audit of the smart contract code to identify and eliminate any potential vulnerabilities or weaknesses. This is especially vital for the mainnet, as the code will be accessible to everyone and any security flaws could result in substantial losses. Learn about the common vulnerabilities and contract security practices. External auditors can also help optimize your contract's performance.
Ensure proper management of contract ownership and consider implementing a multi-sig mechanism for increased security. This will allow you to maintain deployment ownership within your team instead of one specific owner that might leave the team.
Last but not least, verify that any external libraries or dependencies used by the contract are up-to-date and secure.
### Contract upgradeability
Consider the possibility of upgrading the contract in the future and implement upgrade mechanisms if needed. This will enable you to make changes to the contract without having to redeploy it, creating a new contract.
### Costs
Evaluate the gas costs associated with deploying and executing the smart contract, including the cost of deploying the contract and executing its functions are sufficient or efficient for end users.
### Contract documentation
Provide clear and comprehensive documentation for the contract, including its purpose, functions, and potential risks. This will assist users in understanding how to use the contract and make it easier for other developers to review and contribute to the code.
## Token distribution
You're dApp might issue an ERC-20 token, e.g. to give token holders additional benefits. In this case, you will need to decide on how to distribute them and what kind of narrative you want to create.
### Airdrop
One option is to distribute tokens to users through an airdrop. For some inspiration on how to select eligible receivers of an airdrop have a look at the \[HyperPaxeer Rektdrop]\([https://medium.com/Paxeer-Network/the-Paxeer](https://medium.com/Paxeer-Network/the-Paxeer) Network-rektdrop-abbe931ba823).
### Token Registration
HyperPaxeer allows for ERC-20 tokens to be used cross-chain. Once some of your tokens have been minted, you can register a token pair through governance, which will allow users to send your tokens across chains. Head over to our Academy to learn how to [register your ERC-20 token](https://academy.evmosd.org/articles/advanced/erc20-registration).
## Community
Make yourself heard in the HyperPaxeer community and explain what value your dApp provides. An essential part of building a dApp is getting in touch with the community to showcase how they can take ownership or start contributing to your project. This will not only help your dApp's visibility but might result in a new community of users, that want to improve your dApp.
Head over to the [HyperPaxeer Telegram](https://t.me/paxeernetwork) channel get in touch with the community and contributors and showcase your dApp on one of the next community calls.
# Oracles
Source: https://sidiorresearchlabs.mintlify.app/develop/oracles/index
Connect smart contracts to off-chain data sources.
# Oracles
HyperPaxeer supports several oracle providers to enable smart contracts to access
off-chain data and interact with the real world (e.g. price feeds or
randomness). These oracles serve as a bridge between the decentralized,
trustless environment of blockchain and the centralized, traditional internet.
An oracle is a piece of software that retrieves data from external sources and feeds it into smart contracts on the blockchain.
This enables smart contracts to respond to real-world events, trigger automated actions, and execute their intended functions.
## List of Oracles
### Mainnet
| Service | Description | Links & Features |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **[Pyth](https://docs.pyth.network/)** | Leverages over [70 first-party publishers](https://pyth.network/publishers) to publish financial market data to numerous blockchains. They provide data feeds to various assets classes, such as [US equities, commodities, and cryptocurrencies](https://pyth.network/price-feeds/). |
[Developer Docs](https://docs.pyth.network/)
[Pyth Client for Linux](https://github.com/pyth-network/pyth-client)
|
| **[Adrastia](https://docs.adrastia.io/)** | Provides a decentralized and permissionless oracle network that is secure, reliable, and easy to use. It uses [three types of contracts](https://docs.adrastia.io/structure/contracts) to provide secure data feeds: Accumulators, Intermediate oracles & Aggregator oracles |
HyperPaxeer data and contract address can be found [here](https://docs.adrastia.io/deployments/Paxeer-Network)
|
| **[DIA](https://docs.diadata.org/introduction/readme)** | Enables the sourcing, validation and sharing of transparent and verified data feeds for traditional and digital financial applications. DIAβs institutional-grade data feeds cover asset prices, metaverse data, lending rates and more. Data is directly sourced from a broad array of on-chain and off-chain sources at individual trade-level |
DIA feeds are fully customizable with regards to the mix of sources and methodologies, resulting in tailor-made, high resilience feeds
[HyperPaxeer](https://docs.diadata.org/documentation/oracle-documentation/deployed-contracts#HyperPaxeer) Mainnet and Testnet contracts available for use. Update frequency is 2 hrs.
[Link to DIA's API](https://docs.diadata.org/products/token-price-feeds/access-api-endpoints/api-endpoints)
DIA has a [custom feed builder](https://app.diadata.org/feed-builder) and the supported token pairs are located [here](https://docs.diadata.org/documentation/oracle-documentation/deployed-contracts#HyperPaxeer)
the [DIA team Discord](https://go.diadata.org/dev-discord)
|
| **[Redstone](https://docs.redstone.finance/docs/introduction)** | Offers a radically different design of Oracles catering for the needs of modern Defi protocols |
Data providers can avoid the requirement of continuous on-chain data delivery
Allow end users to self-deliver signed Oracle data on-chain
Use the decentralized Streamr network to deliver signed oracle data to the end users
Use token incentives to motivate data providers to maintain data integrity and uninterrupted service
Leverage the Arweave blockchain as a cheap and permanent storage for archiving Oracle data and maintaining data providers' accountability
Examples of Redstone EVM Connector can be found [here](https://github.com/redstone-finance/redstone-evm-connector-examples/blob/main/contracts/example-custom-urls.sol)
|
| **[SEDA Network](https://docs.seda.xyz/seda-network/introduction/the-oracle-problem)** | A multi-chain-native data transmission protocol built on an entirely decentralized foundation. The SEDA network is a Proof-of-Stake on-chain data provision solution that allows anyone to provide and access high-quality data on all blockchain networks |
|
## How do Oracles work?
```sql theme={null}
+------------+ +------------+ +-------------+
| External | | Oracle | | Smart |
| Data Source| | Service | | Contract |
+------------+ +------------+ +-------------+
| | |
| API Call | |
|---------------------> | |
| | Retrieve External |
| | Data via API Call |
| |---------------------->|
| | |
| | Use External Data |
| | in Smart Contract |
| |<----------------------|
| | |
| | Return Result to |
| | Smart Contract |
| |<----------------------|
| | |
```
In this diagram:
* External Data Source refers to a source of data outside the blockchain network,
such as a stock market, weather service, or other external API.
* Oracle Service is a third-party service that acts as a bridge between the external data source and the smart contract.
It retrieves the data from the external source and provides it to the smart contract.
* Smart Contract is a self-executing contract that is deployed on the blockchain network.
It uses the data provided by the oracle to perform certain actions, such as releasing funds or triggering events.
* API Call refers to the request made by the smart contract to the oracle service, asking for the required external data.
* Retrieve External Data refers to the process of retrieving the requested data
from the external data source via the API call.
* Use External Data refers to the process of using the retrieved data in the smart contract to perform actions,
such as condition checking and state changes.
* Return Result refers to the process of returning the result of the action performed in the smart contract back to the oracle.
# Custom improvement proposals
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/custom-improvement-proposals
# Custom Improvement Proposals
With the release [v19.0.0](https://github.com/Paxeer-Network/Paxeer-Network/releases/tag/v19.0.0)
a new feature called custom improvement proposals has been introduced in the
HyperPaxeer framework. Custom improvement proposals allow protocol developers to
modify the behavior of the EVM opcodes to tailor their functionalities to the
specific needs.
## Operations
Operations are the base components of the Ethereum Virtual Machine (EVM) which
allow the execution of the smart contract logic. When a developer builds a smart
contract, the code written in Solidity, or Vyper, is not directly interpretable
by the EVM. Before being able to execute the code in the blockchain, the
contract has to be compiled via one of the available compilers, like
[solc](https://docs.soliditylang.org/en/latest/using-the-compiler.html). The
compilation converts the human-readable contract code into a sequence of operations
that the virtual machine can interpret and execute
to perform state transitions or query the latest committed state.
These operations are called **opcodes**, and are contained
in a structure called [**jump table**](https://github.com/Paxeer-Network/Paxeer-Network/blob/v19.0.0/x/evm/core/vm/jump_table.go#L120-L1094).
Each opcode is defined by specifying the logic that has to be executed when it
is called inside the EVM, its relationship with the memory, and the gas cost
associated with it. More specifically, an opcode is completely defined by:
* `SetExecute`: update the execution logic for the opcode.
* `SetConstantGas`: update the value used for the constant gas cost.
* `SetDynamicGas`: update the function used to compute the dynamic gas cost.
* `SetMinStack`: update the minimum number of items in the stack required to
execute the operation.
* `SetMaxStack`: update the maximum number of items that will be in the stack
after executing the operation.
* `SetMemorySize`: the memory size required by the operation.
Within the HyperPaxeer framework, developers can modify any of the previous properties.
## Improvement Proposals
Improvement proposals are the approach used by HyperPaxeer and Ethereum to modify the
behavior of opcodes. They are composed of a function, which has access
to the jump table to apply specific changes to operation behavior, and a name.
In the context of Ethereum, these protocol changes are
named Ethereum Improvement Proposals (EIPs) and are identified by a unique ID.
For example, [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) is
used to introduce the base fee.
To allow any HyperPaxeer partner to define their own specific
improvements without overlapping with HyperPaxeer and Ethereum ones, each
proposal is identified by a string, that is composed of the chain name and a number. For
example, default HyperPaxeer improvements are associated with the string `HyperPaxeer_XXXX`.
This allows each chain to define their improvements without having to worry
about existing or future ID clashes between different chains.
Additionally, the ability to start enumeration at 0 is better for chain developers
and allows having a better overview of the historical progress for each chain.
Below, you will find an example of how the HyperPaxeer chain uses this functionality to modify the
behavior of the `CREATE` and `CREATE2` opcodes. First, the modifier function has
to be defined:
```go theme={null}
// Enable0000 contains the logic to modify the CREATE and CREATE2 opcodes
// constant gas value.
func Enable0000(jt *vm.JumpTable) {
multiplier := 10
currentValCreate := jt[vm.CREATE].GetConstantGas()
jt[vm.CREATE].SetConstantGas(currentValCreate * multiplier)
currentValCreate2 := jt[vm.CREATE2].GetConstantGas()
jt[vm.CREATE2].SetConstantGas(currentValCreate2 * multiplier)
}
```
Then, the function as to be associated with a name via a custom activator:
```go theme={null}
HyperPaxeerActivators = map[string]func(*vm.JumpTable){
"HyperPaxeer_0": eips.Enable0000,
}
```
## Activation of Improvement Proposals
Due to continuous changes in the users' interaction with the protocol, and to
introduce a safety measure along with the freedom to customize the virtual
machine behavior, custom improvement proposals are not active by default.
The activation of selected improvement proposals is controlled by the [EVM module's parameters](https://github.com/Paxeer-Network/Paxeer-Network/blob/main/proto/ethermint/evm/v1/evm.proto#L17-L18).
There are two ways of introducing the required parameter changes:
1. **Upgrade**: create a protocol upgrade handler which introduces the proposal name
in the active list.
2. **Governance**: create governance proposal to add an improvement proposal to the EVM module parameters.
This approach gives developers the ability to react to security issues or market conditions,
while keeping the chain's participants in the loop.
## Additional Resources
1. [HyperPaxeer Custom EIPs](https://github.com/Paxeer-Network/Paxeer-Network/blob/main/app/eips/README.md):
please refer to this document for a detailed description of how opcodes and
custom improvement proposals have to be used in the HyperPaxeer framework.
# Authorization
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/authorization
# Authorization
The user should grant authorization to allow smart contracts
to send messages on behalf of a user account.
This is achieved by the `Authorization.sol`
that provides the necessary functions to grant approvals and allowances.
The precompiled contracts use the `AuthorizationI` interface,
to allow users to approve the corresponding messages and amounts.
## Solidity Interfaces
### `Authorization.sol`
Find the [Solidity interface in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/common/Authorization.sol).
## Transactions
* `approve`
Approves a list of Cosmos or IBC transactions with a specific amount of tokens
```solidity theme={null}
function approve(
address spender,
uint256 amount,
string[] calldata methods
) external returns (bool approved);
```
* `revoke`
Revokes authorizations of Cosmos transactions.
```solidity theme={null}
function revoke(
address spender,
string[] calldata methods
) external returns (bool revoked);
```
* `increaseAllowance`
Increase the allowance of a given spender by a specific amount of tokens for IBC transfer methods or staking
```solidity theme={null}
function increaseAllowance(
address spender,
uint256 amount,
string[] calldata methods
) external returns (bool approved);
```
* `decreaseAllowance`
Decreases the allowance of a given spender by a specific amount of tokens for IBC transfer methods or staking
```solidity theme={null}
function decreaseAllowance(
address spender,
uint256 amount,
string[] calldata methods
) external returns (bool approved);
```
## Queries
* `allowance`
Returns the remaining number of tokens that the spender will be allowed to
spend on behalf of the owner through IBC transfer methods or staking.
This is zero by default
```solidity theme={null}
function allowance(
address owner,
address spender,
string calldata method
) external view returns (uint256 remaining);
```
## Events
* `Approval`
This event is emitted when the allowance of a spender is set by a call to the `approve` method.
The `value` field specifies the new allowance and the `methods`
field holds the information for which methods the approval was set.
```solidity theme={null}
event Approval(
address indexed owner,
address indexed spender,
string[] methods,
uint256 value
);
```
* `Revocation`
This event is emitted when an owner revokes a spender's allowance.
```solidity theme={null}
event Revocation(
address indexed owner,
address indexed spender,
string[] methods
);
```
* `AllowanceChange`
This event is emitted when the allowance of a spender is changed by a call to the decrease or increase allowance method.
The `values` field specifies the new allowances and the `methods`
field holds the information for which methods the approval was set.
```solidity theme={null}
event AllowanceChange(
address indexed owner,
address indexed spender,
string[] methods,
uint256[] values
);
```
# Distribution
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/distribution
# Distribution
## Solidity Interface & ABI
`Distribution.sol` is an interface through which Solidity contracts can interact with Cosmos SDK distribution.
This is convenient for developers as they donβt need to know the implementation details behind
the `x/distribution` module in the Cosmos SDK. Instead,
they can interact with distribution functions using the Ethereum interface they are familiar with.
### Interface `Distribution.sol`
Find the [Solidity interface in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/Distribution.sol).
### ABI
Find the [ABI in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/abi/distribution.json).
## Transactions
* `setWithdrawAddress`
```solidity theme={null}
/// @dev Change the address, that can withdraw the rewards of a delegator.
/// Note that this address cannot be a module account.
/// @param delegatorAddress The address of the delegator
/// @param withdrawerAddress The address that will be capable of withdrawing rewards for
/// the given delegator address
function setWithdrawAddress(
address delegatorAddress,
string memory withdrawerAddress
) external returns (bool success);
```
* `withdrawDelegatorRewards`
```solidity theme={null}
/// @dev Withdraw the rewards of a delegator from a validator
/// @param delegatorAddress The address of the delegator
/// @param validatorAddress The address of the validator
/// @return amount The amount of Coin withdrawn
function withdrawDelegatorRewards(
address delegatorAddress,
string memory validatorAddress
)
external
returns (
Coin[] calldata amount
);
```
* `withdrawValidatorCommission`
```solidity theme={null}
/// @dev Withdraws the rewards commission of a validator.
/// @param validatorAddress The address of the validator
/// @return amount The amount of Coin withdrawn
function withdrawValidatorCommission(
string memory validatorAddress
)
external
returns (
Coin[] calldata amount
);
```
## Queries
* `validatorDistribution`
```solidity theme={null}
/// @dev Queries validator commission and self-delegation rewards for validator.
/// @param validatorAddress The address of the validator
/// @return distributionInfo The validator's distribution info
function validatorDistributionInfo(
string memory validatorAddress
)
external
view
returns (
ValidatorDistributionInfo calldata distributionInfo
);
```
* `validatorOutstandingRewards`
```solidity theme={null}
/// @dev Queries the outstanding rewards of a validator address.
/// @param validatorAddress The address of the validator
/// @return rewards The validator's outstanding rewards
function validatorOutstandingRewards(
string memory validatorAddress
)
external
view
returns (
DecCoin[] calldata rewards
);
```
* `validatorCommission`
```solidity theme={null}
/// @dev Queries the accumulated commission for a validator.
/// @param validatorAddress The address of the validator
/// @return commission The validator's commission
function validatorCommission(
string memory validatorAddress
)
external
view
returns (
DecCoin[] calldata commission
);
```
* `validatorSlashes`
```solidity theme={null}
/// @dev Queries the slashing events for a validator in a given height interval
/// defined by the starting and ending height.
/// @param validatorAddress The address of the validator
/// @param startingHeight The starting height
/// @param endingHeight The ending height
/// @return slashes The validator's slash events
/// @return pageResponse The pagination response for the query
function validatorSlashes(
string memory validatorAddress,
uint64 startingHeight,
uint64 endingHeight
)
external
view
returns (
ValidatorSlashEvent[] calldata slashes,
PageResponse calldata pageResponse
);
```
* `delegationRewards`
```solidity theme={null}
/// @dev Queries the total rewards accrued by a delegation from a specific address to a given validator.
/// @param delegatorAddress The address of the delegator
/// @param validatorAddress The address of the validator
/// @return rewards The total rewards accrued by a delegation.
function delegationRewards(
address delegatorAddress,
string memory validatorAddress
)
external
view
returns (
DecCoin[] calldata rewards
);
```
* `delegationTotalRewards`
```solidity theme={null}
/// @dev Queries the total rewards accrued by each validator, that a given
/// address has delegated to.
/// @param delegatorAddress The address of the delegator
/// @return rewards The total rewards accrued by each validator for a delegator.
/// @return total The total rewards accrued by a delegator.
function delegationTotalRewards(
address delegatorAddress
)
external
view
returns (
DelegationDelegatorReward[] calldata rewards,
DecCoin[] calldata total
);
```
* `delegatorValidators`
```solidity theme={null}
/// @dev Queries all validators, that a given address has delegated to.
/// @param delegatorAddress The address of the delegator
/// @return validators The addresses of all validators, that were delegated to by the given address.
function delegatorValidators(
address delegatorAddress
) external view returns (string[] calldata validators);
```
* `delegatorWithdrawAddress`
`delegatorWithdrawAddress` queries withdraw address of a delegator
```solidity theme={null}
/// @dev Queries the address capable of withdrawing rewards for a given delegator.
/// @param delegatorAddress The address of the delegator
/// @return withdrawAddress The address capable of withdrawing rewards for the delegator.
function delegatorWithdrawAddress(
address delegatorAddress
) external view returns (string memory withdrawAddress);
```
## Events
Each of the transactions emits its corresponding event. These are:
* `SetWithdrawerAddress`
```solidity theme={null}
/// @dev SetWithdrawerAddress defines an Event emitted when a new withdrawer address is being set
/// @param caller the caller of the transaction
/// @param withdrawerAddress the newly set withdrawer address
event SetWithdrawerAddress(
address indexed caller,
string withdrawerAddress
);
```
* `WithdrawDelegatorRewards`
```solidity theme={null}
/// @dev WithdrawDelegatorRewards defines an Event emitted when rewards from a delegation are withdrawn
/// @param delegatorAddress the address of the delegator
/// @param validatorAddress the address of the validator
/// @param amount the amount being withdrawn from the delegation
event WithdrawDelegatorRewards(
address indexed delegatorAddress,
string indexed validatorAddress,
uint256 amount
);
```
* `WithdrawValidatorCommission`
```solidity theme={null}
/// @dev WithdrawValidatorCommission defines an Event emitted when validator commissions are being withdrawn
/// @param validatorAddress is the address of the validator
/// @param commission is the total commission earned by the validator
event WithdrawValidatorCommission(
string indexed validatorAddress,
uint256 commission
);
```
## Interact with the Solidity Interface
Below are some examples of how to interact with this Solidity interface from your smart contracts.
Make sure to import the precompiled interface, e.g.:
```solidity theme={null}
import "https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/Distribution.sol";
```
### Set withdraw address
The `changeWithdrawAddress` function allows a user to set a new withdraw address in the Cosmos `x/distribution` module.
For this transaction to be successful, make sure the user had already approved the `MSG_SET_WITHDRAWER_ADDRESS` message.
```solidity theme={null}
function changeWithdrawAddress(
string memory _withdrawAddr
) public returns (bool) {
return
distribution.DISTRIBUTION_CONTRACT.setWithdrawAddress(
msg.sender,
_withdrawAddr
);
}
```
### Withdraw staking rewards
The `withdrawStakingRewards` function allows a user to withdraw his/her rewards corresponding to a specified validator.
For this transaction to be successful, make sure the user had already approved the `MSG_WITHDRAW_DELEGATOR_REWARD` message.
```solidity theme={null}
function withdrawStakingRewards(
string memory _valAddr
) public returns (types.Coin[] memory) {
return
distribution.DISTRIBUTION_CONTRACT.withdrawDelegatorRewards(
msg.sender,
_valAddr
);
}
```
### Withdraw validator commission
If the user is running a validator, he/she could withdraw the corresponding commission using a smart contract.
The user could use a function similar to `withdrawCommission`.
For this transaction to be successful,
make sure the user had already approved the `MSG_WITHDRAW_VALIDATOR_COMMISSION` message.
```solidity theme={null}
function withdrawCommission(
string memory _valAddr
) public returns (types.Coin[] memory) {
return
distribution.DISTRIBUTION_CONTRACT.withdrawValidatorCommission(
_valAddr
);
}
```
### Queries
Similarly to transactions, smart contracts can use query methods. These are read-only methods.
Examples of this are the `getDelegationRewards` and `getValidatorCommision`
functions that return the information for the specified validator address.
```solidity theme={null}
getDelegationRewards(
string memory _valAddr
) public view returns (types.DecCoin[] memory) {
return
distribution.DISTRIBUTION_CONTRACT.delegationRewards(
msg.sender,
_valAddr
);
}
function getValidatorCommission(
string memory _valAddr
) public view returns (types.DecCoin[] memory) {
return distribution.DISTRIBUTION_CONTRACT.validatorCommission(_valAddr);
}
```
# Evm extensions
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/evm-extensions
# EVM Extensions
Stateful EVM Extensions on the core protocol allow dApps and users to access logic outside of the EVM.
Acting as a gateway, these EVM Extensions define how smart contracts can perform cross-chain transactions
(via IBC) and interact with core functionalities on the HyperPaxeer chain (e.g. staking, voting) from the EVM.
:::tip
**Note**: Not sure what EVM extensions are?
EVM extensions behave like smart contracts that are compiled and deployed within the EVM.
If you are familiar with the EVM, you may know them as Precompiles.
These have predefined addresses and, according to their logic, can be classified as stateful or stateless.
When they change the state of the chain (transactions)
or access state data (queries), extensions are considered "stateful";
when they don't, they're "stateless".
:::
## EVM Extensions documentation
Find in this section an outline of the currently implemented EVM extensions with transactions,
queries, and examples of using them:
* [Authorization interface (read first if you're new to EVM extensions)](./authorization.md)
* [EVM Extensions shared types](./types.md)
* [`x/staking` module EVM extension](./staking.md)
* [`x/distribution` module EVM extension](./distribution.md)
* [`ibc/transfer` module EVM extension](./ibc-transfer.md)
* [`x/vesting` module EVM extension](./vesting.md)
:::tip
**Note**: Find the EVM Extensions Solidity interfaces and examples in the [HyperPaxeer Extensions repo](https://github.com/Paxeer-Network/extensions).
:::
## Other Learning Resources
* [EVM Extensions - Staking & Distribution](https://academy.evmosd.org/articles/advanced/evm-extensions-stk-distr)
academy article
* [Diving into EVM Extensions Workshop (DoraHacks Hackathon)](https://www.youtube.com/live/pJhOfZ0ScAE?feature=share)
# Ibc transfer
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/ibc-transfer
# IBC Transfer
## Solidity Interface & ABI
`ICS20.sol` - previously known as `IBCTransfer.sol` -
is an interface through which Solidity contracts can interact with the IBC protocol on HyperPaxeer chain.
This is convenient for developers as they donβt need to know the implementation details behind the `transfer` module in [IBC-go](https://ibc.cosmos.network/).
Instead, they can perform IBC transfers using the Ethereum interface they are familiar with.
An example of a simple implementation can be found in the [HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/tree/main/examples/simple-ibc-transfer).
### Interface `ICS20.sol`
Find the [Solidity interface in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/ICS20.sol).
### ABI
Find the [ABI in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/abi/ics20.json).
## Transactions
* `approve`
```solidity theme={null}
/// @dev Approves IBC transfer with a specific amount of tokens.
/// @param spender spender The address which will spend the funds.
/// @param allocations The allocations for the authorization.
function approve(
address spender,
Allocation[] calldata allocations
) external returns (bool approved);
```
* `revoke`
```solidity theme={null}
/// @dev Revokes IBC transfer authorization for a specific spender
/// @param spender The address which will spend the funds.
function revoke(address spender) external returns (bool revoked);
```
* `increaseAllowance`
```solidity theme={null}
/// @dev Increase the allowance of a given spender by a specific amount of tokens and IBC connection for IBC transfer methods.
/// @param spender The address which will spend the funds.
/// @param sourcePort The source port of the IBC transaction.
/// @param sourceChannel The source channel of the IBC transaction.
/// @param denom The denomination of the tokens transferred.
/// @param amount The amount of tokens to be spent.
function increaseAllowance(
address spender,
string calldata sourcePort,
string calldata sourceChannel,
string calldata denom,
uint256 amount
) external returns (bool approved);
```
* `decreaseAllowance`
```solidity theme={null}
/// @dev Decreases the allowance of a given spender by a specific amount of tokens for for IBC transfer methods.
/// @param spender The address which will spend the funds.
/// @param sourcePort The source port of the IBC transaction.
/// @param sourceChannel The source channel of the IBC transaction.
/// @param denom The denomination of the tokens transferred.
/// @param amount The amount of tokens to be spent.
function decreaseAllowance(
address spender,
string calldata sourcePort,
string calldata sourceChannel,
string calldata denom,
uint256 amount
) external returns (bool approved);
```
* `transfer`
```solidity theme={null}
/// @dev Transfer defines a method for performing an IBC transfer.
/// @param sourcePort the address of the validator
/// @param sourceChannel the address of the validator
/// @param denom the denomination of the Coin to be transferred to the receiver
/// @param amount the amount of the Coin to be transferred to the receiver
/// @param sender the hex address of the sender
/// @param receiver the bech32 address of the receiver
/// @param timeoutHeight the bech32 address of the receiver
/// @param timeoutTimestamp the bech32 address of the receiver
/// @param memo the bech32 address of the receiver
function transfer(
string memory sourcePort,
string memory sourceChannel,
string memory denom,
uint256 amount,
address sender,
string memory receiver,
Height memory timeoutHeight,
uint64 timeoutTimestamp,
string memory memo
) external returns (uint64 nextSequence);
```
## Queries
* `denomTrace`
```solidity theme={null}
/// @dev DenomTrace defines a method for returning a denom trace.
function denomTrace(
string memory hash
) external returns (DenomTrace memory denomTrace);
```
* `denomTraces`
```solidity theme={null}
/// @dev DenomTraces defines a method for returning all denom traces.
function denomTraces(
PageRequest memory pageRequest
)
external
returns (
DenomTrace[] memory denomTraces,
PageResponse memory pageResponse
);
```
* `denomHash`
```solidity theme={null}
/// @dev DenomHash defines a method for returning a hash of the denomination trace info.
function denomHash(
string memory trace
) external returns (string memory hash);
```
* `allowance`
```solidity theme={null}
/// @dev Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through
/// IBC transfers. This is an empty array by default.
/// @param owner The address of the account owning tokens.
/// @param spender The address of the account able to transfer the tokens.
/// @return allocations The remaining amounts allowed to spend for
/// corresponding source port and channel.
function allowance(
address owner,
address spender
) external view returns (Allocation[] memory allocations);
```
## Events
Each of the transactions emits its corresponding event. These are:
* `IBCTransfer`
```solidity theme={null}
/// @dev Emitted when an ICS-20 transfer is executed.
/// @param sender The address of the sender.
/// @param receiver The address of the receiver.
/// @param sourcePort The source port of the IBC transaction.
/// @param sourceChannel The source channel of the IBC transaction.
/// @param denom The denomination of the tokens transferred.
/// @param amount The amount of tokens transferred.
/// @param memo The IBC transaction memo.
event IBCTransfer(
address indexed sender,
string indexed receiver,
string sourcePort,
string sourceChannel,
string denom,
uint256 amount,
string memo
);
```
* `IBCTransferAuthorization`
```solidity theme={null}
/// @dev Emitted when an ICS-20 transfer authorization is granted.
/// @param grantee The address of the grantee.
/// @param granter The address of the granter.
/// @param sourcePort The source port of the IBC transaction.
/// @param sourceChannel The source channel of the IBC transaction.
/// @param spendLimit The coins approved in the allocation
event IBCTransferAuthorization(
address indexed grantee,
address indexed granter,
string sourcePort,
string sourceChannel,
Coin[] spendLimit
);
```
* `RevokeIBCTransferAuthorization`
```solidity theme={null}
/// @dev This event is emitted when an owner revokes a spender's allowance.
/// @param owner The owner of the tokens.
/// @param spender The address which will spend the funds.
event RevokeIBCTransferAuthorization(
address indexed owner,
address indexed spender
);
```
* `AllowanceChange`
```solidity theme={null}
/// @dev This event is emitted when the allowance of a spender is changed by a call to the decrease or increase
/// allowance method. The values field specifies the new allowances and the methods field holds the
/// information for which methods the approval was set.
/// @param owner The owner of the tokens.
/// @param spender The address which will spend the funds.
/// @param methods The message type URLs of the methods for which the approval is set.
/// @param values The amounts of tokens approved to be spent.
event AllowanceChange(
address indexed owner,
address indexed spender,
string[] methods,
uint256[] values
);
```
# Staking
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/staking
# Staking
## Solidity Interface & ABI
`Staking.sol` is an interface through which Solidity contracts can interact with Cosmos SDK staking.
This is convenient for developers as they donβt need to know the implementation details behind the `x/staking`
module in the Cosmos SDK. Instead,
they can interact with staking functions using the Ethereum interface they are familiar with.
### Interface `Staking.sol`
Find the [Solidity interface in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/Staking.sol).
### ABI
Find the [ABI in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/abi/staking.json).
## Transactions
The Staking solidity interface includes the following transactions
* `delegate`
`delegate` defines a method for performing a delegation of coins from a delegator to a validator.
```solidity theme={null}
function delegate(
address delegatorAddress,
string memory validatorAddress,
uint256 amount
) external returns (bool success);
```
* `undelegate`
`undelegate` defines a method for performing an undelegation from a delegate and a validator.
```solidity theme={null}
function undelegate(
address delegatorAddress,
string memory validatorAddress,
uint256 amount
) external returns (int64 completionTime);
```
* `redelegate`
Redelegate defines a method for performing a redelegation
of coins from a delegator and source validator to a destination validator
```solidity theme={null}
function redelegate(
address delegatorAddress,
string memory validatorSrcAddress,
string memory validatorDstAddress,
uint256 amount
) external returns (int64 completionTime);
```
* `cancelUnbondingDelegation`
`cancelUnbondingDelegation` allows delegators to cancel the unbondingDelegation entry
and to delegate back to a previous validator.
```solidity theme={null}
function cancelUnbondingDelegation(
address delegatorAddress,
string memory validatorAddress,
uint256 amount,
uint256 creationHeight
) external returns (bool success);
```
## Queries
* `delegation`
get the given amount of the bond denomination to a validator.
```solidity theme={null}
function delegation(
address delegatorAddress,
string memory validatorAddress
) external view returns (uint256 shares, Coin calldata balance);
```
* `unbondingDelegation`
`unbondingDelegation` returns the unbonding delegation
```solidity theme={null}
function unbondingDelegation(
address delegatorAddress,
string memory validatorAddress
) external view returns (UnbondingDelegationEntry[] calldata entries);
```
* `validator`
`validator` queries validator info for given validator address
```solidity theme={null}
function validator(
string memory validatorAddress
)
external view returns (
Validator calldata validator
);
```
* `validators`
`validators` queries all validators that match the given status
```solidity theme={null}
function validators(
string memory status,
PageRequest calldata pageRequest
) external view returns (
Validator[] calldata validators,
PageResponse calldata pageResponse
);
```
* `redelegation`
`redelegation` queries all redelegations from a source to a destination validator for a given delegator
```solidity theme={null}
function redelegation(
address delegatorAddress,
string memory srcValidatorAddress,
string memory dstValidatorAddress
) external view returns (RedelegationEntry[] calldata entries);
```
* `redelegations`
`redelegations` queries all redelgations based on the specified criteria:
for a given delegator and/or origin validator address
and/or destination validator address
in a specified pagination manner.
```solidity theme={null}
function redelegations(
address delegatorAddress,
string memory srcValidatorAddress,
string memory dstValidatorAddress,
PageRequest calldata pageRequest
)
external
view
returns (
RedelegationResponse[] calldata response,
PageResponse calldata pageResponse
);
```
## Events
Each of the transactions emits its corresponding event. These are:
* `Delegate`
Delegate defines an Event emitted when a given amount
of tokens are delegated from the delegator address to the validator address
```solidity theme={null}
event Delegate(
address indexed delegatorAddress,
string indexed validatorAddress,
uint256 amount,
uint256 newShares
);
```
* `Unbond`
Unbond defines an Event emitted when a given amount
of tokens are unbonded from the validator address to the delegator address
```solidity theme={null}
event Unbond(
address indexed delegatorAddress,
string indexed validatorAddress,
uint256 amount,
uint256 completionTime
);
```
* `Redelegate`
Redelegate defines an Event emitted when a given amount
of tokens are redelegated from the source validator address to the destination validator address
```solidity theme={null}
event Redelegate(
address indexed delegatorAddress,
string indexed validatorSrcAddress,
string indexed validatorDstAddress,
uint256 amount,
uint256 completionTime
);
```
* `CancelUnbondingDelegation`
CancelUnbondingDelegation defines an Event emitted when
a given amount of tokens that are in the process of unbonding
from the validator address are bonded again
```solidity theme={null}
event CancelUnbondingDelegation(
address indexed delegatorAddress,
string indexed validatorAddress,
uint256 amount,
uint256 creationHeight
);
```
## Interact with the Solidity Interface
Below are some examples of how to interact with this Solidity interface from your smart contracts.
Make sure to import the precompiled interface, e.g.:
```solidity theme={null}
import "https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/Staking.sol";
```
### Grant approval for the desired messages
See below a function that grants approval to the smart contract to send all `x/staking` module messages
on behalf of the sender account. In this case,
the allowance amount is the maximum amount possible.
You can tweak this function to approve only the desired messages and amounts.
```solidity theme={null}
string[] private stakingMethods = [
MSG_DELEGATE,
MSG_UNDELEGATE,
MSG_REDELEGATE,
MSG_CANCEL_UNDELEGATION
];
/// @dev Approves this smart contract to perform all staking transactions with the maximum amount of tokens on behalf of the transaction signer.
/// @dev This creates a Cosmos Authorization Grant for the given methods.
/// @dev This emits an Approval event.
function approveAllStakingMethodsWithMaxAmount() public {
bool success = STAKING_CONTRACT.approve(
address(this),
type(uint256).max,
stakingMethods
);
require(success, "Failed to approve staking methods");
}
```
### Delegate to a validator
The `stakeTokens` function allows the transaction sender to delegate the specified amount to his/her favorite validator.
Keep in mind that, for this transaction to be successful, the user should have approved the `MSG_DELEGATE` previously
(see the `approveAllStakingMethodsWithMaxAmount` defined in the code snippet above as an example).
This function returns the completion time of the staking transaction and emits a `Delegate` event.
```solidity theme={null}
/// @dev stake a given amount of tokens. Returns the completion time of the staking transaction.
/// @dev This emits an Delegate event.
/// @param _validatorAddr The address of the validator.
/// @param _amount The amount of tokens to stake in ahpx.
/// @return success Boolean to inform if the operation was successful or not.
function stakeTokens(
string memory _validatorAddr,
uint256 _amount
) public returns (bool success) {
return STAKING_CONTRACT.delegate(msg.sender, _validatorAddr, _amount);
}
```
### Undelegate from a validator
The `unstakeTokens` function allows a user to unstake a given amount of tokens.
It returns the completion time of the unstaking transaction and emits an `Undelegate` event.
```solidity theme={null}
/// @dev unstake a given amount of tokens. Returns the completion time of the unstaking transaction.
/// @dev This emits an Undelegate event.
/// @param _validatorAddr The address of the validator.
/// @param _amount The amount of tokens to unstake in ahpx.
/// @return completionTime The completion time of the unstaking transaction.
function unstakeTokens(
string memory _validatorAddr,
uint256 _amount
) public returns (int64 completionTime) {
return STAKING_CONTRACT.undelegate(msg.sender, _validatorAddr, _amount);
}
```
### Redelegate to another validator
With the `redelegateTokens` function, a user can redelegate a given amount of tokens.
It returns the completion time of the redelegate transaction and emits a `Redelegate` event.
```solidity theme={null}
/// @dev redelegate a given amount of tokens. Returns the completion time of the redelegate transaction.
/// @dev This emits a Redelegate event.
/// @param _validatorSrcAddr The address of the source validator.
/// @param _validatorDstAddr The address of the destination validator.
/// @param _amount The amount of tokens to redelegate in ahpx.
/// @return completionTime The completion time of the redelegate transaction.
function redelegateTokens(
string memory _validatorSrcAddr,
string memory _validatorDstAddr,
uint256 _amount
) public returns (int64 completionTime) {
return
STAKING_CONTRACT.redelegate(
msg.sender,
_validatorSrcAddr,
_validatorDstAddr,
_amount
);
}
```
### Cancel unbonding from a validator
With the `cancelUnbondingDelegation` function, a user can cancel an unbonding delegation.
This function returns the completion time of the unbonding delegation cancellation transaction
and emits a `CancelUnbondingDelegation` event.
```solidity theme={null}
/// @dev cancel an unbonding delegation. Returns the completion time of the unbonding delegation cancellation transaction.
/// @dev This emits an CancelUnbondingDelegation event.
/// @param _validatorAddr The address of the validator.
/// @param _amount The amount of tokens to cancel the unbonding delegation in ahpx.
/// @param _creationHeight The creation height of the unbonding delegation.
function cancelUnbondingDelegation(
string memory _validatorAddr,
uint256 _amount,
uint256 _creationHeight
) public returns (bool success) {
return
STAKING_CONTRACT.cancelUnbondingDelegation(
msg.sender,
_validatorAddr,
_amount,
_creationHeight
);
}
```
### Queries
Similarly to transactions, smart contracts can use query methods.
To use these methods, there is no need for authorization, as these are read-only methods.
Examples of this are these `getDelegation` and `getUnbondingDelegation`
functions that return the information for the specified validator address.
```solidity theme={null}
/// @dev Returns the delegation information for a given validator for the msg sender.
/// @param _validatorAddr The address of the validator.
/// @return shares and balance. The delegation information for a given validator for the msg sender.
function getDelegation(
string memory _validatorAddr
) public view returns (uint256 shares, Coin memory balance) {
return STAKING_CONTRACT.delegation(msg.sender, _validatorAddr);
}
/// @dev Returns the unbonding delegation information for a given validator for the msg sender.
/// @param _validatorAddr The address of the validator.
/// @return entries The unbonding delegation entries for a given validator for the msg sender.
function getUnbondingDelegation(
string memory _validatorAddr
) public view returns (UnbondingDelegationEntry[] memory entries) {
return STAKING_CONTRACT.unbondingDelegation(msg.sender, _validatorAddr);
}
```
# Vesting
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/evm-extensions/vesting
# Vesting
## Solidity Interface & ABI
`Vesting.sol` is an interface through which Solidity contracts can interact with HyperPaxeer vesting module.
This is convenient for developers as they donβt need to know the implementation details behind the `x/vesting`
module in HyperPaxeer. Instead,
they can interact with vesting accounts using the Ethereum interface they are familiar with.
:::tip
To learn more about the `x/vesting` module, check out the [module's docs](https://docs.paxeer.app/protocol/modules/vesting).
:::
### Interface `Vesting.sol`
Find the [Solidity interface in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/stateful/Vesting.sol).
### ABI
Find the [ABI in the HyperPaxeer/extensions repo](https://github.com/Paxeer-Network/extensions/blob/main/precompiles/abi/vesting.json).
## Transactions
The Vesting solidity interface includes the following transactions
* `createClawbackVestingAccount`
`createClawbackVestingAccount` defines a method for the creation of a `ClawbackVestingAccount`.
```solidity theme={null}
function createClawbackVestingAccount(
address funderAddress,
address vestingAddress,
bool enableGovClawback
) external returns (bool success);
```
* `fundVestingAccount`
`fundVestingAccount` defines a method for funding a vesting account.
```solidity theme={null}
function fundVestingAccount(
address funderAddress,
address vestingAddress,
uint64 startTime,
Period[] calldata lockupPeriods,
Period[] calldata vestingPeriods
) external returns (bool success);
```
* `clawback`
`clawback` defines a method for clawing back coins from a vesting account.
```solidity theme={null}
function clawback(
address funderAddress,
address accountAddress,
address destAddress
) external returns (Coin[] memory);
```
* `updateVestingFunder`
`updateVestingFunder` defines a method for updating the funder of a vesting account.
```solidity theme={null}
function updateVestingFunder(
address funderAddress,
address newFunderAddress,
address vestingAddress
) external returns (bool success);
```
* `convertVestingAccount`
`convertVestingAccount` defines a method for converting a clawback vesting account to an eth account.
```solidity theme={null}
function convertVestingAccount(
address vestingAddress
) external returns (bool success);
```
## Queries
* `balances`
`balances` query the balances of a vesting account
```solidity theme={null}
function balances(
address vestingAddress
) external view returns (Coin[] memory locked, Coin[] memory unvested, Coin[] memory vested);
```
## Events
Each of the transactions emits its corresponding event. These are:
* `CreateClawbackVestingAccount`
Event that is emitted when a clawback vesting account is created.
```solidity theme={null}
event CreateClawbackVestingAccount(
address indexed funderAddress,
address indexed vestingAddress
);
```
* `FundVestingAccount`
Event that is emitted when a clawback vesting account is funded.
```solidity theme={null}
event FundVestingAccount(
address indexed funderAddress,
address indexed vestingAddress,
uint64 startTime,
Period[] lockupPeriods,
Period[] vestingPeriods
);
```
* `Clawback`
Event that is emitted when a vesting account is clawed back.
```solidity theme={null}
event Clawback(
address indexed funderAddress,
address indexed accountAddress,
address destAddress
);
```
* `UpdateVestingFunder`
Event that is emitted when a vesting account's funder is updated.
```solidity theme={null}
event UpdateVestingFunder(
address indexed funderAddress,
address indexed vestingAddress,
address newFunderAddress
);
```
* `ConvertVestingAccount`
Event that is emitted when a vesting account is converted to a clawback vesting account.
```solidity theme={null}
event ConvertVestingAccount(
address indexed vestingAddress
);
```
# Smart Contracts
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/index
Build and deploy smart contracts on HyperPaxeer EVM.
# Smart Contracts
Since the introduction of Ethereum in 2015,
the ability to control digital assets through [smart contracts](https://ethereum.org/en/smart-contracts/)
has attracted a large community of developers
to build decentralized applications on the Ethereum Virtual Machine (EVM).
This community is continuously creating extensive tooling and introducing standards,
which are further increasing the adoption rate of EVM-compatible technology.
Whether you are building new use cases on HyperPaxeer
or porting an existing dApp from another EVM-based chain (e.g. Ethereum),
you can easily build and deploy EVM smart contracts on HyperPaxeer to implement the core business logic of your dApp.
HyperPaxeer is fully compatible with the EVM,
so it allows you to use the same tools (Solidity, Remix, Oracles, etc.)
and APIs (i.e. Ethereum JSON-RPC) that are available on the EVM.
Leveraging the interoperability of Cosmos chains,
HyperPaxeer enables you to build scalable cross-chain applications within a familiar EVM environment.
Learn about the essential components when building and deploying EVM smart contracts on HyperPaxeer below.
## Build with Solidity
You can develop EVM smart contracts on HyperPaxeer using [Solidity](https://github.com/ethereum/solidity).
Solidity is also used to build smart contracts on Ethereum.
So if you have deployed smart contracts on Ethereum (or any other EVM-compatible chain)
you can use the same contracts on HyperPaxeer.
Since it is the most widely used smart contract programming language in Blockchain,
Solidity comes with well-documented and rich language support.
Head over to our list of Tools and IDE Plugins to help you get started.
### EVM Extensions
EVM Extensions are precompiled contracts that are built into the Ethereum Virtual Machine (EVM).
Each offers specific functionality, that can be used by other smart contracts.
Generally, they are used to perform operations that are either not possible
or would be too expensive to perform with a regular smart contract
implementation, such as hashing, elliptic curve cryptography, and modular exponentiation.
By adding custom EVM extensions to Ethereum's basic feature set,
HyperPaxeer allows developers to use previously unavailable functionality in smart contracts, like staking and governance operations.
This will allow more complex smart contracts to be built on HyperPaxeer
and further improves the interoperability between Cosmos and Ethereum.
It also is a key feature to achieve HyperPaxeer' vision of being the definitive dApp
chain, where any dApp can be deployed once and users can interact with
a wide range of different blockchains natively.
To enable the described functionalities, HyperPaxeer introduces so-called *stateful* precompiled smart contracts,
which can perform a state transition,
as opposed to those offered by the standard Go-Ethereum implementation,
which can only read state information.
This is necessary because an operation like e.g. staking tokens
will ultimately change the chain state.
View a list of available evm extensions [here](./list-evm-extensions.md).
### Oracles
Blockchain oracles provide a way for smart contracts to access external information,
such as price feeds from financial exchanges or carbon emission measurements.
They serve as bridges between blockchains and the outside world.
Head over to our [Oracles section](./oracles) to find out
how smart contracts can make use of oracles on HyperPaxeer for real-life activities
such as insurance, borrowing, lending, or gaming.
## Deploy with Ethereum JSON-RPC
HyperPaxeer is fully compatible with the [Ethereum JSON-RPC](./../../develop/api/ethereum-json-rpc/) APIs,
allowing you to deploy and interact with smart contracts on HyperPaxeer
and connect with existing Ethereum-compatible web3 tooling.
This gives you direct access to reading Ethereum-formatted transactions
or sending them to the network which otherwise wouldn't be possible on a Cosmos chain, such as HyperPaxeer.
You can connect to the HyperPaxeer [Testnet](./testnet)
to deploy and test your smart contracts before moving to Mainnet.
### Block Explorers
You can use [block explorers](./block-explorers)
to view and debug interactions with your smart contracts deployed on HyperPaxeer.
Block explorers index blocks and their transactions
so that you can search for real-time and historical information about the blockchain,
including data related to blocks, transactions, addresses, and more.
### Contract Verification
Once deployed, smart contract data is deployed as non-human readable EVM bytecode.
You can use [contract verification tools](./tools/contract-verifications)
that publish and verify your original Solidity code
to prove to users that they are interacting with the correct smart contract.
## HyperPaxeer Features
The core protocol team is continuously building features
that enhance the experience of smart contract developers on HyperPaxeer.
Head over to our Mainnet sections to learn more about these functionalities.
# EVM Extensions
Source: https://sidiorresearchlabs.mintlify.app/develop/smart-contracts/list-evm-extensions
Precompiled contracts and Cosmos module extensions available on HyperPaxeer mainnet
## Available extensions
HyperPaxeer is mainnet-only today. The table below lists the extensions available on HyperPaxeer mainnet.
| Address | Name | Stateful | Standard / source | Mainnet |
| -------------------------------------------- | ------------------------------ | -------: | ------------------------------------------------- | ------- |
| `0x0000000000000000000000000000000000000001` | ecRecover | No | Ethereum precompile | Active |
| `0x0000000000000000000000000000000000000002` | SHA256 Hash | No | Ethereum precompile | Active |
| `0x0000000000000000000000000000000000000003` | RIPEMD-160 Hash | No | Ethereum precompile | Active |
| `0x0000000000000000000000000000000000000004` | Data Copy | No | Ethereum precompile | Active |
| `0x0000000000000000000000000000000000000005` | ExpMod | No | [EIP-198](https://eips.ethereum.org/EIPS/eip-198) | Active |
| `0x0000000000000000000000000000000000000006` | BN256Add | No | [EIP-196](https://eips.ethereum.org/EIPS/eip-196) | Active |
| `0x0000000000000000000000000000000000000007` | BN256ScalarMul | No | [EIP-196](https://eips.ethereum.org/EIPS/eip-196) | Active |
| `0x0000000000000000000000000000000000000008` | BN256Pairing | No | [EIP-197](https://eips.ethereum.org/EIPS/eip-197) | Active |
| `0x0000000000000000000000000000000000000009` | Blake2F | No | [EIP-152](https://eips.ethereum.org/EIPS/eip-152) | Active |
| `0x0000000000000000000000000000000000000400` | Bech32 encoding | No | HyperPaxeer extension | Active |
| `0x0000000000000000000000000000000000000800` | Staking module | Yes | Cosmos SDK extension | Active |
| `0x0000000000000000000000000000000000000801` | Distribution module | Yes | Cosmos SDK extension | Active |
| `0x0000000000000000000000000000000000000802` | IBC Transfer | Yes | Cosmos SDK extension | Active |
| `0x0000000000000000000000000000000000000803` | Vesting module | Yes | Cosmos SDK extension | Active |
| `0x0000000000000000000000000000000000000901` | PaxSpot OROBResolver | No | PaxSpot precompile | Active |
| `0x0000000000000000000000000000000000000902` | PaxSpot BatchClearing | No | PaxSpot precompile | Active |
| `0x0000000000000000000000000000000000000903` | PaxSpot OracleAggregator / VOM | Mixed | PaxSpot + `x/paxoracle` precompile | Active |
| `0x0000000000000000000000000000000000000904` | PaxSpot PoFQScorer | No | PaxSpot precompile | Active |
Use the [PaxSpot precompile reference](/paxspot/precompiles) for Solidity and frontend examples for `0x901` through `0x904`.
## Further reading
* [EVM precompiled contracts](https://www.evm.codes/precompiled)
* [Current network facts](/current-network)
* [PaxSpot precompiles](/paxspot/precompiles)
# Client integrations
Source: https://sidiorresearchlabs.mintlify.app/develop/tools/client-integrations
# HyperPaxeer Client Integrations
Client integration libraries play a crucial role in blockchain technology by making it easier for developers to interact
with the blockchain network. Libraries abstract away complexities and provide integrations and methods to allow developers
to create product in a more consistent manner.
## HyperPaxeer-specific Client Integrations
HyperPaxeer-specific libraries are useful in aiding developers speed up development by providing interfaces, types, and methods
to signing, address converter (between `eth` and `HyperPaxeer` addresses), and `EIP-712` transaction generator. There are two
library bindings, in Javascript/Typescript and Python.
* [HyperPaxeerJS](https://github.com/Paxeer-Network/Paxeer-Networkjs) - is the official HyperPaxeer client Typescript library. This library contains
several packages:
* [Address Converter](https://www.npmjs.com/package/@HyperPaxeer/address-converter)
* [EIP-712](https://www.npmjs.com/package/@HyperPaxeer/eip712)
* [Proto](https://www.npmjs.com/package/@HyperPaxeer/proto)
* [Provider](https://www.npmjs.com/package/@HyperPaxeer/provider)
* [Transactions](https://www.npmjs.com/package/@HyperPaxeer/transactions)
* [PyHyperPaxeer](https://github.com/sterliakov/pyHyperPaxeer) - is a community-led Python library developed by [sterliakov](https://github.com/sterliakov)
## Ethereum Client Integrations
EthersJS and Web3JS are two most commonly used libraries in dApp development. Developer uses these libraries to interact
with blockchain and query JSON-RPC data, for example. Additionally, both of these libraries contain utilities to aid in
task like converting large numbers (BigNumber).
* [Ethers.js](https://docs.ethers.org/v5/) is the latest JS library that aims to be a complete and compact library for
interacting with the Ethereum Blockchain and its ecosystem.
* [web3js](https://web3js.readthedocs.io/en/v1.8.2/) is a collection of libraries that allow you to interact with a local
or remote ethereum node using HTTP, IPC or WebSocket.
# Contract verifications
Source: https://sidiorresearchlabs.mintlify.app/develop/tools/contract-verifications
# Contract Verification
Contract verification refers to the process of auditing and verifying the code of smart contracts
before they are deployed on the blockchain.
This is an important step in ensuring that smart contracts function as intended
and are free of vulnerabilities or security flaws.
It is typically performed by independent auditors, security experts, or automated tools.
The process involves a thorough analysis of the contract code to identify potential issues,
such as bugs, security vulnerabilities, or potential attacks.
This can involve both manual and automated testing to ensure that the code meets certain standards and best practices.
## [Escan](https://escan.live/)
Escan is a service that allows block exploration as well as contract verification.
For more information about the different block explorers, please proceed to our [block explorers's page](../block-explorers).
[Link](https://escan.live/verifyContract) to verify and publish the contract source code.
## [Mintscan](https://www.mintscan.io/Paxeer-Network/evm)
Mintscan, is another block explorer that offers permissioned contract verification.
To view all the EVM contracts, proceed to [this link](https://www.mintscan.io/Paxeer-Network/evm).
Verified contracts will have a green checkbox.
To submit your contract for verification,
please head to this [link](https://docs.google.com/forms/d/e/1FAIpQLScid7oF2ajNFG8xSwRupU_fgYOB-oqZVK-8bYScj_LsLB-Ejw/viewform)
and fill out as much of the request detail.
The Mintscan team will review the contract and get back to you.
# Tools & Plugins
Source: https://sidiorresearchlabs.mintlify.app/develop/tools/index
Development tools, SDKs, and plugins for building on Paxeer.
# Other Tools
Tools play a crucial role in blockchain development as they help streamline the development process and make it easier
for developers to build and deploy decentralized applications (dApps). Decentralized applications (dApps) are built on
blockchain technology, which requires specific tools and frameworks for development. Some of the most commonly used tools
in dApp development include:
* [Tools and Plugins](./tools-plugins.md): There are many tools and plugins to aid in the development of dApps. These include
smart contract languages and frameworks, development environments, wallet and identity management plugins, and analytics
and monitoring tools.
* [Client Integration](./client-integrations.md): HyperPaxeerJS and PyHyperPaxeer are two examples of client integration toolings to
help developers interact with our core protocol features by providing interfaces, types, signing abstractions, and more.
* [Contract Verifications](./contract-verifications.md): This is an important process in blockchain development that
involves validating the authenticity and accuracy of smart contract code before deploying it to the blockchain. Contract
verification serves to increase transparency, improves contract accuracy, prevents fraud and malicious activities,
and increases adoption.
Dive in further into the above toolings by visiting the subsequent pages.
# Wallet Integration
Source: https://sidiorresearchlabs.mintlify.app/develop/wallet-integration/index
Integrate wallets like MetaMask and Keplr into your dApp.
# Wallet Integration
Wallet integration is an essential aspect of dApp development that allows users to securely interact with blockchain-based
applications. Here are some key points from various sources on wallet integration in dApp development:
* The integration implementation checklist for dApp developers consists of three categories: frontend features,
transactions and wallet interactions, and more. Developers enabling transactions on their dApp have to determine
the wallet type of the user, create the transaction, request signatures from the corresponding wallet, and finally broadcast.
* Leverage Keplr, Metamask, Ledger, WalletConnect and more with HyperPaxeer. The latest wallets are located [here](https://academy.evmosd.org/articles/wallet).
* Head over to our [HyperPaxeer Client Integrations](./../../develop/tools/client-integrations)
to leverage our Typescript or Python libraries.
## Gas & Estimation
When developing and running dApps on HyperPaxeer, the wallet configuration will attempt to calculate the correct gas amount
for user's to sign. [Gas and Fees](./../../../protocol/concepts/gas-and-fees) breaks down these concepts in more detail.
We have a module called [feemarket](./../../../protocol/modules/feemarket#concepts) that describes our module implementation
of transaction prioritization since prior to Cosmos SDK 0.46 it did not have such implementation.
# Code Examples
Source: https://sidiorresearchlabs.mintlify.app/examples
Integration guides and code samples for building on HyperPaxeer
## Overview
Code examples and integration guides for building on HyperPaxeer. All examples work with standard Ethereum tools and libraries.
## Wallet Connection
### Connect Wallet with wagmi
React component for connecting wallets to HyperPaxeer.
```typescript WalletConnect.tsx theme={null}
'use client'
import { useAccount, useConnect, useDisconnect } from 'wagmi'
import { Button } from '@/components/ui/button'
export function WalletConnect() {
const { address, isConnected } = useAccount()
const { connect, connectors } = useConnect()
const { disconnect } = useDisconnect()
if (isConnected) {
return (
)
}
```
## Best Practices
Always handle errors gracefully:
```typescript theme={null}
try {
const tx = await writeContract({...});
await tx.wait();
} catch (error) {
if (error.code === 'ACTION_REJECTED') {
console.log('User rejected transaction');
} else if (error.code === 'INSUFFICIENT_FUNDS') {
console.log('Insufficient funds');
} else {
console.error('Transaction failed:', error);
}
}
```
Show loading states for better UX:
```typescript theme={null}
const { isPending, isLoading, isSuccess } = useWriteContract();
if (isPending) return
Confirm in wallet...
;
if (isLoading) return
Transaction pending...
;
if (isSuccess) return
Success!
;
```
Estimate gas before transactions:
```javascript theme={null}
const gasEstimate = await contract.transfer.estimateGas(
toAddress,
amount
);
const gasLimit = gasEstimate * 120n / 100n; // 20% buffer
```
## Next Steps
Set up your development environment
Deploy your own contracts
Explore all available methods
Discover development tools
# Paxeer Network
Source: https://sidiorresearchlabs.mintlify.app/index
Developer documentation for Paxeer Network β Alexandria Fork, HyperPaxeer runtime, Argus VM, and network-operated protocols
**Chain ID:** `125` | **Cosmos:** `hyperpax_125-1` | **Token:** PAX (`ahpx`, 18 decimals) | **Bech32:** `pax` | **Block time:** 277 ms average | **Binary:** `hyperpaxd_2.0.3`
## The Network
HyperPaxeer is a sovereign Proof-of-Stake blockchain purpose-built for capital orchestration. Running on the **Alexandria Fork**, it pairs a production EVM execution layer with the **Argus Virtual Machine (AVM)** β a C++ register-based runtime that handles risk, capital allocation, and funded smart-wallet management. The April 2026 performance report shows 10 active validators, 48 RPC nodes, 14 active regions, and 277 ms average block production.
Genesis-to-report mainnet history
47 EVM RPC nodes online across 14 active regions
Official average block time with 341 ms p95
***
## Dual-VM Architecture
```text theme={null}
Paxeer Network
+----------------------+ +----------------------+
| EVM OS Layer |β | Argus VM (AVM) |β
| Alexandria Fork |β | C++ runtime, .avm |β
| Solidity contracts |β | Risk engine |β
| Custom precompiles |β | Capital orchestration|β
| 0x901β0x904 |β | Smart wallet |β
| Standard EVM tooling|β |ArgLang scripts (.arg)|β
+----------------------+β +----------------------+β
ββββββββββββββββββββββββ ββββββββββββββββββββββββ
CometBFT Consensus Β· Cosmos SDK Β· IBC
```
The **EVM OS** is the blockchain shell β consensus, networking, smart-contract execution, JSON-RPC. The **AVM** is the value engine β capital allocation, drawdown policy, funded-wallet lifecycle. Both layers communicate through on-chain contract boundaries (`IPaxSpotReader`, `IAllowanceProvider`).
***
## Quick Navigation
Install a node with one command, connect a wallet, deploy a contract
Deploy and verify contracts with Foundry, Hardhat, or Remix
wagmi, viem, ethers.js, and web3.js setup snippets
Deploy RPC or Validator nodes with HyperPaxeer tooling
***
## Core Technology
Register-based VM with 256-bit native arithmetic, deterministic gas metering, and the ArgLang smart-contract language
Four stateful/stateless precompiles at 0x901β0x904 β OROB resolution, batch clearing, oracle aggregation, PoFQ scoring
Native fungible-token spec for ArgusVM β Rust-inspired syntax, built-in overflow protection, optimised gas
Cosmos SDK module for validator-submitted price feeds with confidence-weighted median aggregation
***
## Ecosystem Protocols
On-chain spot exchange with Oracle-Relative Order Book (OROB), dual-mode matching, lazy-netting settlement, and capital-integrated trading
Adaptive Sigmoid AMM β tanh bonding curve, progressive quadratic fees, LP loyalty rewards, oracle-pegged pools, Diamond Standard upgradeability
Network-operated perpetual futures protocol with Diamond facets, on-chain order book, and oracle pricing
Launchpad AMM with virtual USDL reserves, per-pool Beacon proxies, and Opticals
Meta-AG routing layer for Paxeer liquidity, adapters, quotes, and execution tracking
REST API for querying transactions, blocks, addresses, and tokens on PaxScan
***
## Network Details
```json theme={null}
{
"networkName": "HyperPaxeer",
"rpcUrl": "https://public-rpc.paxeer.app/rpc",
"chainId": 125,
"cosmosChainId": "hyperpax_125-1",
"currencySymbol": "PAX",
"baseDenom": "ahpx",
"displayDenom": "hpx",
"decimals": 18,
"bech32Prefix": "pax",
"blockExplorer": "https://paxscan.io",
"averageBlockTime": "277ms",
"binary": "hyperpaxd_2.0.3"
}
```
***
## Developer Resources
Test Ethereum JSON-RPC, Cosmos gRPC, and CometBFT RPC methods
End-to-end integration samples in TypeScript, Python, and Solidity
Foundry, Hardhat, wagmi, viem, cosmjs, and hpx CLI
Live node health, latency benchmarks, and validator set
# Network Status
Source: https://sidiorresearchlabs.mintlify.app/network-status
Live node health, latency benchmarks, and validator set for HyperPaxeer
## Validator Set
HyperPaxeer runs on 10 active validators with balanced voting power. Consensus requires a two-thirds supermajority of voting power.
| Metric | Value |
| -------------------- | ----------------: |
| Active validators | `10` |
| Total voting power | `167,294,521` |
| Voting-power range | `5.9%` to `13.1%` |
| Nakamoto coefficient | `4` |
Data from the official April 2026 HyperPaxeer performance report.
***
## Block Timing
| Metric | Value |
| ------------ | --------------------- |
| **Average** | 277 ms |
| **Min** | 197 ms |
| **Max** | 358 ms |
| **p95** | 341 ms |
| **Std Dev** | 40.3 ms |
| **Finality** | Instant deterministic |
***
## RPC / Full Node Fleet
48 RPC nodes and 47 EVM RPC nodes are online across 14 active regions.
| Region group | Observed latency |
| ------------- | ---------------: |
| Best RPC | 4.2 ms |
| Europe | 4-65 ms |
| United States | 215-390 ms |
***
## Chain Statistics
| Metric | Value |
| ---------------- | ---------------------------------------------- |
| **Chain ID** | `hyperpax_125-1` (EVM: `125`) |
| **Block Height** | 5.25M+ blocks in the report sample |
| **Genesis** | Block 1 (all nodes retain full history) |
| **Consensus** | CometBFT v0.38.15 (PoS) |
| **Fork** | Alexandria (Cosmos SDK + CometBFT) |
| **Binary** | `hyperpaxd_2.0.3` |
| **Token** | HPX (`ahpx` base / `hpx` display, 18 decimals) |
***
## Endpoints
| Type | URL |
| ------------------ | ------------------------------------- |
| **JSON-RPC (EVM)** | `https://public-rpc.paxeer.app/rpc` |
| **CometBFT RPC** | `https://public-rpc.paxeer.app:26657` |
| **REST API** | `https://public-rpc.paxeer.app:1317` |
| **gRPC** | `https://public-rpc.paxeer.app:9090` |
| **Block Explorer** | [paxscan.io](https://paxscan.io) |
***
## Resources
Deploy your own RPC or Validator node with the hpx CLI
View live chain data on PaxScan
# API Reference
Source: https://sidiorresearchlabs.mintlify.app/openapi/index
Explore and test HyperPaxeer APIs directly from the docs.
# API Reference
Explore HyperPaxeer APIs interactively. This section includes GraphQL schemas for our indexer services and OpenAPI specifications for REST APIs.
## GraphQL APIs
Real-time indexer data via GraphQL:
* **[LaunchPad GraphQL](/docs/openapi/launchpad-graphql)** - Bonding curve markets, swaps, and token launches
* **[Perpetuals GraphQL](/docs/openapi/perpetual-graphql)** - Perpetual futures positions, trades, and liquidations
* **[StableSwap GraphQL](/docs/openapi/stableswap-graphql)** - Stable AMM pools, swaps, and liquidity
## OpenAPI / JSON-RPC
Interactive API playgrounds for REST and RPC endpoints:
# LaunchPad GraphQL
Source: https://sidiorresearchlabs.mintlify.app/openapi/launchpad-graphql
GraphQL schema for the Paxeer LaunchPad indexer.
# LaunchPad GraphQL Schema
GraphQL schema for the LaunchPad indexer β bonding curve markets, swaps, transfers, holders, and candle data.
**Endpoint:** `https://launchpad-indexer-production.up.railway.app/graphql`
## Schema
```graphql theme={null}
type Market {
id: Int!
poolAddress: String!
tokenAddress: String!
nftId: Int!
creator: String!
name: String!
symbol: String!
metadata: JSON
metadataImageUrl: String
virtualReserveUSD: String!
realReserveUSD: String!
reserveToken: String!
spotPrice: String!
marketCap: String!
volume24h: String!
volumeTotal: String!
trades24h: Int!
tradesTotal: Int!
feeStrategy: Int!
volatility: Int!
holders: Int!
createdAtBlock: Int!
createdAt: String!
updatedAt: String!
}
type Swap {
id: Int!
txHash: String!
poolAddress: String!
sender: String!
stablecoinIn: String
stablecoinOut: String
tokenIn: String!
tokenOut: String!
amountIn: String!
amountOut: String!
feeAmount: String!
reserveUsdAfter: String!
reserveTokenAfter: String!
priceUsd: String!
blockNumber: Int!
timestamp: String!
}
type TokenTransfer {
id: Int!
txHash: String!
tokenAddress: String!
fromAddress: String!
toAddress: String!
amount: String!
blockNumber: Int!
timestamp: String!
}
type FeeClaim {
id: Int!
txHash: String!
poolAddress: String
nftId: Int!
recipient: String!
amount: String!
blockNumber: Int!
timestamp: String!
}
type Holder {
holderAddress: String!
balance: String!
percentage: Float!
}
type Candle {
openTime: String!
open: String!
high: String!
low: String!
close: String!
volume: String!
trades: Int!
}
type TokenMetadata {
tokenAddress: String!
name: String!
symbol: String!
metadata: JSON
imageUrl: String
description: String
links: JSON
}
type VolatilitySnapshot {
volatility: Int!
blockNumber: Int!
timestamp: String!
}
type IndexerStatus {
lastBlock: Int!
headBlock: Int
lag: Int
marketsIndexed: Int!
totalSwaps: Int!
totalTransfers: Int!
uptime: String!
}
scalar JSON
type Query {
markets(orderBy: MarketOrderBy, limit: Int, offset: Int): [Market!]!
market(poolAddress: String, tokenAddress: String, symbol: String): Market
marketsByCreator(creator: String!): [Market!]!
searchMarkets(query: String!): [Market!]!
trendingMarkets(limit: Int): [Market!]!
swaps(poolAddress: String!, limit: Int, offset: Int): [Swap!]!
swapsByUser(sender: String!, limit: Int, offset: Int): [Swap!]!
recentSwaps(limit: Int): [Swap!]!
tokenTransfers(tokenAddress: String!, limit: Int, offset: Int): [TokenTransfer!]!
transfersByAddress(address: String!, limit: Int, offset: Int): [TokenTransfer!]!
topHolders(tokenAddress: String!, limit: Int): [Holder!]!
holderCount(tokenAddress: String!): Int!
feeClaims(nftId: Int!, limit: Int): [FeeClaim!]!
candles(poolAddress: String!, interval: String!, limit: Int): [Candle!]!
tokenMetadata(tokenAddress: String!): TokenMetadata
volatilityHistory(poolAddress: String!, limit: Int): [VolatilitySnapshot!]!
indexerStatus: IndexerStatus!
}
enum MarketOrderBy {
MARKET_CAP_DESC
MARKET_CAP_ASC
VOLUME_DESC
CREATED_DESC
CREATED_ASC
PRICE_DESC
HOLDERS_DESC
}
type Subscription {
marketUpdated(poolAddress: String): Market
newSwap(poolAddress: String): Swap
newMarket: Market
}
```
# Perpetuals GraphQL
Source: https://sidiorresearchlabs.mintlify.app/openapi/perpetual-graphql
GraphQL schema for the Paxeer Perpetuals indexer.
# Perpetuals GraphQL Schema
GraphQL schema for the Perpetuals indexer β markets, positions, trades, orders, liquidations, funding rates, and vault operations.
**Endpoint:** `https://perps.sidiora.xyz/api/subgraph`
## Schema
```graphql theme={null}
directive @oneOf on INPUT_OBJECT
scalar BigDecimal
scalar DateTime
type Market {
marketId: Int!
name: String!
symbol: String!
maxLeverage: BigDecimal!
enabled: Boolean!
createdAt: DateTime
latestPrice: LatestPrice
poolState: PoolState
fundingRate: FundingRate
}
type Position {
positionId: BigDecimal!
userAddress: String!
marketId: Int!
isLong: Boolean!
sizeUsd: BigDecimal!
leverage: BigDecimal!
entryPrice: BigDecimal!
collateralToken: String
collateralAmount: BigDecimal!
collateralUsd: BigDecimal!
status: String!
realizedPnl: BigDecimal
exitPrice: BigDecimal
openedAt: DateTime
closedAt: DateTime
openBlock: Int
closeBlock: Int
openTxHash: String
closeTxHash: String
market: Market
}
type Trade {
id: Int!
positionId: BigDecimal!
userAddress: String
marketId: Int
tradeType: String!
isLong: Boolean
sizeUsd: BigDecimal!
price: BigDecimal!
realizedPnl: BigDecimal
feeUsd: BigDecimal
blockNumber: Int!
txHash: String!
blockTimestamp: DateTime!
}
type Order {
orderId: BigDecimal!
userAddress: String!
marketId: Int!
orderType: Int!
isLong: Boolean!
triggerPrice: BigDecimal!
sizeUsd: BigDecimal!
status: String!
positionId: BigDecimal
executionPrice: BigDecimal
placedAt: DateTime
resolvedAt: DateTime
placedBlock: Int
resolvedBlock: Int
placedTxHash: String
resolvedTxHash: String
}
type Liquidation {
id: Int!
positionId: BigDecimal!
userAddress: String!
marketId: Int!
price: BigDecimal!
penalty: BigDecimal!
keeper: String!
blockNumber: Int!
txHash: String!
blockTimestamp: DateTime!
}
type PriceUpdate {
id: Int!
marketId: Int!
price: BigDecimal!
onchainTimestamp: Int!
blockNumber: Int!
txHash: String!
blockTimestamp: DateTime!
}
type LatestPrice {
marketId: Int!
price: BigDecimal!
onchainTimestamp: Int!
blockNumber: Int!
updatedAt: DateTime
}
type FundingRate {
id: Int!
marketId: Int!
ratePerSecond: BigDecimal!
rate24h: BigDecimal!
blockNumber: Int!
txHash: String!
blockTimestamp: DateTime!
}
type UserVault {
userAddress: String!
vaultAddress: String!
createdAt: DateTime
blockNumber: Int
txHash: String
}
type VaultEvent {
id: Int!
eventType: String!
userAddress: String
tokenAddress: String!
amount: BigDecimal!
blockNumber: Int!
txHash: String!
logIndex: Int!
blockTimestamp: DateTime!
}
type CollateralToken {
tokenAddress: String!
decimals: Int!
isActive: Boolean!
addedAt: DateTime
}
type PoolState {
marketId: Int!
baseReserve: BigDecimal!
quoteReserve: BigDecimal!
oraclePrice: BigDecimal
updatedAt: DateTime
blockNumber: Int
}
type FeeConfig {
takerFeeBps: Int!
makerFeeBps: Int!
liquidationFeeBps: Int!
insuranceFeeBps: Int!
updatedAt: DateTime
}
type ProtocolEvent {
id: Int!
eventName: String!
eventData: String!
blockNumber: Int!
txHash: String!
logIndex: Int!
blockTimestamp: DateTime!
}
type IndexerStatus {
lastIndexedBlock: Int!
chainHead: Int
blocksScanned: Int
eventsProcessed: Int
isSynced: Boolean
}
type UserStats {
userAddress: String!
totalPositions: Int!
openPositions: Int!
closedPositions: Int!
liquidatedPositions: Int!
totalTrades: Int!
totalRealizedPnl: BigDecimal!
totalOrders: Int!
activeOrders: Int!
}
type MarketStats {
marketId: Int!
symbol: String
totalPositions: Int!
openPositions: Int!
totalTrades: Int!
totalLiquidations: Int!
totalVolume: BigDecimal!
latestPrice: BigDecimal
latestFundingRate: BigDecimal
}
type GlobalStats {
totalMarkets: Int!
totalPositions: Int!
openPositions: Int!
totalTrades: Int!
totalLiquidations: Int!
totalVolume: BigDecimal!
totalUsers: Int!
indexerBlock: Int!
}
type Query {
position(positionId: String!): Position
positions(userAddress: String, marketId: Int, status: String, limit: Int, offset: Int): [Position!]!
trades(userAddress: String, marketId: Int, positionId: String, tradeType: String, limit: Int, offset: Int): [Trade!]!
order(orderId: String!): Order
orders(userAddress: String, marketId: Int, status: String, limit: Int, offset: Int): [Order!]!
liquidations(userAddress: String, marketId: Int, limit: Int, offset: Int): [Liquidation!]!
market(marketId: Int!): Market
markets: [Market!]!
latestPrices: [LatestPrice!]!
priceHistory(marketId: Int!, limit: Int, offset: Int): [PriceUpdate!]!
fundingRates(marketId: Int!, limit: Int, offset: Int): [FundingRate!]!
userVault(userAddress: String!): UserVault
vaultEvents(userAddress: String, eventType: String, limit: Int, offset: Int): [VaultEvent!]!
collateralTokens: [CollateralToken!]!
poolStates: [PoolState!]!
poolState(marketId: Int!): PoolState
feeConfig: FeeConfig
protocolEvents(eventName: String, limit: Int, offset: Int): [ProtocolEvent!]!
userStats(userAddress: String!): UserStats
marketStats(marketId: Int!): MarketStats
globalStats: GlobalStats
indexerStatus: IndexerStatus
}
```
# StableSwap GraphQL
Source: https://sidiorresearchlabs.mintlify.app/openapi/stableswap-graphql
GraphQL schema for the Paxeer StableSwap indexer.
# StableSwap GraphQL Schema
GraphQL schema for the StableSwap indexer β pools, tokens, swaps, liquidity events, fee claims, and positions.
**Endpoint:** `https://us-east-1.stable-swap.sidiora.exchange/graphql`
## Schema
```graphql theme={null}
directive @oneOf on INPUT_OBJECT
scalar BigDecimal
scalar DateTime
type protocol {
id: String!
}
type pool {
id: String!
}
type pools {
first: Int
skip: Int
}
type token {
id: String!
}
type tokens {
first: Int
skip: Int
}
type swap {
id: String!
}
type swaps {
first: Int
skip: Int
poolId: String
orderBy: String
orderDirection: String
}
type liquidityEvents {
first: Int
skip: Int
poolId: String
orderBy: String
orderDirection: String
}
type feeClaims {
first: Int
skip: Int
poolId: String
}
type position {
id: String!
}
type positions {
first: Int
skip: Int
owner: String
}
type user {
id: String!
}
type users {
first: Int
skip: Int
}
type indexerStatus {
lastIndexedBlock: Int!
chainHead: Int
blocksScanned: Int
eventsProcessed: Int
isSynced: Boolean
}
```
# PAX-28 Token Standard
Source: https://sidiorresearchlabs.mintlify.app/pax-28
Native fungible token standard for ArgusVM β Rust-inspired syntax, built-in overflow protection, and register-optimised gas
## Overview
PAX-28 is the native fungible token standard for HyperPaxeer, designed for **ArgusVM's register-based architecture** and the **ArgLang** smart-contract language. It provides the same functional surface as ERC-20 but with compile-time safety guarantees, optimised gas on register hardware, and Rust-inspired ergonomics.
Designed for register-based execution β no stack overhead
Automatic overflow/underflow protection at the language level
Statically typed, Rust-inspired syntax that compiles to AVM bytecode
***
## Interface
All HPX-28 compliant tokens must implement:
```arglang theme={null}
trait HPX28 {
pub view fn name() -> bytes;
pub view fn symbol() -> bytes;
pub view fn decimals() -> u256;
pub view fn total_supply() -> u256;
pub view fn balance_of(owner: address) -> u256;
pub view fn allowance(owner: address, spender: address) -> u256;
pub fn transfer(to: address, amount: u256) -> bool;
pub fn transfer_from(from: address, to: address, amount: u256) -> bool;
pub fn approve(spender: address, amount: u256) -> bool;
}
```
### Events
```arglang theme={null}
event Transfer(from: address indexed, to: address indexed, amount: u256);
event Approval(owner: address indexed, spender: address indexed, amount: u256);
```
***
## Reference Implementation
```arglang theme={null}
contract HPX28Token {
state name: bytes;
state symbol: bytes;
state decimals: u256;
state total_supply: u256;
state balances: Map;
state allowances: Map>;
event Transfer(from: address indexed, to: address indexed, amount: u256);
event Approval(owner: address indexed, spender: address indexed, amount: u256);
init(name_: bytes, symbol_: bytes, decimals_: u256, initial_supply: u256) {
name = name_;
symbol = symbol_;
decimals = decimals_;
total_supply = initial_supply;
balances[msg.sender] = initial_supply;
emit Transfer(address(0), msg.sender, initial_supply);
}
pub view fn name() -> bytes { return name; }
pub view fn symbol() -> bytes { return symbol; }
pub view fn decimals() -> u256 { return decimals; }
pub view fn total_supply() -> u256 { return total_supply; }
pub view fn balance_of(owner: address) -> u256 { return balances[owner]; }
pub view fn allowance(owner: address, spender: address) -> u256 {
return allowances[owner][spender];
}
pub fn transfer(to: address, amount: u256) -> bool {
require(to != address(0), "transfer to zero address");
require(balances[msg.sender] >= amount, "insufficient balance");
balances[msg.sender] = balances[msg.sender] - amount;
balances[to] = balances[to] + amount;
emit Transfer(msg.sender, to, amount);
return true;
}
pub fn transfer_from(from: address, to: address, amount: u256) -> bool {
require(from != address(0), "transfer from zero address");
require(to != address(0), "transfer to zero address");
require(balances[from] >= amount, "insufficient balance");
require(allowances[from][msg.sender] >= amount, "insufficient allowance");
balances[from] = balances[from] - amount;
balances[to] = balances[to] + amount;
allowances[from][msg.sender] = allowances[from][msg.sender] - amount;
emit Transfer(from, to, amount);
return true;
}
pub fn approve(spender: address, amount: u256) -> bool {
require(spender != address(0), "approve to zero address");
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
}
```
***
## Storage Model
PAX-28 uses Keccak256-based storage slot hashing, adapted for ArgusVM's register architecture:
* **Simple state variables** get sequential slots (`counter` β slot 0, `owner` β slot 1)
* **Maps** use `keccak256(key || base_slot)` for slot computation
* **Nested maps** (e.g. allowances) apply hashing recursively: `keccak256(spender || keccak256(owner || base_slot))`
### Gas Costs
| Operation | Gas (Estimated) |
| ------------------------------ | ----------------------------- |
| `balance_of()` / `allowance()` | \~251 gas (KECCAK256 + SLOAD) |
| `transfer()` | \~21,000 gas |
| `transfer_from()` | \~35,000 gas |
| `approve()` | \~46,000 gas |
Gas costs are lower than ERC-20 because register-based execution eliminates stack push/pop overhead for every intermediate value.
***
## Differences from ERC-20
| Aspect | ERC-20 | HPX-28 |
| ------------------- | ----------------------------------------------------------- | -------------------------------------------------------- |
| **Language** | Solidity (`function`, `mapping`) | ArgLang (`fn`, `Map`, `->` return types) |
| **Overflow** | Requires SafeMath or Solidity 0.8+ checks | Built into language β all arithmetic reverts on overflow |
| **VM** | Stack-based EVM | Register-based ArgusVM (32 x 256-bit registers) |
| **Compilation** | Solidity β EVM bytecode | ArgLang β AVM bytecode (`.avm`) |
| **Storage hashing** | `keccak256(key . slot)` (concatenation with period padding) | `keccak256(key \|\| slot)` (direct concatenation) |
***
## Optional Extensions
### HPX-28 Capped
```arglang theme={null}
pub view fn cap() -> u256;
pub fn mint(to: address, amount: u256) {
require(total_supply + amount <= cap, "cap exceeded");
// mint logic
}
```
### HPX-28 Burnable
```arglang theme={null}
pub fn burn(amount: u256) {
require(balances[msg.sender] >= amount, "insufficient balance");
balances[msg.sender] -= amount;
total_supply -= amount;
emit Transfer(msg.sender, address(0), amount);
}
```
### HPX-28 Mintable
```arglang theme={null}
pub fn mint(to: address, amount: u256) {
require(msg.sender == minter, "only minter");
balances[to] += amount;
total_supply += amount;
emit Transfer(address(0), to, amount);
}
```
***
## Security Considerations
* **Overflow protection** is automatic β no SafeMath needed
* **Zero-address checks** prevent accidental token burns
* **Approval race condition**: set allowance to 0 before changing, or use `increase_allowance()` / `decrease_allowance()` extensions
* **Reentrancy**: follows checks-effects-interactions pattern β state changes before any external interaction
***
## Cross-Chain Compatibility
PAX-28 is **not** bytecode-compatible with ERC-20 (different VM architecture). Cross-chain bridges must implement explicit translation:
1. Lock HPX-28 tokens on HyperPaxeer
2. Bridge translates to ERC-20 format
3. Mint equivalent ERC-20 on destination chain
4. Reverse: burn ERC-20, unlock HPX-28
The **CrossVerse Bridge** handles this translation natively.
***
## Status
| Field | Value |
| -------- | -------------- |
| Standard | HPX-28 |
| Status | Draft |
| Category | Token Standard |
| Network | HyperPaxeer |
## Resources
Register set, ISA, gas model, and bytecode format
Deploy contracts on HyperPaxeer
# PaxSpot
Source: https://sidiorresearchlabs.mintlify.app/paxspot
On-chain spot trading system with oracle-relative orders, dual-mode matching, and capital-integrated execution
## Overview
PaxSpot is a spot exchange built entirely in the EVM layer of HyperPaxeer. It introduces six novel primitives that exploit chain-level advantages β custom precompiles, validator-integrated keepers, and native gas policy β to deliver execution quality that no protocol on a shared chain can match.
Orders stored as basis-point offsets from oracle price, not absolute prices
Continuous in calm markets, sealed-bid batch auctions under volatility
Funded smart wallets trade as first-class participants via Argus VM
***
## Six Primitives
### 1. Oracle-Relative Order Book (OROB)
All orders and liquidity positions are stored as **basis-point offsets from the oracle price**, not absolute prices. A limit buy at "anchor - 5 bps" automatically follows the market.
```
Traditional: BUY 1 ETH @ $3,842.50 (stale in seconds)
OROB: BUY 1 ETH @ anchor - 5 bps (always relative, auto-tracks)
```
* State compression: orders do not need repricing when the market moves
* Fills outside configurable oracle bands are rejected (anti-manipulation)
* LP positions track the market without active management
* Resolution computed by **precompile `0x901`** (OROBResolver) β near-zero gas
### 2. Adaptive Dual-Mode Execution
The protocol dynamically switches matching mode per market based on conditions:
| Condition | Mode | Benefit |
| -------------------------------- | --------------------------------------------------------------- | -------------------------- |
| Normal / low volatility | **Continuous** β orders fill within the block they arrive | Fast UX, tight spreads |
| High volatility / anomalous flow | **Sealed-bid batch auction** β uniform clearing price per block | MEV-immune, fair execution |
Trigger logic (on-chain, per market):
* Oracle confidence interval exceeds threshold
* Block volume > 3 sigma of rolling 50-block average
* Governance-configurable sensitivity
Batch clearing price computed by **precompile `0x902`** (BatchClearing).
### 3. Programmable Liquidity Vaults (PLVs)
Composable strategy vaults that implement a standard interface:
```solidity theme={null}
interface ILiquidityVault {
function quote(Side side, uint256 size, int256 oraclePrice, uint256 volatility)
external view returns (int256 price, uint256 maxFillSize);
function fill(Side side, uint256 size, int256 price) external returns (bool);
function rebalance(int256 oraclePrice, int256 inventorySkew) external;
}
```
Building blocks: constant-product, concentrated-range, sigmoid, and linear base curves with volatility-scaling, inventory-skew, and momentum overlay modifiers. A factory contract lets anyone compose new strategies by parameter configuration alone.
### 4. Proof-of-Fill-Quality (PoFQ)
```
fill_quality_score = 1 - |fill_price - oracle_price| / oracle_price
```
Every fill is scored against the oracle at execution time via **precompile `0x904`** (PoFQScorer). Vaults accumulate a rolling quality score on-chain. Higher score yields higher fee share, priority routing, and increased capital allocation from the Argus risk engine.
### 5. Lazy Netting Settlement
```
[Trade Execution] β [Virtual Balance Update (same block)] β [Net Settlement (every N blocks)]
```
* Users trade against virtual balances updated in the same block
* Every settlement epoch (\~5 blocks / 10 s), the protocol computes net transfers across all participants
* Gas reduction: 5β10x vs. per-trade settlement
* **Fast-settle lane**: 1 bps premium for same-block finality
### 6. Capital-Integrated Trading
PaxSpot interfaces with the **Argus VM** for funded smart-wallet trading:
```
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β ARGUS VM ββββββΆβ SMART WALLET ββββββΆβ HPXSPOT β
β Risk engine βββββββ Capital set βββββββ PoFQ score β
β Allocation β β by Argus β β PnL feed β
β Drawdown β β Allowance β β Volume data β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
```
PaxSpot exposes `IPaxSpotReader` (PoFQ scores, PnL, positions) and enforces per-address limits via `IAllowanceProvider`. Funded wallets are indistinguishable from self-funded wallets at the matching-engine level.
***
## Contract Architecture
PaxSpot is the exchange architecture layer for HyperPaxeer's spot markets. It relies on native precompiles for oracle-relative pricing, batch clearing, validator oracle aggregation, and fill-quality scoring.
| Contract | Purpose |
| -------------------- | ----------------------------------------------------------------------------------- |
| **PaxSpotRouter** | Order gateway β signature validation, rate limiting, funded-wallet allowance checks |
| **MatchingEngine** | OROB continuous + batch matching via precompiles `0x901`, `0x902`, and `0x904` |
| **SettlementEngine** | Virtual-balance ledger, epoch netting, fast-settle lane |
| **OracleAdapter** | Pyth primary + Validator Oracle Module (VOM) fallback via precompile 0x903 |
### Custom Precompiles
| Address | Name | Type | Purpose |
| -------------------------------------------- | ---------------------- | --------- | ------------------------------------------------------------------------ |
| `0x0000000000000000000000000000000000000901` | OROBResolver | Stateless | Convert offset orders to absolute prices and back |
| `0x0000000000000000000000000000000000000902` | BatchClearing | Stateless | Compute uniform clearing price for sealed-bid auctions |
| `0x0000000000000000000000000000000000000903` | OracleAggregator / VOM | Mixed | Confidence-weighted median of validator-submitted prices (`x/paxoracle`) |
| `0x0000000000000000000000000000000000000904` | PoFQScorer | Stateless | Score fill quality against oracle at execution time |
See the [PaxSpot precompile reference](/paxspot/precompiles) for Solidity and TypeScript examples.
***
## Oracle Architecture
PaxSpot uses a two-tier oracle with automatic fallback:
1. **Primary β Pyth Network**: Sub-second pull-oracle with confidence intervals
2. **Fallback β Validator Oracle Module (VOM)**: Validators submit prices via the `0x903` precompile (`submitPrice`). The `x/paxoracle` Cosmos SDK module aggregates submissions using a confidence-weighted median with staleness filtering (15-block threshold) and quorum enforcement.
```solidity theme={null}
contract OracleAdapter {
function getPrice(bytes32 feedId) external view returns (int256 price, uint256 confidence) {
// Try Pyth first; fall back to VOM if stale or unavailable
}
}
```
***
## Test Results
**155 unit tests, 0 failures, 95.73% line coverage** (Foundry, `vm.mockCall` for precompiles).
| Contract | Lines | Branches | Functions |
| ---------------- | ------ | -------- | --------- |
| MatchingEngine | 98.87% | 89.47% | 100% |
| SettlementEngine | 98.06% | 100% | 94.74% |
| PaxSpotRouter | 98.48% | 91.67% | 100% |
| OracleAdapter | 96.25% | 83.33% | 100% |
Local-chain integration tests (all passing):
* Precompile 0x901 `resolveOffset` + `toOffset`
* Precompile 0x902 `computeClearing`
* Precompile 0x903 `submitPrice` + `getValidatorPrice` round-trip
* Precompile 0x904 `scoreFill`
* OracleAdapter `getPrice` (Pyth primary + VOM fallback)
* MatchingEngine market creation + state query
* PaxSpotRouter `submitOrder` end-to-end
***
## Resources
Full technical specification
General deployment and verification guide
# PaxSpot Precompiles
Source: https://sidiorresearchlabs.mintlify.app/paxspot/precompiles
Solidity and frontend reference for the live PaxSpot precompiles at 0x901 through 0x904
## Overview
PaxSpot uses four custom EVM precompiles for exchange-critical computation. They run as native HyperPaxeer consensus code and are live on mainnet.
| Address | Name | Purpose |
| -------------------------------------------- | ---------------------- | ----------------------------------------------------------------------- |
| `0x0000000000000000000000000000000000000901` | OROBResolver | Convert oracle-relative basis-point offsets to absolute prices and back |
| `0x0000000000000000000000000000000000000902` | BatchClearing | Compute uniform clearing prices for batch auctions |
| `0x0000000000000000000000000000000000000903` | OracleAggregator / VOM | Read validator oracle prices and submit validator attestations |
| `0x0000000000000000000000000000000000000904` | PoFQScorer | Score fill quality against oracle prices |
All price values in these examples use 18-decimal fixed point integers.
## `0x901` OROBResolver
OROB orders store signed basis-point offsets from the oracle price instead of stale absolute prices.
```solidity theme={null}
interface IOROBResolver {
function resolveOffset(int256 oraclePrice, int16 offsetBps)
external
view
returns (int256 absolutePrice);
function resolveOffsetBatch(int256 oraclePrice, int16[] calldata offsetsBps)
external
view
returns (int256[] memory absolutePrices);
function toOffset(int256 oraclePrice, int256 absolutePrice)
external
view
returns (int16 offsetBps);
}
```
Formula:
```text theme={null}
absolutePrice = oraclePrice * (10000 + offsetBps) / 10000
offsetBps = ((absolutePrice - oraclePrice) * 10000) / oraclePrice
```
### Solidity example
```solidity theme={null}
IOROBResolver constant OROB =
IOROBResolver(0x0000000000000000000000000000000000000901);
function limitPrice(int256 oraclePrice) external view returns (int256) {
return OROB.resolveOffset(oraclePrice, -5);
}
```
### viem example
```typescript theme={null}
import { createPublicClient, http, parseUnits } from 'viem'
import { hyperpaxeer } from './chains'
const client = createPublicClient({
chain: hyperpaxeer,
transport: http('https://public-rpc.paxeer.app/rpc'),
})
const price = await client.readContract({
address: '0x0000000000000000000000000000000000000901',
abi: [{
type: 'function',
name: 'resolveOffset',
stateMutability: 'view',
inputs: [
{ name: 'oraclePrice', type: 'int256' },
{ name: 'offsetBps', type: 'int16' },
],
outputs: [{ name: 'absolutePrice', type: 'int256' }],
}],
functionName: 'resolveOffset',
args: [parseUnits('3842.50', 18), -5],
})
```
## `0x902` BatchClearing
BatchClearing computes the supply-demand crossing for a sealed-bid auction and returns a uniform clearing price.
```solidity theme={null}
interface IBatchClearing {
struct ClearingResult {
int16 clearingOffsetBps;
int256 clearingPrice;
uint256 matchedVolume;
}
function computeClearing(
int256 oraclePrice,
int16[] calldata buyOffsets,
uint128[] calldata buySizes,
int16[] calldata sellOffsets,
uint128[] calldata sellSizes
) external view returns (ClearingResult memory result);
}
```
Input expectations:
* `buyOffsets` are sorted from most aggressive to least aggressive.
* `sellOffsets` are sorted from cheapest to most expensive.
* `buySizes.length` must equal `buyOffsets.length`.
* `sellSizes.length` must equal `sellOffsets.length`.
* Empty buy or sell sides return zero matched volume.
```solidity theme={null}
IBatchClearing constant CLEARING =
IBatchClearing(0x0000000000000000000000000000000000000902);
function previewBatch(
int256 oraclePrice,
int16[] calldata buyOffsets,
uint128[] calldata buySizes,
int16[] calldata sellOffsets,
uint128[] calldata sellSizes
) external view returns (IBatchClearing.ClearingResult memory) {
return CLEARING.computeClearing(
oraclePrice,
buyOffsets,
buySizes,
sellOffsets,
sellSizes
);
}
```
## `0x903` OracleAggregator / VOM
OracleAggregator reads validator-consensus prices from `x/paxoracle` and lets active validators submit price attestations.
```solidity theme={null}
interface IOracleAggregator {
function getValidatorPrice(bytes32 marketId)
external
view
returns (int256 price, uint256 quorum, uint256 timestamp);
function submitPrice(bytes32 marketId, int256 price, uint256 confidence)
external
returns (bool success);
}
```
### Read the validator price
```solidity theme={null}
IOracleAggregator constant VOM =
IOracleAggregator(0x0000000000000000000000000000000000000903);
function readBtcPrice() external view returns (int256 price, uint256 quorum) {
bytes32 marketId = keccak256("BTC/USD");
(price, quorum,) = VOM.getValidatorPrice(marketId);
}
```
### Submit a validator price
`submitPrice()` is for active validators. Transactions from non-validator addresses are rejected by the oracle module.
```solidity theme={null}
IOracleAggregator constant VOM =
IOracleAggregator(0x0000000000000000000000000000000000000903);
function submitBtcPrice(int256 price) external returns (bool) {
bytes32 marketId = keccak256("BTC/USD");
uint256 confidence = 1e18;
return VOM.submitPrice(marketId, price, confidence);
}
```
```typescript theme={null}
import { createWalletClient, http, keccak256, parseUnits, stringToBytes } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { hyperpaxeer } from './chains'
const account = privateKeyToAccount(process.env.VALIDATOR_EVM_PRIVATE_KEY as `0x${string}`)
const wallet = createWalletClient({
account,
chain: hyperpaxeer,
transport: http('https://public-rpc.paxeer.app/rpc'),
})
const hash = await wallet.writeContract({
address: '0x0000000000000000000000000000000000000903',
abi: [{
type: 'function',
name: 'submitPrice',
stateMutability: 'nonpayable',
inputs: [
{ name: 'marketId', type: 'bytes32' },
{ name: 'price', type: 'int256' },
{ name: 'confidence', type: 'uint256' },
],
outputs: [{ name: 'success', type: 'bool' }],
}],
functionName: 'submitPrice',
args: [
keccak256(stringToBytes('BTC/USD')),
parseUnits('97250', 18),
parseUnits('1', 18),
],
})
```
## `0x904` PoFQScorer
Proof-of-Fill-Quality scores execution quality relative to the oracle price. Scores range from `0` to `1e18`, where `1e18` means the fill matched the oracle price.
```solidity theme={null}
interface IPoFQScorer {
function scoreFill(int256 fillPrice, int256 oraclePrice)
external
view
returns (uint256 score);
function scoreBatch(
int256[] calldata fillPrices,
int256[] calldata oraclePrices,
uint128[] calldata sizes
) external view returns (uint256 avgScore, uint256 totalVolume);
function updateRollingScore(
uint256 currentScore,
uint256 currentWeight,
uint256 newScore,
uint256 newWeight,
uint16 decayBps
) external view returns (uint256 updatedScore, uint256 updatedWeight);
}
```
```solidity theme={null}
IPoFQScorer constant POFQ =
IPoFQScorer(0x0000000000000000000000000000000000000904);
function score(int256 fillPrice, int256 oraclePrice) external view returns (uint256) {
return POFQ.scoreFill(fillPrice, oraclePrice);
}
```
## Related docs
* [PaxSpot overview](/paxspot)
* [x/paxoracle module](/protocol/modules/paxoracle)
* [EVM extensions](/develop/smart-contracts/list-evm-extensions)
# Performance
Source: https://sidiorresearchlabs.mintlify.app/performance
Official HyperPaxeer mainnet performance metrics, validator distribution, and RPC fleet data
## Summary
The April 2026 performance report measures HyperPaxeer as a sub-second EVM L1 with deterministic CometBFT finality and a globally distributed RPC fleet.
197-358 ms observed range with 341 ms p95.
CometBFT finality with `timeout_commit = 0`.
47 EVM RPC nodes online across 14 active regions.
## Block production
| Metric | Value |
| ------------------ | -----------------------------: |
| Average block time | `277 ms` |
| Minimum block time | `197 ms` |
| Maximum block time | `358 ms` |
| P95 block time | `341 ms` |
| Standard deviation | `40.3 ms` |
| Consensus engine | CometBFT `v0.38.15` |
| `timeout_commit` | `0` |
| Finality | Instant deterministic finality |
## Validator set
| Metric | Value |
| -------------------- | ----------------: |
| Active validators | `10` |
| Total voting power | `167,294,521` |
| Voting-power range | `5.9%` to `13.1%` |
| Nakamoto coefficient | `4` |
The validator set is intentionally balanced: no validator controls enough voting power to dominate proposal or finality behavior alone.
## Chain activity
| Metric | Value |
| ------------------ | -----------: |
| Blocks analyzed | `15.25M+` |
| Transactions | `~2M` |
| Unique addresses | `27K+` |
| Contracts | `1.4K+` |
| Live throughput | `0.41 tx/s` |
| Peak block density | `3 tx/block` |
| Active blocks | `11%` |
Live throughput reflects current demand, not maximum chain capacity.
## Infrastructure
| Metric | Value |
| -------------------------- | -----------: |
| RPC nodes online | `48` |
| EVM RPC nodes online | `47` |
| Active regions | `14` |
| Best observed RPC latency | `4.2 ms` |
| Europe latency band | `4-65 ms` |
| United States latency band | `215-390 ms` |
## What developers should expect
* Transactions confirm in the next finalized block under normal network conditions.
* Public JSON-RPC is available at `https://public-rpc.paxeer.app/rpc`.
* Use `paxscan.io` to inspect confirmed blocks, transactions, contracts, and addresses.
* Contracts that assume Ethereum-like block cadence should be reviewed for sub-second block timing.
## Related docs
* [Current network facts](/current-network)
* [Network status](/network-status)
* [Architecture overview](/concepts/architecture/overview)
# Bugs
Source: https://sidiorresearchlabs.mintlify.app/protocol/bugs
# Bugs
When creating a Layer 1 (L1) protocol chain, taking security seriously is of utmost importance. L1 protocols are the
backbone of the blockchain ecosystem, and any security vulnerabilities within the L1 can lead to a range of potential
consequences, from financial loss to reputation damage to even the collapse of the entire network. As such, security
is an essential aspect of developing any L1 protocol chain, and security must be considered at every step of the
development process. Check out our [Audits](./security/audits).
Despite our best efforts, security issues may still arise in our L1 protocol chain. In such cases, we encourage our users
to report any vulnerabilities or bugs they may find. For sensitive bugs, we ask that users submit the issue to
[HyperPaxeer Security](mailto:security@HyperPaxeer.org), which is a third-party security platform that helps us identify, triage,
and resolve security issues in a confidential and secure manner. For non-sensitive bugs, we encourage users to file an
open ticket on our [HyperPaxeer Github Repo](https://github.com/Paxeer-Network/Paxeer-Network) so that our team can address the issue as quickly
as possible.
# Cli commands
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/cli-commands
# CLI Commands
## CLI Flags
A list of commonly used flags of `hyperpaxd` is listed below:
| Option | Description | Type | Default Value |
| ------------------- | --------------------------------------------- | --------------- | ------------------------- |
| `--chain-id` | Full Chain ID | `string` | `""` |
| `--home` | Directory for config and data | `string` | `~/.hyperpaxd` |
| `--keyring-backend` | Select keyring's backend | `string` | `"os"` |
| `--output` | Output format | `string` | `"text"` |
| `--node` | Tendermint RPC interface | `:` | `"tcp://localhost:26657"` |
| `--from` | Name or address of account with which to sign | `string` | `""` |
## Command list
A list of commonly used `hyperpaxd` commands. You can obtain the full list by using the `hyperpaxd -h` command.
| Command | Description | Subcommands (example) |
| ------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `keys` | Keys management | `list`, `show`, `add`, `add --recover`, `delete` |
| `tx` | Transactions subcommands | `bank send`, `ibc-transfer transfer`, `distribution withdraw-all-rewards` |
| `query` | Query subcommands | `bank balance`, `staking validators`, `gov proposals` |
| `tendermint` | Tendermint subcommands | `show-address`, `show-node-id`, `version` |
| `config` | Client configuration | |
| `init` | Initialize full node | |
| `start` | Run full node | |
| `version` | HyperPaxeer version | |
| `validate-genesis` | Validates the genesis file | |
| `status` | Query remote node for status | |
| `block` | Query a specific block persisted in the db (defaults to latest) | |
# Configuration
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/configuration
# Configuration
The following page will guide you through the configuration of a node and a client.
The node is used to run the blockchain network, produce blocks and validate transactions.
The client is used as a gateway to interact with the blockchain network by sending transactions and querying the state.
Additionally we walk through [running the JSON-RPC server](#running-the-json-rpc-server).
These configurations can impact the performance, security, and functionality of your node.
Thus, understanding and correctly configuring your node and client is essential.
## Config and data directory
By default, your config and data are stored in the folder located at the `~/.hyperpaxd` directory.
You can easily change the default directory by using the `--home` flag. It is important to note that
you can have multiple home directories that each represent a different blockchain.
```bash theme={null}
. # ~/.hyperpaxd
βββ data/ # Contains the databases used by the node.
βββ config/
βββ app.toml # Application-related configuration file.
βββ config.toml # Tendermint-related configuration file.
βββ genesis.json # The genesis file.
βββ node_key.json # Private key to use for node authentication in the p2p protocol.
βββ priv_validator_key.json # Private key to use as a validator in the consensus protocol.
```
To specify the `hyperpaxd` config and data storage directory; you can update it using the global flag `--home `.
## Node Configuration
The Cosmos SDK automatically generates two configuration files inside `~/.hyperpaxd/config`:
* `config.toml`: used to configure the Tendermint, learn more on [Tendermint's documentation](https://docs.tendermint.com/v0.34/tendermint-core/configuration.html),
* `app.toml`: generated by the Cosmos SDK, and used to configure your app, such as state pruning strategies, telemetry, gRPC and REST servers configuration, state sync, JSON-RPC, etc.
Both files are heavily commented, please refer to them directly to tweak your node.
One example config to tweak is the `minimum-gas-prices` field inside `app.toml`, which defines the minimum amount the validator node is willing to accept for processing a transaction. It is an anti spam mechanism and it will reject incoming transactions with less than the minimum gas prices.
If it's empty, make sure to edit the field with some value, for example `10token`, or else the node will halt on startup.
```toml theme={null}
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1;0.0001token2).
minimum-gas-prices = "0ahpx"
```
### Pruning of State
There are four strategies for pruning state. These strategies apply only to state and do not apply to block storage.
To set pruning, adjust the `pruning` parameter in the `~/.hyperpaxd/config/app.toml` file.
The following pruning state settings are available:
* `everything`: Prune all saved states other than the current state.
* `nothing`: Save all states and delete nothing.
* `default`: Save the last 100 states and the state of every 10,000th block.
* `custom`: Specify pruning settings with the `pruning-keep-recent`, `pruning-keep-every`, and `pruning-interval` parameters.
By default, every node is in `default` mode which is the recommended setting for most environments.
If you would like to change your nodes pruning strategy then you must do so when the node is initialized. Passing a flag when starting `HyperPaxeer` will always override settings in the `app.toml` file, if you would like to change your node to the `everything` mode then you can pass the `--pruning everything` flag when you call `hyperpaxd start`.
:::warning
**IMPORTANT**:
When you are pruning state you will not be able to query the heights that are not in your store.
:::
## Client Configuration
We can view the default client config setting by using `hyperpaxd config` command:
```bash theme={null}
hyperpaxd config
{
"chain-id": "",
"keyring-backend": "os",
"output": "text",
"node": "tcp://localhost:26657",
"broadcast-mode": "sync"
}
```
We can make changes to the default settings upon our choices, so it allows users to set the configuration beforehand all at once, so it would be ready with the same config afterward.
For example, the chain identifier can be changed to `hyperpax_125-4` from a blank name by using:
```bash theme={null}
hyperpaxd config "chain-id" hyperpax_125-4
hyperpaxd config
{
"chain-id": "hyperpax_125-4",
"keyring-backend": "os",
"output": "text",
"node": "tcp://localhost:26657",
"broadcast-mode": "sync"
}
```
Other values can be changed in the same way.
Alternatively, we can directly make the changes to the config values in one place at client.toml. It is under the path of `.hyperpaxd/config/client.toml` in the folder where we installed HyperPaxeer:
```toml theme={null}
############################################################################
### Client Configuration ###
############################################################################
# The network chain ID
chain-id = "hyperpax_125-4"
# The keyring's backend, where the keys are stored (os|file|kwallet|pass|test|memory)
keyring-backend = "os"
# CLI output format (text|json)
output = "number"
# : to Tendermint RPC interface for this chain
node = "tcp://localhost:26657"
# Transaction broadcasting mode (sync|async|block)
broadcast-mode = "sync"
```
After the necessary changes are made in the `client.toml`, then save. For example, if we directly change the chain-id from `hyperpax_125-1` to a custom value, and output to number, it would change instantly as shown below.
```bash theme={null}
hyperpaxd config
{
"chain-id": "hyperpax_125-1",
"keyring-backend": "os",
"output": "number",
"node": "tcp://localhost:26657",
"broadcast-mode": "sync"
}
```
## Running the JSON-RPC Server
This section walks through the steps to enable the JSON-RPC server.
JSON-RPC is provided on multiple transports. HyperPaxeer supports JSON-RPC over HTTP and WebSocket.
In terms of requirements we recommend a server with minimum 8-core CPU and 64gb of RAM.
You must have ports 8545 and 8546 open on your firewall.
:::tip
**Important**: You cannot use all JSON RPC methods unless your node stores the entire copy of the blockchain locally. Do you need archives/snapshots of our networks? Go to [this section](./../../develop/api/snapshots-archives).
:::
### Enable Server
To enable RPC server use the following flag (set to true by default).
```bash theme={null}
hyperpaxd start --json-rpc.enable
```
### Defining Namespaces
`Eth`,`Net` and `Web3` namespaces are enabled by default, but for the JSON-RPC you need to add more namespaces.
In order to enable other namespaces edit `app.toml` file.
```toml theme={null}
# API defines a list of JSON-RPC namespaces that should be enabled
# Example: "eth,txpool,personal,net,debug,web3"
api = "eth,net,web3,txpool,debug,personal"
```
### Set a Gas Cap
`eth_call` and `eth_estimateGas` define a global gas cap over rpc for DoS protection. You can override the default gas cap value of 25,000,000 by passing a custom value in `app.toml`:
```toml theme={null}
# GasCap sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). Default: 25,000,000.
gas-cap = 25000000
```
### CORS
If accessing the RPC from a browser, CORS will need to be enabled with the appropriate domain set. Otherwise, JavaScript calls are limit by the same-origin policy and requests will fail.
The CORS setting can be updated from the `app.toml`
```toml theme={null}
###############################################################################
### API Configuration ###
###############################################################################
[api]
# ...
# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
enabled-unsafe-cors = true # default false
```
### Pruning
For all methods to work correctly, your node must be archival (store the entire copy of the blockchain locally). Pruning must be disabled.
The pruning settings can be updated from the `app.toml`
```toml theme={null}
###############################################################################
### Base Configuration ###
###############################################################################
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1;0.0001token2).
# ...
# default: the last 100 states are kept in addition to every 500th state; pruning at 10 block intervals
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
# everything: all saved states will be deleted, storing only the current state; pruning at 10 block intervals
# custom: allow pruning options to be manually specified through 'pruning-keep-recent', 'pruning-keep-every', >
pruning = "nothing"
pruning-keep-recent = "0"
pruning-keep-every = "0"
pruning-interval = "0"
```
### WebSocket Server
Websocket is a bidirectional transport protocol. A Websocket connection is maintained by client and server until it is explicitly terminated by one. Most modern browsers support Websocket which means it has good tooling.
Because Websocket is bidirectional, servers can push events to clients. That makes Websocket a good choice for use-cases involving event subscription.
Another benefit of Websocket is that after the handshake procedure, the overhead of individual messages is low, making it good for sending high number of requests.
The WebSocket Server can be enabled from the `app.toml`
```toml theme={null}
# Address defines the EVM WebSocket server address to bind to.
ws-address = "0.0.0.0:8546"
```
# Working with Docker
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/docker-build
# Working with Docker
There are multiple ways to use HyperPaxeer with Docker.
If you want to run HyperPaxeer inside a Docker setup and possibly connect the Docker container
to other containerized compatible blockchain binaries, check out the guide on
[building a Docker image containing the HyperPaxeer binary](#building-a-docker-image-containing-the-binary).
If you instead want to generate a binary for use outside of Docker,
but want to ensure the correct dependencies are used by building the binary inside a Docker container,
then go ahead to the section on [building the HyperPaxeer binary with Docker](#building-the-binary-with-docker).
:::note
The given instructions have been tested on *Ubuntu 18.04.2 LTS* with *Docker 20.10.2* and *macOS 13.2.1* with *Docker 20.10.22*.
:::
## Prerequisites
* [Install Docker](https://docs.docker.com/get-docker/)
## General Setup
In order to build HyperPaxeer binaries with Docker, it is necessary to
* clone the HyperPaxeer repository to your local machine (e.g. `git clone git@github.com/Paxeer-Network/Paxeer-Network.git`)
* checkout the commit, branch, or release tag you want to build (e.g. `git checkout v11.0.2`)
## Building A Docker Image Containing The Binary
To build a Docker image, that contains the HyperPaxeer binary,
step into the cloned repository and run the following command in a terminal session:
```bash theme={null}
make build-docker
```
This will create an image with the name `tharsishq/Paxeer-Network` and the version tag `latest`.
Now it is possible to run the `hyperpaxd` binary in the container, e.g. evaluating its version:
```bash theme={null}
docker run -it --rm tharsishq/Paxeer-Network:latest hyperpaxd version
```
## Building The Binary With Docker
It is possible to build the `hyperpaxd` binary deterministically using Docker.
The container system that Docker provides offers the ability
to create an instance of the HyperPaxeer binary in an isolated environment.
### Building the Image
Run the following command to launch a build for all supported architectures (currently **linux/amd64**):
```bash theme={null}
make distclean build-reproducible
```
The build system generates both the binaries and deterministic build report in the `artifacts` directory.
The `artifacts/build_report` file contains the list of the build artifacts and their respective checksums,
and can be used to verify build sanity. An example of its contents follows:
```
App: hyperpaxd
Version: 11.0.2
Commit: 8eeeac7ae42a5b2695fea7f56868f3c6e9bc2378
Files:
6b5939adfd9a8ce964d78fcaab16091a hyperpaxd-11.0.2-linux-amd64
ac503925c535ddb8ee0fbebbb96d0eb9 hyperpaxd-11.0.2.tar.gz
Checksums-Sha256:
0857d59c285a87b7d354aa6d566db90c56663d938a88d41d35415da490708aea hyperpaxd-11.0.2-linux-amd64
5005814fc34abc02d7e30dcfbe67e363c1b593efb774e0c97ebb7ec713baf306 hyperpaxd-11.0.2.tar.gz
```
### Builder Image
The [Tendermint builder Docker image](https://github.com/tendermint/images/tree/master/rbuilder)
provides a deterministic build environment that is used to build Cosmos SDK applications.
It provides a way to be reasonably sure that the executables are really built from the git source.
It also makes sure that the same, tested dependencies are used and statically built into the executable.
***
Now that you have built the HyperPaxeer binary, either for local use or in a Docker container,
you'll find information to run a node instance in the following section
on [setting up a local network](./single-node).
# CLI
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/index
Command-line tools and node operation guides.
# HyperPaxeer CLI
`hyperpaxd` is the all-in-one command-line interface (CLI). It allows you to run an HyperPaxeer node, manage wallets and interact
with the HyperPaxeer network through queries and transactions. This introduction will explain how to install the `hyperpaxd`
binary onto your system and guide you through some simple examples how to use hyperpaxd.
## Prerequisites
#### Go
HyperPaxeer is built using [Go](https://golang.org/dl/) version `1.20+`. Check your version with:
```bash theme={null}
go version
```
Once you have installed the right version, confirm that your [`GOPATH`](https://golang.org/doc/gopath_code#GOPATH)
is correctly configured by running the following command and adding it to your shell startup script:
```bash theme={null}
export PATH=$PATH:$(go env GOPATH)/bin
```
#### jq
HyperPaxeer scripts are using [jq](https://stedolan.github.io/jq/download/) version `1.6+`. Check your version with:
```
jq --version
```
## Installation
You can download the latest binaries from the repo and install them, or
you can build and install the `hyperpaxd` binaries from source or using Docker.
### Download the binaries
* Go to the [releases section of the repository](https://github.com/Paxeer-Network/Paxeer-Network/releases)
* Choose the desired release or pre-release you want to install on your machine
* Select and download from the `Assets` dropdown the corresponding tar or zip file for your OS
* Extract the files. The `hyperpaxd` binaries is located in the `bin` directory of the extrated files
* Add the `hyperpaxd` binaries to your path, e.g. you can move it to `$(go env GOPATH)/bin`
After installation is done, check that the `hyperpaxd` binaries have been successfully installed:
```bash theme={null}
hyperpaxd version
```
### Build From Source
Clone and build the HyperPaxeer from source using `git`. The `` refers to a release tag on Github. Check the latest HyperPaxeer
version on the [releases section of the repository](https://github.com/Paxeer-Network/Paxeer-Network/releases):
```bash theme={null}
git clone https://github.com/Paxeer-Network/Paxeer-Network.git
cd HyperPaxeer
git fetch
git checkout
make install
```
After installation is done, check that the hyperpaxd binaries have been successfully installed:
```bash theme={null}
hyperpaxd version
```
:::info
If the `hyperpaxd: command not found` error message is returned, confirm that you have configured [Go](#go) correctly.
:::
### Docker
When it comes to using Docker with HyperPaxeer, there are two options available:
Build a binary of the HyperPaxeer daemon inside a dockerized build environment
or build a Docker image, that can be used to spin up individual containers running the HyperPaxeer binary.
For information on how to achieve this,
proceed to the dedicated page on [working with Docker](./docker-build.md).
## Run an HyperPaxeer node
To become familiar with HyperPaxeer, you can run a local blockchain node that produces blocks and exposes EVM and Cosmos
endpoints. This allows you to deploy and interact with smart contracts locally or test core protocol functionality.
Run the local node by executing the `local_node.sh` script in the base directory of the repository:
```bash theme={null}
./local_node.sh
```
The script stores the node configuration including the local default endpoints under `~/.tmp-hyperpaxd/config/config.toml`.
If you have previously run the script, the script allows you to overwrite the existing configuration and start a new
local node.
Once your node is running you will see it validating and producing blocks in your local HyperPaxeer blockchain:
```bash theme={null}
12:59PM INF executed block height=1 module=state num_invalid_txs=0 num_valid_txs=0 server=node
# ...
1:00PM INF indexed block exents height=7 module=txindex server=node
```
For more information on how to customize a local node,
head over to the [Single Node](./Paxeer-Network-cli/single-node) page.
## Using `hyperpaxd`
After installing the `hyperpaxd` binary, you can run commands using:
```bash theme={null}
hyperpaxd [command]
```
There is also a `-h`, `--help` command available
```bash theme={null}
hyperpaxd -h
```
It is possible to maintain multiple node configurations at the same time. To specify a configuration use the `--home`
flag. In the following examples we will be using the default config for a local node, located at `~/.tmp-hyperpaxd`.
### Manage wallets
You can manage your wallets using the hyperpaxd binary to store private keys and sign transactions over CLI. To view all
keys use:
```bash theme={null}
hyperpaxd keys list \
--home ~/.tmp-hyperpaxd \
--keyring-backend test
# Example Output:
# - address: HyperPaxeer19xnmslvl0pcmydu4m52h2gf0std5ee5pfgpyuf
# name: dev0
# pubkey: '{"@type":"/hyperpaxeer.crypto.v1.ethsecp256k1.PubKey","key":"AzKouyoUL0UUS1qRUZdqyVsTPkCAFWwxx3+BTOw36nKp"}'
# type: local
```
You can generate a new key/mnemonic with a `$NAME` with:
```bash theme={null}
hyperpaxd keys add [name] \
--home ~/.tmp-hyperpaxd \
--keyring-backend test
```
To export your HyperPaxeer key as an Ethereum private key (for use with [Metamask](https://academy.evmosd.org/articles/beginner/connect-your-wallet/metamask)
for example):
```bash theme={null}
hyperpaxd keys unsafe-export-eth-key [name] \
--home ~/.tmp-hyperpaxd \
--keyring-backend test
```
For more about the available key commands, use the `--help` flag
```bash theme={null}
hyperpaxd keys -h
```
:::tip
For more information about the Keyring and its backend options, click [here](../concepts/keyring.md).
:::
### Interact with a Network
You can use hyperpaxd to query information or submit transactions on the blockchain. Queries and transactions are requests
that you send to an HyperPaxeer node through the Tendermint RPC.
:::tip
π To use the CLI, you will need to provide a Tendermint RPC address for the `--node` flag.
Look for a publicly available addresses for testnet and mainnet in the [Networks](./../../develop/api/networks) page.
:::
#### Set Network Config
In the local setup the node is set to `tcp://localhost:26657`. You can view your node configuration with:
```bash theme={null}
hyperpaxd config \
--home ~/.tmp-hyperpaxd
# Example Output
# {
# "chain-id": "hyperpax_125-1",
# "keyring-backend": "test",
# "output": "text",
# "node": "tcp://localhost:26657",
# "broadcast-mode": "sync"
# }
```
You can set your node configuration to send requests to a different network by changing the endpoint with:
```bash theme={null}
hyperpaxd config node [tendermint-rpc-endpoint] \
--home ~/.tmp-hyperpaxd
```
Learn about more node configurations [here](configuration.mdx).
#### Queries
You can query information on the blockchain using `hyperpaxd query` (short `hyperpaxd q`). To view the account balances by its
address stored in the bank module, use:
```bash theme={null}
hyperpaxd q bank balances [adress] \
--home ~/.tmp-hyperpaxd
# # Example Output:
# balances:
# - amount: "99999000000000000000002500"
# denom: ahpx
```
To view other available query commands, use:
```bash theme={null}
# for all Queries
hyperpaxd q
# for querying commands in the bank module
hyperpaxd q bank
```
#### Transactions
You can submit transactions to the network using `hyperpaxd tx`. This creates, signs and broadcasts a tx in one command. To
send tokens from an account in the keyring to another address with the bank module, use:
```bash theme={null}
hyperpaxd tx bank send [from_key_or_address] [to_address] [amount] \
--home ~/.tmp-hyperpaxd \
--fees 50000000000ahpx \
-b block
# Example Output:
# ...
# txhash: 7BA2618295B789CC24BB13E654D9187CDD264F61FC446EB756EAC07AF3E7C40A
```
To view other available transaction commands, use:
```bash theme={null}
# for all transaction commands
hyperpaxd tx
# for Bank transaction subcommands
hyperpaxd tx bank
```
Now that you've learned the basics of how to run and interact with an HyperPaxeer network,
head over to [configurations](configuration.mdx) for futher customization.
# Multi nodes
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/multi-nodes
# Multi Node
Following this page, you can run a localnet setup with docker
that consists of a 4-node local chain.
This setup can be useful for developers to test their applications and
protocol features on a multi-node setup.
A similar setup is used by the HyperPaxeer team to get insights
about the impact of new features and testing different user flows.
This testing setup can be found on the [HyperPaxeer testing repository](https://github.com/Paxeer-Network/testing).
### Build & Start
To build start a 4 node testnet using [docker](https://docs.docker.com/engine/installation/), run:
```bash theme={null}
make localnet-start
```
This command creates a 4-node network using the `hyperpaxdnode` Docker image.
The ports for each node are found in this table:
| Node ID | P2P Port | Tendermint RPC Port | REST/ Ethereum JSON-RPC Port | WebSocket Port |
| ------------------ | -------- | ------------------- | ---------------------------- | -------------- |
| `HyperPaxeernode0` | `26656` | `26657` | `8545` | `8546` |
| `HyperPaxeernode1` | `26659` | `26660` | `8547` | `8548` |
| `HyperPaxeernode2` | `26661` | `26662` | `8549` | `8550` |
| `HyperPaxeernode3` | `26663` | `26664` | `8551` | `8552` |
To update the binary, just rebuild it and restart the nodes
```bash theme={null}
make localnet-start
```
The command above command will run containers in the background using Docker compose. You will see the network being created:
```bash theme={null}
...
Creating network "HyperPaxeer_localnet" with driver "bridge"
Creating hyperpaxdnode0 ... done
Creating hyperpaxdnode2 ... done
Creating hyperpaxdnode1 ... done
Creating hyperpaxdnode3 ... done
```
### Stop Localnet
Once you are done, execute:
```bash theme={null}
make localnet-stop
```
### Configuration
The `make localnet-start` creates files for a 4-node testnet in `./build` by
calling the `hyperpaxd testnet` command. This outputs a handful of files in the
`./build` directory:
```bash theme={null}
tree -L 3 build/
build/
βββ hyperpaxd
βββ hyperpaxd
βββ gentxs
β βββ node0.json
β βββ node1.json
β βββ node2.json
β βββ node3.json
βββ node0
β βββ hyperpaxd
β β βββ key_seed.json
β β βββ keyring-test-cosmos
β βββ hyperpaxd
β βββ config
β βββ data
β βββ hyperpaxd.log
βββ node1
β βββ hyperpaxd
β β βββ key_seed.json
β β βββ keyring-test-cosmos
β βββ hyperpaxd
β βββ config
β βββ data
β βββ hyperpaxd.log
βββ node2
β βββ hyperpaxd
β β βββ key_seed.json
β β βββ keyring-test-cosmos
β βββ hyperpaxd
β βββ config
β βββ data
β βββ hyperpaxd.log
βββ node3
βββ hyperpaxd
β βββ key_seed.json
β βββ keyring-test-cosmos
βββ hyperpaxd
βββ config
βββ data
βββ hyperpaxd.log
```
Each `./build/nodeN` directory is mounted to the `/hyperpaxd` directory in each container.
### Logging
In order to see the logs of a particular node you can use the following command:
```bash theme={null}
# node 0: daemon logs
docker exec hyperpaxdnode0 tail hyperpaxd.log
# node 0: REST & RPC logs
docker exec hyperpaxdnode0 tail hyperpaxd.log
```
The logs for the daemon will look like:
```bash theme={null}
I[2020-07-29|17:33:52.452] starting ABCI with Tendermint module=main
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 272a247b837653cf068d39efd4c407ffbd9a0e6f@192.168.10.5:26656"
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 3e05d3637b7ebf4fc0948bbef01b54d670aa810a@192.168.10.4:26656"
E[2020-07-29|17:33:53.394] Can't add peer's address to addrbook module=p2p err="Cannot add non-routable address 689f8606ede0b26ad5b79ae244c14cc67ab4efe7@192.168.10.3:26656"
I[2020-07-29|17:33:58.828] Executed block module=state height=88 validTxs=0 invalidTxs=0
I[2020-07-29|17:33:58.830] Committed state module=state height=88 txs=0 appHash=90CC5FA53CF8B5EC49653A14DA20888AD81C92FCF646F04D501453FD89FCC791
I[2020-07-29|17:34:04.032] Executed block module=state height=89 validTxs=0 invalidTxs=0
I[2020-07-29|17:34:04.034] Committed state module=state height=89 txs=0 appHash=0B54C4DB1A0DACB1EEDCD662B221C048C826D309FD2A2F31FF26BAE8D2D7D8D7
I[2020-07-29|17:34:09.381] Executed block module=state height=90 validTxs=0 invalidTxs=0
I[2020-07-29|17:34:09.383] Committed state module=state height=90 txs=0 appHash=75FD1EE834F0669D5E717C812F36B21D5F20B3CCBB45E8B8D415CB9C4513DE51
I[2020-07-29|17:34:14.700] Executed block module=state height=91 validTxs=0 invalidTxs=0
```
:::tip
You can disregard the `Can't add peer's address to addrbook` warning. As long as the blocks are
being produced and the app hashes are the same for each node, there should not be any issues.
:::
Whereas the logs for the REST & RPC server would look like:
```bash theme={null}
I[2020-07-30|09:39:17.488] Starting application REST service (chain-id: "7305661614933169792")... module=rest-server
I[2020-07-30|09:39:17.488] Starting RPC HTTP server on 127.0.0.1:8545 module=rest-server
...
```
#### Follow Logs
You can also watch logs as they are produced via Docker with the `--follow` (`-f`) flag, for
example:
```bash theme={null}
docker logs -f hyperpaxdnode0
```
### Interact with the Localnet
#### Ethereum JSON-RPC & Websocket Ports
To interact with the testnet via WebSockets or RPC/API, you will send your request to the corresponding ports:
| EVM JSON-RPC | Eth Websocket |
| ------------ | ------------- |
| `8545` | `8546` |
You can send a curl command such as:
```bash theme={null}
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" 192.162.10.1:8545
```
:::tip
The IP address will be the public IP of the docker container.
:::
Additional instructions on how to interact with the WebSocket can be found on the
[events documentation](./../../develop/api/ethereum-json-rpc#ethereum-websocket).
### Keys & Accounts
To interact with `hyperpaxd` and start querying state or creating txs, you use the
`hyperpaxd` directory of any given node as your `home`, for example:
```bash theme={null}
hyperpaxd keys list --home ./build/node0/hyperpaxd
```
Now that accounts exists, you may create new accounts and send those accounts
funds!
:::tip
**Note**: Each node's seed is located at `./build/nodeN/hyperpaxd/key_seed.json` and can be restored to the CLI using the
`hyperpaxd keys add --restore` command
:::
### Special Binaries
If you have multiple binaries with different names, you can specify which one to run with the BINARY environment
variable. The path of the binary is relative to the attached volume. For example:
```bash theme={null}
# Run with custom binary
BINARY=HyperPaxeer make localnet-start
```
# Single node
Source: https://sidiorresearchlabs.mintlify.app/protocol/cli/single-node
# Single Node
Following this page, you can run a single node local network manually or
by using the already prepared automated script. Running a single node setup is useful
for developers who want to test their applications and protocol features because of
its simplicity and speed. For more complex setups, please refer to the [Multi Node Setup](./multi-nodes) page.
## Prerequisite Readings
* [Install Binary](./)
## Automated Script
The simplest way to start a local HyperPaxeer node is by using the provided helper script on the base level of the [HyperPaxeer repository](https://github.com/Paxeer-Network/Paxeer-Network/blob/main/local_node.sh),
which will create a sensible default configuration for testing purposes:
```bash theme={null}
$ local_node.sh
...
```
:::tip
To avoid overwriting any data for a real node used in production, it was decided to store the automatically generated testing configuration at `~/.tmp-hyperpaxd` instead of the default `~/.hyperpaxd`.
:::
When working with the `local_node.sh` script, it is necessary to extend all `hyperpaxd` commands, that target the local test node, with the `--home ~/.tmp-hyperpaxd` flag. This is mandatory, because the `home` directory cannot be stored in the `hyperpaxd` configuration, which can be seen in the output below. For ease of use, it might be sensible to export this directory path as an environment variable:
```
$ export TMP=$HOME/.tmp-hyperpaxd`
$ hyperpaxd config --home $TMP
{
"chain-id": "hyperpax_125-1",
"keyring-backend": "test",
"output": "text",
"node": "tcp://localhost:26657",
"broadcast-mode": "sync"
}
```
You can customize the local node script by changing the configuration variables.
See the following excerpt from the script for ideas on what can be adjusted:
```bash theme={null}
# Customize the name of your keys, the chain-id, moniker of the node, keyring backend, and more
KEYS[0]="dev0"
KEYS[1]="dev1"
KEYS[2]="dev2"
CHAINID="hyperpax_125-1"
MONIKER="localtestnet"
# Remember to change to other types of keyring like 'file' in-case exposing to outside world,
# otherwise your balance will be wiped quickly
# The keyring test does not require private key to steal tokens from you
KEYRING="test"
KEYALGO="eth_secp256k1"
LOGLEVEL="info"
# Set dedicated home directory for the hyperpaxd instance
HOMEDIR="$HOME/.tmp-hyperpaxd"
# to trace evm
#TRACE="--trace"
TRACE=""
[...]
# Adjust this set a different maximum gas limit
jq '.consensus_params["block"]["max_gas"]="10000000"' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS"
[...]
```
## Manual Deployment
This guide helps you create a single validator node that runs a network locally for testing and other development
related uses.
### Initialize the chain
Before actually running the node, we need to initialize the chain, and most importantly its genesis file. This is done
with the `init` subcommand:
```bash theme={null}
$MONIKER=testing
$KEY=dev0
$CHAINID="hyperpax_125-4"
# The argument $MONIKER is the custom username of your node, it should be human-readable.
hyperpaxd init $MONIKER --chain-id=$CHAINID
```
:::tip
You can [edit](./configuration#client-configuration) this `moniker` later by updating the `config.toml` file.
:::
The command above creates all the configuration files needed for your node and validator to run, as well as a default
genesis file, which defines the initial state of the network. All these
[configuration files](./configuration#client-configuration) are in `~/.hyperpaxd` by default, but you can overwrite the
location of this folder by passing the `--home` flag.
### Genesis Procedure
### Adding Genesis Accounts
Before starting the chain, you need to populate the state with at least one account using the [keyring](./../../protocol/concepts/keyring#add-keys):
```bash theme={null}
hyperpaxd keys add my_validator
```
Once you have created a local account, go ahead and grant it some `ahpx` tokens in your chain's genesis file. Doing
so will also make sure your chain is aware of this account's existence:
```bash theme={null}
hyperpaxd add-genesis-account my_validator 10000000000ahpx
```
Now that your account has some tokens, you need to add a validator to your chain.
For this guide, you will add your local node (created via the `init` command above) as a validator of your chain.
Validators can be declared before a chain is first started via a special transaction included in the genesis
file called a `gentx`:
```bash theme={null}
# Create a gentx
# NOTE: this command lets you set the number of coins.
# Make sure this account has some coins with the genesis.app_state.staking.params.bond_denom denom
hyperpaxd add-genesis-account my_validator 1000000000stake,10000000000ahpx
```
A `gentx` does three things:
1. Registers the `validator` account you created as a validator operator account (i.e. the account that controls the validator).
2. Self-delegates the provided `amount` of staking tokens.
3. Link the operator account with a Tendermint node pubkey that will be used for signing blocks. If no `--pubkey` flag
is provided, it defaults to the local node pubkey created via the `hyperpaxd init` command above.
For more information on `gentx`, use the following command:
```bash theme={null}
hyperpaxd gentx --help
```
### Collecting `gentx`
By default, the genesis file do not contain any `gentxs`. A `gentx` is a transaction that bonds
staking token present in the genesis file under `accounts` to a validator, essentially creating a
validator at genesis. The chain will start as soon as more than 2/3rds of the validators (weighted
by voting power) that are the recipient of a valid `gentx` come online after `genesis_time`.
A `gentx` can be added manually to the genesis file, or via the following command:
```bash theme={null}
# Add the gentx to the genesis file
hyperpaxd collect-gentxs
```
This command will add all the `gentxs` stored in `~/.hyperpaxd/config/gentx` to the genesis file.
### Run Single Node
Finally, check the correctness of the `genesis.json` file:
```bash theme={null}
hyperpaxd validate-genesis
```
Now that everything is set up, you can finally start your node:
```bash theme={null}
hyperpaxd start
```
:::tip
To check all the available customizable options when running the node, use the `--help` flag.
:::
You should see blocks come in.
The previous command allow you to run a single node. This is enough for the next section on interacting with this node,
but you may wish to run multiple nodes at the same time, and see how consensus happens between them.
You can then stop the node using `Ctrl+C`.
## Further Configuration
### Key Management
To run a node with the same key every time: replace `hyperpaxd keys add $KEY` in `./local_node.sh` with:
```bash theme={null}
echo "your mnemonic here" | hyperpaxd keys add $KEY --recover
```
:::tip
HyperPaxeer currently only supports 24 word mnemonics.
:::
You can generate a new key/mnemonic with:
```bash theme={null}
hyperpaxd keys add $KEY
```
To export your HyperPaxeer key as an Ethereum private key (for use with [Metamask](https://academy.evmosd.org/articles/beginner/connect-your-wallet/metamask)
for example):
```bash theme={null}
hyperpaxd keys unsafe-export-eth-key $KEY
```
For more about the available key commands, use the `--help` flag
```bash theme={null}
hyperpaxd keys -h
```
### Keyring backend options
The instructions above include commands to use `test` as the `keyring-backend`. This is an unsecured
keyring that doesn't require entering a password and should not be used in production. Otherwise,
HyperPaxeer supports using a file or OS keyring backend for key storage. To create and use a file
stored key instead of defaulting to the OS keyring, add the flag `--keyring-backend file` to any
relevant command and the password prompt will occur through the command line. This can also be saved
as a CLI config option with:
```bash theme={null}
hyperpaxd config keyring-backend file
```
:::tip
For more information about the Keyring and its backend options, click [here](./../concepts/keyring).
:::
### Enable Tracing
To enable tracing when running the node, modify the last line of the `local_node.sh` script to be the following command,
where:
* `$TRACER` is the EVM tracer type to collect execution traces from the EVM transaction execution (eg. `json|struct|access_list|markdown`)
* `$TRACESTORE` is the output file which contains KVStore tracing (eg. `store.txt`)
```bash theme={null}
hyperpaxd start --evm.tracer $TRACER --tracestore $TRACESTORE --pruning=nothing $TRACE --log_level $LOGLEVEL --minimum-gas-prices=0.0001ahpx --json-rpc.api eth,txpool,personal,net,debug,web3
```
## Clearing data from chain
### Reset Data
Alternatively, you can **reset** the blockchain database, remove the node's address book files, and reset the `priv_validator.json` to the genesis state.
:::danger
If you are running a **validator node**, always be careful when doing `hyperpaxd unsafe-reset-all`. You should never use
this command if you are not switching `chain-id`.
:::
:::danger
**IMPORTANT**: Make sure that every node has a unique `priv_validator.json`. **Do not** copy the `priv_validator.json`
from an old node to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to double sign!
:::
First, remove the outdated files and reset the data.
```bash theme={null}
rm $HOME/.hyperpaxd/config/addrbook.json $HOME/.hyperpaxd/config/genesis.json
hyperpaxd tendermint unsafe-reset-all --home $HOME/.hyperpaxd
```
Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`.
If you had any sentry nodes or full nodes setup before, your node will still try to connect to them,
but may fail if they haven't also been upgraded.
### Delete Data
Data for the `hyperpaxd` binary should be stored at `~/.hyperpaxd`,
respectively by default. To **delete** the existing binaries and configuration, run:
```bash theme={null}
rm -rf ~/.hyperpaxd
```
To clear all data except key storage (if keyring backend chosen) and then you can rerun the full node installation
commands from above to start the node again.
## Recording Transactions Per Second (TPS)
In order to get a progressive value of the transactions per second, we use Prometheus to return the values.
The Prometheus exporter runs at address `http://localhost:8877` so please add this
section to your [Prometheus installation](https://opencensus.io/codelabs/prometheus/#1) config.yaml file like this
```yaml theme={null}
global:
scrape_interval: 10s
external_labels:
monitor: 'HyperPaxeer'
scrape_configs:
- job_name: 'HyperPaxeer'
scrape_interval: 10s
static_configs:
- targets: ['localhost:8877']
```
and then run Prometheus like this
```shell theme={null}
prometheus --config.file=prom_config.yaml
```
and then visit the Prometheus dashboard at [http://localhost:9090/](http://localhost:9090/) then navigate to the expression area and enter the
following expression
```shell theme={null}
rate(hyperpaxd_transactions_processed[1m])
```
which will show the rate of transactions processed.
:::tip
HyperPaxeer currently only supports 24 word mnemonics.
:::
# Accounts
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/accounts
# Accounts
Crypto Wallets (or Accounts) can be created
and represented in unique ways on different blockchains.
For developers who interface with account types on HyperPaxeer,
e.g. during wallet integration on their dApp frontend,
it is therefore important to understand that accounts on HyperPaxeer are implemented
to be compatible with Ethereum type addresses.
## Prerequisite Readings
* [Cosmos SDK Accounts](https://docs.cosmos.network/main/learn/beginner/accounts)
* [Ethereum Accounts](https://ethereum.org/en/whitepaper/#ethereum-accounts)
## Creating Accounts
To create one account you can either
create a private key, a keystore file (a private key protected by a password),
or a mnemonic phrase (a string of words that can access multiple private keys).
Aside from having different security features,
the biggest difference between each of these is
that a private key or keystore file only creates one account.
Creating a mnemonic phrase gives you control of many accounts,
all accessible with that same phrase.
Cosmos blockchains, like HyperPaxeer, support creating accounts with mnemonic phrases,
otherwise known as
[hierarchical deterministic key generation](https://github.com/confio/cosmos-hd-key-derivation-spec) (HD keys).
This allows the user to create accounts on multiple blockchains
without having to manage multiple secrets.
HD keys generate addresses by taking the mnemonic phrase
and combining it with a piece of information called a [derivation path](https://learnmeabitcoin.com/technical/derivation-paths).
Blockchains can differ in which derivation path they support.
To access all accounts from an mnemonic phrase on a blockchain,
it is therefore important to use that blockchain's specific derivation path.
## Representing Accounts
The terms "account" and "address" are often used interchangeably to describe crypto wallets.
In the Cosmos SDK, an account designates a pair of public key (PubKey) and private key (PrivKey).
The derivation path defines what the private key, public key, and address would be.
The PubKey can be derived to generate various addresses in different formats,
which are used to identify users (among other parties) in the application.
A common address form for Cosmos chains is the bech32 format (e.g. `HyperPaxeer1...`).
Addresses are also associated with messages to identify the sender of the message.
The PrivKey is used to generate digital signatures to prove
that an address associated with the PrivKey approved of a given message.
The proof is performed by applying a cryptographic scheme to the PrivKey,
known as Elliptic Curve Digital Signature Algorithm (ECDSA),
to generate a PubKey that is compared with the address in the message.
## HyperPaxeer Accounts
HyperPaxeer defines its own custom `Account` type
to implement a HD wallet that is compatible with Ethereum type addresses.
It uses Ethereum's ECDSA secp256k1 curve for keys (`eth_secp265k1`)
and satisfies the [EIP84](https://github.com/ethereum/EIPs/issues/84)
for full [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) paths.
This cryptographic curve is not to be confused with [Bitcoin's ECDSA secp256k1](https://en.bitcoin.it/wiki/Secp256k1) curve.
The root HD path for HyperPaxeer-based accounts is `m/44'/60'/0'/0`.
HyperPaxeer uses the Coin type `60` to support Ethereum type accounts,
unlike many other Cosmos chains that use Coin type `118` ([list of coin types](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)
The custom HyperPaxeer [EthAccount](https://github.com/Paxeer-Network/Paxeer-Network/blob/main/types/account.go#L28-L33)
satisfies the `AccountI` interface from the Cosmos SDK auth module
and includes additional fields that are required for Ethereum type addresses:
```go theme={null}
// EthAccountI represents the interface of an EVM compatible account
type EthAccountI interface {
authtypes.AccountI
// EthAddress returns the ethereum Address representation of the AccAddress
EthAddress() common.Address
// CodeHash is the keccak256 hash of the contract code (if any)
GetCodeHash() common.Hash
// SetCodeHash sets the code hash to the account fields
SetCodeHash(code common.Hash) error
// Type returns the type of Ethereum Account (EOA or Contract)
Type() int8
}
```
For more information on Ethereum accounts head over to the [x/evm module](../modules/evm.md#concepts).
### Addresses and Public Keys
[BIP-0173](https://github.com/satoshilabs/slips/blob/master/slip-0173.md) defines a new format for segregated witness
output addresses that contains a human-readable part that identifies the Bech32 usage. HyperPaxeer uses the following
HRP (human readable prefix) as the base HRP:
| Network | Mainnet | Testnet |
| ----------- | ------- | ------- |
| HyperPaxeer | `pax` | `pax` |
There are 3 main types of HRP for the `Addresses`/`PubKeys` available by default on HyperPaxeer (bech32 prefix: `pax`):
* Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using
the **`eth_secp256k1`** curve.
* Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using
the **`eth_secp256k1`** curve.
* Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are
derived using the **`ed25519`** curve.
| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
| ------------------ | --------------------- | -------------------- | --------------- | ------------------- | ------------------ |
| Accounts | `pax` | `paxpub` | `eth_secp256k1` | `20` | `33` (compressed) |
| Validator Operator | `paxvaloper` | `paxvaloperpub` | `eth_secp256k1` | `20` | `33` (compressed) |
| Consensus Nodes | `paxvalcons` | `paxvalconspub` | `ed25519` | `20` | `32` |
### Address formats for clients
`EthAccount` can be represented in both [Bech32](https://en.bitcoin.it/wiki/Bech32) (`pax1...`)
and hex (`0x...`) formats for Ethereum's Web3 tooling compatibility.
The Bech32 format is the default format for Cosmos-SDK queries and transactions through CLI and REST
clients. The hex format on the other hand, is the Ethereum `common.Address` representation of a
Cosmos `sdk.AccAddress`.
* **Address (Bech32)**: `pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw`
* **Address ([EIP55](https://eips.ethereum.org/EIPS/eip-55) Hex)**: `0x91defC7fE5603DFA8CC9B655cF5772459BF10c6f`
* **Compressed Public Key**: `{"@type":"/hyperpaxeer.crypto.v1.ethsecp256k1.PubKey","key":"AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2"}`
### Address conversion
The `hyperpaxd debug addr ` can be used to convert an address between hex and bech32 formats. For example:
```bash title="Bech32" theme={null}
$ hyperpaxd debug addr pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
Address: [20 87 74 109 255 45 223 158 7 130 139 67 69 211 4 9 25 175 86 82]
Address (hex): 14574A6DFF2DDF9E07828B4345D3040919AF5652
Bech32 Acc: pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
Bech32 Val: paxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
```
```bash title="Hex" theme={null}
$ hyperpaxd debug addr 14574A6DFF2DDF9E07828B4345D3040919AF5652
Address: [20 87 74 109 255 45 223 158 7 130 139 67 69 211 4 9 25 175 86 82]
Address (hex): 14574A6DFF2DDF9E07828B4345D3040919AF5652
Bech32 Acc: pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
Bech32 Val: paxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
```
### Key output
:::tip
The Cosmos SDK Keyring output (i.e `hyperpaxd keys`) only supports addresses and public keys in Bech32 format.
:::
We can use the `keys show` command of `hyperpaxd` with the flag `--bech (acc|val|cons)` to
obtain the addresses and keys as mentioned above,
```bash title="Accounts" theme={null}
$ hyperpaxd keys show dev0 --bech acc
- name: dev0
type: local
address: pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
pubkey: '{"@type":"/hyperpaxeer.crypto.v1.ethsecp256k1.PubKey","key":"AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2"}'
mnemonic: ""
```
```bash title="Validator" theme={null}
$ hyperpaxd keys show dev0 --bech val
- name: dev0
type: local
address: paxvaloper1z3t55m0l9h0eupuz3dp5t5cypyv674jjn4d6nn
pubkey: '{"@type":"/hyperpaxeer.crypto.v1.ethsecp256k1.PubKey","key":"AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2"}'
mnemonic: ""
```
```bash title="Consensus" theme={null}
$ hyperpaxd keys show dev0 --bech cons
- name: dev0
type: local
address: paxvalcons1rllqa5d97n6zyjhy6cnscc7zu30zjn3f7wyj2n
pubkey: '{"@type":"/hyperpaxeer.crypto.v1.ethsecp256k1.PubKey","key":"A/fVLgIqiLykFQxum96JkSOoTemrXD0tFaFQ1B0cpB2c"}'
mnemonic: ""
```
## Querying an Account
You can query an account address using the CLI, gRPC or
### Command Line Interface
```bash theme={null}
# NOTE: the --output (-o) flag will define the output format in JSON or YAML (text)
hyperpaxd q auth account $(hyperpaxd keys show dev0 -a) -o text
'@type': /hyperpaxeer.types.v1.EthAccount
base_account:
account_number: "0"
address: pax1z3t55m0l9h0eupuz3dp5t5cypyv674jj7mz2jw
pub_key:
'@type': /hyperpaxeer.crypto.v1.ethsecp256k1.PubKey
key: AsV5oddeB+hkByIJo/4lZiVUgXTzNfBPKC73cZ4K1YD2
sequence: "1"
code_hash: 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
```
### Cosmos gRPC and REST
```bash theme={null}
# GET /cosmos/auth/v1beta1/accounts/{address}
curl -X GET "http://localhost:10337/cosmos/auth/v1beta1/accounts/Paxeer-Network14au322k9munkmx5wrchz9q30juf5wjgz2cfqku" -H "accept: application/json"
```
### JSON-RPC
To retrieve the Ethereum hex address using Web3,
use the JSON-RPC [`eth_accounts`](./../../develop/api/ethereum-json-rpc/methods#eth-accounts)
or [`personal_listAccounts`](./../../develop/api/ethereum-json-rpc/methods#personal-listAccounts) endpoints:
```bash theme={null}
# query against a local node
curl -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
curl -X POST --data '{"jsonrpc":"2.0","method":"personal_listAccounts","params":[],"id":1}' -H "Content-Type: application/json" http://localhost:8545
```
# Chain ID
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/chain-id
# Chain ID
A chain ID is a unique identifier that represents a blockchain network. We use it to distinguish different blockchain
networks from each other and to ensure that transactions and messages are sent to the correct network. HyperPaxeer network
follows the format of `identifier_EIP155-version` format.
## Official Chain IDs
:::tip
**NOTE**: The latest Chain ID (i.e highest Version Number) is the latest version of the software and mainnet. Also note, that the following upgrades technically did not require a Chain ID change:
* `HyperPaxeer_9001-1` -> `HyperPaxeer_9001-2`
* `hyperpax_125-3` -> `hyperpax_125-4`
:::
### Mainnet
| Name | Chain ID | Identifier | EIP-155 Number | Version | Active |
| ------------------- | ---------------- | ---------- | -------------- | ------- | ------ |
| HyperPaxeer Mainnet | `hyperpax_125-1` | `hyperpax` | `125` | `1` | β |
**No public testnet available.** Developers should use local development networks. See the [Single Node](../cli/single-node) guide for setting up a local development environment.
:::tip
You can also look up the [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) `Chain ID` by referring
to [chainlist.org](https://chainlist.org/).
:::
## The Chain Identifier
Every chain must have a unique identifier or `chain-id`. Tendermint requires each application to
define its own `chain-id` in the [genesis.json fields](https://docs.tendermint.com/master/spec/core/genesis.html#genesis-fields).
However, to comply with both EIP-155 and Cosmos standard for chain upgrades, HyperPaxeer-compatible chains must implement
a special structure for their chain identifiers.
## Structure
The HyperPaxeer Chain ID contains 3 main components
* **Identifier**: Unstructured string that defines the name of the application.
* **EIP-155 Number**: Immutable [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) `CHAIN_ID` that
defines the replay attack protection number.
* **Version Number**: Is the version number (always positive) that the chain is currently running.
This number **MUST** be incremented every time the chain is upgraded or forked to avoid network or consensus errors.
### Format
The format for specifying and HyperPaxeer compatible chain-id in genesis is the following:
```bash theme={null}
{identifier}_{EIP155}-{version}
```
The following table provides an example where the second row corresponds to an upgrade from the first one:
| ChainID | Identifier | EIP-155 Number | Version Number |
| ---------------- | ----------- | -------------- | -------------- |
| `hyperpax_125-1` | HyperPaxeer | 9000 | 1 |
| `hyperpax_125-2` | HyperPaxeer | 9000 | 2 |
| `...` | ... | ... | ... |
| `hyperpax_125-N` | HyperPaxeer | 9000 | N |
# Encoding
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/encoding
# Encoding
Encoding refers to the process of converting data from one format to another to make it more secure and efficient.
In the context of blockchain, encoding is used to ensure that data is stored and transmitted in a way that is secure and
easily accessible.
The Recursive Length Prefix (RLP) is a serialization format used extensively in Ethereum's execution clients. Its purpose
is to encode arbitrarily nested arrays of binary data, and it is the main encoding method used to serialize objects in
Ethereum. RLP only encodes structure and leaves encoding specific atomic data types, such as strings, integers, and floats,
to higher-order protocols.
In Ethereum, integers must be represented in big-endian binary form with no leading zeroes,
making the integer value zero equivalent to the empty byte array. The RLP encoding function takes in an item, which is
defined as a single byte whose value is in the \[0x00, 0x7f] range or a string of 0-55 bytes long. If the string is
more than 55 bytes long, the RLP encoding consists of a single byte with value 0xb7 (dec. 183) plus the length in
bytes of the length of the string in binary form, followed by the length of the string, followed by the string. RLP
is used for hash verification, where a transaction is signed by signing the RLP hash of the transaction
data, and blocks are identified by the RLP hash of their header. RLP is also used for encoding data over the wire
and for some cases where there should be support for efficient encoding of the merkle tree data structure. The
Ethereum execution layer uses RLP as the primary encoding method to serialize objects, but the newer Simple
Serialize (SSZ) replaces RLP as the encoding for the new consensus layer in Ethereum 2.0.
The Cosmos Stargate release introduces protobuf as the main encoding format for both client and state serialization.
All the EVM module types that are used for state and clients, such as transaction messages, genesis, query services,
etc., will be implemented as protocol buffer messages. The Cosmos SDK also supports the legacy Amino encoding.
Protocol Buffers (protobuf) is a language-agnostic binary serialization format that is smaller and faster than JSON.
It is used to serialize structured data, such as messages, and is designed to be highly efficient and extensible. The
encoding format is defined in a language-agnostic language called Protocol Buffers Language (proto3), and the encoded
messages can be used to generate code for a variety of programming languages. The main advantage of protobuf is its
efficiency, which results in smaller message sizes and faster serialization and deserialization times. The RLP decoding
process is as follows: according to the first byte (i.e., prefix) of input data and decoding the data type, the length
of the actual data and offset; according to the type and offset of data, decode the data correspondingly.
## Prerequisite Readings
* [Cosmos SDK Encoding](https://docs.cosmos.network/main/learn/advanced/encoding)
* [Ethereum RLP](https://eth.wiki/en/fundamentals/rlp)
## Encoding Formats
### Protocol Buffers
The Cosmos [Stargate](https://stargate.cosmos.network/) release introduces
[protobuf](https://developers.google.com/protocol-buffers) as the main encoding format for both
client and state serialization. All the EVM module types that are used for state and clients
(transaction messages, genesis, query services, etc) will be implemented as protocol buffer messages.
### Amino
The Cosmos SDK also supports the legacy Amino encoding format for backwards compatibility with
previous versions, specially for client encoding and signing with Ledger devices. HyperPaxeer does not
support Amino in the EVM module, but it is supported for all other Cosmos SDK modules that enable it.
### RLP
Recursive Length Prefix ([RLP](https://eth.wiki/en/fundamentals/rlp)),
is an encoding/decoding algorithm that serializes a message and
allows for quick reconstruction of encoded data. HyperPaxeer uses RLP to encode/decode Ethereum
messages for JSON-RPC handling to conform messages to the proper Ethereum format. This allows
messages to be encoded and decoded in the exact format as Ethereum's.
The `x/evm` transactions (`MsgEthereumTx`) encoding is performed by casting the message to a go-ethereum's `Transaction`
and then marshaling the transaction data using RLP:
```go theme={null}
// TxEncoder overwrites sdk.TxEncoder to support MsgEthereumTx
func (g txConfig) TxEncoder() sdk.TxEncoder {
return func(tx sdk.Tx) ([]byte, error) {
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if ok {
return msg.AsTransaction().MarshalBinary()
}
return g.TxConfig.TxEncoder()(tx)
}
}
// TxDecoder overwrites sdk.TxDecoder to support MsgEthereumTx
func (g txConfig) TxDecoder() sdk.TxDecoder {
return func(txBytes []byte) (sdk.Tx, error) {
tx := ðtypes.Transaction{}
err := tx.UnmarshalBinary(txBytes)
if err == nil {
msg := &evmtypes.MsgEthereumTx{}
msg.FromEthereumTx(tx)
return msg, nil
}
return g.TxConfig.TxDecoder()(txBytes)
}
}
```
# Gas and fees
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/gas-and-fees
# Gas and Fees
Users need to pay a fee to submit transactions on the HyperPaxeer network.
As fees are handled differently on Ethereum and Cosmos,
it is important to understand how the HyperPaxeer blockchain implements an Ethereum-type fee calculation,
that is compatible with the Cosmos SDK.
Therefore this overview explains the basics of gas calculation,
how to provide fees for transactions
and how the Ethereum-type fee calculation uses a fee market (EIP-1559)
for prioritizing transactions.
## Prerequisite Readings
* [Cosmos SDK Gas](https://docs.cosmos.network/main/learn/beginner/gas-fees.html)
* [Ethereum Gas](https://ethereum.org/en/developers/docs/gas/)
## Basics
### Why do Transactions Need Fees?
If anyone can submit transactions to a network at no cost,
the network can be overrun by a handful of actors
sending large numbers of fraudulent transactions
to clog up the network and stop it from working.
The solution to this is a concept called βgas,"
which is a resource consumed throughout transaction execution.
In practice, a small amount of gas is spent on each step of code execution,
thus effectively charging for use of a validatorβs resources
and preventing malicious actors from halting a network at will.
### What is Gas?
In general, gas is a unit that measures the computational intensity of a particular transaction
β in other words, how much work would be required to evaluate and perform the job.
Complex, multi-step transactions,
such as a Cosmos transaction that delegates to a dozen validators,
require more gas than simple, single-step transactions,
such as a Cosmos transaction to send tokens to another address.
When referring to a transaction,
βgasβ refers to the total quantity of gas required for the transaction.
For example, a transaction may require 300,000 units of gas to be executed.
Gas can be thought of as electricity (kWh) within a house or factory,
or fuel for automobiles.
The idea is that it costs something to get somewhere.
More on Gas:
* [Cosmos Gas Fees](https://docs.cosmos.network/main/learn/beginner/gas-fees)
* [Cosmos Tx Lifecycle](https://docs.cosmos.network/main/learn/beginner/tx-lifecycle.html)
* [Ethereum Gas](https://ethereum.org/en/developers/docs/gas/)
### How is Gas Calculated?
In general, thereβs no way to know exactly how much gas a transaction will cost
without simply running it.
Using the Cosmos SDK, this can be done by [simulating the Tx](https://docs.cosmos.network/main/run-node/txs#simulating-a-transaction).
Otherwise, there are ways to estimate the amount of gas a transaction will require,
based on the details of the transaction fields, and data.
In the case of the EVM, for example, each bytecode operation
has a [corresponding amount of gas](https://ethereum.org/en/developers/docs/evm/opcodes/).
More on Gas Calculations:
* [Estimate Gas](https://docs.ethers.org/v5/api/providers/provider/#Provider-estimateGas)
* [Executing EVM Bytecode](https://ethereum.org/en/developers/docs/evm/opcodes/)
* [Simulate a Cosmos SDK Tx](https://docs.cosmos.network/main/run-node/txs#simulating-a-transaction)
### How does Gas Relate to Fees?
While gas refers to the computational work required for execution,
fees refer to the amount of the tokens you actually spend to execute the transaction.
They are derived using the following formula:
```markdown theme={null}
Total Fees = Gas * Gas Price (the price per unit of gas)
```
If βgasβ was measured in kWh, the βgas priceβ would be the rate (in dollars per kWh)
determined by your energy provider,
and the βfeesβ would be your bill.
Just as with electricity, gas price is liable to fluctuate over a given day,
depending on network traffic.
More on Gas vs. Fees:
* [Cosmos Gas and Fees](https://docs.cosmos.network/main/learn/beginner/gas-fees)
* [Ethereum Gas and Fees](https://ethereum.org/en/developers/docs/gas/)
### How are Fees Handled on Cosmos?
Gas fees on Cosmos are relatively straightforward. As a user, you specify two fields:
1. A `GasLimit` corresponding to an upper bound on execution gas, defined as `GasWanted`
2. One of `Fees` or `GasPrice`, which will be used to specify or calculate the transaction fees
The node will entirely consume the fees provided, then begin to execute the transaction. If the `GasLimit` is found to
be insufficient during execution, the transaction will fail and roll back any changes made, without refunding the fees provided.
Validators for Cosmos SDK-based chains can specify their `min-gas-prices` that they will enforce when selecting
transactions to include in blocks. Thus, transactions with insufficient fees will encounter delays or fail outright.
At the beginning of each block, fees from the previous block are
[allocated to validators and delegators](https://docs.cosmos.network/main/modules/distribution), after which they can
be withdrawn and spent.
### How are Fees Handled on Ethereum?
Fees on Ethereum include multiple implementations that were introduced over time.
Originally, a user would specify a `GasPrice` and `GasLimit` within a transactionβmuch like a Cosmos SDK transaction. A
block proposer would receive the entire gas fee from each transaction in the block, and they would select transactions
to include accordingly.
With proposal EIP-1559 and the London Hard fork, gas calculation changed. The `GasPrice` from above has now been split
into two separate components: a `BaseFee` and `PriorityFee`. The `BaseFee` is calculated automatically based on the
block size and is burned once the block is mined. The `PriorityFee` goes to the proposer and represents a tip, or an
incentive for a proposer to include the transaction in a block.
```markdown theme={null}
Gas Price = Base Fee + Priority Fee
```
Within a transaction, users can specify a `max_fee_per_gas` corresponding to the total `GasPrice` and a
`max_priority_fee_per_gas` corresponding to a maximum `PriorityFee`, in addition to specifying the `gas_limit` as before.
All surplus gas that was not required for execution is refunded to the user.
More on Ethereum Fees:
* [Gas Calculation Docs](https://ethereum.org/en/developers/docs/gas/)
* [Proposal EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)
## Implementation
### How are Gas and Fees Handled on HyperPaxeer?
Fundamentally, HyperPaxeer is a Cosmos SDK chain that enables EVM compatibility as part of a Cosmos SDK module. As a result of
this architecture, all EVM transactions are ultimately encoded as Cosmos SDK transactions and update a Cosmos
SDK-managed state.
Since all transactions are represented as Cosmos SDK transactions, transaction fees can be treated identically across
execution layers. In practice, dealing with fees includes standard Cosmos SDK logic, some Ethereum logic, and custom
HyperPaxeer logic. For the most part, fees are collected by the `fee_collector` module, then paid out to validators and
delegators. A few key distinctions are as follows:
1. Fee Market Module
In order to support EIP-1559 gas and fee calculation on HyperPaxeerβ EVM layer, HyperPaxeer tracks the gas supplied for each
block and uses that to calculate a base fee for future EVM transactions, thus enabling EVM dynamic fees and
transaction prioritization as specified by EIP-1559.
For EVM transactions, each node bypasses their local `min-gas-prices` configuration, and instead applies EIP-1559 fee
logicβthe gas price simply must be greater than both the global `min-gas-price` and the block's `BaseFee`, and the
surplus is considered a priority tip. This allows validators to compute Ethereum fees without applying Cosmos SDK
fee logic.
Unlike on Ethereum, the `BaseFee` on HyperPaxeer is not burned, and instead is distributed to validators and delegators.
Furthermore, the `BaseFee` is lower-bounded by the global `min-gas-price` (currently, the global `min-gas-price`
parameter is set to zero, although it can be updated via Governance).
2. EVM Gas Refunds
HyperPaxeer refunds a fraction (at least 50% by default) of the unused gas for EVM transactions to approximate the current
behavior on Ethereum. [Why not always 100%?](https://github.com/paxeer-network/hyperpaxeer/issues/1085)
### Detailed Timeline
1. Nodes execute the previous block and run the `EndBlock` hook
* As part of this hook, the FeeMarket (EIP-1559) module tracks the total `TransientGasWanted` from the transactions
on this block. This will be used for the next blockβs `BaseFee`.
2. Nodes receive transactions for a subsequent block and gossip these transactions to peers
* These can be sorted and prioritized by the included fee price (using EIP-1559 fee priority mechanics for EVM
transactions - [code snippet](https://github.com/paxeer-network/hyperpaxeer/blob/57ed355c985d9f3116aba6aabfa2ee0f3f38e966/app/ante/eth.go#L137)),
to be included in the next block
3. Nodes run `BeginBlock` for the subsequent block
* The FeeMarket module calculates the `BaseFee` ([code snippet](https://github.com/paxeer-network/hyperpaxeer/blob/89fdd1984826ea524cb9b8feb089a99b6cfe8ace/x/feemarket/keeper/abci.go#L14))
to be applied for this block using the total `GasWanted` from the previous block.
* The Distribution module [distributes](https://docs.cosmos.network/main/modules/distribution#begin-block) the
previous blockβs fee rewards to validators and delegators
4. For each valid transaction that will be included in this block, nodes perform the following:
* They run an `AnteHandler` corresponding to the transaction type. This process:
1. Performs basic transaction validation
2. Verifies the fees provided are greater than the global and local minimum validator values *and* greater than
the `BaseFee` calculated
3. (For Ethereum transactions) Preemptively consumes gas for the EVM transaction
4. Deducts the transaction fees from the user and transfers them to the `fee_collector` module
5. Increments the `TransientGasWanted` in the current block, to be used to calculate the next blockβs `BaseFee`
* Then, for standard Cosmos Transactions, nodes:
1. Execute the transaction and update the state
2. Consume gas for the transaction
* For Ethereum Transactions, nodes:
1. Execute the transaction and update the state
2. Calculate the gas used and compare it to the gas supplied, then refund a designated portion of the surplus
5. Nodes run `EndBlock` for this block and store the blockβs `GasWanted`
## Detailed Mechanics
### Cosmos `Gas`
In the Cosmos SDK, gas is tracked in the main `GasMeter` and the `BlockGasMeter`:
* `GasMeter`: keeps track of the gas consumed during executions that lead to state transitions. It is reset on every
transaction execution.
* `BlockGasMeter`: keeps track of the gas consumed in a block and enforces that the gas does not go over a predefined
limit. This limit is defined in the Tendermint consensus parameters and can be changed via governance parameter change proposals.
Since gas is priced per-byte, the same interaction is more gas-intensive with larger parameter values than smaller
(unlike Ethereum's `uint256` values, Cosmos SDK numericals are represented using [Big.Int](https://pkg.go.dev/math/big#Int)
types, which are dynamically sized).
More information regarding gas as part of the Cosmos SDK can be found [here](https://docs.cosmos.network/main/learn/beginner/gas-fees.html).
### Matching EVM Gas consumption
HyperPaxeer is an EVM-compatible chain that supports Ethereum Web3 tooling. For this reason, gas consumption must be equatable
with other EVMs, most importantly Ethereum.
The main difference between EVM and Cosmos state transitions, is that the EVM uses a [gas table](https://github.com/ethereum/go-ethereum/blob/master/params/protocol_params.go)
for each OPCODE, whereas Cosmos uses a `GasConfig` that charges gas for each CRUD operation by setting a flat and
per-byte cost for accessing the database.
\+++ [https://github.com/cosmos/cosmos-sdk/blob/3fd376bd5659f076a4dc79b644573299fd1ec1bf/store/types/gas.go#L187-L196](https://github.com/cosmos/cosmos-sdk/blob/3fd376bd5659f076a4dc79b644573299fd1ec1bf/store/types/gas.go#L187-L196)
In order to match the gas consumed by the EVM, the gas consumption logic from the SDK is ignored, and instead the gas consumed
is calculated by subtracting the state transition leftover gas plus refund from the gas limit defined on the message.
To ignore the SDK gas consumption, we reset the transaction `GasMeter` count to 0 and manually set it to the `gasUsed`
value computed by the EVM module at the end of the execution.
\+++ [https://github.com/paxeer-network/hyperpaxeer/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/state\_transition.go#L188](https://github.com/paxeer-network/hyperpaxeer/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/state_transition.go#L188)
### `AnteHandler`
The Cosmos SDK [`AnteHandler`](https://docs.cosmos.network/main/learn/beginner/gas-fees.html#antehandler)
performs basic checks prior to transaction execution. These checks are usually signature
verification, transaction field validation, transaction fees, etc.
Regarding gas consumption and fees, the `AnteHandler` checks that the user has enough balance to
cover for the tx cost (amount plus fees) as well as checking that the gas limit defined in the
message is greater or equal than the computed intrinsic gas for the message.
### Gas Refunds
In the EVM, gas can be specified prior to execution. The totality of the gas specified is consumed at the beginning of
the execution (during the `AnteHandler` step) and the remaining gas is refunded back to the user if any gas is left over
after the execution. Additionally the EVM can also define gas to be refunded back to the user but those will be capped
to a fraction of the used gas depending on the fork/version being used.
### Zero-Fee Transactions
In Cosmos, a minimum gas price is not enforced by the `AnteHandler` as the `min-gas-prices` is
checked against the local node/validator. In other words, the minimum fees accepted are determined
by the validators of the network, and each validator can specify a different minimum value for their fees.
This potentially allows end users to submit 0 fee transactions if there is at least one single
validator that is willing to include transactions with `0` gas price in their blocks proposed.
For this same reason, in HyperPaxeer it is possible to send transactions with `0` fees for transaction
types other than the ones defined by the `evm` module. EVM module transactions cannot have `0` fees
as gas is required inherently by the EVM. This check is done by the EVM transactions stateless validation
(i.e `ValidateBasic`) function as well as on the custom `AnteHandler` defined by HyperPaxeer.
### Gas Estimation
Ethereum provides a JSON-RPC endpoint `eth_estimateGas` to help users set up a correct gas limit in their transactions.
For that reason, a specific query API `EstimateGas` is implemented in HyperPaxeer. It will apply the transaction against the
current block/state and perform a binary search in order to find the optimal gas value to return to the user (the same
transaction will be applied over and over until we find the minimum gas needed before it fails). The reason we need to
use a binary search is that the gas required for the
transaction might be higher than the value returned by the EVM after applying the transaction, so we need to try until
we find the optimal value.
A cache context will be used during the whole execution to avoid changes be persisted in the state.
\+++ [https://github.com/paxeer-network/hyperpaxeer/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/grpc\_query.go#L100](https://github.com/paxeer-network/hyperpaxeer/blob/098da6d0cc0e0c4cefbddf632df1057383973e4a/x/evm/keeper/grpc_query.go#L100)
For Cosmos Tx's, developers can use Cosmos SDK's [transaction simulation](https://docs.cosmos.network/main/run-node/txs#simulating-a-transaction)
to create an accurate estimate.
### Cross-Chain Gas and Fees
Letβs say a user transfers tokens from Chain A to HyperPaxeer via IBC-transfer and wants to execute an HyperPaxeer transactionβhowever,
they donβt have any HyperPaxeer tokens to cover fees. The Cosmos SDK introduced `Tips` as a solution to this issue; a user can
cover fees using a different tokenβin this case, tokens from Chain A.
To cover transaction fees using a tip, this user can sign a transaction with a tip and no fees, then send the transaction
to a fee relayer. The fee relayer will then cover the fee in the native currency (HyperPaxeer in this case), and receive the
tip in payment, behaving as an intermediary exchange.
## Dealing with gas and fees with the HyperPaxeer CLI
When broadcasting a transaction using the HyperPaxeer CLI client, users should keep into consideration the options available.
There are three flags to consider when sending a transaction to the network:
* `--fees`: fees to pay along with transaction; eg: 10ahpx. Defaults to the required fees.
* `--gas`: the gas limit to set per-transaction; the default value is 200000.
* `--gas-prices`: gas prices to determine the transaction fee (e.g. 10ahpx).
However, not all of them need to be defined on each transaction.
The correct combinations are:
* `--fees=auto`: estimates fees and gas automatically (same behavior as `--gas=auto`).
Throws an error if using any other fees-related flag (e.i, `--gas-prices` , `--fees`)
* `--gas=auto`: same behavior as `--fees=auto`.
Throws an error if using any other fees-related flag (e.i, `--gas-prices` , `--fees`)
* `--gas={int}`: uses the specified gas amount and the required fees for the transaction
* `--fees={int}{denom}`: uses the specified fees for the tx. Uses gas default value (200000) for the tx.
* `--fees={int}{denom} --gas={int}`: uses specified gas and fees. Calculates gas-prices with the provided params
* `--gas-prices={int}{denom}`: uses the provided gas price and the default gas amount (200000)
* `--gas-prices={int}{denom} --gas={int}`: uses the gas specified on for the tx and calculates
the fee with the corresponding parameters.
The reader should note that the former two options provide a frendlier user experience for new users,
and the latter are for more advanced users, who desire more control over these parameters.
The team introduced the `auto` flag option that calculates automatically the gas and fees required to execute a transaction.
In this way, new users or developers can perform transactions without the hustle of defining specific gas and
fees values.
Using the `auto` flag sometimes may fail on estimating the right gas and fees based on network traffic.
To overcome this, you can use a higher value for the `--gas-adjustment` flag.
By default, this is set to `1.2`.
When the estimated values are insufficient,
retry with a higher gas adjustment, for example, `--gas-adjustment 1.3`.
It is not possible to use the `--gas-prices` and `--fees` flags combined.
If so, the user will get an error stating that cannot provide both fees and gas prices.
Keep in mind that the above combinations may fail if the provided fees or gas amount is insufficient.
If that is the case, the CLI will return an error message with the specific reason. For example:
```shell theme={null}
raw_log: 'out of gas in location: submit proposal; gasWanted: 200000, gasUsed: 263940.
Please retry with a gas (--gas flag) amount higher than gasUsed: out of gas'
```
# Keyring
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/keyring
# Keyring
Create, import, export and delete keys using the CLI keyring.
The keyring holds the private/public keypairs used to interact with the node. For instance, a validator key needs to be
set up before running the node, so that blocks can be correctly signed. The private key can be stored in different
locations, called ["backends"](#keyring-backends), such as a file or the operating system's own key storage.
:::tip
In case, you need a refresher on private key and key management, please reference our [Key Management](./key-management).
:::
## Add keys
You can use the following commands for help with the `keys` command and for more information about a particular subcommand,
respectively:
```bash theme={null}
hyperpaxd keys
```
```bash theme={null}
hyperpaxd keys [command] --help
```
To create a new key in the keyring, run the `add` subcommand with a `` argument. You will have to provide a password
for the newly generated key. This key will be used in the next section.
```bash theme={null}
hyperpaxd keys add dev0
# Put the generated address in a variable for later use.
MY_VALIDATOR_ADDRESS=$(hyperpaxd keys show dev0 -a)
```
This command generates a new 24-word mnemonic phrase, persists it to the relevant backend, and outputs information about
the keypair. If this keypair will be used to hold value-bearing tokens, be sure to write down the mnemonic phrase
somewhere safe!
By default, the keyring generates a `eth_secp256k1` key. The keyring also supports `ed25519` keys, which may be created
by passing the `--algo` flag. A keyring can of course hold both types of keys simultaneously.
:::tip
**Note**: The Ethereum address associated with a public key can be derived by taking the full Ethereum public key of type
`eth_secp256k1`, computing the `Keccak-256` hash, and truncating the first twelve bytes.
:::
:::warning
**NOTE**: Cosmos `secp256k1` keys are not supported on HyperPaxeer due to compatibility issues with Ethereum transactions.
:::
## Keyring Backends
### OS
:::tip
**`os`** is the default option since operating system's default credentials managers are
designed to meet users' most common needs and provide them with a comfortable
experience without compromising on security.
:::
The `os` backend relies on operating system-specific defaults to handle key storage
securely. Typically, an operating system's credential sub-system handles password prompts,
private keys storage, and user sessions according to the user's password policies. Here
is a list of the most popular operating systems and their respective passwords manager:
* macOS (since Mac OS 8.6): [Keychain](https://support.apple.com/en-gb/guide/keychain-access/welcome/mac)
* Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management)
* GNU/Linux:
* [libsecret](https://gitlab.gnome.org/GNOME/libsecret)
* [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html)
GNU/Linux distributions that use GNOME as default desktop environment typically come with
[Seahorse](https://wiki.gnome.org/Apps/Seahorse). Users of KDE based distributions are
commonly provided with [KDE Wallet Manager](https://userbase.kde.org/KDE_Wallet_Manager).
Whilst the former is in fact a `libsecret` convenient frontend, the latter is a `kwallet`
client.
The recommended backends for headless environments are `file` and `pass`.
### File
The `file` stores the keyring encrypted within the app's configuration directory. This
keyring will request a password each time it is accessed, which may occur multiple
times in a single command resulting in repeated password prompts. If using bash scripts
to execute commands using the `file` option you may want to utilize the following format
for multiple prompts:
```bash theme={null}
# assuming that KEYPASSWD is set in the environment
yes $KEYPASSWD | hyperpaxd keys add me
yes $KEYPASSWD | hyperpaxd keys show me
# start hyperpaxd with keyring-backend flag
hyperpaxd --keyring-backend=file start
```
:::tip
The first time you add a key to an empty keyring, you will be prompted to type the password twice.
:::
### Password Store
The `pass` backend uses the [pass](https://www.passwordstore.org/) utility to manage on-disk
encryption of keys' sensitive data and metadata. Keys are stored inside `gpg` encrypted files
within app-specific directories. `pass` is available for the most popular UNIX
operating systems as well as GNU/Linux distributions. Please refer to its manual page for
information on how to download and install it.
:::tip
**`pass`** uses [GnuPG](https://gnupg.org/) for encryption. `gpg` automatically invokes the `gpg-agent`
daemon upon execution, which handles the caching of GnuPG credentials. Please refer to `gpg-agent`
man page for more information on how to configure cache parameters such as credentials TTL and
passphrase expiration.
:::
The password store must be set up prior to first use:
```sh theme={null}
pass init
```
Replace `` with your GPG key ID. You can use your personal GPG key or an alternative
one you may want to use specifically to encrypt the password store.
### KDE Wallet Manager
The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the
GNU/Linux distributions that ships KDE as default desktop environment. Please refer to
[KWallet Handbook](https://docs.kde.org/stable5/en/kwalletmanager/kwallet5/) for more
information.
### Testing
The `test` backend is a password-less variation of the `file` backend. Keys are stored
**unencrypted** on disk. This keyring is provided for testing purposes only. Use at your own risk!
:::danger
π¨ **DANGER**: Never create your mainnet validator keys using a `test` keying backend. Doing so might result in
a loss of funds by making your funds remotely accessible via the `eth_sendTransaction` JSON-RPC endpoint.
Ref: [Security Advisory: Insecurely configured geth can make funds remotely accessible](https://blog.ethereum.org/2015/08/29/security-alert-insecurely-configured-geth-can-make-funds-remotely-accessible/)
:::
### In Memory
The `memory` backend stores keys in memory. The keys are immediately deleted after the program has exited.
:::danger
**IMPORTANT**: Provided for testing purposes only. The `memory` backend is **not** recommended for use in production
environments. Use at your own risk!
:::
# Multisig
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/multisig
# Multisig
Learn how to generate, sign and broadcast a transaction using the keyring multisig.
A **multisig account** is an HyperPaxeer account with a special key that can require more than one signature to sign transactions.
This can be useful for increasing the security of the account or for requiring the consent of multiple parties to make
transactions. Multisig accounts can be created by specifying:
* threshold number of signatures required
* the public keys involved in signing
To sign with a multisig account, the transaction must be signed individually by the different keys specified for the account.
Then, the signatures will be combined into a multi-signature which can be used to sign the transaction. If fewer than the
threshold number of signatures needed are present, the resultant multi-signature is considered invalid.
## Generate a Multisig key
```bash theme={null}
hyperpaxd keys add --multisig=name1,name2,name3[...] --multisig-threshold=K new_key_name
```
`K` is the minimum number of private keys that must have signed the transactions that carry the public key's address as signer.
The `--multisig` flag must contain the name of public keys that will be combined into a public key that will be
generated and stored as `new_key_name` in the local database. All names supplied through `--multisig` must already exist
in the local database.
Unless the flag `--nosort` is set, the order in which the keys are supplied on the command line does not matter, i.e. the
following commands generate two identical keys:
```bash theme={null}
hyperpaxd keys add --multisig=p1,p2,p3 --multisig-threshold=2 multisig_address
hyperpaxd keys add --multisig=p2,p3,p1 --multisig-threshold=2 multisig_address
```
Multisig addresses can also be generated on-the-fly and printed through the which command:
```bash theme={null}
hyperpaxd keys show --multisig-threshold=K name1 name2 name3 [...]
```
## Signing a transaction
### Step 1: Create the multisig key
Let's assume that you have `test1` and `test2` want to make a multisig account with `test3`.
First import the public keys of `test3` into your keyring.
```sh theme={null}
hyperpaxd keys add \
test3 \
--pubkey=HyperPaxeerpub1addwnpepqgcxazmq6wgt2j4rdfumsfwla0zfk8e5sws3p3zg5dkm9007hmfysxas0u2
```
Generate the multisig key with 2/3 threshold.
```sh theme={null}
hyperpaxd keys add \
multi \
--multisig=test1,test2,test3 \
--multisig-threshold=2
```
You can see its address and details:
```sh theme={null}
hyperpaxd keys show multi
- name: multi
type: multi
address: HyperPaxeer1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m
pubkey: HyperPaxeerpub1ytql0csgqgfzd666axrjzq3mxw59ys6yqcd3ydjvhgs0uzs6kdk5fp4t73gmkl8t6y02yfq7tvfzd666axrjzq3sd69kp5usk492x6nehqjal67ynv0nfqapzrzy3gmdk27la0kjfqfzd666axrjzq6utqt639ka2j3xkncgk65dup06t297ccljmxhvhu3rmk92u3afjuyz9dg9
mnemonic: ""
threshold: 0
pubkeys: []
```
Let's add 10 HyperPaxeer to the multisig wallet:
```bash theme={null}
hyperpaxd tx bank send \
test1 \
HyperPaxeer1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
10000000000000000000ahpx \
--chain-id=hyperpax_125-4 \
--gas=auto \
--fees=1000000ahpx \
--broadcast-mode=block
```
### Step 2: Create the multisig transaction
We want to send 5 HyperPaxeer from our multisig account to `HyperPaxeer1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft`.
```bash theme={null}
hyperpaxd tx bank send \
HyperPaxeer1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft \
HyperPaxeer157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq \
5000000000000000000ahpx \
--gas=200000 \
--fees=1000000ahpx \
--chain-id=hyperpax_125-4 \
--generate-only > unsignedTx.json
```
The file `unsignedTx.json` contains the unsigned transaction encoded in JSON.
```json theme={null}
{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "HyperPaxeer1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
"to_address": "HyperPaxeer157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
"amount": [
{
"denom": "ahpx",
"amount": "5000000000000000000"
}
]
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [
{
"denom": "ahpx",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": []
}
```
### Step 3: Sign individually
Sign with `test1` and `test2` and create individual signatures.
```sh theme={null}
hyperpaxd tx sign \
unsignedTx.json \
--multisig=HyperPaxeer1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
--from=test1 \
--output-document=test1sig.json \
--chain-id=hyperpax_125-4
```
```sh theme={null}
hyperpaxd tx sign \
unsignedTx.json \
--multisig=HyperPaxeer1e0fx0q9meawrcq7fmma9x60gk35lpr4xk3884m \
--from=test2 \
--output-document=test2sig.json \
--chain-id=hyperpax_125-4
```
### Step 4: Create multisignature
Combine signatures to sign transaction.
```sh theme={null}
hyperpaxd tx multisign \
unsignedTx.json \
multi \
test1sig.json test2sig.json \
--output-document=signedTx.json \
--chain-id=hyperpax_125-4
```
The TX is now signed:
```json theme={null}
{
"body": {
"messages": [
{
"@type": "/cosmos.bank.v1beta1.MsgSend",
"from_address": "HyperPaxeer1rgjxswhuxhcrhmyxlval0qa70vxwvqn2e0srft",
"to_address": "HyperPaxeer157g6rn6t6k5rl0dl57zha2wx72t633axqyvvwq",
"amount": [
{
"denom": "ahpx",
"amount": "5000000000000000000"
}
]
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [
{
"public_key": {
"@type": "/cosmos.crypto.multisig.LegacyAminoPubKey",
"threshold": 2,
"public_keys": [
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "ApCzSG8k7Tr4aM6e4OJRExN7cNtvH21L9azbh+uRrvt4"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "Ah91erz8ChNanqLe9ea948rvAiXMCRlR5Ka7EE/c0xUK"
},
{
"@type": "/cosmos.crypto.secp256k1.PubKey",
"key": "A0OjtIUCFJM3AobJ9HJTWKP9RZV2+WPcwVjLgsAidrZ/"
}
]
},
"mode_info": {
"multi": {
"bitarray": {
"extra_bits_stored": 3,
"elems": "wA=="
},
"mode_infos": [
{
"single": {
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
}
},
{
"single": {
"mode": "SIGN_MODE_LEGACY_AMINO_JSON"
}
}
]
}
},
"sequence": "1"
}
],
"fee": {
"amount": [
{
"denom": "ahpx",
"amount": "1000000"
}
],
"gas_limit": "200000",
"payer": "",
"granter": ""
}
},
"signatures": [
"CkCEeIbeGc+I1ipZuhp/0KhVNnWAv2tTlvgo5x61lzk1KHmLPV38m/YFurrFt5cm5+fqIXrn+FlOjrJuzBhw8ogYCkCawm9mpXsBHk0CFsE5618fVnvScEkfrzW0c2jCcjqV8EPuj3ut74UWzZyQkwtJGxUWtro9EgnGsB7Di1Gzizst"
]
}
```
### Step 5: Broadcast transaction
```sh theme={null}
hyperpaxd tx broadcast signedTx.json \
--chain-id=hyperpax_125-4 \
--broadcast-mode=block
```
# Pending state
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/pending-state
# Pending State
When a transaction is submitted to the Ethereum network, it first goes into the pending status, waiting to be executed
by the nodes. A transaction can be in the pending state for a longer duration if the gas price is set very low in the
transaction and the nodes are busy processing other higher gas price transactions.
During the pending state, the transaction initiator is allowed to change the transaction fields at any time. They can do
so by sending another transaction with the same nonce.
## Prerequisite Readings
* [Cosmos SDK Mempool](https://docs.cosmos.network/main/building-apps/app-mempool)
## HyperPaxeer vs Ethereum
In Ethereum, pending blocks are generated as they are queued for production by miners. These pending
blocks include pending transactions that are picked out by miners, based on the highest reward paid
in gas. This mechanism exists as block finality is not possible on the Ethereum network. Blocks are
committed with probabilistic finality, which means that transactions and blocks become less likely
to become reverted as more time (and blocks) passes.
HyperPaxeer is designed quite differently on this front as there is no concept of a "pending state".
HyperPaxeer uses [Tendermint Core](https://docs.tendermint.com/) BFT consensus which provides instant
finality for transaction. For this reason, HyperPaxeer EVM does not require a pending state mechanism, as
all (if not most) of the transactions will be committed to the next block (avg. block time on Cosmos chains is \~8s).
However, this causes a
few hiccups in terms of the Ethereum Web3-compatible queries that can be made to pending state.
Another significant difference with Ethereum, is that blocks are produced by validators or block producers, who include
transactions from their local mempool into blocks in a
first-in-first-out (FIFO) fashion. Transactions on HyperPaxeer cannot be ordered or cherry picked out from the Tendermint node
[mempool](https://docs.tendermint.com/v0.34/tendermint-core/mempool.html).
## Pending State Queries
HyperPaxeer will make queries which will account for any unconfirmed transactions present in a node's
transaction mempool. A pending state query made will be subjective and the query will be made on the
target node's mempool. Thus, the pending state will not be the same for the same query to two
different nodes.
### JSON-RPC Calls on Pending Transactions
* [`eth_getBalance`](./../../develop/api/ethereum-json-rpc/methods#eth_getbalance)
* [`eth_getTransactionCount`](./../../develop/api/ethereum-json-rpc/methods#eth_gettransactioncount)
* [`eth_getBlockTransactionCountByNumber`](./../../develop/api/ethereum-json-rpc/methods#eth_getblocktransactioncountbynumber)
* [`eth_getBlockByNumber`](./../../develop/api/ethereum-json-rpc/methods#eth_getblockbynumber)
* [`eth_getTransactionByHash`](./../../develop/api/ethereum-json-rpc/methods#eth_gettransactionbyhash)
* [`eth_getTransactionByBlockNumberAndIndex`](./../../develop/api/ethereum-json-rpc/methods#eth_gettransactionbyblockhashandindex)
* [`eth_sendTransaction`](./../../develop/api/ethereum-json-rpc/methods#eth_sendtransaction)
# Signing
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/signing
# Signing
Signing is the process of creating a digital signature using a private key to verify a transaction
on the HyperPaxeer network. The signature is created using a specific cryptographic algorithm that
ensures the authenticity and integrity of the transaction using methods like
[wallets](https://academy.evmosd.org/articles/wallet) and the [CLI](./../Paxeer-Network-cli).
There are different methods for signing, but one of the most commonly used methods is the
[EIP-712](https://eips.ethereum.org/EIPS/eip-712) standard.
HyperPaxeer leverages EIP-712 to homogenize the interaction between the EVM and Cosmos.
## EIP-712
EIP-712 introduces a standard for signing "typed-data" in a human-readable format. This standard allowed users to understand
the data they are signing more easily and provides a more secure way to sign data, as it is less susceptible to phishing
attacks. EIP-712 is not an Ethereum transaction type, but a method for signing structured data that can be used for
authentication and indirect influence on program logic.
To support signing Cosmos transactions, HyperPaxeer utilizes the EIP-712 protocol for encoding Cosmos transactions in a
format that can be understood and processed by Ethereum signers, including Ledger hardware wallets. This approach
helps to overcome the limitations of Ethereum signing devices, which often do not support signing arbitrary bytes
for security reasons.
The process works as follows:
1. A Cosmos transaction is represented as a JSON sign-doc.
2. The JSON sign-doc is converted to an EIP-712 object, which consists of types and messages.
3. The EIP-712 object is signed using an Ethereum signer, such as MetaMask or a Ledger hardware device.
4. The same process is performed on the node to verify the signature.
By using EIP-712 for signing Cosmos transactions, HyperPaxeer ensures compatibility with popular Ethereum signing tools
like MetaMask and Ledger devices as well as Keplr. This compatibility makes it easier for users to interact with both
Ethereum and Cosmos networks, ultimately fostering greater interoperability between the two ecosystems.
:::note
HyperPaxeerJS supports signing with EIP-712. More information about the library can be found [here](https://github.com/Paxeer-Network/Paxeer-Networkjs).
Supported: [Ledger support](https://academy.evmosd.org/articles/beginner/connect-your-wallet/ledger) and [CLI Commands](./../Paxeer-Network-cli/cli-commands).
:::
# Tokens
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/tokens
# Tokens
## Native token
The native token secures HyperPaxeer, pays gas, supports governance flows, and denominates validator and protocol rewards.
| Field | Value |
| ----------------- | -------------------- |
| Display symbol | `HPX` / `hpx` |
| Base denomination | `ahpx` |
| Decimals | `18` |
| Conversion | `1 hpx = 10^18 ahpx` |
HyperPaxeer uses an atto-denominated base unit to maintain parity with Ethereum-style 18-decimal tooling:
```text theme={null}
1 hpx = 1,000,000,000,000,000,000 ahpx
1 ETH = 1,000,000,000,000,000,000 wei
```
## Asset types
HyperPaxeer supports:
* Native `hpx` / `ahpx` balances
* Cosmos SDK coins, including IBC-transferred assets
* EVM tokens, including ERC-20, ERC-721, and ERC-1155 contracts
## Cosmos coins
Cosmos balances are used for staking, IBC transfers, governance deposits, and SDK-module operations. Native balances use the `ahpx` base denomination.
## EVM tokens
HyperPaxeer is EVM-compatible and supports standard Solidity token contracts. Use the EVM chain ID `125` and 18-decimal native currency configuration when integrating wallets, viem, ethers.js, Foundry, Hardhat, or other Ethereum tooling.
## Related docs
* [Current network facts](/current-network)
* [Network configuration](/configuration)
# Transactions
Source: https://sidiorresearchlabs.mintlify.app/protocol/concepts/transactions
# Transactions
A transaction refers to an action initiated by an account which changes the state of the blockchain.
To effectively perform the state change, every transaction is broadcasted to the whole network.
Any node can broadcast a request for a transaction to be executed on the blockchain state machine;
after this happens, a validator will validate, execute the transaction and propagate the resulting state change
to the rest of the network.
To process every transaction, computation resources on the network are consumed.
Thus, the concept of "gas" arises as a reference to the computation required to process the transaction by a validator.
Users have to pay a fee for this computation, all transactions require an associated fee.
This fee is calculated based on the gas required to execute the transaction and the gas price.
Additionally, a transaction needs to be signed using the sender's private key.
This proves that the transaction could only have come from the sender and was not sent fraudulently.
In a nutshell, the transaction lifecycle once a signed transaction is submitted to the network is the following:
* A transaction hash is cryptographically generated.
* The transaction is broadcasted to the network and added to a transaction pool consisting of all other pending network transactions.
* A validator must pick your transaction and include it in a block in order to verify the transaction and consider it "successful".
For a more detailed explanation of the transaction lifecyle, see [the corresponding section](https://docs.cosmos.network/main/basics/tx-lifecycle).
The transaction hash is a unique identifier and can be used to check transaction information,
for example, the events emitted, if was successful or not.
Transactions can fail for various reasons.
For example, the provided gas or fees may be insufficient.
Also, the transaction validation may fail.
Each transaction has specific conditions that must fullfil to be considered valid.
A widespread validation is that the sender is the transaction signer.
In such a case, if you send a transaction where the sender address is different than the signer's address,
the transation will fail, even if the fees are sufficient.
Nowadays, transactions can not only perform state transitions on the chain in which are submitted,
but also can execute transactions on another blockchains.
Interchain transactions are possible through the [Inter-Blockchain Communication protocol (IBC)](https://ibcprotocol.org/).
Find a more detailed explanation on the section below.
## Transaction Types
HyperPaxeer supports two transaction types:
1. Cosmos transactions
2. Ethereum transactions
This is possible because HyperPaxeer uses the [Cosmos-SDK](https://docs.cosmos.network/main)
and implements the [Ethereum Virtual Machine](https://ethereum.org/en/developers/docs/evm/) as a module.
In this way, HyperPaxeer provides the features and functionalities of Ethereum and Cosmos chains combined, and more.
Although most of the information included on both of these transaction types is similar,
there are differences among them.
An important difference, is that Cosmos transactions allow multiple messages on the same transaction.
Conversely, Ethereum transactions don't have this possibility.
To bring these two types together, HyperPaxeer implements Ethereum transactions as a single [`sdk.Msg`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#Msg)
contained in an [`auth.StdTx`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/x/auth#StdTx).
All relevant Ethereum transaction information is contained in this message.
This includes the signature, gas, payload, etc.
Find more information about these two types on the following sections.
### Cosmos Transactions
On Cosmos chains, transactions are comprised of metadata held in contexts and `sdk.Msg`s
that trigger state changes within a module through the module's Protobuf [Msg service](https://docs.cosmos.network/main/building-modules/msg-services).
When users want to interact with an application and make state changes (e.g. sending coins), they create transactions.
Cosmos transactions can have multiple `sdk.Msg`s.
Each of these must be signed using the private key associated with the appropriate account(s),
before the transaction is broadcasted to the network.
A Cosmos transaction includes the following information:
* `Msgs`: an array of msgs (`sdk.Msg`)
* `GasLimit`: option chosen by the users for how to calculate how much gas they will need to pay
* `FeeAmount`: max amount user is willing to pay in fees
* `TimeoutHeight`: block height until which the transaction is valid
* `Signatures`: array of signatures from all signers of the tx
* `Memo`: a note or comment to send with the transaction
To submit a Cosmos transaction, users must use one of the provided clients.
### Ethereum Transactions
Ethereum transactions refer to actions initiated by EOAs (externally-owned accounts, managed by humans),
rather than internal smart contract calls. Ethereum transactions transform the state of the EVM
and therefore must be broadcasted to the entire network.
Ethereum transactions also require a fee, known as `gas`. ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559))
introduced the idea of a base fee, along with a priority fee which serves as an incentive
for miners to include specific transactions in blocks.
There are several categories of Ethereum transactions:
* regular transactions: transactions from one account to another
* contract deployment transactions: transactions without a `to` address, where the contract code is sent in the `data` field
* execution of a contract: transactions that interact with a deployed smart contract,
where the `to` address is the smart contract address
An Ethereum transaction includes the following information:
* `recipient`: receiving address
* `signature`: sender's signature
* `nonce`: counter of tx number from account
* `value`: amount of ETH to transfer (in wei)
* `data`: include arbitrary data. Used when deploying a smart contract or making a smart contract method call
* `gasLimit`: max amount of gas to be consumed
* `maxPriorityFeePerGas`: mas gas to be included as tip to validators
* `maxFeePerGas`: max amount of gas to be paid for tx
For more information on Ethereum transactions and the transaction lifecycle, [go here](https://ethereum.org/en/developers/docs/transactions/).
HyperPaxeer supports the following Ethereum transactions.
:::tip
**Note**: Unprotected legacy transactions are not supported by default.
:::
* Dynamic Fee Transactions ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559))
* Access List Transactions ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930))
* Legacy Transactions ([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718))
HyperPaxeer is capable of processing Ethereum transactions by wrapping them on a `sdk.Msg`.
HyperPaxeer achieves this by using the `MsgEthereumTx`.
This message encapsulates an Ethereum transaction as an SDK message and contains the necessary transaction data fields.
One remark about the `MsgEthereumTx` is that it implements both the `sdk.Msg` and `sdk.Tx` interfaces
(generally SDK messages only implement the former, while the latter is a group of messages bundled together).
The reason of this, is because the `MsgEthereumTx` must not be included in a `auth.StdTx`
(SDK's standard transaction type) as it performs gas and fee checks using the Ethereum logic
from Geth instead of the Cosmos SDK checks done on the auth module `AnteHandler`.
#### Ethereum Tx Type
There are three types of transaction types used in HyperPaxeer's [Go Ethereum](https://github.com/ethereum/go-ethereum/blob/b946b7a13b749c99979e312c83dce34cac8dd7b1/core/types/transaction.go#L43-L48)
implementation that came from Ethereum Improvement Proposals(EIPs):
1. LegacyTxType (EIP-155):
The LegacyTxType represents the original transaction format that existed before Ethereum Improvement Proposal (EIP) 155.
These transactions do not include a chain ID, which makes them vulnerable to replay attacks. EIP-155 was introduced
to solve this problem by incorporating a chain ID, which uniquely identifies a specific Ethereum chain to prevent
cross-chain replay attacks.
2. AccessListTxType (EIP-2930):
AccessListTxType was introduced with EIP-2930 as part of the Berlin upgrade. This new transaction type allows users to
specify an access list β a list of addresses and storage keys that the transaction plans to access. The primary goal
of access lists is to mitigate some of the gas cost increases introduced with EIP-2929, which increased gas costs
for state access operations to improve denial-of-service (DoS) attack resistance. By specifying an access list, users
can avoid paying higher gas costs for subsequent accesses to the same addresses and storage keys within the same transaction.
3. DynamicFeeTxType (EIP-1559):
DynamicFeeTxType was introduced with EIP-1559 as part of the London upgrade. This transaction type brought significant
changes to Ethereum's fee market, with the aim of making gas fees more predictable and improving user experience.
EIP-1559 transactions include two main components: a base fee and a priority fee (or tip). The base fee is algorithmically
determined by the network, while the priority fee is set by users to incentivize miners to include their transaction.
The base fee is burned, effectively reducing the overall ETH supply, while the priority fee goes to miners as a reward
for their work. DynamicFeeTxType transactions allow for more predictable and efficient gas fee management.
These transaction types represent Ethereum's continuous evolution and improvements to its network, helping address
challenges related to scalability, security, and user experience.
### Interchain Transactions
Interchain transactions refer to the transfer of digital assets or data between two or more different blockchain networks.
Each blockchain network has its own unique protocol and data structure,
making it difficult to directly transfer assets or data from one blockchain to another.
Interchain transactions allow for the transfer of assets and data between different blockchains
by using intermediary mechanisms or protocols.
One such mechanism is a cross-chain bridge, which acts as a connector between different blockchains,
enabling the transfer of assets or data.
Cross-chain bridges typically require some form of trust or
consensus mechanism to ensure the security and integrity of the transaction.
Another possibility is to use the [IBC (Inter-Blockchain Communication)](https://ibcprotocol.org/) protocol.
To make an interchain transaction using IBC a user needs to:
* Choose the source and destination blockchain networks that the user wants to transfer assets or data between.
* Ensure that both blockchain networks have implemented the IBC protocol
* Ensure there's a connection and channel established between the two blockchain networks using IBC
* Initiate the transfer of assets or data: this is done by sending a transaction from the source blockchain
to the destination blockchain through the IBC channel
Interchain transactions are becoming increasingly important as the number of different blockchain networks
and applications continues to grow.
They enable the interoperability of different blockchain networks,
allowing for greater flexibility and efficiency in the transfer of digital assets and data.
## Transaction Receipts
A transaction receipt shows data returned by an Ethereum client to represent the result of a particular transaction,
including a hash of the transaction, its block number, the amount of gas used, and,
in case of deployment of a smart contract, the address of the contract.
Additionally, it includes custom information from the events emitted in the smart contract.
A receipt contains the following information:
* `transactionHash` : hash of the transaction.
* `transactionIndex`: integer of the transactions index position in the block.
* `blockHash`: hash of the block where this transaction was in.
* `blockNumber`: block number where this transaction was in.
* `from`: address of the sender.
* `to`: address of the receiver. null when its a contract creation transaction.
* `cumulativeGasUsed` : The total amount of gas used when this transaction was executed in the block.
* `effectiveGasPrice` : The sum of the base fee and tip paid per unit of gas.
* `gasUsed` : The amount of gas used by this specific transaction alone.
* `contractAddress` : The contract address created, if the transaction was a contract creation, otherwise null.
* `logs`: Array of log objects, which this transaction generated.
* `logsBloom`: Bloom filter for light clients to quickly retrieve related logs.
* `type`: integer of the transaction type, 0x00 for legacy transactions, 0x01 for access list types,
0x02 for dynamic fees. It also returns either.
* `root` : transaction stateroot (pre Byzantium)
* `status`: either 1 (success) or 0 (failure)
# Faq
Source: https://sidiorresearchlabs.mintlify.app/protocol/faq
# Frequently Asked Questions
## Concepts
What is the difference between "secp256k1" and "ed25519"?
secp256k1 and ed25519 are both popular cryptographic algorithms used for digital signatures and key generation, but
they have some differences in terms of security, performance, and compatibility with different systems.
secp256k1 is an elliptic curve algorithm that is widely used in Bitcoin and many other cryptocurrencies. It provides
128-bit security, which is considered sufficient for most practical purposes. secp256k1 is relatively fast and
efficient, making it a good choice for applications that require high performance. It is widely supported by most
cryptographic libraries and software, which makes it a good choice for cross-platform applications.
ed25519 is a newer elliptic curve algorithm that provides 128-bit security, similar to secp256k1. However, ed25519 is
generally considered to be more secure than secp256k1, due to its resistance to certain types of attacks such as
[side-channel attacks](https://en.wikipedia.org/wiki/Side-channel_attack). It is also faster than many other elliptic
curve algorithms, including secp256k1, making it a good choice for applications that require high performance.
In terms of compatibility, secp256k1 is more widely supported by existing systems, while ed25519 is less widely
supported. However, ed25519 is gaining popularity, and is supported by many cryptographic libraries and software.
When choosing between secp256k1 and ed25519, you should consider your specific needs in terms of security, performance,
and compatibility. If you are building an application that requires high performance and compatibility with existing
systems, secp256k1 may be a better choice. However, if you are building an application that requires a higher level
of security and performance, and you can afford to sacrifice some compatibility, ed25519 may be a better choice.
Where can I find the Protobuf interfaces for HyperPaxeer?
Head over to our [Buf](https://buf.build/Paxeer-Network).
# Ibc channels
Source: https://sidiorresearchlabs.mintlify.app/protocol/ibc-channels
# IBC Channels
IBC channels are a key component of the Inter-blockchain Communication (IBC) protocol used in the Cosmos ecosystem.
IBC channels enable communication between different Cosmos chains,
allowing the transfer of tokens and data between them.
Each IBC channel has a unique identifier known as the channel ID,
which is used to specify the source and destination of a transfer.
The channel ID can change depending on which relayers are active, so it's important to
double-check the channel IDs before making a transfer.
:::tip
You can also view a full list of IBC Relayers and Channels on [Mintscan](https://www.mintscan.io/Paxeer-Network/relayers)
:::
# Protocol
Source: https://sidiorresearchlabs.mintlify.app/protocol/index
Technical architecture and core network design.
# Technical Architecture
HyperPaxeer is a capital orchestration network built as part of the Alexandria Fork upgrade, migrating validators from the original HyperPaxeer (geth PoS, chain ID 229) to this new high-throughput Proof-of-Stake EVM blockchain (chain ID 125).
It is built using the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/)
which runs on top of the [CometBFT](https://github.com/cometbft/cometbft)
consensus engine, providing full Ethereum compatibility and interoperability
with instant deterministic finality and sub-second block production.
## Network Information
| Parameter | Value |
| -------------------- | ----------------------------------- |
| Chain ID (Cosmos) | `hyperpax_125-1` |
| EVM Chain ID | `125` |
| Token Symbol | `HPX` / `hpx` |
| Base Denomination | `ahpx` |
| Display Denomination | `hpx` |
| Decimals | `18` |
| Bech32 Prefix | `pax` |
| RPC Endpoint | `https://public-rpc.paxeer.app/rpc` |
| Block Explorer | [paxscan.io](https://paxscan.io) |
This architecture allows users to perform both Cosmos and EVM formatted transactions,
developers to scale EVM dApps cross-chain via [IBC](https://cosmos.network/ibc),
and tokens and assets in the network to come from different independent sources.
HyperPaxeer enables these key features by:
* Leveraging [modules](https://docs.cosmos.network/v0.47/build/building-modules/intro)
and other mechanisms implemented by the [Cosmos SDK](https://docs.cosmos.network/).
* Implementing CometBFT's Application Blockchain Interface ([ABCI](https://docs.tendermint.com/master/spec/abci/))
to manage the blockchain.
* Utilizing [`geth`](https://github.com/ethereum/go-ethereum) as a library to promote code reuse and improve maintainability.
* Exposing a fully compatible Web3 [JSON-RPC](./../develop/api/ethereum-json-rpc/methods) layer
for interacting with existing Ethereum clients and tooling (Metamask, Remix, Truffle, etc).
The sum of these features allows developers to leverage existing Ethereum ecosystem tooling and
software to seamlessly deploy smart contracts which interact with the rest of the Cosmos
[ecosystem](https://cosmos.network/ecosystem).
## Cosmos SDK
HyperPaxeer enables the full composability and modularity of the [Cosmos SDK](https://docs.cosmos.network/).
As a Cosmos chain, HyperPaxeer is a sovereign blockchain with its own native token,
that can connect to other chains through IBC. It includes standard modules from the Cosmos SDK,
that work side to side with HyperPaxeer-specific modules, built by the HyperPaxeer core development team.
Check out the [list of modules](modules/index.md) to get an overview of what each module is responsible for.
## CometBFT & ABCI
[CometBFT](https://github.com/cometbft/cometbft) consists of two chief technical components:
a blockchain consensus engine and a generic application interface.
The consensus engine ensures that the same transactions
are recorded on every machine in the same order.
The application interface, called the [Application Blockchain Interface (ABCI)](https://docs.tendermint.com/master/spec/abci/),
enables the transactions to be processed in any programming language.
CometBFT has evolved to be a general-purpose blockchain consensus engine that
can host arbitrary application states. Since it can replicate arbitrary
applications, it can be used as a plug-and-play replacement for the consensus
engines of other blockchains. HyperPaxeer is an example of an ABCI application
replacing Ethereum's PoW via CometBFT's consensus engine.
Another example of a cryptocurrency application built on CometBFT is the Cosmos
network. CometBFT can decompose the blockchain design by offering a very
simple API (ie. the ABCI) between the application process and consensus process.
## EVM Compatibility
HyperPaxeer enables EVM compatibility by implementing various components
that together support all the EVM state transitions
while ensuring the same developer experience as Ethereum:
* Ethereum's transaction format as a Cosmos SDK `Tx` and `Msg` interface
* Ethereum's `secp256k1` curve for the Cosmos Keyring
* `StateDB` interface for state updates and queries
* [JSON-RPC](../develop/api/ethereum-json-rpc) client for interacting with the EVM
Most components are implemented in the [EVM module](modules/evm.md)
To achieve a seamless developer UX, however, some of the components are implemented
outside of the module.
If you want to learn more about how HyperPaxeer achieves EVM compatibility as a Cosmos chain,
we recommend understanding the following concepts:
* [Accounts](./concepts/accounts.md)
* [Gas and Fees](./concepts/gas-and-fees.md)
* [Token representations](./concepts/tokens.md)
* [Transactions](./concepts/transactions.md)
## Contributing
There are several ways to contribute to the HyperPaxeer core protocol. To get some hands-on experience,
we recommend you spin up a local node using the [Paxeer CLI](./paxeer-cli)
and interact with it through queries and transactions using the supported [clients](../develop/api#clients).
Then if you're hooked you can
* Contribute open-source to [issues on GitHub](https://github.com/paxeer-network/PaxeerNetwork-Alexandria-Fork/issues)
using the [Contributor Guidelines](https://github.com/paxeer-network/PaxeerNetwork-Alexandria-Fork/blob/main/CONTRIBUTING.md)
* Search for [bugs and earn a bounty](bugs.md)
# Metrics
Source: https://sidiorresearchlabs.mintlify.app/protocol/metrics
# Metrics
HyperPaxeer nodes can enable [Cosmos SDK telemetry](https://docs.cosmos.network/main/learn/advanced/telemetry)
to allow for observing and gathering insights about the HyperPaxeer application.
Under the hood, it uses the [`go-metrics`](https://github.com/hashicorp/go-metrics) package
and the Prometheus client library to expose different [types of metrics](https://prometheus.io/docs/concepts/metric_types/)
like gauges and counters.
For best practices on how to use different metrics types,
check this [blog article](https://blog.pvincent.io/2017/12/prometheus-blog-series-part-2-metric-types/).
Find below a list of supported HyperPaxeer modules with custom metrics and telemetry.
Using the metrics you can e.g. run performance profiles
and display them in a [Grafana](https://grafana.com/) dashboard.
## Supported Metrics
| Metric | Description | Unit | Type |
| :--------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | :------- | :-------- |
| `feemarket_base_fee` | Amount of base fee per EIP-1559 block | token | gauge |
| `feemarket_block_gas` | Amount of gas used in an EIP-1559 block | token | gauge |
| `erc20_ibc_on_recv_total` | Total amount of times an IBC coin was autoconverted to an ERC20 token in the ibc `onRecvPacket` callback | transfer | counter |
| `erc20_ibc_err_total` | Total amount of times an IBC coin autoconvertion to ERC20 token failed during an ibc transaction | transfer | counter |
| `erc20_ibc_transfer_total` | Total amount of times an IBC coin or its ERC20 representation was transferred via ibc (outgoing transaction) | transfer | counter |
| `tx_msg_convert_coin_amount_total` | Total amount of converted coins using a `ConvertCoin` msg | token | counter |
| `tx_msg_convert_coin_total` | Total number of txs with a `ConvertCoin` msg | tx | counter |
| `tx_msg_convert_erc20_amount_total` | Total amount of converted erc20 using a `ConvertERC20` msg | token | counter |
| `tx_msg_convert_erc20_total` | Total number of txs with a `ConvertERC20` msg | tx | counter |
| `tx_msg_ethereum_tx_total` | Total number of txs processed via the EVM | tx | counter |
| `tx_msg_ethereum_tx_gas_used_total` | Total amount of gas used by an ethereum tx | gas | counter |
| `tx_msg_ethereum_tx_gas_limit_per_gas_used` | Ratio of gas limit to gas used for an ethereum tx | ratio | gauge |
| `tx_msg_ethereum_tx_incentives_total` | Total number of txs with an incentivized contract processed via the EVM | tx | counter |
| `tx_msg_ethereum_tx_incentives_gas_used_total` | Total amount of gas used by txs with an incentivized contract processed via the EVM | gas | counter |
| `inflation_allocate_total` | Total amount of tokens allocated through inflation | token | counter |
| `inflation_allocate_staking_total` | Total amount of tokens allocated through inflation to staking | token | counter |
| `inflation_allocate_incentives_total` | Total amount of tokens allocated through inflation to incentives | token | counter |
| `inflation_allocate_community_pool_total` | Total amount of tokens allocated through inflation to community pool | token | counter |
| `tx_create_clawback_vesting_account_gas_used` | Total amount of gas used by a `CreateClawbackVestingAccount` msg | gas | counter |
| `tx_fund_vesting_account_gas_used` | Total amount of gas used by a `FundVestingAccount` msg | gas | counter |
| `tx_clawback_gas_used` | Total amount of gas used by a `Clawback` msg | gas | counter |
| `tx_update_vesting_funder_gas_used` | Total amount of gas used by a `UpdateVestingFunder` msg | gas | counter |
| `epochs_begin_blocker` | Time spent during `BeginBlocker` of the `x/epochs` module | ms | histogram |
| `burned_tx_fee_amount` | Total amount of fees burned on a tx | token | counter |
# Module accounts
Source: https://sidiorresearchlabs.mintlify.app/protocol/module-accounts
# Module Accounts
Some modules have their own module account. Think of this as a wallet that can only be controlled by that module.
Below is a table of modules, their respective wallet addresses and permissions:
## List of Module Accounts
| Name | Address | Permissions |
| :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- |
| `erc20` | [HyperPaxeer1glht96kr2rseywuvhhay894qw7ekuc4qg9z5nw](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1glht96kr2rseywuvhhay894qw7ekuc4qg9z5nw) | `minter` `burner` |
| `fee_collector` | [HyperPaxeer17xpfvakm2amg962yls6f84z3kell8c5ljcjw34](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network17xpfvakm2amg962yls6f84z3kell8c5ljcjw34) | `none` |
| `inflation` | [HyperPaxeer1d4e35hk3gk4k6t5gh02dcm923z8ck86qygxf38](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1d4e35hk3gk4k6t5gh02dcm923z8ck86qygxf38) | `minter` |
| `transfer` | [HyperPaxeer1yl6hdjhmkf37639730gffanpzndzdpmhv788dt](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1yl6hdjhmkf37639730gffanpzndzdpmhv788dt) | `minter` `burner` |
| `bonded_tokens_pool` | [HyperPaxeer1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3h6cprl](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1fl48vsnmsdzcv85q5d2q4z5ajdha8yu3h6cprl) | `burner` `staking` |
| `not_bonded_tokens_pool` | [HyperPaxeer1tygms3xhhs3yv487phx3dw4a95jn7t7lr6ys4t](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1tygms3xhhs3yv487phx3dw4a95jn7t7lr6ys4t) | `burner` `staking` |
| `gov` | [HyperPaxeer10d07y265gmmuvt4z0w9aw880jnsr700jcrztvm](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network10d07y265gmmuvt4z0w9aw880jnsr700jcrztvm) | `burner` |
| `distribution` | [HyperPaxeer1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8974jnh](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8974jnh) | `none` |
| `evm` | [HyperPaxeer1vqu8rska6swzdmnhf90zuv0xmelej4lq0n56wq](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1vqu8rska6swzdmnhf90zuv0xmelej4lq0n56wq) | `minter` `burner` |
| `ibc` | [HyperPaxeer1a53udazy8ayufvy0s434pfwjcedzqv345dnt3x](https://www.mintscan.io/Paxeer-Network/account/Paxeer-Network1a53udazy8ayufvy0s434pfwjcedzqv345dnt3x) | `minter` `burner` |
## Account Permissions
* The `burner` permission means this account has the permission to burn or destroy tokens.
* The `minter` permission means this account has permission to mint or create new tokens.
* The `staking` permission means this account has permission to stake tokens on behalf of its owner.
## IBC Module Accounts
Additionally, there are module accounts associated with IBC transfers.
For each IBC connection, there's an account of type `ModuleAccount` used to escrow the transferred coins
when HyperPaxeer is the source chain.
Their addresses are derived using the first 20 bytes of the SHA256 checksum of the account name and following the format
as outlined in [ADR 028](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-028-public-key-addresses.md):
```go theme={null}
// accountName is composed by the current version the IBC transfer module supports (in this case, ics20-1), the portID (transfer) and the channelID
accountName := Version + "\0" + portID + "/" + channelID
addr := sha256.Sum256(accountName)[:20]
// example for channel-0
addr := sha256.Sum256("ics20-1\0transfer/channel-0")[:20]
```
This can be calculated with the [`GetEscrowAccount` function on IBC-go](https://github.com/cosmos/ibc-go/blob/c56f78905a5d2db01d867381d106c403fa9e5c4b/modules/apps/transfer/types/keys.go#L41-L55).
:::tip
**Note**: These escrow accounts are not listed when performing the query:
```shell theme={null}
hyperpaxd q auth module-accounts
```
This happens because the [`GetModuleAccount` function](https://github.com/cosmos/cosmos-sdk/blob/74d7a0dfcd9f47d8a507205f82c264a269ef0612/x/auth/keeper/keeper.go#L194-L224)
used on the query considers only the accounts on the [`permAddrs` map of the `AccountKeeper`](https://github.com/cosmos/cosmos-sdk/blob/74d7a0dfcd9f47d8a507205f82c264a269ef0612/x/auth/keeper/keeper.go#L54-L68).
This address map is set at compile time and cannot be changed on runtime.
:::
# Epochs
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/epochs
# `epochs`
## Abstract
This document specifies the internal `x/epochs` module of the HyperPaxeer Hub.
Often, when working with the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk),
we would like to run certain pieces of code every so often.
The purpose of the `epochs` module is to allow other modules to maintain
that they would like to be signaled once in a time period.
So, another module can specify it wants to execute certain code once a week, starting at UTC-time = x.
`epochs` creates a generalized epoch interface to other modules so they can be more easily signaled upon such events.
## Contents
1. **[Concept](#concepts)**
2. **[State](#state)**
3. **[Events](#events)**
4. **[Keeper](#keepers)**
5. **[Hooks](#hooks)**
6. **[Queries](#queries)**
7. **[Future improvements](#future-improvements)**
## Concepts
The `epochs` module defines on-chain timers that execute at fixed time intervals.
Other HyperPaxeer modules can then register logic to be executed at the timer ticks.
We refer to the period in between two timer ticks as an "epoch".
Every timer has a unique identifier, and every epoch will have a start time and an end time,
where `end time = start time + timer interval`.
## State
### State Objects
The `x/epochs` module keeps the following `objects in state`:
| State Object | Description | Key | Value | Store |
| ------------ | ------------------- | -------------------- | ------------------- | ----- |
| `EpochInfo` | Epoch info bytecode | `[]byte{identifier}` | `[]byte{epochInfo}` | KV |
#### EpochInfo
An `EpochInfo` defines several variables:
1. `identifier` keeps an epoch identification string
2. `start_time` keeps the start time for epoch counting:
if block height passes `start_time`, then `epoch_counting_started` is set
3. `duration` keeps the target epoch duration
4. `current_epoch` keeps the current active epoch number
5. `current_epoch_start_time` keeps the start time of the current epoch
6. `epoch_counting_started` is a flag set with `start_time`, at which point `epoch_number` will be counted
7. `current_epoch_start_height` keeps the start block height of the current epoch
```protobuf theme={null}
message EpochInfo {
string identifier = 1;
google.protobuf.Timestamp start_time = 2 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"start_time\""
];
google.protobuf.Duration duration = 3 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true,
(gogoproto.jsontag) = "duration,omitempty",
(gogoproto.moretags) = "yaml:\"duration\""
];
int64 current_epoch = 4;
google.protobuf.Timestamp current_epoch_start_time = 5 [
(gogoproto.stdtime) = true,
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"current_epoch_start_time\""
];
bool epoch_counting_started = 6;
reserved 7;
int64 current_epoch_start_height = 8;
}
```
The `epochs` module keeps these `EpochInfo` objects in state, which are initialized at genesis
and are modified on begin blockers or end blockers.
#### Genesis State
The `x/epochs` module's `GenesisState` defines the state necessary for initializing the chain
from a previously exported height.
It contains a slice containing all the `EpochInfo` objects kept in state:
```go theme={null}
// Genesis State defines the epoch module's genesis state
type GenesisState struct {
// list of EpochInfo structs corresponding to all epochs
Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
```
## Events
The `x/epochs` module emits the following events:
### BeginBlocker
| Type | Attribute Key | Attribute Value |
| ------------- | ---------------- | ---------------- |
| `epoch_start` | `"epoch_number"` | `{epoch_number}` |
| `epoch_start` | `"start_time"` | `{start_time}` |
### EndBlocker
| Type | Attribute Key | Attribute Value |
| ----------- | ---------------- | ---------------- |
| `epoch_end` | `"epoch_number"` | `{epoch_number}` |
## Keepers
The `x/epochs` module only exposes one keeper, the epochs keeper, which can be used to manage epochs.
### Epochs Keeper
Presently only one fully-permissioned epochs keeper is exposed,
which has the ability to both read and write the `EpochInfo` for all epochs,
and to iterate over all stored epochs.
```go theme={null}
// Keeper of epoch nodule maintains collections of epochs and hooks.
type Keeper struct {
cdc codec.Codec
storeKey storetypes.StoreKey
hooks types.EpochHooks
}
```
```go theme={null}
// Keeper is the interface for epoch module keeper
type Keeper interface {
// GetEpochInfo returns epoch info by identifier
GetEpochInfo(ctx sdk.Context, identifier string) types.EpochInfo
// SetEpochInfo set epoch info
SetEpochInfo(ctx sdk.Context, epoch types.EpochInfo)
// DeleteEpochInfo delete epoch info
DeleteEpochInfo(ctx sdk.Context, identifier string)
// IterateEpochInfo iterate through epochs
IterateEpochInfo(ctx sdk.Context, fn func(index int64, epochInfo types.EpochInfo) (stop bool))
// Get all epoch infos
AllEpochInfos(ctx sdk.Context) []types.EpochInfo
}
```
## Hooks
The `x/epochs` module implements hooks so that other modules can use epochs
to allow facets of the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) to run on specific schedules.
### Hooks Implementation
```go theme={null}
// combine multiple epoch hooks, all hook functions are run in array sequence
type MultiEpochHooks []types.EpochHooks
// AfterEpochEnd is called when epoch is going to be ended, epochNumber is the
// number of epoch that is ending
func (mh MultiEpochHooks) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {...}
// BeforeEpochStart is called when epoch is going to be started, epochNumber is
// the number of epoch that is starting
func (mh MultiEpochHooks) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64) {...}
// AfterEpochEnd executes the indicated hook after epochs ends
func (k Keeper) AfterEpochEnd(ctx sdk.Context, identifier string, epochNumber int64) {...}
// BeforeEpochStart executes the indicated hook before the epochs
func (k Keeper) BeforeEpochStart(ctx sdk.Context, identifier string, epochNumber int64) {...}
```
### Recieving Hooks
When other modules (outside of `x/epochs`) recieve hooks,
they need to filter the value `epochIdentifier`, and only do executions for a specific `epochIdentifier`.
The filtered values from `epochIdentifier` could be stored in the `Params` of other modules,
so they can be modified by governance.
Governance can change epoch periods from `week` to `day` as needed.
## Queries
The `x/epochs` module provides the following queries to check the module's state.
```protobuf theme={null}
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {}
// CurrentEpoch provide current epoch of specified identifier
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {}
}
```
## Future Improvements
### Correct Usage
In the current design, each epoch should be at least two blocks, as the start block should be different from the endblock.
Because of this, the time allocated to each epoch will be `max(block_time x 2, epoch_duration)`.
For example: if the `epoch_duration` is set to `1s`, and `block_time` is `5s`, actual epoch time should be `10s`.
It is recommended to configure `epoch_duration` to be more than two times the `block_time`, to use this module correctly.
If there is a mismatch between the `epoch_duration` and the actual epoch time, as in the example above,
then module logic could become invalid.
### Block-Time Drifts
This implementation of the `x/epochs` module has block-time drifts based on the value of `block_time`.
For example: if we have an epoch of 100 units that ends at `t=100`,
and we have a block at `t=97` and a block at `t=104` and `t=110`, this epoch ends at `t=104`,
and the new epoch will start at `t=110`.
There are time drifts here, varying about 1-2 blocks time, which will slow down epochs.
# Erc20
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/erc20
# `erc20`
:::tip
**Note:** Working on a governance proposal related to the ERC-20 Module?
Make sure to look at [HyperPaxeer Governance](https://academy.evmosd.org/articles/governance/),
and specifically the [best practices](https://academy.evmosd.org/articles/governance/best-practices).
:::
## Abstract
This document specifies the internal `x/erc20` module of the HyperPaxeer Hub.
The `x/erc20` module enables the HyperPaxeer Hub to support a trustless, on-chain bidirectional internal conversion of tokens
between HyperPaxeer' EVM and Cosmos runtimes, specifically the `x/evm` and `x/bank` modules.
This allows token holders on HyperPaxeer to instantaneously convert their native Cosmos `sdk.Coins`
(in this document referred to as "Coin(s)") to ERC-20 (aka "Token(s)") and vice versa,
while retaining fungibility with the original asset on the issuing environment/runtime (EVM or Cosmos)
and preserving ownership of the ERC-20 contract.
This conversion functionality is fully governed by native HyperPaxeer token holders
who manage the canonical `TokenPair` registrations (ie, ERC20 ββ Coin mappings).
This governance functionality is implemented using the Cosmos-SDKΒ `gov`Β module
with custom proposal types for registering and updating the canonical mappings respectively.
Why is this important? Cosmos and the EVM are two runtimes that are not compatible by default.
The native Cosmos Coins cannot be used in applications that require the ERC-20 standard.
Cosmos coins are held on the `x/bank` module (with access to module methods like querying the supply or balances)
and ERC-20 Tokens live on smart contracts.
This problem is similar to [wETH](https://coinmarketcap.com/alexandria/article/what-is-wrapped-ethereum-weth),
with the difference, that it not only applies to gas tokens (like HyperPaxeer),
but to all Cosmos Coins (IBC vouchers, staking and gov coins, etc.) as well.
With the `x/erc20` users on HyperPaxeer can
* use existing native cosmos assets (like OSMO or ATOM) on EVM-based chains, e.g.
for Trading IBC tokens on DeFi protocols, buying NFT, etc.
* transfer existing tokens on Ethereum and other EVM-based chains to HyperPaxeer
to take advantage of application-specific chains in the Cosmos ecosystem
* build new applications that are based on ERC-20 smart contracts and have access to the Cosmos ecosystem.
## Contents
1. **[Concepts](#concepts)**
2. **[State](#state)**
3. **[State Transitions](#state-transitions)**
4. **[Transactions](#transactions)**
5. **[Hooks](#hooks)**
6. **[Events](#events)**
7. **[Parameters](#parameters)**
8. **[Clients](#clients)**
## Concepts
### Token Pair
The `x/erc20` module maintains a canonical one-to-one mapping of native Cosmos Coin denomination
to ERC20 Token contract addresses (i.e `sdk.Coin` ββ ERC20), called `TokenPair`.
The conversion of the ERC20 tokens ββ Coin of a given pair can be enabled or disabled via governance.
### Token Pair Registration
Users can register a new token pair proposal through the governance module
and initiate a vote to include the token pair in the module.
Depending on which exists first, the coin or the token,
you can either register a Cosmos Coin or a ERC20 Token to create a token pair.
One proposal can inculde several token pairs.
When the proposal passes, the erc20 module registers the Cosmos Coin and ERC20 Token mapping on the application's store.
#### Registration of a Cosmos Coin
A native Cosmos Coin corresponds to an `sdk.Coin` that is native to the bank module.
It can be either the native staking/gas denomination (e.g. HyperPaxeer, ATOM, etc)
or an IBC fungible token voucher (i.e. with denom format of `ibc/{hash}`).
When a proposal is initiated for an existing native Cosmos Coin,
the erc20 module will deploy a factory ERC20 contract,
representing the ERC20 token for the token pair,
giving the module ownership of that contract.
#### Registration of an ERC20 token
A proposal for an existing (i.e already deployed) ERC20 contract can be initiated too.
In this case, the ERC20 maintains the original owner of the contract
and uses an escrow & mint / burn & unescrow mechanism similar to the one defined by the
[ICS20 - Fungible Token Transfer](https://github.com/cosmos/ibc/blob/master/spec/app/ics-020-fungible-token-transfer)
specification.
The token pair is composed of the original ERC20 token and a corresponding native Cosmos coin denomination.
#### Token details and metadata
Coin metadata is derived from the ERC20 token details (name, symbol, decimals) and vice versa.
A special case is also described below that for the ERC20 representation of IBC fungible token (ICS20) vouchers.
#### Coin Metadata to ERC20 details
During the registration of a Cosmos Coin the following bank `Metadata` is used to deploy a ERC20 contract:
* **Name**
* **Symbol**
* **Decimals**
The native Cosmos Coin contains a more extensive metadata than the ERC20
and includes all necessary details for the conversion into a ERC20 Token,
which requires no additional population of data.
#### IBC voucher Metadata to ERC20 details
IBC vouchers should comply to the following standard:
* **Name**: `{NAME} channel-{channel}`
* **Symbol**: `ibc{NAME}-{channel}`
* **Decimals**: derived from bank `Metadata`
#### ERC20 details to Coin Metadata
During the Registration of an ERC20 Token the Coin metadata is derived from the ERC20 metadata and the bank metadata:
* **Description**: `Cosmos coin token representation of {contractAddress}`
* **DenomUnits**:
* Coin: `0`
* ERC20: `{uint32(erc20Data.Decimals)}`
* **Base**: `{"erc20/%s", address}`
* **Display**: `{erc20Data.Name}`
* **Name**: `{types.CreateDenom(strContract)}`
* **Symbol:** `{erc20Data.Symbol}`
### Token Pair Modifiers
A valid token pair can be modified through several governance proposals.
The internal conversion of a token pair can be toggled with `ToggleTokenConversionProposal`,
so that the conversions between the token pair's tokens can be enabled or disabled.
### Token Conversion
Once a token pair proposal passes, the module allows for the conversion of that token pair.
Holders of native Cosmos coins and IBC vouchers on the HyperPaxeer chain can convert their Coin into ERC20 Tokens,
which can then be used in HyperPaxeer EVM, by creating a `ConvertCoin` Tx.
Vice versa, the `ConvertERC20` Tx allows holders of ERC20 tokens on the HyperPaxeer chain
to convert ERC-20 tokens back to their native Cosmos Coin representation.
Depending on the ownership of the ERC20 contract,
the ERC20 tokens either follow a burn/mint or a transfer/escrow mechanism during conversion.
### Malicious Contracts
The ERC20 standard is an interface that defines a set of method signatures (name, arguments and output)
without defining its methods' internal logic.
Therefore it is possible for developers to deploy contracts that contain hidden malicious behaviour within those methods.
For instance, the ERC20 `transfer` method,
which is responsible for sending an `amount` of tokens to a given `recipient` could include code
to siphon some amount of tokens intended for the recipient into a different predefined account,
which is owned by the malicious contract deployer.
More sophisticated malicious implementations
might also inherit code from customized ERC20 contracts that include malicous behaviour.
For an overview of more extensive examples,
please review the x/erc20 audit, section `IF-HyperPaxeer-06: IERC20 Contracts may execute arbitrary code`.
As the `x/erc20` module allows any arbitrary ERC20 contract to be registered through governance,
it is essential that the proposer or the voters manually verify during voting phase
that the proposed contract uses the default ERC20.sol implementation.
Here are our recommendations for the reviewing process:
* contract solidity code should be verified and accessable (e.g. using an explorer)
* contract should be audited by a reputabele auditor
* inherited contracts need to be verified for correctness
## State
### State Objects
The `x/erc20` module keeps the following objects in state:
| State Object | Description | Key | Value | Store |
| ------------------ | ---------------------------------------------- | --------------------------- | ------------------- | ----- |
| `TokenPair` | Token Pair bytecode | `[]byte{1} + []byte(id)` | `[]byte{tokenPair}` | KV |
| `TokenPairByERC20` | Token Pair id bytecode by erc20 contract bytes | `[]byte{2} + []byte(erc20)` | `[]byte(id)` | KV |
| `TokenPairByDenom` | Token Pair id bytecode by denom string | `[]byte{3} + []byte(denom)` | `[]byte(id)` | KV |
#### Token Pair
One-to-one mapping of native Cosmos coin denomination to ERC20 token contract addresses (i.e `sdk.Coin` ββ ERC20).
```go theme={null}
type TokenPair struct {
// address of ERC20 contract token
Erc20Address string `protobuf:"bytes,1,opt,name=erc20_address,json=erc20Address,proto3" json:"erc20_address,omitempty"`
// cosmos base denomination to be mapped to
Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom,omitempty"`
// shows token mapping enable status
Enabled bool `protobuf:"varint,3,opt,name=enabled,proto3" json:"enabled,omitempty"`
// ERC20 owner address ENUM (0 invalid, 1 ModuleAccount, 2 external address
ContractOwner Owner `protobuf:"varint,4,opt,name=contract_owner,json=contractOwner,proto3,enum=HyperPaxeer.erc20.v1.Owner" json:"contract_owner,omitempty"`
}
```
#### Token pair ID
The unique identifier of a `TokenPair` is obtained by obtaining the SHA256 hash of the ERC20 hex contract address
and the Coin denomination using the following function:
```tsx theme={null}
tokenPairId = sha256(erc20 + "|" + denom)
```
#### Token Origin
The `ConvertCoin` and `ConvertERC20` functionalities use the owner field to check
whether the token being used is a native Coin or a native ERC20.
The field is based on the token registration proposal type (`RegisterCoinProposal` = 1, `RegisterERC20Proposal` = 2).
The `Owner` enumerates the ownership of a ERC20 contract.
```go theme={null}
type Owner int32
const (
// OWNER_UNSPECIFIED defines an invalid/undefined owner.
OWNER_UNSPECIFIED Owner = 0
// OWNER_MODULE erc20 is owned by the erc20 module account.
OWNER_MODULE Owner = 1
// EXTERNAL erc20 is owned by an external account.
OWNER_EXTERNAL Owner = 2
)
```
The `Owner` can be checked with the following helper functions:
```go theme={null}
// IsNativeCoin returns true if the owner of the ERC20 contract is the
// erc20 module account
func (tp TokenPair) IsNativeCoin() bool {
return tp.ContractOwner == OWNER_MODULE
}
// IsNativeERC20 returns true if the owner of the ERC20 contract not the
// erc20 module account
func (tp TokenPair) IsNativeERC20() bool {
return tp.ContractOwner == OWNER_EXTERNAL
}
```
#### Token Pair by ERC20 and by Denom
`TokenPairByERC20` and `TokenPairByDenom` are additional state objects for querying a token pair id.
### Genesis State
The `x/erc20` module's `GenesisState` defines the state necessary
for initializing the chain from a previous exported height.
It contains the module parameters and the registered token pairs :
```go theme={null}
// GenesisState defines the module's genesis state.
type GenesisState struct {
// module parameters
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
// registered token pairs
TokenPairs []TokenPair `protobuf:"bytes,2,rep,name=token_pairs,json=tokenPairs,proto3" json:"token_pairs"`
}
```
## State Transitions
The erc20 modules allows for two types of registration state transitions.
Depending on how token pairs are registered, with `RegisterCoinProposal` or `RegisterERC20Proposal`,
there are four possible conversion state transitions.
### Token Pair Registration
Both the Cosmos coin and the ERC20 token registration allow for registering several token pairs with one proposal.
For simplicity, the following description describes the registration of only one token pair per proposal.
#### 1. Register Coin
A user registers a native Cosmos Coin.
Once the proposal passes (i.e is approved by governance),
the ERC20 module uses a factory pattern to deploy an ERC20 token contract representation of the Cosmos Coin.
Note that the native HyperPaxeer coin cannot be registered,
as any coin including "evm" in its denomination cannot be registered.
Instead, the HyperPaxeer token can be converted by Nomand's wrapped HyperPaxeer (WHyperPaxeer) contract.
1. User submits a `RegisterCoinProposal`
2. Validators of the HyperPaxeer Hub vote on the proposal usingΒ `MsgVote`Β and proposal passes
3. If Cosmos coin or IBC voucher exist on the bank module supply,
create the [ERC20 token contract](https://github.com/Paxeer-Network/Paxeer-Network/blob/main/contracts/ERC20MinterBurnerDecimals.sol)
on the EVM based on the ERC20Mintable
([ERC20Mintable by openzeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20))
interface
* Initial supply: 0
* Token details (Name, Symbol, Decimals, etc) are derived
from the bank module `Metadata` field on the proposal content.
#### 2. Register ERC20
A user registers a ERC20 token contract that is already deployed on the EVM module.
Once the proposal passes (i.e. is approved by governance),
the ERC20 module creates a Cosmos coin representation of the ERC20 token.
1. User submits a `RegisterERC20Proposal`
2. Validators of the HyperPaxeer chain vote on the proposal usingΒ `MsgVote`Β and proposal passes
3. If ERC-20 contract is deployed on the EVM module, create a bank coinΒ `Metadata`Β from the ERC20 details.
### Token Pair Conversion
Conversion of a registered `TokenPair` can be done via:
* Cosmos transaction (`ConvertCoin` and `ConvertERC20)`
* Ethereum transaction (i.e sending a `MsgEthereumTx` that leverages the EVM hook)
#### 1. Registered Coin
:::tip
π **Context:** A `TokenPair` has been created through a `RegisterCoinProposal` governance proposal.
The proposal created an `ERC20` contract
([ERC20Mintable by openzeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20))
of the ERC20 token representation of the Coin from the `ModuleAccount`,
assigning it as the `owner` of the contract
and thus granting it the permission to call the `mint()` and `burnFrom()` methods of the ERC20.
:::
##### Invariants
* Only the `ModuleAccount` should have the Minter Role on the ERC20. Otherwise,
the user could unilaterally mint an infinite supply of the ERC20 token and
then convert them to the native Coin
* The user and the `ModuleAccount` (owner) should be the only ones that have the
Burn Role for a Cosmos Coin
* There shouldn't exist any native Cosmos Coin ERC20 Contract (eg HyperPaxeer, Atom,
Osmo ERC20 contracts) that is not owned by the governance
* Token/Coin supply is maintained at all times:
* Total Coin supply = Coins + Escrowed Coins
* Total Token supply = Escrowed Coins = Minted Tokens
##### 1.1 Coin to ERC20
1. User submits `ConvertCoin` Tx
2. Check if conversion is allowed for the pair, sender and recipient
* global parameter is enabled
* token pair is enabled
* sender tokens are not vesting (checked in the bank module)
* recipient address is not blacklisted
3. If Coin is a native Cosmos Coin and Token Owner is `ModuleAccount`
1. Escrow Cosmos coin by sending them to the erc20 module account
2. Call `mint()`Β ERC20 tokens from the `ModuleAccount` address and send minted tokens to recipient address
4. Check if token balance increased by amount
##### 1.2 ERC20 to Coin
1. User submits a `ConvertERC20` Tx
2. Check if conversion is allowed for the pair, sender and recipient (see [1.1 Coin to ERC20](#11-coin-to-erc20))
3. If token is a ERC20 and Token Owner is `ModuleAccount`
1. Call `burnCoins()` on ERC20 to burn ERC20 tokens from the user balance
2. Send Coins (previously escrowed, see [1.1 Coin to ERC20](#11-coin-to-erc20))
from module to the recipient address.
4. Check if
* Coin balance increased by amount
* Token balance decreased by amount
#### 2. Registered ERC20
:::tip
π **Context:** A `TokenPair` has been created through a `RegisterERC20Proposal` governance proposal.
The `ModuleAccount` is not the owner of the contract, so it can't mint new tokens or burn on behalf of the user.
The mechanism described below follows the same model as the ICS20 standard,
by using escrow & mint / burn & unescrow logic.
:::
##### Invariants
* ERC20 Token supply on the EVM runtime is maintained at all times:
* Escrowed ERC20 + Minted Cosmos Coin representation of ERC20 = Burned Cosmos Coin representation of ERC20 +
Unescrowed ERC20
* Convert 10 ERC20 β Coin, the total supply increases by 10. Mint on Cosmos side, no changes on EVM
* Convert 10 Coin β ERC20, the total supply decreases by 10. Burn on Cosmos side , no changes of supply on EVM
* Total ERC20 token supply = Non Escrowed Tokens + Escrowed Tokens (on Module account address)
* Total Coin supply for the native ERC20 = Escrowed ERC20 Tokens on module account (i.e balance) = Minted Coins
##### 2.1 ERC20 to Coin
1. User submits a `ConvertERC20` Tx
2. Check if conversion is allowed for the pair, sender and recipient (See [1.1 Coin to ERC20](#11-coin-to-erc20))
3. If token is a ERC20 and Token Owner is **not** `ModuleAccount`
1. Escrow ERC20 token by sending them to the erc20 module account
2. Mint Cosmos coins of the corresponding token pair denomination and send coins to the recipient address
4. Check if
* Coin balance increased by amount
* Token balance decreased by amount
5. Fail if unexpected `Approval` event found in logs to prevent malicious contract behaviour
##### 2.2 Coin to ERC20
1. User submits `ConvertCoin` Tx
2. Check if conversion is allowed for the pair, sender and recipient
3. If coin is a native Cosmos coin and Token Owner is **not** `ModuleAccount`
1. Escrow Cosmos Coins by sending them to the erc20 module account
2. Unlock escrowed ERC20 from the module address by sending it to the recipient
3. Burn escrowed Cosmos coins
4. Check if token balance increased by amount
5. Fail if unexpected `Approval` event found in logs to prevent malicious contract behaviour
## Transactions
This section defines the `sdk.Msg` concrete types that result in the state transitions defined on the previous section.
### `RegisterCoinProposal`
A gov `Content` type to register a token pair from a Cosmos Coin.
Governance users vote on this proposal
and it automatically executes the custom handler forΒ `RegisterCoinProposal`Β when the vote passes.
```go theme={null}
type RegisterCoinProposal struct {
// title of the proposal
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
// proposal description
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
// metadata slice of the native Cosmos coins
Metadata []types.Metadata `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata"`
}
```
The proposal content stateless validation fails if:
* Title is invalid (length or char)
* Description is invalid (length or char)
* Metadata is invalid
* Name and Symbol are not blank
* Base and Display denominations are valid coin denominations
* Base and Display denominations are present in the DenomUnit slice
* Base denomination has exponent 0
* Denomination units are sorted in ascending order
* Denomination units not duplicated
### `RegisterERC20Proposal`
A gov `Content` type to register a token pair from an ERC20 Token.
Governance users vote on this proposal
and it automatically executes the custom handler forΒ `RegisterERC20Proposal`Β when the vote passes.
```go theme={null}
type RegisterERC20Proposal struct {
// title of the proposal
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
// proposal description
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
// contract addresses of ERC20 tokens
Erc20Addresses []string `protobuf:"bytes,3,rep,name=erc20addresses,proto3" json:"erc20addresses,omitempty"`
}
```
The proposal Content stateless validation fails if:
* Title is invalid (length or char)
* Description is invalid (length or char)
* ERC20Addresses is invalid
### `MsgConvertCoin`
A user broadcastsΒ a `MsgConvertCoin`Β message to convert a Cosmos Coin to a ERC20 token.
```go theme={null}
type MsgConvertCoin struct {
// Cosmos coin which denomination is registered on erc20 bridge.
// The coin amount defines the total ERC20 tokens to convert.
Coin types.Coin `protobuf:"bytes,1,opt,name=coin,proto3" json:"coin"`
// recipient hex address to receive ERC20 token
Receiver string `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"`
// cosmos bech32 address from the owner of the given ERC20 tokens
Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"`
}
```
Message stateless validation fails if:
* Coin is invalid (invalid denom or non-positive amount)
* Receiver hex address is invalid
* Sender bech32 address is invalid
### `MsgConvertERC20`
A user broadcastsΒ a `MsgConvertERC20`Β message to convert a ERC20 token to a native Cosmos coin.
```go theme={null}
type MsgConvertERC20 struct {
// ERC20 token contract address registered on erc20 bridge
ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"`
// amount of ERC20 tokens to mint
Amount github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"amount"`
// bech32 address to receive SDK coins.
Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"`
// sender hex address from the owner of the given ERC20 tokens
Sender string `protobuf:"bytes,4,opt,name=sender,proto3" json:"sender,omitempty"`
}
```
Message stateless validation fails if:
* Contract address is invalid
* Amount is not positive
* Receiver bech32 address is invalid
* Sender hex address is invalid
### `ToggleTokenConversionProposal`
A gov Content type to toggle the internal conversion of a token pair.
```go theme={null}
type ToggleTokenConversionProposal struct {
// title of the proposal
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
// proposal description
Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
// token identifier can be either the hex contract address of the ERC20 or the
// Cosmos base denomination
Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"`
}
```
## Hooks
The erc20 module implements transaction hooks from the EVM in order to trigger token pair conversion.
### EVM Hooks
The EVM hooks allows users to convert ERC20s to Cosmos Coins
by sending an Ethereum tx transfer to the module account address.
This enables native conversion of tokens via Metamask and EVM-enabled wallets for both token pairs
that have been registered through a native Cosmos coin or an ERC20 token.
Note that additional coin/token balance checks for sender and receiver to prevent malicious contract behaviour
(as performed in the [`ConvertERC20` msg](#state-transitions)) cannot be done here,
as the balance prior to the transaction is not available in the hook.
#### Registered Coin: ERC20 to Coin
1. User transfers ERC20 tokens to the `ModuleAccount` address to escrow them
2. Check if the ERC20 Token that was transferred from the sender is a native ERC20
or a native Cosmos Coin by looking at the
[Ethereum event logs](https://medium.com/mycrypto/understanding-event-logs-on-the-ethereum-blockchain-f4ae7ba50378#:~:text=A%20log%20record%20can%20be,or%20a%20change%20of%20ownership.\&text=Each%20log%20record%20consists%20of,going%20on%20in%20an%20event)
3. If the token contract address corresponds to the ERC20 representation of a native Cosmos Coin
1. Call `burn()` ERC20 method from the `ModuleAccount`.
Note that this is the same as 1.2, but since the tokens are already on the ModuleAccount balance,
we burn the tokens from the module address instead of calling `burnFrom()`.
Also note that we don't need to mint
because [1.1 coin to erc20](#state-transitions) escrows the coin
2. Transfer Cosmos Coin to the bech32 account address of the sender hex address
#### Registered ERC20: ERC20 to Coin
1. User transfers coins to the`ModuleAccount` to escrow them
2. Check if the ERC20 Token that was transferred is a native ERC20 or a native cosmos coin
3. If the token contract address is a native ERC20 token
1. Mint Cosmos Coin
2. Transfer Cosmos Coin to the bech32 account address of the sender hex
## Events
The `x/erc20` module emits the following events:
### Register Coin Proposal
| Type | Attribute Key | Attribute Value |
| --------------- | --------------- | ----------------- |
| `register_coin` | `"cosmos_coin"` | `{denom}` |
| `register_coin` | `"erc20_token"` | `{erc20_address}` |
### Register ERC20 Proposal
| Type | Attribute Key | Attribute Value |
| ---------------- | --------------- | ----------------- |
| `register_erc20` | `"cosmos_coin"` | `{denom}` |
| `register_erc20` | `"erc20_token"` | `{erc20_address}` |
### Toggle Token Conversion
| Type | Attribute Key | Attribute Value |
| ------------------------- | --------------- | ----------------- |
| `toggle_token_conversion` | `"erc20_token"` | `{erc20_address}` |
| `toggle_token_conversion` | `"cosmos_coin"` | `{denom}` |
### Convert Coin
| Type | Attribute Key | Attribute Value |
| -------------- | --------------- | ---------------------------- |
| `convert_coin` | `"sender"` | `{msg.Sender}` |
| `convert_coin` | `"receiver"` | `{msg.Receiver}` |
| `convert_coin` | `"amount"` | `{msg.Coin.Amount.String()}` |
| `convert_coin` | `"cosmos_coin"` | `{denom}` |
| `convert_coin` | `"erc20_token"` | `{erc20_address}` |
### Convert ERC20
| Type | Attribute Key | Attribute Value |
| --------------- | --------------- | ----------------------- |
| `convert_erc20` | `"sender"` | `{msg.Sender}` |
| `convert_erc20` | `"receiver"` | `{msg.Receiver}` |
| `convert_erc20` | `"amount"` | `{msg.Amount.String()}` |
| `convert_erc20` | `"cosmos_coin"` | `{denom}` |
| `convert_erc20` | `"erc20_token"` | `{msg.ContractAddress}` |
## Parameters
The erc20 module contains the following parameters:
| Key | Type | Default Value |
| --------------- | ---- | ------------- |
| `EnableErc20` | bool | `true` |
| `EnableEVMHook` | bool | `true` |
### Enable ERC20
The `EnableErc20` parameter toggles all state transitions in the module.
When the parameter is disabled, it will prevent all token pair registration and conversion functionality.
### Enable EVM Hook
The `EnableEVMHook` parameter enables the EVM hook to convert an ERC20 token
to a Cosmos Coin by transferring the Tokens through a `MsgEthereumTx` to the `ModuleAddress` Ethereum address.
## Clients
### CLI
Find below a list of Β `hyperpaxd`Β commands added with the `x/erc20` module.
You can obtain the full list by using theΒ `hyperpaxd -h`Β command.
A CLI command can look like this:
```bash theme={null}
hyperpaxd query erc20 params
```
#### Queries
| Command | Subcommand | Description |
| --------------- | ------------- | ------------------------------ |
| `query` `erc20` | `params` | Get erc20 params |
| `query` `erc20` | `token-pair` | Get registered token pair |
| `query` `erc20` | `token-pairs` | Get all registered token pairs |
#### Transactions
| Command | Subcommand | Description |
| ------------ | --------------- | ------------------------------ |
| `tx` `erc20` | `convert-coin` | Convert a Cosmos Coin to ERC20 |
| `tx` `erc20` | `convert-erc20` | Convert a ERC20 to Cosmos Coin |
#### Proposals
The `tx gov submit-legacy-proposal` commands allow users to query create a proposal using the governance module CLI:
**`register-coin`**
Allows users to submit a `RegisterCoinProposal`.
Submit a proposal to register a Cosmos coin to the erc20 along with an initial deposit.
Upon passing, the proposal details must be supplied via a JSON file.
```bash theme={null}
hyperpaxd tx gov submit-legacy-proposal register-coin METADATA_FILE [flags]
```
Where METADATA\_FILE contains (example):
```json theme={null}
{
"metadata": [
{
"description": "The native staking and governance token of the Osmosis chain",
"denom_units": [
{
"denom": "ibc/",
"exponent": 0,
"aliases": ["ibcuosmo"]
},
{
"denom": "OSMO",
"exponent": 6
}
],
"base": "ibc/",
"display": "OSMO",
"name": "Osmo",
"symbol": "OSMO"
}
]
}
```
**`register-erc20`**
Allows users to submit a `RegisterERC20Proposal`.
Submit a proposal to register ERC20 tokens along with an initial deposit.
To register multiple tokens in one proposal pass them after each other e.g.
`register-erc20 `.
```bash theme={null}
hyperpaxd tx gov submit-legacy-proposal register-erc20 ERC20_ADDRESS... [flags]
```
**`toggle-token-conversion`**
Allows users to submit a `ToggleTokenConversionProposal`.
```bash theme={null}
hyperpaxd tx gov submit-legacy-proposal toggle-token-conversion TOKEN [flags]
```
**Update Params**
Allows users to submit a `MsgUpdateParams` with the desired changes on the `x/erc20` module parameters.
To do this, you will have to provide a JSON file with the correspondiong message in the `submit-proposal` command.
For more information on how to draft a proposal, refer to the [Drafting a proposal section](../Paxeer-Network-cli/proposal-draft.md).
```bash theme={null}
hyperpaxd tx gov submit-proposal proposal.json [flags]
```
### gRPC
#### Queries
| Verb | Method | Description |
| ------ | --------------------------------------- | ------------------------------ |
| `gRPC` | `HyperPaxeer.erc20.v1.Query/Params` | Get erc20 params |
| `gRPC` | `HyperPaxeer.erc20.v1.Query/TokenPair` | Get registered token pair |
| `gRPC` | `HyperPaxeer.erc20.v1.Query/TokenPairs` | Get all registered token pairs |
| `GET` | `/Paxeer-Network/erc20/v1/params` | Get erc20 params |
| `GET` | `/Paxeer-Network/erc20/v1/token_pair` | Get registered token pair |
| `GET` | `/Paxeer-Network/erc20/v1/token_pairs` | Get all registered token pairs |
#### Transactions
| Verb | Method | Description |
| ------ | ------------------------------------------- | ------------------------------ |
| `gRPC` | `HyperPaxeer.erc20.v1.Msg/ConvertCoin` | Convert a Cosmos Coin to ERC20 |
| `gRPC` | `HyperPaxeer.erc20.v1.Msg/ConvertERC20` | Convert a ERC20 to Cosmos Coin |
| `GET` | `/Paxeer-Network/erc20/v1/tx/convert_coin` | Convert a Cosmos Coin to ERC20 |
| `GET` | `/Paxeer-Network/erc20/v1/tx/convert_erc20` | Convert a ERC20 to Cosmos Coin |
# Evm
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/evm
# `evm`
## Abstract
This document defines the specification of the Ethereum Virtual Machine (EVM) as a Cosmos SDK module.
Since the introduction of Ethereum in 2015,
the ability to control digital assets through [**smart contracts**](https://www.fon.hum.uva.nl/rob/Courses/InformationInSpeech/CDROM/Literature/LOTwinterschool2006/szabo.best.vwh.net/idea.html)
has attracted a large community of developers
to build decentralized applications on the Ethereum Virtual Machine (EVM).
This community is continuously creating extensive tooling and introducing standards,
which are further increasing the adoption rate of EVM compatible technology.
The growth of EVM-based chains (e.g.
Ethereum), however, has uncovered several scalability challenges
that are often referred to as the [trilemma of decentralization, security, and scalability](https://vitalik.eth.limo/general/2021/04/07/sharding.html).
Developers are frustrated by high gas fees, slow transaction speed & throughput,
and chain-specific governance that can only undergo slow change
because of its wide range of deployed applications.
A solution is required that eliminates these concerns for developers,
who build applications within a familiar EVM environment.
The `x/evm` module provides this EVM familiarity on a scalable, high-throughput Proof-of-Stake blockchain.
It is built as a [Cosmos SDK module](https://docs.cosmos.network/main/build/building-modules/intro)
which allows for the deployment of smart contracts,
interaction with the EVM state machine (state transitions),
and the use of EVM tooling.
It can be used on Cosmos application-specific blockchains,
which alleviate the aforementioned concerns through high transaction throughput
via [Tendermint Core](https://github.com/tendermint/tendermint), fast transaction finality,
and horizontal scalability via [IBC](https://ibcprotocol.org/).
The `x/evm` module is part of the HyperPaxeer EVM stack, forked from the hyperpaxeer library.
## Contents
1. **[Concepts](#concepts)**
2. **[State](#state)**
3. **[State Transitions](#state-transitions)**
4. **[Transactions](#transactions)**
5. **[ABCI](#abci)**
6. **[Hooks](#hooks)**
7. **[Events](#events)**
8. **[Parameters](#parameters)**
9. **[Client](#client)**
## Module Architecture
> **NOTE:**: If you're not familiar with the overall module structure from
> the SDK modules, please check this [document](https://docs.cosmos.network/main/build/building-modules/structure) as
> prerequisite reading.
```shell theme={null}
evm/
βββ client
β βββ cli
β βββ query.go # CLI query commands for the module
β Β Β βββ tx.go # CLI transaction commands for the module
βββ keeper
β βββ keeper.go # ABCI BeginBlock and EndBlock logic
β βββ keeper.go # Store keeper that handles the business logic of the module and has access to a specific subtree of the state tree.
β βββ params.go # Parameter getter and setter
β βββ querier.go # State query functions
β βββ statedb.go # Functions from types/statedb with a passed in sdk.Context
βββ types
βΒ Β βββ chain_config.go
βΒ Β βββ codec.go # Type registration for encoding
βΒ Β βββ errors.go # Module-specific errors
βΒ Β βββ events.go # Events exposed to the Tendermint PubSub/Websocket
βΒ Β βββ genesis.go # Genesis state for the module
βΒ Β βββ journal.go # Ethereum Journal of state transitions
βΒ Β βββ keys.go # Store keys and utility functions
βΒ Β βββ logs.go # Types for persisting Ethereum tx logs on state after chain upgrades
βΒ Β βββ msg.go # EVM module transaction messages
βΒ Β βββ params.go # Module parameters that can be customized with governance parameter change proposals
βΒ Β βββ state_object.go # EVM state object
βΒ Β βββ statedb.go # Implementation of the StateDb interface
βΒ Β βββ storage.go # Implementation of the Ethereum state storage map using arrays to prevent non-determinism
βΒ Β βββ tx_data.go # Ethereum transaction data types
βββ genesis.go # ABCI InitGenesis and ExportGenesis functionality
βββ handler.go # Message routing
βββ module.go # Module setup for the module manager
```
## Concepts
### EVM
The Ethereum Virtual Machine (EVM) is a computation engine
which can be thought of as one single entity maintained by thousands of connected computers (nodes)
running an Ethereum client.
As a virtual machine ([VM](https://en.wikipedia.org/wiki/Virtual_machine)),
the EVM is responsible for computing changes to the state deterministically
regardless of its environment (hardware and OS).
This means that every node has to get the exact same result
given an identical starting state and transaction (tx).
The EVM is considered to be the part of the Ethereum protocol
that handles the deployment and execution of [smart contracts](https://ethereum.org/en/developers/docs/smart-contracts/).
To make a clear distinction:
* The Ethereum protocol describes a blockchain,
in which all Ethereum accounts and smart contracts live.
It has only one canonical state (a data structure, which keeps allΒ accounts)
at any given block in the chain.
* The EVM, however, is the [state machine](https://en.wikipedia.org/wiki/Finite-state_machine)
that defines the rules for computing a new valid state from block to block.
It is an isolated runtime, which means
that code running inside the EVM has no access to network, filesystem, or other processes (not external APIs).
The `x/evm` module implements the EVM as a Cosmos SDK module.
It allows users to interact with the EVM by submitting Ethereum txs
and executing their containing messages on the given state to evoke a state transition.
#### State
The Ethereum state is a data structure,
implemented as a [Merkle Patricia Tree](https://en.wikipedia.org/wiki/Merkle_tree),
that keeps all accounts on the chain.
The EVM makes changes to this data structure resulting in a new state with a different state root.
Ethereum can therefore be seen as a state chain
that transitions from one state to another
by executing transactions in a block using the EVM.
A new block of txs can be described through its block header
(parent hash, block number, time stamp, nonce, receipts,...).
#### Accounts
There are two types of accounts that can be stored in state at a given address:
* **Externally Owned Account (EOA)**: Has nonce (tx counter) and balance
* **Smart Contract**: Has nonce, balance, (immutable) code hash, storage root (another Merkle Patricia Trie)
Smart contracts are just like regular accounts on the blockchain,
which additionally store executable code in an Ethereum-specific binary format,
known as **EVM bytecode**.
They are typically written in an Ethereum high level language, such as Solidity,
which is compiled down to EVM bytecode
and deployed on the blockchain by submitting a transaction using an Ethereum client.
#### Architecture
The EVM operates as a stack-based machine.
It's main architecture components consist of:
* Virtual ROM: contract code is pulled into this read only memory when processing txs
* Machine state (volatile): changes as the EVM runs and is wiped clean after processing each tx
* Program counter (PC)
* Gas: keeps track of how much gas is used
* Stack and Memory: compute state changes
* Access to account storage (persistent)
#### State Transitions with Smart Contracts
Typically smart contracts expose a public ABI,
which is a list of supported ways a user can interact with a contract.
To interact with a contract and invoke a state transition,
a user will submit a tx carrying any amount of gas and a data payload formatted according to the ABI,
specifying the type of interaction and any additional parameters.
When the tx is received, the EVM executes the smart contracts' EVM bytecode using the tx payload.
#### Executing EVM bytecode
A contract's EVM bytecode consists of basic operations (add, multiply, store, etc...), called **Opcodes**.
Each Opcode execution requires gas that needs to be paid with the tx.
The EVM is therefore considered quasi-turing complete,
as it allows any arbitrary computation,
but the amount of computations during a contract execution is limited to the amount of gas provided in the tx.
Each Opcode's [**gas cost**](https://www.evm.codes/) reflects the cost of running these operations on actual computer hardware
(e.g. `ADD = 3gas` and `SSTORE = 100gas`).
To calculate the gas consumption of a tx, the gas cost is multiplied by the **gas price**,
which can change depending on the demand of the network at the time.
If the network is under heavy load, you might have to pay a higher gas price to get your tx executed.
If the gas limit is hit (out of gas exception) no changes to the Ethereum state are applied,
except that the sender's nonce increments and their balance goes down to pay for wasting the EVM's time.
Smart contracts can also call other smart contracts.
Each call to a new contract creates a new instance of the EVM (including a new stack and memory).
Each call passes the sandbox state to the next EVM.
If the gas runs out, all state changes are discarded.
Otherwise, they are kept.
For further reading, please refer to:
* [EVM](https://eth.wiki/concepts/evm/evm)
* [EVM Architecture](https://cypherpunks-core.github.io/ethereumbook/13evm.html#evm_architecture)
* [What is Ethereum](https://ethdocs.org/en/latest/introduction/what-is-ethereum.html#what-is-ethereum)
* [Opcodes](https://www.ethervm.io/)
### HyperPaxeer as Geth implementation
HyperPaxeer contains an implementation of the [Ethereum protocol in Golang](https://geth.ethereum.org/docs/getting-started)
(Geth) as a Cosmos SDK module.
Geth includes an implementation of the EVM to compute state transitions.
Have a look at the [go-ethereum source code](https://github.com/ethereum/go-ethereum/blob/master/core/vm/instructions.go)
to see how the EVM opcodes are implemented.
Just as Geth can be run as an Ethereum node,
HyperPaxeer can be run as a node to compute state transitions with the EVM.
HyperPaxeer supports Geth's standard Ethereum JSON-RPC APIs
in order to be Web3 and EVM compatible.
#### JSON-RPC
JSON-RPC is a stateless, lightweight remote procedure call (RPC) protocol.
Primarily this specification defines several data structures
and the rules around their processing.
It is transport agnostic in that the concepts can be used within the same process,
over sockets, over HTTP, or in many various message passing environments.
It uses JSON (RFC 4627) as a data format.
##### JSON-RPC Example: `eth_call`
The JSON-RPC method [`eth_call`](https://docs.paxeer.app/develop/api/ethereum-json-rpc/methods#eth-call) allows you
to execute messages against contracts.
Usually, you need to send a transaction to a Geth node to include it in the mempool,
then nodes gossip between each other and eventually the transaction is included in a block and gets executed.
`eth_call` however lets you send data to a contract and see what happens without committing a transaction.
In the Geth implementation, calling the endpoint roughly goes through the following steps:
1. The `eth_call` request is transformed to call the `func (s *PublicBlockchainAPI) Call()` function using the `eth` namespace
2. [`Call()`](https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L982) is given
the transaction arguments, the block to call against and optional arguments that modify the state to call against.
It then calls `DoCall()`.
3. [`DoCall()`](https://github.com/ethereum/go-ethereum/blob/d575a2d3bc76dfbdefdd68b6cffff115542faf75/internal/ethapi/api.go#L891)
transforms the arguments into a `ethtypes.message`, instantiates an EVM
and applies the message with `core.ApplyMessage`
4. [`ApplyMessage()`](https://github.com/ethereum/go-ethereum/blob/d575a2d3bc76dfbdefdd68b6cffff115542faf75/core/state_transition.go#L180)
calls the state transition `TransitionDb()`
5. [`TransitionDb()`](https://github.com/ethereum/go-ethereum/blob/d575a2d3bc76dfbdefdd68b6cffff115542faf75/core/state_transition.go#L275)
either `Create()`s a new contract or `Call()`s a contract
6. [`evm.Call()`](https://github.com/ethereum/go-ethereum/blob/d575a2d3bc76dfbdefdd68b6cffff115542faf75/core/vm/evm.go#L168)
runs the interpreter `evm.interpreter.Run()` to execute the message.
If the execution fails, the state is reverted to a snapshot taken before the execution and gas is consumed.
7. [`Run()`](https://github.com/ethereum/go-ethereum/blob/d575a2d3bc76dfbdefdd68b6cffff115542faf75/core/vm/interpreter.go#L116)
performs a loop to execute the opcodes.
The HyperPaxeer implementation is similar and makes use of the gRPC query client which is included in the Cosmos SDK:
1. `eth_call` request is transformed to call the `func (e *PublicAPI) Call` function using the `eth` namespace
2. [`Call()`](https://github.com/paxeer-network/hyperpaxeer/blob/main/rpc/namespaces/ethereum/eth/api.go#L639) calls `doCall()`
3. [`doCall()`](https://github.com/paxeer-network/hyperpaxeer/blob/main/rpc/namespaces/ethereum/eth/api.go#L656)
transforms the arguments into a `EthCallRequest` and calls `EthCall()` using the query client of the evm module.
4. [`EthCall()`](https://github.com/paxeer-network/hyperpaxeer/blob/main/x/evm/keeper/grpc_query.go#L212)
transforms the arguments into a `ethtypes.message` and calls \`ApplyMessageWithConfig()
5. [`ApplyMessageWithConfig()`](https://github.com/paxeer-network/hyperpaxeer/blob/d5598932a7f06158b7a5e3aa031bbc94eaaae32c/x/evm/keeper/state_transition.go#L341)
instantiates an EVM and either `Create()`s a new contract or `Call()`s a contract using the Geth implementation.
#### StateDB
The `StateDB` interface from [go-ethereum](https://github.com/ethereum/go-ethereum/blob/master/core/vm/interface.go)
represents an EVM database for full state querying.
EVM state transitions are enabled by this interface, which in the `x/evm` module is implemented by the `Keeper`.
This implementation of this interface is what makes HyperPaxeer EVM compatible.
### Consensus Engine
The application using the `x/evm` module interacts with the Tendermint Core Consensus Engine
over an Application Blockchain Interface (ABCI).
Together, the application and Tendermint Core form the programs that run a complete blockchain
and combine business logic with decentralized data storage.
Ethereum transactions which are submitted to the `x/evm` module take part in this consensus process
before being executed and changing the application state.
We encourage to understand the basics of the [Tendermint consensus engine](https://docs.tendermint.com/main/introduction/what-is-tendermint.html#intro-to-abci)
in order to understand state transitions in detail.
### Transaction Logs
On every `x/evm` transaction, the result contains the Ethereum `Log`s from the state machine execution
that are used by the JSON-RPC Web3 server for filter querying and for processing the EVM Hooks.
The tx logs are stored in the transient store during tx execution
and then emitted through cosmos events after the transaction has been processed.
They can be queried via gRPC and JSON-RPC.
### Block Bloom
Bloom is the bloom filter value in bytes for each block that can be used for filter queries.
The block bloom value is stored in the transient store
and then emitted through a cosmos event during `EndBlock` processing.
They can be queried via gRPC and JSON-RPC.
:::tip
π **Note**: Since they are not stored on state, Transaction Logs and Block Blooms are not persisted after upgrades.
A user must use an archival node after upgrades in order to obtain legacy chain events.
:::
## State
This section gives you an overview of the objects stored in the `x/evm` module state,
functionalities that are derived from the go-ethereum `StateDB` interface,
and its implementation through the Keeper as well as the state implementation at genesis.
### State Objects
The `x/evm` module keeps the following objects in state:
#### State
| | Description | Key | Value | Store |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------- | --------- |
| Code | Smart contract bytecode | `[]byte{1} + []byte(address)` | `[]byte{code}` | KV |
| Storage | Smart contract storage | `[]byte{2} + [32]byte{key}` | `[32]byte(value)` | KV |
| Block Bloom | Block bloom filter, used to accumulate the bloom filter of current block, emitted to events at end blocker. | `[]byte{1} + []byte(tx.Hash)` | `protobuf([]Log)` | Transient |
| Tx Index | Index of current transaction in current block. | `[]byte{2}` | `BigEndian(uint64)` | Transient |
| Log Size | Number of the logs emitted so far in current block. Used to decide the log index of following logs. | `[]byte{3}` | `BigEndian(uint64)` | Transient |
| Gas Used | Amount of gas used by ethereum messages of current cosmos-sdk tx, it's necessary when cosmos-sdk tx contains multiple ethereum messages. | `[]byte{4}` | `BigEndian(uint64)` | Transient |
### StateDB
The `StateDB` interface is implemented by the `StateDB` in the `x/evm/statedb` module
to represent an EVM database for full state querying of both contracts and accounts.
Within the Ethereum protocol, `StateDB`s are used to store anything
within the IAVL tree and take care of caching and storing nested states.
```go theme={null}
// github.com/ethereum/go-ethereum/core/vm/interface.go
type StateDB interface {
CreateAccount(common.Address)
SubBalance(common.Address, *big.Int)
AddBalance(common.Address, *big.Int)
GetBalance(common.Address) *big.Int
GetNonce(common.Address) uint64
SetNonce(common.Address, uint64)
GetCodeHash(common.Address) common.Hash
GetCode(common.Address) []byte
SetCode(common.Address, []byte)
GetCodeSize(common.Address) int
AddRefund(uint64)
SubRefund(uint64)
GetRefund() uint64
GetCommittedState(common.Address, common.Hash) common.Hash
GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash)
Suicide(common.Address) bool
HasSuicided(common.Address) bool
// Exist reports whether the given account exists in state.
// Notably this should also return true for suicided accounts.
Exist(common.Address) bool
// Empty returns whether the given account is empty. Empty
// is defined according to EIP161 (balance = nonce = code = 0).
Empty(common.Address) bool
PrepareAccessList(sender common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList)
AddressInAccessList(addr common.Address) bool
SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool)
// AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
// even if the feature/fork is not active yet
AddAddressToAccessList(addr common.Address)
// AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
// even if the feature/fork is not active yet
AddSlotToAccessList(addr common.Address, slot common.Hash)
RevertToSnapshot(int)
Snapshot() int
AddLog(*types.Log)
AddPreimage(common.Hash, []byte)
ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error
}
```
The `StateDB` in the `x/evm` provides the following functionalities:
#### CRUD of Ethereum accounts
You can create `EthAccount` instances from the provided address
and set the value to store on the `AccountKeeper`with `createAccount()`.
If an account with the given address already exists,
this function also resets any preexisting code and storage associated with that address.
An account's coin balance can be is managed through the `BankKeeper`
and can be read with `GetBalance()` and updated with `AddBalance()` and `SubBalance()`.
* `GetBalance()` returns the EVM denomination balance of the provided address.
The denomination is obtained from the module parameters.
* `AddBalance()` adds the given amount to the address balance coin
by minting new coins and transferring them to the address.
The coin denomination is obtained from the module parameters.
* `SubBalance()` subtracts the given amount from the address balance
by transferring the coins to an escrow account and then burning them.
The coin denomination is obtained from the module parameters.
This function performs a no-op if the amount is negative or the user doesn't have enough funds for the transfer.
The nonce (or transaction sequence) can be obtained from the Account `Sequence` via the auth module `AccountKeeper`.
* `GetNonce()` retrieves the account with the given address and returns the tx sequence (i.e nonce).
The function performs a no-op if the account is not found.
* `SetNonce()` sets the given nonce as the sequence of the address' account.
If the account doesn't exist, a new one will be created from the address.
The smart contract bytecode containing arbitrary contract logic is stored on the `EVMKeeper`
and it can be queried with `GetCodeHash()` ,`GetCode()` & `GetCodeSize()`and updated with `SetCode()`.
* `GetCodeHash()` fetches the account from the store and returns its code hash.
If the account doesn't exist or is not an EthAccount type, it returns the empty code hash value.
* `GetCode()` returns the code byte array associated with the given address.
If the code hash from the account is empty, this function returns nil.
* `SetCode()` stores the code byte array to the application KVStore and sets the code hash to the given account.
The code is deleted from the store if it is empty.
* `GetCodeSize()` returns the size of the contract code associated with this object, or zero if none.
Gas refunded needs to be tracked and stored in a separate variable in
order to add it subtract/add it from/to the gas used value after the EVM
execution has finalized. The refund value is cleared on every transaction and at the end of every block.
* `AddRefund()` adds the given amount of gas to the in-memory refund value.
* `SubRefund()` subtracts the given amount of gas from the in-memory refund value.
This function will panic if gas amount is greater than the current refund.
* `GetRefund()` returns the amount of gas available for return after the tx execution finalizes.
This value is reset to 0 on every transaction.
The state is stored on the `EVMKeeper`.
It can be queried with `GetCommittedState()`, `GetState()` and updated with `SetState()`.
* `GetCommittedState()` returns the value set in store for the given key hash.
If the key is not registered this function returns the empty hash.
* `GetState()` returns the in-memory dirty state for the given key hash,
if not exist load the committed value from KVStore.
* `SetState()` sets the given hashes (key, value) to the state.
If the value hash is empty, this function deletes the key from the state,
the new value is kept in dirty state at first, and will be committed to KVStore in the end.
Accounts can also be set to a suicide state.
When a contract commits suicide, the account is marked as suicided,
when committing the code, storage and account are deleted
(from the next block and forward).
* `Suicide()` marks the given account as suicided and clears the account balance of the EVM tokens.
* `HasSuicided()` queries the in-memory flag to check if the account has been marked as suicided in the current transaction.
Accounts that are suicided will be returned as non-nil during queries and "cleared" after the block has been committed.
To check account existence use `Exist()` and `Empty()`.
* `Exist()` returns true if the given account exists in store or if it has been
marked as suicided.
* `Empty()` returns true if the address meets the following conditions:
* nonce is 0
* balance amount for evm denom is 0
* account code hash is empty
#### EIP2930 functionality
Supports a transaction type that contains an [access list](https://eips.ethereum.org/EIPS/eip-2930),
a list of addresses and storage keys, that the transaction plans to access.
The access list state is kept in memory and discarded after the transaction committed.
* `PrepareAccessList()` handles the preparatory steps for executing a state transition
in regard to both EIP-2929 and EIP-2930.
This method should only be called if Yolov3/Berlin/2929+2930 is applicable at the current number.
* Add sender to access list (EIP-2929)
* Add destination to access list (EIP-2929)
* Add precompiles to access list (EIP-2929)
* Add the contents of the optional tx access list (EIP-2930)
* `AddressInAccessList()` returns true if the address is registered.
* `SlotInAccessList()` checks if the address and the slots are registered.
* `AddAddressToAccessList()` adds the given address to the access list.
If the address is already in the access list, this function performs a no-op.
* `AddSlotToAccessList()` adds the given (address, slot) to the access list.
If the address and slot are already in the access list, this function performs a no-op.
#### Snapshot state and Revert functionality
The EVM uses state-reverting exceptions to handle errors.
Such an exception will undo all changes made to the state in the current call (and all its sub-calls),
and the caller could handle the error and don't propagate.
You can use `Snapshot()` to identify the current state with a revision
and revert the state to a given revision with `RevertToSnapshot()` to support this feature.
* `Snapshot()` creates a new snapshot and returns the identifier.
* `RevertToSnapshot(rev)` undo all the modifications up to the snapshot identified as `rev`.
HyperPaxeer adapted the [go-ethereum journal implementation](https://github.com/ethereum/go-ethereum/blob/master/core/state/journal.go#L39)
to support this, it uses a list of journal logs to record all the state modification operations done so far,
snapshot is consists of a unique id and an index in the log list,
and to revert to a snapshot it just undoes the journal logs after the snapshot index in reversed order.
#### Ethereum Transaction logs
With `AddLog()` you can append the given Ethereum `Log` to the list of logs
associated with the transaction hash kept in the current state.
This function also fills in the tx hash, block hash, tx index and log index fields before setting the log to store.
### Keeper
The EVM module `Keeper` grants access to the EVM module state
and implements `statedb.Keeper` interface to support the `StateDB` implementation.
The Keeper contains a store key that allows the DB
to write to a concrete subtree of the multistore that is only accessible by the EVM module.
Instead of using a trie and database for querying and persistence (the `StateDB` implementation),
HyperPaxeer uses the Cosmos `KVStore` (key-value store) and Cosmos SDK `Keeper` to facilitate state transitions.
To support the interface functionality, it imports 4 module Keepers:
* `auth`: CRUD accounts
* `bank`: accounting (supply) and CRUD of balances
* `staking`: query historical headers
* `fee market`: EIP-1559 base fee for processing `DynamicFeeTx`
after the `London` hard fork has been activated on the `ChainConfig` parameters
```go theme={null}
type Keeper struct {
// Protobuf codec
cdc codec.BinaryCodec
// Store key required for the EVM Prefix KVStore. It is required by:
// - storing account's Storage State
// - storing account's Code
// - storing Bloom filters by block height. Needed for the Web3 API.
// For the full list, check the module specification
storeKey sdk.StoreKey
// key to access the transient store, which is reset on every block during Commit
transientKey sdk.StoreKey
// module specific parameter space that can be configured through governance
paramSpace paramtypes.Subspace
// access to account state
accountKeeper types.AccountKeeper
// update balance and accounting operations with coins
bankKeeper types.BankKeeper
// access historical headers for EVM state transition execution
stakingKeeper types.StakingKeeper
// fetch EIP1559 base fee and parameters
feeMarketKeeper types.FeeMarketKeeper
// chain ID number obtained from the context's chain id
eip155ChainID *big.Int
// Tracer used to collect execution traces from the EVM transaction execution
tracer string
// trace EVM state transition execution. This value is obtained from the `--trace` flag.
// For more info check https://geth.ethereum.org/docs/dapp/tracing
debug bool
// EVM Hooks for tx post-processing
hooks types.EvmHooks
}
```
### Genesis State
The `x/evm` module `GenesisState` defines the state necessary for initializing the chain from a previous exported height.
It contains the `GenesisAccounts` and the module parameters
```go theme={null}
type GenesisState struct {
// accounts is an array containing the ethereum genesis accounts.
Accounts []GenesisAccount `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts"`
// params defines all the parameters of the module.
Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"`
}
```
### Genesis Accounts
The `GenesisAccount` type corresponds to an adaptation of the Ethereum `GenesisAccount` type.
It defines an account to be initialized in the genesis state.
Its main difference is that the one on HyperPaxeer uses a custom `Storage` type
that uses a slice instead of maps for the evm `State` (due to non-determinism),
and that it doesn't contain the private key field.
It is also important to note that since the `auth` module on the Cosmos SDK manages the account state,
the `Address` field must correspond to an existing `EthAccount`
that is stored in the `auth`'s module `Keeper` (i.e `AccountKeeper`).
Addresses use the **[EIP55](https://eips.ethereum.org/EIPS/eip-55)** hex **[format](https://docs.paxeer.app/protocol/concepts/accounts#address-formats-for-clients)**
on `genesis.json`.
```go theme={null}
type GenesisAccount struct {
// address defines an ethereum hex formated address of an account
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
// code defines the hex bytes of the account code.
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
// storage defines the set of state key values for the account.
Storage Storage `protobuf:"bytes,3,rep,name=storage,proto3,castrepeated=Storage" json:"storage"`
}
```
## State Transitions
The `x/evm` module allows for users to submit Ethereum transactions (`Tx`)
and execute their containing messages to evoke state transitions on the given state.
Users submit transactions client-side to broadcast it to the network.
When the transaction is included in a block during consensus, it is executed server-side.
We highly recommend to understand the basics of the [Tendermint consensus engine](https://docs.tendermint.com/main/introduction/what-is-tendermint.html#intro-to-abci)
to understand the State Transitions in detail.
### Client-Side
:::tip
π This is based on the `eth_sendTransaction` JSON-RPC
:::
1. A user submits a transaction via one of the available JSON-RPC endpoints
using an Ethereum-compatible client or wallet (eg Metamask, WalletConnect, Ledger, etc):
a. eth (public) namespace:
* `eth_sendTransaction`
* `eth_sendRawTransaction`
b. personal (private) namespace:
* `personal_sendTransaction`
2. An instance of `MsgEthereumTx` is created after populating the RPC transaction
using `SetTxDefaults` to fill missing tx arguments with default values
3. The `Tx` fields are validated (stateless) using `ValidateBasic()`
4. The `Tx` is **signed** using the key associated with the sender address
and the latest ethereum hard fork (`London`, `Berlin`, etc) from the `ChainConfig`
5. The `Tx` is **built** from the msg fields using the Cosmos Config builder
6. The `Tx` is **broadcast** in [sync mode](https://docs.cosmos.network/main/user/run-node/txs#broadcasting-a-transaction)
to ensure to wait for
a [`CheckTx`](https://docs.tendermint.com/main/introduction/what-is-tendermint.html#intro-to-abci) execution response.
Transactions are validated by the application using `CheckTx()`,
before being added to the mempool of the consensus engine.
7. JSON-RPC user receives a response with the [`RLP`](https://eth.wiki/en/fundamentals/rlp) hash of the transaction fields.
This hash is different from the default hash used by SDK Transactions
that calculates the `sha256` hash of the transaction bytes.
### Server-Side
Once a block (containing the `Tx`) has been committed during consensus,
it is applied to the application in a series of ABCI msgs server-side.
Each `Tx` is handled by the application by calling [`RunTx`](https://docs.cosmos.network/main/learn/advanced/baseapp).
After a stateless validation on eachΒ `sdk.Msg` in theΒ `Tx`,
the `AnteHandler` confirms whether the `Tx` is an Ethereum or SDK transaction.
As an Ethereum transaction it's containing msgs are then handled
by the `x/evm` module to update the application's state.
#### AnteHandler
The `anteHandler` is run for every transaction.
It checks if the `Tx` is an Ethereum transaction and routes it to an internal ante handler.
Here, `Tx`s are handled using EthereumTx extension options to process them differently than normal Cosmos SDK transactions.
The `antehandler` runs through a series of options and their `AnteHandle` functions for each `Tx`:
* `EthSetUpContextDecorator()` is adapted from SetUpContextDecorator from cosmos-sdk,
it ignores gas consumption by setting the gas meter to infinite
* `EthValidateBasicDecorator(evmKeeper)` validates the fields of an Ethereum type Cosmos `Tx` msg
* `EthSigVerificationDecorator(evmKeeper)` validates that the registered chain id is the same as the one on the message,
and that the signer address matches the one defined on the message.
It's not skipped for RecheckTx, because it set `From` address which is critical from other ante handler to work.
Failure in RecheckTx will prevent tx to be included into block, especially when CheckTx succeed,
in which case user won't see the error message.
* `EthAccountVerificationDecorator(ak, bankKeeper, evmKeeper)`
will verify, that the sender balance is greater than the total transaction cost.
The account will be set to store if it doesn't exist, i.e cannot be found on store.
This AnteHandler decorator will fail if:
* any of the msgs is not a MsgEthereumTx
* from address is empty
* account balance is lower than the transaction cost
* `EthNonceVerificationDecorator(ak)` validates that the transaction nonces are valid
and equivalent to the sender accountβs current nonce.
* `EthGasConsumeDecorator(evmKeeper)` validates that the Ethereum tx message has enough
to cover intrinsic gas (during CheckTx only) and that the sender has enough balance to pay for the gas cost.
Intrinsic gas for a transaction is the amount of gas that the transaction uses before the transaction is executed.
The gas is a constant value plus any cost incurred by additional bytes of data supplied with the transaction.
This AnteHandler decorator will fail if:
* the transaction contains more than one message
* the message is not a MsgEthereumTx
* sender account cannot be found
* transaction's gas limit is lower than the intrinsic gas
* user doesn't have enough balance to deduct the transaction fees (gas\_limit \* gas\_price)
* transaction or block gas meter runs out of gas
* `CanTransferDecorator(evmKeeper, feeMarketKeeper)` creates an EVM from the message
and calls the BlockContext CanTransfer function to see if the address can execute the transaction.
* `EthIncrementSenderSequenceDecorator(ak)` handles incrementing the sequence of the signer (i.e sender).
If the transaction is a contract creation, the nonce will be incremented
during the transaction execution and not within this AnteHandler decorator.
The options `authante.NewMempoolFeeDecorator()`, `authante.NewTxTimeoutHeightDecorator()`
and `authante.NewValidateMemoDecorator(ak)` are the same as for a Cosmos `Tx`.
ClickΒ [here](https://docs.cosmos.network/main/learn/beginner/gas-fees.html#antehandler)Β for more on theΒ `anteHandler`.
#### EVM module
After authentication through the `antehandler`,
each `sdk.Msg` (in this case `MsgEthereumTx`) in the `Tx`
is delivered to the Msg Handler in the `x/evm` module
and runs through the following the steps:
1. Convert `Msg` to an ethereum `Tx` type
2. Apply `Tx` with `EVMConfig` and attempt to perform a state transition,
that will only be persisted (committed) to the underlying KVStore
if the transaction does not fail:
1. Confirm that `EVMConfig` is created
2. Create the ethereum signer using chain config value from `EVMConfig`
3. Set the ethereum transaction hash to the (impermanent) transient store so
that it's also available on the StateDB functions
4. Generate a new EVM instance
5. Confirm that EVM params for contract creation (`EnableCreate`)
and contract execution (`EnableCall`) are enabled
6. Apply message. If `To` address is `nil`, create new contract using code as deployment code.
Else call contract at given address with the given input as parameters
7. Calculate gas used by the evm operation
3. If `Tx` applied successfully
1. Execute EVM `Tx` postprocessing hooks. If hooks return error, revert the whole `Tx`
2. Refund gas according to Ethereum gas accounting rules
3. Update block bloom filter value using the logs generated from the tx
4. Emit SDK events for the transaction fields and tx logs
## Transactions
This section defines theΒ `sdk.Msg`Β concrete types that result in the state transitions defined on the previous section.
## `MsgEthereumTx`
An EVM state transition can be achieved by using the `MsgEthereumTx`.
This message encapsulates an Ethereum transaction data (`TxData`) as a `sdk.Msg`.
It contains the necessary transaction data fields.
Note, that the `MsgEthereumTx` implements both the [`sdk.Msg`](https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/types/tx_msg.go#L7-L29)
and [`sdk.Tx`](https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/types/tx_msg.go#L33-L41) interfaces.
Normally, SDK messages only implement the former, while the latter is a group of messages bundled together.
```go theme={null}
type MsgEthereumTx struct {
// inner transaction data
Data *types.Any `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
// DEPRECATED: encoded storage size of the transaction
Size_ float64 `protobuf:"fixed64,2,opt,name=size,proto3" json:"-"`
// transaction hash in hex format
Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty" rlp:"-"`
// ethereum signer address in hex format. This address value is checked
// against the address derived from the signature (V, R, S) using the
// secp256k1 elliptic curve
From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"`
}
```
This message field validation is expected to fail if:
* `From` field is defined and the address is invalid
* `TxData` stateless validation fails
The transaction execution is expected to fail if:
* Any of the custom `AnteHandler` Ethereum decorators checks fail:
* Minimum gas amount requirements for transaction
* Tx sender account doesn't exist or hasn't enough balance for fees
* Account sequence doesn't match the transaction `Data.AccountNonce`
* Message signature verification fails
* EVM contract creation (i.e `evm.Create`) fails, or `evm.Call` fails
#### Conversion
The `MsgEthreumTx` can be converted to the go-ethereum `Transaction` and `Message` types
in order to create and call evm contracts.
```go theme={null}
// AsTransaction creates an Ethereum Transaction type from the msg fields
func (msg MsgEthereumTx) AsTransaction() *ethtypes.Transaction {
txData, err := UnpackTxData(msg.Data)
if err != nil {
return nil
}
return ethtypes.NewTx(txData.AsEthereumData())
}
// AsMessage returns the transaction as a core.Message.
func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
msg := Message{
nonce: tx.Nonce(),
gasLimit: tx.Gas(),
gasPrice: new(big.Int).Set(tx.GasPrice()),
gasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
gasTipCap: new(big.Int).Set(tx.GasTipCap()),
to: tx.To(),
amount: tx.Value(),
data: tx.Data(),
accessList: tx.AccessList(),
isFake: false,
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap)
}
var err error
msg.from, err = Sender(s, tx)
return msg, err
}
```
#### Signing
In order for the signature verification to be valid, the `TxData` must contain the `v | r | s` values from the `Signer`.
Sign calculates a secp256k1 ECDSA signature and signs the transaction.
It takes a keyring signer and the chainID to sign an Ethereum transaction according to EIP-155 standard.
This method mutates the transaction as it populates the V, R, S fields of the Transaction's Signature.
The function will fail if the sender address is not defined for the msg
or if the sender is not registered on the keyring.
```go theme={null}
// Sign calculates a secp256k1 ECDSA signature and signs the transaction. It
// takes a keyring signer and the chainID to sign an Ethereum transaction according to
// EIP-155 standard.
// This method mutates the transaction as it populates the V, R, S
// fields of the Transaction's Signature.
// The function will fail if the sender address is not defined for the msg or if
// the sender is not registered on the keyring
func (msg *MsgEthereumTx) Sign(ethSigner ethtypes.Signer, keyringSigner keyring.Signer) error {
from := msg.GetFrom()
if from.Empty() {
return fmt.Errorf("sender address not defined for message")
}
tx := msg.AsTransaction()
txHash := ethSigner.Hash(tx)
sig, _, err := keyringSigner.SignByAddress(from, txHash.Bytes())
if err != nil {
return err
}
tx, err = tx.WithSignature(ethSigner, sig)
if err != nil {
return err
}
msg.FromEthereumTx(tx)
return nil
}
```
### TxData
The `MsgEthereumTx` supports the 3 valid Ethereum transaction data types from go-ethereum:
`LegacyTx`, `AccessListTx` and `DynamicFeeTx`.
These types are defined as protobuf messages
and packed into a `proto.Any` interface type in the `MsgEthereumTx` field.
* `LegacyTx`: [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) transaction type
* `DynamicFeeTx`: [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) transaction type.
Enabled by London hard fork block
* `AccessListTx`: [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) transaction type.
Enabled by Berlin hard fork block
### `LegacyTx`
The transaction data of regular Ethereum transactions.
```go theme={null}
type LegacyTx struct {
// nonce corresponds to the account nonce (transaction sequence).
Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
// gas price defines the value for each gas unit
GasPrice *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=gas_price,json=gasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"gas_price,omitempty"`
// gas defines the gas limit defined for the transaction.
GasLimit uint64 `protobuf:"varint,3,opt,name=gas,proto3" json:"gas,omitempty"`
// hex formatted address of the recipient
To string `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"`
// value defines the unsigned integer value of the transaction amount.
Amount *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,5,opt,name=value,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"value,omitempty"`
// input defines the data payload bytes of the transaction.
Data []byte `protobuf:"bytes,6,opt,name=data,proto3" json:"data,omitempty"`
// v defines the signature value
V []byte `protobuf:"bytes,7,opt,name=v,proto3" json:"v,omitempty"`
// r defines the signature value
R []byte `protobuf:"bytes,8,opt,name=r,proto3" json:"r,omitempty"`
// s define the signature value
S []byte `protobuf:"bytes,9,opt,name=s,proto3" json:"s,omitempty"`
}
```
This message field validation is expected to fail if:
* `GasPrice` is invalid (`nil` , negative or out of int256 bound)
* `Fee` (gasprice \* gaslimit) is invalid
* `Amount` is invalid (negative or out of int256 bound)
* `To` address is invalid (non valid ethereum hex address)
### `DynamicFeeTx`
The transaction data of EIP-1559 dynamic fee transactions.
```go theme={null}
type DynamicFeeTx struct {
// destination EVM chain ID
ChainID *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"chainID"`
// nonce corresponds to the account nonce (transaction sequence).
Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
// gas tip cap defines the max value for the gas tip
GasTipCap *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=gas_tip_cap,json=gasTipCap,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"gas_tip_cap,omitempty"`
// gas fee cap defines the max value for the gas fee
GasFeeCap *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,4,opt,name=gas_fee_cap,json=gasFeeCap,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"gas_fee_cap,omitempty"`
// gas defines the gas limit defined for the transaction.
GasLimit uint64 `protobuf:"varint,5,opt,name=gas,proto3" json:"gas,omitempty"`
// hex formatted address of the recipient
To string `protobuf:"bytes,6,opt,name=to,proto3" json:"to,omitempty"`
// value defines the the transaction amount.
Amount *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,7,opt,name=value,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"value,omitempty"`
// input defines the data payload bytes of the transaction.
Data []byte `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"`
Accesses AccessList `protobuf:"bytes,9,rep,name=accesses,proto3,castrepeated=AccessList" json:"accessList"`
// v defines the signature value
V []byte `protobuf:"bytes,10,opt,name=v,proto3" json:"v,omitempty"`
// r defines the signature value
R []byte `protobuf:"bytes,11,opt,name=r,proto3" json:"r,omitempty"`
// s define the signature value
S []byte `protobuf:"bytes,12,opt,name=s,proto3" json:"s,omitempty"`
}
```
This message field validation is expected to fail if:
* `GasTipCap` is invalid (`nil` , negative or overflows int256)
* `GasFeeCap` is invalid (`nil` , negative or overflows int256)
* `GasFeeCap` is less than `GasTipCap`
* `Fee` (gas price \* gas limit) is invalid (overflows int256)
* `Amount` is invalid (negative or overflows int256)
* `To` address is invalid (non-valid ethereum hex address)
* `ChainID` is `nil`
### `AccessListTx`
The transaction data of EIP-2930 access list transactions.
```go theme={null}
type AccessListTx struct {
// destination EVM chain ID
ChainID *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"chainID"`
// nonce corresponds to the account nonce (transaction sequence).
Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
// gas price defines the value for each gas unit
GasPrice *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,3,opt,name=gas_price,json=gasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"gas_price,omitempty"`
// gas defines the gas limit defined for the transaction.
GasLimit uint64 `protobuf:"varint,4,opt,name=gas,proto3" json:"gas,omitempty"`
// hex formatted address of the recipient
To string `protobuf:"bytes,5,opt,name=to,proto3" json:"to,omitempty"`
// value defines the unsigned integer value of the transaction amount.
Amount *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,6,opt,name=value,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"value,omitempty"`
// input defines the data payload bytes of the transaction.
Data []byte `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"`
Accesses AccessList `protobuf:"bytes,8,rep,name=accesses,proto3,castrepeated=AccessList" json:"accessList"`
// v defines the signature value
V []byte `protobuf:"bytes,9,opt,name=v,proto3" json:"v,omitempty"`
// r defines the signature value
R []byte `protobuf:"bytes,10,opt,name=r,proto3" json:"r,omitempty"`
// s define the signature value
S []byte `protobuf:"bytes,11,opt,name=s,proto3" json:"s,omitempty"`
}
```
This message field validation is expected to fail if:
* `GasPrice` is invalid (`nil` , negative or overflows int256)
* `Fee` (gas price \* gas limit) is invalid (overflows int256)
* `Amount` is invalid (negative or overflows int256)
* `To` address is invalid (non-valid ethereum hex address)
* `ChainID` is `nil`
## ABCI
The Application Blockchain Interface (ABCI) allows the application to interact with the Tendermint Consensus engine.
The application maintains several ABCI connections with Tendermint.
The most relevant for the `x/evm` is the [Consensus connection at Commit](https://docs.tendermint.com/v0.33/app-dev/app-development.html#consensus-connection).
This connection is responsible for block execution and calls the functionsΒ `InitChain`
(containing `InitGenesis`),Β `BeginBlock`,Β `DeliverTx`,Β `EndBlock`,Β `Commit`Β .
`InitChain`Β is only called the first time a new blockchain is started
andΒ `DeliverTx`Β is called for each transaction in the block.
### InitGenesis
`InitGenesis` initializes the EVM module genesis state by setting the `GenesisState` fields to the store.
In particular, it sets the parameters and genesis accounts (state and code).
### ExportGenesis
The `ExportGenesis` ABCI function exports the genesis state of the EVM module.
In particular, it retrieves all the accounts with their bytecode, balance and storage, the transaction logs,
and the EVM parameters and chain configuration.
### BeginBlock
The EVM module `BeginBlock` logic is executed prior to handling the state transitions from the transactions.
The main objective of this function is to:
* Set the context for the current block so that the block header, store, gas meter, etc.
are available to the `Keeper` once one of the `StateDB` functions are called during EVM state transitions.
* Set the EIP-155 `ChainID` number (obtained from the full chain-id),
in case it hasn't been set before during `InitChain`
### EndBlock
The EVM module `EndBlock` logic occurs after executing all the state transitions from the transactions.
The main objective of this function is to:
* Emit Block bloom events
* This is due for web3 compatibility as the Ethereum headers contain this type as a field.
The JSON-RPC service uses this event query to construct an Ethereum header from a Tendermint header.
* The block bloom filter value is obtained from the transient store and then emitted
## Hooks
The `x/evm` module implements an `EvmHooks` interface that extend and customize the `Tx` processing logic externally.
This supports EVM contracts to call native cosmos modules by
1. defining a log signature and emitting the specific log from the smart contract,
2. recognizing those logs in the native tx processing code, and
3. converting them to native module calls.
To do this, the interface includes a `PostTxProcessing` hook that registers custom `Tx` hooks in the `EvmKeeper`.
These `Tx` hooks are processed after the EVM state transition is finalized and doesn't fail.
Note that there are no default hooks implemented in the EVM module.
```go theme={null}
type EvmHooks interface {
// Must be called after tx is processed successfully, if return an error, the whole transaction is reverted.
PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error
}
```
## `PostTxProcessing`
`PostTxProcessing` is only called after an EVM transaction finished successfully
and delegates the call to underlying hooks.
If no hook has been registered, this function returns with a `nil` error.
```go theme={null}
func (k *Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error {
if k.hooks == nil {
return nil
}
return k.hooks.PostTxProcessing(k.Ctx(), msg, receipt)
}
```
It's executed in the same cache context as the EVM transaction,
if it returns an error, the whole EVM transaction is reverted,
if the hook implementor doesn't want to revert the tx, they can always return `nil` instead.
The error returned by the hooks is translated to a VM error `failed to process native logs`,
the detailed error message is stored in the return value.
The message is sent to native modules asynchronously, there's no way for the caller to catch and recover the error.
### Use Case: Call Native ERC20 Module on HyperPaxeer
Here is an example taken from the HyperPaxeer [erc20 module](erc20.md)
that shows how the `EVMHooks` supports a contract calling a native module
to convert ERC-20 Tokens into Cosmos native Coins.
Following the steps from above.
You can define and emit a `Transfer` log signature in the smart contract like this:
```solidity theme={null}
event Transfer(address indexed from, address indexed to, uint256 value);
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
```
The application will register a `BankSendHook` to the `EvmKeeper`.
It recognizes the ethereum tx `Log` and converts it to a call to the bank module's `SendCoinsFromAccountToAccount` method:
```go theme={null}
const ERC20EventTransfer = "Transfer"
// PostTxProcessing implements EvmHooks.PostTxProcessing
func (k Keeper) PostTxProcessing(
ctx sdk.Context,
msg core.Message,
receipt *ethtypes.Receipt,
) error {
params := h.k.GetParams(ctx)
if !params.EnableErc20 || !params.EnableEVMHook {
// no error is returned to allow for other post-processing txs
// to pass
return nil
}
erc20 := contracts.ERC20BurnableContract.ABI
for i, log := range receipt.Logs {
if len(log.Topics) < 3 {
continue
}
eventID := log.Topics[0] // event ID
event, err := erc20.EventByID(eventID)
if err != nil {
// invalid event for ERC20
continue
}
if event.Name != types.ERC20EventTransfer {
h.k.Logger(ctx).Info("emitted event", "name", event.Name, "signature", event.Sig)
continue
}
transferEvent, err := erc20.Unpack(event.Name, log.Data)
if err != nil {
h.k.Logger(ctx).Error("failed to unpack transfer event", "error", err.Error())
continue
}
if len(transferEvent) == 0 {
continue
}
tokens, ok := transferEvent[0].(*big.Int)
// safety check and ignore if amount not positive
if !ok || tokens == nil || tokens.Sign() != 1 {
continue
}
// check that the contract is a registered token pair
contractAddr := log.Address
id := h.k.GetERC20Map(ctx, contractAddr)
if len(id) == 0 {
// no token is registered for the caller contract
continue
}
pair, found := h.k.GetTokenPair(ctx, id)
if !found {
continue
}
// check that conversion for the pair is enabled
if !pair.Enabled {
// continue to allow transfers for the ERC20 in case the token pair is disabled
h.k.Logger(ctx).Debug(
"ERC20 token -> Cosmos coin conversion is disabled for pair",
"coin", pair.Denom, "contract", pair.Erc20Address,
)
continue
}
// ignore as the burning always transfers to the zero address
to := common.BytesToAddress(log.Topics[2].Bytes())
if !bytes.Equal(to.Bytes(), types.ModuleAddress.Bytes()) {
continue
}
// check that the event is Burn from the ERC20Burnable interface
// NOTE: assume that if they are burning the token that has been registered as a pair, they want to mint a Cosmos coin
// create the corresponding sdk.Coin that is paired with ERC20
coins := sdk.Coins{{Denom: pair.Denom, Amount: sdk.NewIntFromBigInt(tokens)}}
// Mint the coin only if ERC20 is external
switch pair.ContractOwner {
case types.OWNER_MODULE:
_, err = h.k.CallEVM(ctx, erc20, types.ModuleAddress, contractAddr, true, "burn", tokens)
case types.OWNER_EXTERNAL:
err = h.k.bankKeeper.MintCoins(ctx, types.ModuleName, coins)
default:
err = types.ErrUndefinedOwner
}
if err != nil {
h.k.Logger(ctx).Debug(
"failed to process EVM hook for ER20 -> coin conversion",
"coin", pair.Denom, "contract", pair.Erc20Address, "error", err.Error(),
)
continue
}
// Only need last 20 bytes from log.topics
from := common.BytesToAddress(log.Topics[1].Bytes())
recipient := sdk.AccAddress(from.Bytes())
// transfer the tokens from ModuleAccount to sender address
if err := h.k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, recipient, coins); err != nil {
h.k.Logger(ctx).Debug(
"failed to process EVM hook for ER20 -> coin conversion",
"tx-hash", receipt.TxHash.Hex(), "log-idx", i,
"coin", pair.Denom, "contract", pair.Erc20Address, "error", err.Error(),
)
continue
}
}
return nil
```
Lastly, register the hook in `app.go`:
```go theme={null}
app.EvmKeeper = app.EvmKeeper.SetHooks(app.Erc20Keeper)
```
## Events
The `x/evm` module emits the Cosmos SDK events after a state execution.
The EVM module emits events of the relevant transaction fields, as well as the transaction logs (ethereum events).
### MsgEthereumTx
| Type | Attribute Key | Attribute Value |
| ------------ | ------------------ | ----------------------- |
| ethereum\_tx | `"amount"` | `{amount}` |
| ethereum\_tx | `"recipient"` | `{hex_address}` |
| ethereum\_tx | `"contract"` | `{hex_address}` |
| ethereum\_tx | `"txHash"` | `{tendermint_hex_hash}` |
| ethereum\_tx | `"ethereumTxHash"` | `{hex_hash}` |
| ethereum\_tx | `"txIndex"` | `{tx_index}` |
| ethereum\_tx | `"txGasUsed"` | `{gas_used}` |
| tx\_log | `"txLog"` | `{tx_log}` |
| message | `"sender"` | `{eth_address}` |
| message | `"action"` | `"ethereum"` |
| message | `"module"` | `"evm"` |
Additionally, the EVM module emits an event during `EndBlock` for the filter query block bloom.
### ABCI
| Type | Attribute Key | Attribute Value |
| ------------ | ------------- | -------------------- |
| block\_bloom | `"bloom"` | `string(bloomBytes)` |
## Parameters
The evm module contains the following parameters:
### Params
| Key | Type | Default Value |
| --------------------- | ------------- | ------------------ |
| `EVMDenom` | string | `"ahpx"` |
| ~~`EnableCreate`~~ | bool | `true` |
| ~~`EnableCall`~~ | bool | `true` |
| `ExtraEIPs` | \[]int | TBD |
| `ChainConfig` | ChainConfig | See ChainConfig |
| `AllowUnprotectedTxs` | bool | false |
| `ActivePrecompiles` | \[]string | \[] |
| `AccessControl` | AccessControl | Permissionless EVM |
### EVM denom
The evm denomination parameter defines the token denomination
used on the EVM state transitions and gas consumption for EVM messages.
For example, on Ethereum, the `evm_denom` would be `ETH`.
In the case of HyperPaxeer, the default denomination is the **atto HyperPaxeer**.
In terms of precision, `HyperPaxeer` and `ETH` share the same value,
*i.e.* `1 HyperPaxeer = 10^18 atto HyperPaxeer` and `1 ETH = 10^18 wei`.
:::tip
Note: SDK applications that want to import the EVM module as a dependency
will need to set their own `evm_denom` (i.e not `"ahpx"`).
:::
### Enable Create
**(deprecated in v19.0.0)**
The enable create parameter toggles state transitions that use the `vm.Create` function.
When the parameter is disabled, it will prevent all contract creation functionality.
### Enable Transfer
**(deprecated in v19.0.0)**
The enable transfer toggles state transitions that use the `vm.Call` function.
When the parameter is disabled, it will prevent transfers between accounts and executing a smart contract call.
### Extra EIPs
The extra EIPs parameter defines the set of activateable Ethereum Improvement Proposals (**[EIPs](https://ethereum.org/en/eips/)**)
on the Ethereum VM `Config` that apply custom jump tables.
:::tip
NOTE: some of these EIPs are already enabled by the chain configuration, depending on the hard fork number.
:::
The supported activateable EIPS are:
* **[EIP 1344](https://eips.ethereum.org/EIPS/eip-1344)**
* **[EIP 1884](https://eips.ethereum.org/EIPS/eip-1884)**
* **[EIP 2200](https://eips.ethereum.org/EIPS/eip-2200)**
* **[EIP 2315](https://eips.ethereum.org/EIPS/eip-2315)**
* **[EIP 2929](https://eips.ethereum.org/EIPS/eip-2929)**
* **[EIP 3198](https://eips.ethereum.org/EIPS/eip-3198)**
* **[EIP 3529](https://eips.ethereum.org/EIPS/eip-3529)**
* **[EIP 3855](https://eips.ethereum.org/EIPS/eip-3855)**
### Chain Config
The `ChainConfig` is a protobuf wrapper type
that contains the same fields as the go-ethereum `ChainConfig` parameters,
but using `*sdk.Int` types instead of `*big.Int`.
By default, all block configuration fields but `ConstantinopleBlock`, are enabled at genesis (height 0).
#### ChainConfig Defaults
| Name | Default Value |
| ------------------- | -------------------------------------------------------------------- |
| HomesteadBlock | 0 |
| DAOForkBlock | 0 |
| DAOForkSupport | `true` |
| EIP150Block | 0 |
| EIP150Hash | `0x0000000000000000000000000000000000000000000000000000000000000000` |
| EIP155Block | 0 |
| EIP158Block | 0 |
| ByzantiumBlock | 0 |
| ConstantinopleBlock | 0 |
| PetersburgBlock | 0 |
| IstanbulBlock | 0 |
| MuirGlacierBlock | 0 |
| BerlinBlock | 0 |
| LondonBlock | 0 |
| ArrowGlacierBlock | 0 |
| GrayGlacierBlock | 0 |
| MergeNetsplitBlock | 0 |
| ShanghaiBlock | 0 |
| CancunBlock. | 0 |
### Allow Unprotected Transactions
This parameter enforces [EIP-155 replay protection](../concepts/replay-protection.md) globally for all nodes
partaking in consensus.
If disabled, this delegates control of replay protection to the individual nodes
(read more [here](../../validate/setup-and-configuration/configuration.md#eip-155-replay-protection)).
### Active Precompiles
This parameter governs which [EVM Extensions](../../develop/smart-contracts/evm-extensions/evm-extensions.md)
are enabled on the given network.
It accepts a list of addresses in Hex format,
which is evaluated in EVM transactions to only allow interactions
with the selected precompiled contracts.
### Access Control
(added in v19.0.0) This parameter enables detailed control of the EVM.
The former parameters `enable_create` and `enable_call` have been extended
to give exact control of who can access these features.
By default, the EVM is *permissionless*, meaning that everyone can deploy smart contracts
and send EVM transaction unless they have specifically been blacklisted.
The blacklisted addresses can be defined in the corresponding `AccessControlList`.
By setting the individual `AccessControlType` for either the create or call functionality as *restricted*,
the EVM does not accept further interactions with the specific functionality.
When defining the control type as being *permissioned*, the given list of addresses is
interpreted as a collection of whitelisted addresses, which are the only ones capable of
deploying contracts or calling the EVM respectively.
## Client
A user can query and interact with theΒ `evm`Β module using the CLI, JSON-RPC, gRPC or REST.
### CLI
Find below a list ofΒ `hyperpaxd`Β commands added with theΒ `x/evm`Β module.
You can obtain the full list by using theΒ `hyperpaxd -h`Β command.
#### Queries
TheΒ `query`Β commands allow users to queryΒ `evm`Β state.
**`code`**
Allows users to query the smart contract code at a given address.
```bash theme={null}
hyperpaxd query evm code ADDRESS [flags]
```
```bash theme={null}
# Example
$ hyperpaxd query evm code 0x7bf7b17da59880d9bcca24915679668db75f9397
# Output
code: "0xef616c92f3cfc9e92dc270d6acff9cea213cecc7020a76ee4395af09bdceb4837a1ebdb5735e11e7d3adb6104e0c3ac55180b4ddf5e54d022cc5e8837f6a4f971b"
```
**`storage`**
Allows users to query storage for an account with a given key and height.
```bash theme={null}
hyperpaxd query evm storage ADDRESS KEY [flags]
```
```bash theme={null}
# Example
$ hyperpaxd query evm storage 0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0 0 --height 0
# Output
value: "0x0000000000000000000000000000000000000000000000000000000000000000"
```
#### Transactions
TheΒ `tx`Β commands allow users to interact with theΒ `evm`Β module.
**`raw`**
Allows users to build cosmos transactions from raw ethereum transaction.
```bash theme={null}
hyperpaxd tx evm raw TX_HEX [flags]
```
```bash theme={null}
# Example
$ hyperpaxd tx evm raw 0xf9ff74c86aefeb5f6019d77280bbb44fb695b4d45cfe97e6eed7acd62905f4a85034d5c68ed25a2e7a8eeb9baf1b84
# Output
value: "0x0000000000000000000000000000000000000000000000000000000000000000"
```
### JSON-RPC
For an overview on the JSON-RPC methods and namespaces supported on HyperPaxeer,
please refer to [https://docs.paxeer.app/develop/api/ethereum-json-rpc/methodsl](https://docs.paxeer.app/develop/api/ethereum-json-rpc/methods)
### gRPC
#### Queries
| Verb | Method | Description |
| ------ | ------------------------------------------------------ | ---------------------------------------------------------------------------- |
| `gRPC` | `hyperpaxeer.evm.v1.Query/Account` | Get an Ethereum account |
| `gRPC` | `hyperpaxeer.evm.v1.Query/CosmosAccount` | Get an Ethereum account's Cosmos Address |
| `gRPC` | `hyperpaxeer.evm.v1.Query/ValidatorAccount` | Get an Ethereum account's from a validator consensus Address |
| `gRPC` | `hyperpaxeer.evm.v1.Query/Balance` | Get the balance of a the EVM denomination for a single EthAccount. |
| `gRPC` | `hyperpaxeer.evm.v1.Query/Storage` | Get the balance of all coins for a single account |
| `gRPC` | `hyperpaxeer.evm.v1.Query/Code` | Get the balance of all coins for a single account |
| `gRPC` | `hyperpaxeer.evm.v1.Query/Params` | Get the parameters of x/evm module |
| `gRPC` | `hyperpaxeer.evm.v1.Query/EthCall` | Implements the eth\_call rpc api |
| `gRPC` | `hyperpaxeer.evm.v1.Query/EstimateGas` | Implements the eth\_estimateGas rpc api |
| `gRPC` | `hyperpaxeer.evm.v1.Query/TraceTx` | Implements the debug\_traceTransaction rpc api |
| `gRPC` | `hyperpaxeer.evm.v1.Query/TraceBlock` | Implements the debug\_traceBlockByNumber and debug\_traceBlockByHash rpc api |
| `GET` | `/hyperpaxeer/evm/v1/account/{address}` | Get an Ethereum account |
| `GET` | `/hyperpaxeer/evm/v1/cosmos_account/{address}` | Get an Ethereum account's Cosmos Address |
| `GET` | `/hyperpaxeer/evm/v1/validator_account/{cons_address}` | Get an Ethereum account's from a validator consensus Address |
| `GET` | `/hyperpaxeer/evm/v1/balances/{address}` | Get the balance of a the EVM denomination for a single EthAccount. |
| `GET` | `/hyperpaxeer/evm/v1/storage/{address}/{key}` | Get the balance of all coins for a single account |
| `GET` | `/hyperpaxeer/evm/v1/codes/{address}` | Get the balance of all coins for a single account |
| `GET` | `/hyperpaxeer/evm/v1/params` | Get the parameters of x/evm module |
| `GET` | `/hyperpaxeer/evm/v1/eth_call` | Implements the eth\_call rpc api |
| `GET` | `/hyperpaxeer/evm/v1/estimate_gas` | Implements the eth\_estimateGas rpc api |
| `GET` | `/hyperpaxeer/evm/v1/trace_tx` | Implements the debug\_traceTransaction rpc api |
| `GET` | `/hyperpaxeer/evm/v1/trace_block` | Implements the debug\_traceBlockByNumber and debug\_traceBlockByHash rpc api |
#### Transactions
| Verb | Method | Description |
| ------ | ----------------------------------- | ------------------------------- |
| `gRPC` | `hyperpaxeer.evm.v1.Msg/EthereumTx` | Submit an Ethereum transactions |
| `POST` | `/hyperpaxeer/evm/v1/ethereum_tx` | Submit an Ethereum transactions |
# Feemarket
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/feemarket
# `feemarket`
## Abstract
This document specifies the feemarket module, which allows defining a global transaction fee for the network.
This module has been designed to support EIP-1559 in cosmos-sdk.
The `MempoolFeeDecorator` in `x/auth` module needs to be overwritten
to check the `baseFee` along with the `minimal-gas-prices` allowing
to implement a global fee mechanism which vary depending on the network activity.
For more reference to EIP-1559:
[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)
## Contents
1. **[Concepts](#concepts)**
2. **[State](#state)**
3. **[Begin Block](#begin-block)**
4. **[End Block](#end-block)**
5. **[Keeper](#keeper)**
6. **[Events](#events)**
7. **[Params](#params)**
8. **[Client](#client)**
9. **[AnteHandlers](#antehandlers)**
## Concepts
### EIP-1559: Fee Market
[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md) describes a pricing mechanism
that was proposed on Ethereum to improve to calculation of transaction fees.
It includes a fixed-per-block network fee that is burned
and dynamically expands/contracts block sizes to deal with peaks of network congestion.
Before EIP-1559 the transaction fee is calculated with
```
fee = gasPrice * gasLimit
```
where `gasPrice` is the price per gas and `gasLimit` describes the amount of gas required to perform the transaction.
The more complex operations a transaction requires, the higher the gas limit
(see [Executing EVM bytecode](evm.md#executing-evm-bytecode)).
To submit a transaction, the signer needs to specify the `gasPrice`.
With EIP-1559 enabled, the transaction fee is calculated with
```
fee = (baseFee + priorityTip) * gasLimit
```
where `baseFee` is the fixed-per-block network fee per gas
and `priorityTip` is an additional fee per gas that can be set optionally.
Note, that both the base fee and the priority tip are gas prices.
To submit a transaction with EIP-1559, the signer needs to specify the `gasFeeCap`,
which is the maximum fee per gas they are willing to pay in total.
Optionally, the `priorityTip` can be specified,
which covers both the priority fee and the block's network fee per gas (aka: base fee).
:::tip
The Cosmos SDK uses a different terminology for `gas` than Ethereum.
What is called `gasLimit` on Ethereum is called `gasWanted` on Cosmos.
You might encounter both terminologies on HyperPaxeer since it builds Ethereum on top of the SDK,
e.g. when using different wallets like Keplr for Cosmos and Metamask for Ethereum.
:::
### Base Fee
The base fee per gas (aka base fee) is a global gas price defined at the consensus level.
It is stored as a module parameter
and is adjusted at the end of each block
based on the total gas used in the previous block
and gas target (`block gas limit / elasticity multiplier`):
* it increases when blocks are above the gas target,
* it decreases when blocks are below the gas target.
Instead of burning the base fee (as implemented on Ethereum),
the `feemarket` module allocates the base fee
for regular [Cosmos SDK fee distribution](https://docs.cosmos.network/main/modules/distribution).
### Priority Tip
In EIP-1559, the `max_priority_fee_per_gas`, often referred to as `tip`,
is an additional gas price that can be added to the `baseFee` in order to incentivize transaction prioritization.
The higher the tip, the more likely the transaction is included in the block.
Until the Cosmos SDK version v0.46, however, there is no notion of transaction prioritization.
Thus, the tip for an EIP-1559 transaction on HyperPaxeer should be zero
(`MaxPriorityFeePerGas` JSON-RPC endpoint returns `0`).
Have a look at the [mempool](https://docs.paxeer.app/validate/setup-and-configuration/mempool) docs
to read more about how to leverage transaction prioritization.
### Effective Gas price
For EIP-1559 transactions (dynamic fee transactions) the effective gas price describes the maximum gas price
that a transaction is willing to provide.
It is derived from the transaction arguments and the base fee parameter.
Depending on which one is smaller, the effective gas price is either the `baseFee + tip` or the `gasFeeCap`
```
min(baseFee + gasTipCap, gasFeeCap)
```
### Local vs. Global Minimum Gas Prices
Minimum gas prices are used to discard spam transactions in the network,
by raising the cost of transactions to the point that it is not economically viable for the spammer.
This is achieved by defining a minimum gas price for accepting txs in the mempool
for both Cosmos and EVM transactions.
A transaction is discarded from the mempool
if it doesn't provide at least one of the two types of min gas prices:
Minimum gas prices are used to discard spam transactions in the network,
by raising the cost of transactions to the point that it is not economically viable for the spammer.
This is achieved by defining a minimum gas price for accepting txs in the mempool for both Cosmos and EVM transactions.
A transaction is discarded from the mempool if it doesn't provide at least one of the two types of min gas prices:
1. the local min gas prices that validators can set on their node config and
2. the global min gas price, which is set as a parameter in the `feemarket` module, which can be changed through governance.
The lower bound for a transaction gas price is determined by comparing of gas price bounds according to three cases:
1. If the effective gas price (`effective gas price = base fee + priority tip`)
or the local minimum gas price is lower than the global `MinGasPrice`
(`min-gas-price (local) < MinGasPrice (global) OR EffectiveGasPrice < MinGasPrice`),
then `MinGasPrice` is used as a lower bound.
2. If transactions are rejected due to having a gas price lower than `MinGasPrice`,
users need to resend the transactions with a gas price higher or equal to `MinGasPrice`.
3. If the effective gas price or the local `minimum-gas-price` is higher than the global `MinGasPrice`,
then the larger value of the two is used as a lower bound.
In the case of EIP-1559, users must increase the priority fee for their transactions to be valid.
The comparison of transaction gas price and the lower bound is implemented through AnteHandler decorators.
For EVM transactions, this is done in the `EthMempoolFeeDecorator` and `EthMinGasPriceDecorator` `AnteHandler`
and for Cosmos transactions in `NewMempoolFeeDecorator` and `MinGasPriceDecorator` `AnteHandler`.
:::tip
If the base fee decreases to a value below the global `MinGasPrice`, it is set to the `MinGasPrice`.
This is implemented, so that the base fee can't drop to gas prices
that wouldn't allow transactions to be accepted in the mempool, because of a higher `MinGasPrice`.
:::
## State
The x/feemarket module keeps in the state variable needed to the fee calculation:
Only BlockGasUsed in previous block needs to be tracked in state for the next base fee calculation.
| | Description | Key | Value | Store |
| ------------ | --------------------- | ----------- | ------------------ | ----- |
| BlockGasUsed | gas used in the block | `[]byte{1}` | `[]byte{gas_used}` | KV |
## Begin block
The base fee is calculated at the beginning of each block.
### Base Fee
#### Disabling base fee
We introduce two parameters : `NoBaseFee`and `EnableHeight`
`NoBaseFee` controls the feemarket base fee value.
If set to true, no calculation is done and the base fee returned by the keeper is zero.
`EnableHeight` controls the height we start the calculation.
* If `NoBaseFee = false` and `height < EnableHeight`,
the base fee value will be equal to `base_fee` defined in the genesis
and the `BeginBlock` will return without further computation.
* If `NoBaseFee = false` and `height >= EnableHeight`,
the base fee is dynamically calculated upon each block at `BeginBlock`.
Those parameters allow us to introduce a static base fee or activate the base fee at a later stage.
#### Enabling base fee
To enable EIP-1559 with the EVM, the following parameters should be set :
* NoBaseFee should be false
* EnableHeight should be set to a positive integer >= upgrade height.
It defines at which height the chain starts the base fee adjustment
* LondonBlock evm's param should be set to a positive integer >= upgrade height.
It defines at which height the chain starts to accept EIP-1559 transactions.
#### Calculation
The base fee is initialized at `EnableHeight` to the `InitialBaseFee` value defined in the genesis file.
The base fee is after adjusted according to the total gas used in the previous block.
```go theme={null}
parent_gas_target = parent_gas_limit / ELASTICITY_MULTIPLIER
if EnableHeight == block.number
base_fee = INITIAL_BASE_FEE
else if parent_gas_used == parent_gas_target:
base_fee = parent_base_fee
else if parent_gas_used > parent_gas_target:
gas_used_delta = parent_gas_used - parent_gas_target
base_fee_delta = max(parent_base_fee * gas_used_delta / parent_gas_target / BASE_FEE_MAX_CHANGE_DENOMINATOR, 1)
base_fee = parent_base_fee + base_fee_delta
else:
gas_used_delta = parent_gas_target - parent_gas_used
base_fee_delta = parent_base_fee * gas_used_delta / parent_gas_target / BASE_FEE_MAX_CHANGE_DENOMINATOR
base_fee = parent_base_fee - base_fee_delta
```
## End block
The `block_gas_used` value is updated at the end of each block.
### Block Gas Used
The total gas used by current block is stored in the KVStore at `EndBlock`.
It is initialized to `block_gas` defined in the genesis.
## Keeper
The feemarket module provides this exported keeper
that can be passed to other modules,
which require access to the base fee value
```go theme={null}
type Keeper interface {
GetBaseFee(ctx sdk.Context) *big.Int
}
```
## Events
The `x/feemarket` module emits the following events:
### BeginBlocker
| Type | Attribute Key | Attribute Value |
| ----------- | ------------- | ----------------- |
| fee\_market | base\_fee | `{baseGasPrices}` |
### EndBlocker
| Type | Attribute Key | Attribute Value |
| ---------- | ------------- | ---------------- |
| block\_gas | height | `{blockHeight}` |
| block\_gas | amount | `{blockGasUsed}` |
## Parameters
The `x/feemarket` module contains the following parameters:
| Key | Type | Default Values | Description |
| ------------------------ | ------- | -------------- | ----------------------------------------------------------------------------------------------------------------------- |
| NoBaseFee | bool | false | control the base fee adjustment |
| BaseFeeChangeDenominator | uint32 | 8 | bounds the amount the base fee that can change between blocks |
| ElasticityMultiplier | uint32 | 2 | bounds the threshold which the base fee will increase or decrease depending on the total gas used in the previous block |
| BaseFee | uint32 | 1000000000 | base fee for EIP-1559 blocks |
| EnableHeight | uint32 | 0 | height which enable fee adjustment |
| MinGasPrice | sdk.Dec | 0 | global minimum gas price that needs to be paid to include a transaction in a block |
## Client
### CLI
A user can query and interact with theΒ `feemarket`Β module using the CLI.
#### Queries
TheΒ `query`Β commands allow users to queryΒ `feemarket`Β state.
```bash theme={null}
hyperpaxd query feemarket --help
```
##### Base Fee
The `base-fee` command allows users to query the block base fee by height.
```bash theme={null}
hyperpaxd query feemarket base-fee [flags]
```
Example:
```bash theme={null}
hyperpaxd query feemarket base-fee ...
```
Example Output:
```
base_fee: "512908936"
```
##### Block Gas
The `block-gas` command allows users to query the block gas by height.
```bash theme={null}
hyperpaxd query feemarket block-gas [flags]
```
Example:
```bash theme={null}
hyperpaxd query feemarket block-gas ...
```
Example Output:
```
gas: "21000"
```
##### Params
The `params` command allows users to query the module params.
```bash theme={null}
hyperpaxd query params subspace [subspace] [key] [flags]
```
Example:
```bash theme={null}
hyperpaxd query params subspace feemarket ElasticityMultiplier ...
```
Example Output:
```
key: ElasticityMultiplier
subspace: feemarket
value: "2"
```
### gRPC
#### Queries
| Verb | Method | Description |
| ------ | ----------------------------------------- | ---------------------- |
| `gRPC` | `hyperpaxeer.feemarket.v1.Query/Params` | Get the module params |
| `gRPC` | `hyperpaxeer.feemarket.v1.Query/BaseFee` | Get the block base fee |
| `gRPC` | `hyperpaxeer.feemarket.v1.Query/BlockGas` | Get the block gas used |
| `GET` | `/hyperpaxeer/feemarket/v1/params` | Get the module params |
| `GET` | `/hyperpaxeer/feemarket/v1/base_fee` | Get the block base fee |
| `GET` | `/hyperpaxeer/feemarket/v1/block_gas` | Get the block gas used |
## AnteHandlers
The `x/feemarket` module provides `AnteDecorator`s that are recursively chained together
into a single [`Antehandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.43.0-alpha1/docs/architecture/adr-010-modular-antehandler.md).
These decorators perform basic validity checks on an Ethereum or Cosmos SDK transaction,
such that it could be thrown out of the transaction Mempool.
Note that the `AnteHandler` is run for every transaction
and called on both `CheckTx` and `DeliverTx`.
### Decorators
### `MinGasPriceDecorator`
Rejects Cosmos SDK transactions with transaction fees lower than `MinGasPrice * GasLimit`.
### `EthMinGasPriceDecorator`
Rejects EVM transactions with transactions fees lower than `MinGasPrice * GasLimit`.
* For `LegacyTx` and `AccessListTx`, the `GasPrice * GasLimit` is used.
* For EIP-1559 (*aka.* `DynamicFeeTx`), the `EffectivePrice * GasLimit` is used.
:::tip
**Note**: For dynamic transactions,
if the `feemarket` formula results in a `BaseFee` that lowers `EffectivePrice < MinGasPrices`,
the users must increase the `GasTipCap` (priority fee) until `EffectivePrice > MinGasPrices`.
Transactions with `MinGasPrices * GasLimit < transaction fee < EffectiveFee`
are rejected by the `feemarket` `AnteHandle`.
:::
### `EthGasConsumeDecorator`
Calculates the effective fees to deduct and the tx priority according to EIP-1559 spec,
then deducts the fees and sets the tx priority in the response.
```
effectivePrice = min(baseFee + tipFeeCap, gasFeeCap)
effectiveTipFee = effectivePrice - baseFee
priority = effectiveTipFee / DefaultPriorityReduction
```
When there are multiple messages in the transaction, choose the lowest priority in them.
# Modules
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/index
Cosmos SDK modules and how they compose the protocol.
# List of Modules
Here is a list of all production-grade modules that can be used on the HyperPaxeer blockchain, along with their respective documentation:
* [epochs](epochs.md) - Executes custom state transitions every period (*aka* epoch).
* [erc20](erc20.md) - Trustless, on-chain bidirectional internal conversion of tokens
between HyperPaxeer' EVM and Cosmos runtimes.
* [evm](evm.md) - Smart Contract deployment and execution on Cosmos
* [feemarket](feemarket.md) - Fee market implementation based on the EIP-1559 specification.
* [inflation](inflation.md) - Mint tokens and allocate them to staking rewards and the community pool.
* [paxoracle](paxoracle.md) - Validator-submitted price feeds exposed to EVM contracts through the `0x903` OracleAggregator precompile.
* [vesting](vesting.md) - Vesting accounts with lockup and clawback capabilities.
## Cosmos SDK
HyperPaxeer uses the following Cosmos SDK modules:
* [auth](https://docs.cosmos.network/main/modules/auth) - Authentication of accounts and transactions for Cosmos SDK applications.
* [authz](https://docs.cosmos.network/main/modules/authz) -
Authorization for accounts to perform actions on behalf of other accounts.
* [bank](https://docs.cosmos.network/main/modules/bank) - Token transfer functionalities.
* [capability](https://ibc.cosmos.network/main/ibc/capability-module) - Object capability implementation.
* [distribution](https://docs.cosmos.network/main/modules/distribution) - Fee distribution, and staking token provision distribution.
* [evidence](https://docs.cosmos.network/main/modules/evidence) - Evidence handling for double signing, misbehaviour, etc.
* [feegrant](https://docs.cosmos.network/main/modules/feegrant) - Grant fee allowances for executing transactions.
* [genutil](https://github.com/cosmos/cosmos-sdk/tree/main/x/genutil) -
variety of genesis utility functionalities for usage within a blockchain application
* [gov](https://docs.cosmos.network/main/modules/gov) - On-chain proposals and voting.
* [params](https://docs.cosmos.network/main/modules/params) - Globally available parameter store.
* [slashing](https://docs.cosmos.network/main/modules/slashing) - Validator punishment mechanisms.
* [staking](https://docs.cosmos.network/main/modules/staking) - Proof-of-Stake layer for public blockchains.
* [upgrade](https://docs.cosmos.network/main/modules/upgrade) - Software upgrades handling and coordination.
## IBC
HyperPaxeer uses the following the IBC modules for the SDK:
* [interchain-accounts](https://ibc.cosmos.network/main/apps/interchain-accounts/overview.html)
* [transfer](https://ibc.cosmos.network/main/apps/transfer/overview.html)
# Inflation
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/inflation
# `inflation`
## Abstract
The `x/inflation` module mints new HyperPaxeer tokens and allocates them in daily
epochs according to the [HyperPaxeer Token
Model](https://Paxeer-Network.blog/the-HyperPaxeer-token-model-edc07014978b) distribution to
* Community Pool `50%`.
* Staking Rewards `50%`,
* Usage Incentives: `0%`,
It replaces the Cosmos SDK `x/mint` module, that other Cosmos chains are using.
The allocation of new coins incentivizes specific behaviour in the HyperPaxeer network.
Inflation allocates funds to 1) the community pool(managed by sdk `x/distribution` module) to fund spending proposals,
and 2) the `Fee Collector account` (in the sdk `x/auth` module) to increase staking rewards.
The now deprecated `x/incentives` module account (3) does not accrue tokens anymore.
## Contents
1. **[Concepts](#concepts)**
2. **[State](#state)**
3. **[Hooks](#hooks)**
4. **[Events](#events)**
5. **[Parameters](#parameters)**
6. **[Clients](#clients)**
## Concepts
### Inflation
In a Proof of Stake (PoS) blockchain, inflation is used as a tool to incentivize
participation in the network. Inflation creates and distributes new tokens to
participants who can use their tokens to either interact with the protocol or
stake their assets to earn rewards and vote for governance proposals.
Especially in an early stage of a network, where staking rewards are high and
there are fewer possibilities to interact with the network, inflation can be
used as the major tool to incentivize staking and thereby securing the network.
With more stakers, the network becomes increasingly stable and decentralized. It
becomes *stable*, because assets are locked up instead of causing price changes
through trading. And it becomes *decentralized,* because the power to vote for
governance proposals is distributed amongst more people.
### HyperPaxeer Token Model
The HyperPaxeer Token Model outlines how the HyperPaxeer network is secured through a
balanced incentivized interest from users, developers and validators. In this
model, inflation plays a major role in sustaining this balance. With an initial
supply of 200 million and over 300 million tokens being issued through inflation
during the first year, the model suggests an exponential decline in inflation to
issue 1 billion HyperPaxeer tokens within the first 4 years.
We implement two different inflation mechanisms to support the token model:
1. linear inflation for team vesting and
2. exponential inflation for staking rewards and community pool.
#### Linear Inflation - Team Vesting
The Team Vesting distribution in the Token Model is implemented in a way that
minimized the amount of taxable events. An initial supply of 200M allocated to
`vesting accounts` at genesis. This amount is equal to the total inflation
allocated for team vesting after 4 years (`20% * 1B = 200M`). Over time,
`unvested` tokens on these accounts are converted into `vested` tokens at a
linear rate. Team members cannot delegate, transfer or execute Ethereum
transaction with `unvested` tokens until they are unlocked represented as
`vested` tokens.
#### Exponential Inflation - **The Half Life**
The inflation distribution for staking and community pool is
implemented through an exponential formula, a.k.a. the Half Life.
Inflation is minted in daily epochs. During a period of 365 epochs (one year),
a daily provision (`epochProvison`) of HyperPaxeer tokens is minted
and allocated to staking rewards and the community pool.
The epoch provision depends on module parameters and is recalculated at the end of every epoch.
The calculation of the epoch provision is done according to the following formula:
```latex theme={null}
periodProvision = exponentialDecay * bondingIncentive
f(x) = (a * (1 - r) ^ x + c) * (1 + maxVariance * (1 - bondedRatio / bondingTarget))
epochProvision = periodProvision / epochsPerPeriod
where (with default values):
x = variable = year
a = 300,000,000 = initial value
r = 0.5 = decay factor
c = 9,375,000 = long term supply
bondedRatio = variable = fraction of the staking tokens which are currently bonded
maxVariance = 0.0 = the max amount to increase inflation
bondingTarget = 0.66 = our optimal bonded ratio
```
```latex theme={null}
Example with bondedRatio = bondingTarget:
period periodProvision cumulated epochProvision
f(0) 309 375 000 309 375 000 847 602
f(1) 159 375 000 468 750 000 436 643
f(2) 84 375 000 553 125 000 231 164
f(3) 46 875 000 600 000 000 128 424
```
Note, that after [discussion](https://www.mintscan.io/Paxeer-Network/proposals/258)
with the validator community, it was decided to decrease the inflation to 1/3
during the upgrade to [v16.0.0](https://www.mintscan.io/Paxeer-Network/proposals/265).
## State
### State Objects
The `x/inflation` module keeps the following objects in state:
| State Object | Description | Key | Value | Store |
| --------------- | ------------------------------ | ----------- | ------------------------- | ----- |
| Period | Period Counter | `[]byte{1}` | `[]byte{period}` | KV |
| EpochIdentifier | Epoch identifier bytes | `[]byte{3}` | `[]byte{epochIdentifier}` | KV |
| EpochsPerPeriod | Epochs per period bytes | `[]byte{4}` | `[]byte{epochsPerPeriod}` | KV |
| SkippedEpochs | Number of skipped epochs bytes | `[]byte{5}` | `[]byte{skippedEpochs}` | KV |
#### Period
Counter to keep track of amount of past periods, based on the epochs per period.
#### EpochIdentifier
Identifier to trigger epoch hooks.
#### EpochsPerPeriod
Amount of epochs in one period
### Genesis State
The `x/inflation` module's `GenesisState` defines the state necessary for
initializing the chain from a previously exported height. It contains the module
parameters, the current period, epoch identifier, epochs per period and
the number of skipped epochs.
:
```go theme={null}
type GenesisState struct {
// params defines all the parameters of the module.
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
// amount of past periods, based on the epochs per period param
Period uint64 `protobuf:"varint,2,opt,name=period,proto3" json:"period,omitempty"`
// inflation epoch identifier
EpochIdentifier string `protobuf:"bytes,3,opt,name=epoch_identifier,json=epochIdentifier,proto3" json:"epoch_identifier,omitempty"`
// number of epochs after which inflation is recalculated
EpochsPerPeriod int64 `protobuf:"varint,4,opt,name=epochs_per_period,json=epochsPerPeriod,proto3" json:"epochs_per_period,omitempty"`
// number of epochs that have passed while inflation is disabled
SkippedEpochs uint64 `protobuf:"varint,5,opt,name=skipped_epochs,json=skippedEpochs,proto3" json:"skipped_epochs,omitempty"`
}
```
## Hooks
The `x/inflation` module implements the `AfterEpochEnd` hook from the
`x/epoch` module in order to allocate inflation.
### Epoch Hook: Inflation
The epoch hook handles the inflation logic which is run at the end of each
epoch. It is responsible for minting and allocating the epoch mint provision as
well as updating it:
1. Check if inflation is disabled. If it is, skip inflation, increment number
of skipped epochs and return without proceeding to the next steps.
2. A block is committed, that signalizes that an `epoch` has ended (block
`header.Time` has surpassed `epoch_start` + `epochIdentifier`).
3. Mint coin in amount of calculated `epochMintProvision` and allocate according to
inflation distribution to staking rewards and community pool.
4. If a period ends with the current epoch, increment the period by `1` and set new value to the store.
## Events
The `x/inflation` module emits the following events:
### Inflation
| Type | Attribute Key | Attribute Value |
| ----------- | -------------------- | --------------------------------------------- |
| `inflation` | `"epoch_provisions"` | `{fmt.Sprintf("%d", epochNumber)}` |
| `inflation` | `"epoch_number"` | `{strconv.FormatUint(uint64(in.Epochs), 10)}` |
| `inflation` | `"amount"` | `{mintedCoin.Amount.String()}` |
## Parameters
The `x/inflation` module contains the parameters described below. All parameters
can be modified via governance.
| Key | Type | Default Value |
| ------------------------------------- | ---------------------- | --------------------------------------------------- |
| `ParamStoreKeyMintDenom` | string | `evm.DefaultEVMDenom` // βahpxβ |
| `ParamStoreKeyExponentialCalculation` | ExponentialCalculation | `A: sdk.NewDec(int64(300_000_000))` |
| | | `R: sdk.NewDecWithPrec(50, 2)` |
| | | `C: sdk.NewDec(int64(9_375_000))` |
| | | `BondingTarget: sdk.NewDecWithPrec(66, 2)` |
| | | `MaxVariance: sdk.ZeroDec()` |
| `ParamStoreKeyInflationDistribution` | InflationDistribution | `StakingRewards: sdk.NewDecWithPrec(500000000, 9)` |
| | | `UsageIncentives: sdk.NewDecWithPrec(000000000, 9)` |
| | | `CommunityPool: sdk.NewDecWithPrec(500000000, 9)` |
| `ParamStoreKeyEnableInflation` | bool | `true` |
### Mint Denom
The `ParamStoreKeyMintDenom` parameter sets the denomination in which new coins are minted.
### Exponential Calculation
The `ParamStoreKeyExponentialCalculation` parameter holds all values required for the
calculation of the `epochMintProvision`. The values `A`, `R` and `C` describe
the decrease of inflation over time. The `BondingTarget` and `MaxVariance`
allow for an increase in inflation, which is automatically regulated by the
`bonded ratio`, the portion of staked tokens in the network. The exact formula
can be found under
[Concepts](#concepts).
### Inflation Distribution
The `ParamStoreKeyInflationDistribution` parameter defines the distribution in which
inflation is allocated through minting on each epoch
(`stakingRewards`, `CommunityPool`).
### Enable Inflation
The `ParamStoreKeyEnableInflation` parameter enables the daily inflation. If it is disabled,
no tokens are minted and the number of skipped epochs increases for each passed
epoch.
## Clients
A user can query the `x/inflation` module using the CLI, JSON-RPC, gRPC or
REST.
### CLI
Find below a list ofΒ `hyperpaxd`Β commands added with theΒ `x/inflation`Β module. You
can obtain the full list by using theΒ `hyperpaxd -h`Β command.
#### Queries
TheΒ `query`Β commands allow users to queryΒ `inflation`Β state.
**`period`**
Allows users to query the current inflation period.
```bash theme={null}
hyperpaxd query inflation period [flags]
```
**`epoch-mint-provision`**
Allows users to query the current inflation epoch provisions value.
```bash theme={null}
hyperpaxd query inflation epoch-mint-provision [flags]
```
**`skipped-epochs`**
Allows users to query the current number of skipped epochs.
```bash theme={null}
hyperpaxd query inflation skipped-epochs [flags]
```
**`total-supply`**
Allows users to query the total supply of tokens in circulation.
```bash theme={null}
hyperpaxd query inflation total-supply [flags]
```
**`inflation-rate`**
Allows users to query the inflation rate of the current period.
```bash theme={null}
hyperpaxd query inflation inflation-rate [flags]
```
**`params`**
Allows users to query the current inflation parameters.
```bash theme={null}
hyperpaxd query inflation params [flags]
```
#### Proposals
**Update Params**
Allows users to submit a `MsgUpdateParams` with the desired changes on the `x/inflation` module parameters.
To do this, you will have to provide a JSON file with the correspondiong message in the `submit-proposal` command.
For more information on how to draft a proposal, refer to the [Drafting a proposal section](../Paxeer-Network-cli/proposal-draft.md).
```bash theme={null}
hyperpaxd tx gov submit-proposal proposal.json [flags]
```
### gRPC
#### Queries
| Verb | Method | Description |
| ------ | --------------------------------------------------- | --------------------------------------------- |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/Period` | Gets current inflation period |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/EpochMintProvision` | Gets current inflation epoch provisions value |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/Params` | Gets current inflation parameters |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/SkippedEpochs` | Gets current number of skipped epochs |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/TotalSupply` | Gets current total supply |
| `gRPC` | `HyperPaxeer.inflation.v1.Query/InflationRate` | Gets current inflation rate |
| `GET` | `/Paxeer-Network/inflation/v1/period` | Gets current inflation period |
| `GET` | `/Paxeer-Network/inflation/v1/epoch_mint_provision` | Gets current inflation epoch provisions value |
| `GET` | `/Paxeer-Network/inflation/v1/skipped_epochs` | Gets current number of skipped epochs |
| `GET` | `/Paxeer-Network/inflation/v1/total_supply` | Gets current total supply |
| `GET` | `/Paxeer-Network/inflation/v1/inflation_rate` | Gets current inflation rate |
| `GET` | `/Paxeer-Network/inflation/v1/params` | Gets current inflation parameters |
# x/paxoracle
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/paxoracle
Validator oracle module backing the OracleAggregator precompile
## Overview
`x/paxoracle` stores validator-submitted market prices and exposes aggregated prices to EVM contracts through the OracleAggregator precompile at `0x0000000000000000000000000000000000000903`.
The module supports PaxSpot, HyperPax Perps, and other protocols that need validator-consensus price data with sub-second chain finality.
## EVM precompile
```solidity theme={null}
interface IOracleAggregator {
function getValidatorPrice(bytes32 marketId)
external
view
returns (int256 price, uint256 quorum, uint256 timestamp);
function submitPrice(bytes32 marketId, int256 price, uint256 confidence)
external
returns (bool success);
}
```
| Field | Meaning |
| ------------ | -------------------------------------------------------------- |
| `marketId` | `bytes32` market identifier, commonly `keccak256("BTC/USD")` |
| `price` | signed 18-decimal fixed-point price |
| `confidence` | validator confidence value, typically `0 < confidence <= 1e18` |
| `quorum` | number of validator attestations included in the aggregate |
| `timestamp` | block timestamp or block-derived timestamp for the aggregate |
## Read a validator price
```solidity theme={null}
IOracleAggregator constant VOM =
IOracleAggregator(0x0000000000000000000000000000000000000903);
function getBtcUsd() external view returns (int256 price, uint256 quorum) {
(price, quorum,) = VOM.getValidatorPrice(keccak256("BTC/USD"));
}
```
## Submit a validator price
Only active validators can submit prices. Non-validator addresses should use `getValidatorPrice()` for reads and should not attempt to post attestations.
```solidity theme={null}
IOracleAggregator constant VOM =
IOracleAggregator(0x0000000000000000000000000000000000000903);
function submitBtcUsd(int256 price) external returns (bool) {
return VOM.submitPrice({
marketId: keccak256("BTC/USD"),
price: price,
confidence: 1e18
});
}
```
```typescript submit-price.ts theme={null}
import { createWalletClient, http, keccak256, parseUnits, stringToBytes } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { hyperpaxeer } from './chains'
const account = privateKeyToAccount(process.env.VALIDATOR_EVM_PRIVATE_KEY as `0x${string}`)
const wallet = createWalletClient({
account,
chain: hyperpaxeer,
transport: http('https://public-rpc.paxeer.app/rpc'),
})
await wallet.writeContract({
address: '0x0000000000000000000000000000000000000903',
abi: [{
type: 'function',
name: 'submitPrice',
stateMutability: 'nonpayable',
inputs: [
{ name: 'marketId', type: 'bytes32' },
{ name: 'price', type: 'int256' },
{ name: 'confidence', type: 'uint256' },
],
outputs: [{ name: 'success', type: 'bool' }],
}],
functionName: 'submitPrice',
args: [
keccak256(stringToBytes('BTC/USD')),
parseUnits('97250', 18),
parseUnits('1', 18),
],
})
```
## Aggregation model
`x/paxoracle` verifies submissions against the active validator set, filters stale submissions, and returns a confidence-weighted median for each market.
| Step | Description |
| ---------------- | ------------------------------------------------------------------ |
| Validator check | The submitter must be an active validator |
| Market lookup | The `marketId` maps to an enabled market |
| Staleness filter | Old attestations are excluded from the aggregate |
| Quorum check | The aggregate must include enough valid submissions |
| Median | Valid submissions are aggregated into a confidence-weighted median |
## Common failure modes
| Failure | Cause |
| ------------------ | ------------------------------------------------------------- |
| Submit reverts | Caller is not an active validator |
| No price returned | Market has no valid recent submissions |
| Quorum too low | Too few validators submitted within the freshness window |
| Invalid confidence | Confidence is zero or outside the accepted range |
| Stale aggregate | Submissions are older than the configured staleness threshold |
## Related docs
* [PaxSpot precompiles](/paxspot/precompiles)
* [EVM extensions](/develop/smart-contracts/list-evm-extensions)
* [Current network facts](/current-network)
# Vesting
Source: https://sidiorresearchlabs.mintlify.app/protocol/modules/vesting
# `vesting`
## Abstract
This document specifies the internalΒ `x/vesting` module of the HyperPaxeer Hub.
The `x/vesting` module introduces the `ClawbackVestingAccount`, a new vesting account type
that implements the Cosmos SDK [`VestingAccount`](https://docs.cosmos.network/main/modules/auth/vesting#vesting-account-types)
interface.
This account is used to allocate tokens that are subject to vesting, lockup, and clawback.
The `ClawbackVestingAccount` allows any two parties to agree on a future rewarding schedule,
where tokens are granted permissions over time.
The parties can use this account to enforce legal contracts or commit to mutual long-term interests.
In this commitment, vesting is the mechanism for gradually earning permission to transfer and delegate allocated tokens.
Additionally, the lockup provides a mechanism to prevent the right to transfer allocated tokens
and perform Ethereum transactions from the account.
Both vesting and lockup are defined in schedules at account creation.
At any time, the funder of a `ClawbackVestingAccount` can perform a clawback to retrieve unvested tokens.
The circumstances under which a clawback should be performed can be agreed upon in a contract
(e.g. smart contract).
For HyperPaxeer, the `ClawbackVestingAccount` is used to allocate tokens to core team members and advisors
to incentivize long-term participation in the project.
## Contents
1. **[Concepts](#concepts)**
2. **[State](#state-transitions)**
3. **[State Transitions](#state-transitions)**
4. **[Transactions](#transactions)**
5. **[AnteHandlers](#antehandlers)**
6. **[Events](#events)**
7. **[Clients](#clients)**
## References
* SDK vesting specification: [https://docs.cosmos.network/main/modules/auth/vesting](https://docs.cosmos.network/main/modules/auth/vesting)
* SDK vesting implementation: [https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/vesting](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/vesting)
* Agoricβs Vesting Clawback Account: [https://github.com/Agoric/agoric-sdk/issues/4085](https://github.com/Agoric/agoric-sdk/issues/4085)
* Agoricβs `vestcalc` tool: [https://github.com/agoric-labs/cosmos-sdk/tree/Agoric/x/auth/vesting/cmd/vestcalc](https://github.com/agoric-labs/cosmos-sdk/tree/Agoric/x/auth/vesting/cmd/vestcalc)
## Concepts
### Vesting
Vesting describes the process of converting `unvested` into `vested` tokens
without transferring the ownership of those tokens.
In an unvested state, tokens cannot be transferred to other accounts, delegated to validators, or used for governance.
A vesting schedule describes the amount and time at which tokens are vested.
The duration until which the first tokens are vested is called the `cliff`.
### Lockup
The lockup describes the schedule by which tokens are converted from a `locked` to an `unlocked` state.
As long as all tokens are locked, the account cannot perform any transaction
that spend HyperPaxeer. However, the account can perform transactions that don't spend HyperPaxeer tokens.
Additionally, locked tokens cannot be transferred to other accounts.
In the case in which tokens are both locked and vested at the same time,
it is possible to delegate them to validators, but not transfer them to other accounts.
The following table summarizes the actions that are allowed for tokens
that are subject to the combination of vesting and lockup:
| Token Status | Transfer | Delegate | Vote | Eth Txs that spend HyperPaxeer\*\* | Eth Txs that don't spend HyperPaxeer (amount = 0)\*\* |
| ----------------------- | :------: | :------: | :--: | :--------------------------------: | :---------------------------------------------------: |
| `locked` & `unvested` | β | β | β | β | β |
| `locked` & `vested` | β | β | β | β | β |
| `unlocked` & `unvested` | β | β | β | β | β |
| `unlocked` & `vested`\* | β | β | β | β | β |
\*Staking rewards are unlocked and vested
\*\*EVM transactions only fail if they involve sending locked or unvested HyperPaxeer tokens,
e.g. send HyperPaxeer to EOA or Smart Contract (fails if amount > 0 ).
### Schedules
Vesting and lockup schedules specify the amount and time at which tokens are vested or unlocked.
They are defined as [`periods`](https://docs.cosmos.network/main/modules/auth/vesting#period)
where each period has its own length and amount.
A typical vesting schedule for instance would be defined starting with a one-year period to represent the vesting cliff,
followed by several monthly vesting periods until the total allocated vesting amount is vested.
Vesting or lockup schedules can be easily created
with Agoricβs [`vestcalc`](https://github.com/agoric-labs/cosmos-sdk/tree/Agoric/x/auth/vesting/cmd/vestcalc) tool.
E.g.
to calculate a four-year vesting schedule with a one year cliff, starting in January 2022, you can run vestcalc with:
```bash theme={null}
vestcalc --write --start=2022-01-01 --coins=200000000000000000000000ahpx --months=48 --cliffs=2023-01-01
```
### Clawback
In case a `ClawbackVestingAccount`'s underlying commitment or contract is breached,
the clawback provides a mechanism to return unvested funds. The account authorized to perform the clawback is
defined during `ClawbackVestingAccount` account creation. It can be:
* The governance module if allowed
* The address specified as the `FunderAddress`
It should be noted that the information if an account has governance clawback enabled or not is not stored with
the account itself but it is stored directly in the vesting module.
When a clawback is initiated, or by the funder or the governance, unvested tokens are send to the destination
address specified in the clawback message. If no destination address is specified, the default is to return
tokens to the funder.
## State
### State Objects
The `x/vesting` module does not keep objects in its own store.
Instead, it uses the SDK `auth` module to store account objects in state
using the [Account Interface](https://docs.cosmos.network/main/modules/auth#account-interface).
Accounts are exposed externally as an interface and stored internally as a clawback vesting account.
### ClawbackVestingAccount
An instance that implements
the [Vesting Account](https://docs.cosmos.network/main/modules/auth/vesting#vesting-account-types) interface.
It provides an account that can hold contributions subject to lockup,
or vesting which is subject to clawback of unvested tokens,
or a combination (tokens vest, but are still locked).
```go theme={null}
type ClawbackVestingAccount struct {
// base_vesting_account implements the VestingAccount interface. It contains
// all the necessary fields needed for any vesting account implementation
*types.BaseVestingAccount `protobuf:"bytes,1,opt,name=base_vesting_account,json=baseVestingAccount,proto3,embedded=base_vesting_account" json:"base_vesting_account,omitempty"`
// funder_address specifies the account which can perform clawback
FunderAddress string `protobuf:"bytes,2,opt,name=funder_address,json=funderAddress,proto3" json:"funder_address,omitempty"`
// start_time defines the time at which the vesting period begins
StartTime time.Time `protobuf:"bytes,3,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
// lockup_periods defines the unlocking schedule relative to the start_time
LockupPeriods []types.Period `protobuf:"bytes,4,rep,name=lockup_periods,json=lockupPeriods,proto3" json:"lockup_periods"`
// vesting_periods defines the vesting schedule relative to the start_time
VestingPeriods []types.Period `protobuf:"bytes,5,rep,name=vesting_periods,json=vestingPeriods,proto3" json:"vesting_periods"`
}
```
#### BaseVestingAccount
Implements the `VestingAccount` interface.
It contains all the necessary fields needed for any vesting account implementation.
#### FunderAddress
Specifies the account which provides the original tokens and can perform clawback.
#### StartTime
Defines the time at which the vesting and lockup schedules begin.
#### LockupPeriods
Defines the unlocking schedule relative to the start time.
#### VestingPeriods
Defines the vesting schedule relative to the start time.
### Genesis State
The `x/vesting` module allows the definition of `ClawbackVestingAccounts` at genesis.
In this case, the account balance must be logged in the SDK `bank` module balances
or automatically adjusted through the `add-genesis-account` CLI command.
## State Transitions
The `x/vesting` module allows for state transitions that create
and update a clawback vesting account with `CreateClawbackVestingAccount`
or perform a clawback of unvested funds with `Clawback`.
### Create Clawback Vesting Account
An externally owned account can be converted to a clawback vesting account by the owner.
Upon creation, the owner assigns a funder, who is able to fund the account with vesting and/or lockup schedules.
The account has also the possibility to specify if the vested tokens can be clawbacked from the governance.
1. Owner submits a `MsgCreateClawbackVestingAccount` through one of the clients.
2. Check if
1. the vesting account address is not blocked.
2. the account at the vesting account address is not already a vesting account.
3. Create a clawback vesting account at the target address with empty vesting and lockup schedules.
### Fund Clawback Vesting Account
The funder of a clawback vesting account can fund it with vesting and/or lockup schedules.
If a vesting account already has funds, the schedules are merged together.
1. Funder submits a `MsgFundVestingAccount` through one of the clients.
2. Check if
1. the vesting address is not a blocked address.
2. the vesting address is a clawback vesting account.
3. there is at least one vesting or lockup schedule provided.
If one of them is absent, default to instant vesting or unlock schedule.
3. lockup and vesting total amounts are equal.
4. Update the clawback vesting account and send coins from the funder to the vesting account,
merging any existing schedules with the new funding.
### Clawback
The funding address is the only address that can perform the clawback.
1. Funder submits a `MsgClawback` through one of the clients.
2. Check if
1. a destination address is given and default to funder address if not
2. the destination address is not blocked
3. the account exists and is a clawback vesting account
4. account funder is same as in msg
3. Transfer unvested tokens from the clawback vesting account to the destination address,
update the lockup schedule and remove future vesting events.
### Update Clawback Vesting Account Funder
The funding address of an existing clawback vesting account can be updated only by the current funder.
1. Funder submits a `MsgUpdateVestingFunder` through one of the clients.
2. Check if
1. the new funder address is not blocked
2. the vesting account exists and is a clawback vesting account
3. account funder is same as in msg
3. Update the vesting account funder with the new funder address.
### Convert Vesting Account
Once all tokens are vested, the vesting account can be converted back to an `EthAccount`.
1. Owner of vesting account submits a `MsgConvertVestingAccount` through one of the clients.
2. Check if
1. the vesting account exists and is a clawback vesting account
2. the vesting account's vesting and locked schedules have concluded
3. Convert the vesting account to an `EthAccount`
## Transactions
This section defines the concrete `sdk.Msg` types, that result in the state transitions defined on the previous section.
### `CreateClawbackVestingAccount`
```go theme={null}
type MsgCreateClawbackVestingAccount struct {
// funder_address specifies the account that will be able to fund the vesting account
FunderAddress string `protobuf:"bytes,1,opt,name=funder_address,json=funderAddress,proto3" json:"funder_address,omitempty"`
// vesting_address specifies the address that will receive the vesting tokens
VestingAddress string `protobuf:"bytes,2,opt,name=vesting_address,json=vestingAddress,proto3" json:"vesting_address,omitempty"`
// enable_gov_clawback specifies whether the governance module can clawback this account
EnableGovClawback bool `protobuf:"varint,3,opt,name=enable_gov_clawback,json=enableGovClawback,proto3" json:"enable_gov_clawback,omitempty"`
}
```
The msg content stateless validation fails if:
* `FunderAddress` or `VestingAddress` are invalid
### `FundVestingAccount`
```go theme={null}
type MsgFundVestingAccount struct {
// funder_address specifies the account that funds the vesting account
FunderAddress string `protobuf:"bytes,1,opt,name=funder_address,json=funderAddress,proto3" json:"funder_address,omitempty"`
// vesting_address specifies the account that receives the funds
VestingAddress string `protobuf:"bytes,2,opt,name=vesting_address,json=vestingAddress,proto3" json:"vesting_address,omitempty"`
// start_time defines the time at which the vesting period begins
StartTime time.Time `protobuf:"bytes,3,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
// lockup_periods defines the unlocking schedule relative to the start_time
LockupPeriods github_com_cosmos_cosmos_sdk_x_auth_vesting_types.Periods `protobuf:"bytes,4,rep,name=lockup_periods,json=lockupPeriods,proto3,castrepeated=github.com/cosmos/cosmos-sdk/x/auth/vesting/types.Periods" json:"lockup_periods"`
// vesting_periods defines the vesting schedule relative to the start_time
VestingPeriods github_com_cosmos_cosmos_sdk_x_auth_vesting_types.Periods `protobuf:"bytes,5,rep,name=vesting_periods,json=vestingPeriods,proto3,castrepeated=github.com/cosmos/cosmos-sdk/x/auth/vesting/types.Periods" json:"vesting_periods"`
}
```
The msg content stateless validation fails if:
* `FunderAddress` or `VestingAddress` are invalid
* `LockupPeriods` and `VestingPeriods`
* include a period with a non-positive length or amount
* do not describe the same total amount
### `Clawback`
```go theme={null}
type MsgClawback struct {
// funder_address is the address which funded the account
FunderAddress string `protobuf:"bytes,1,opt,name=funder_address,json=funderAddress,proto3" json:"funder_address,omitempty"`
// account_address is the address of the ClawbackVestingAccount to claw back from.
AccountAddress string `protobuf:"bytes,2,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"`
// dest_address specifies where the clawed-back tokens should be transferred
// to. If empty, the tokens will be transferred back to the original funder of
// the account.
DestAddress string `protobuf:"bytes,3,opt,name=dest_address,json=destAddress,proto3" json:"dest_address,omitempty"`
}
```
The msg content stateless validation fails if:
* `FunderAddress` or `AccountAddress` are invalid
* `DestAddress` is not empty and invalid
### `UpdateVestingFunder`
```go theme={null}
type MsgUpdateVestingFunder struct {
// funder_address is the current funder address of the ClawbackVestingAccount
FunderAddress string `protobuf:"bytes,1,opt,name=funder_address,json=funderAddress,proto3" json:"funder_address,omitempty"`
// new_funder_address is the new address to replace the existing funder_address
NewFunderAddress string `protobuf:"bytes,2,opt,name=new_funder_address,json=newFunderAddress,proto3" json:"new_funder_address,omitempty"`
// vesting_address is the address of the ClawbackVestingAccount being updated
VestingAddress string `protobuf:"bytes,3,opt,name=vesting_address,json=vestingAddress,proto3" json:"vesting_address,omitempty"`
}
```
The msg content stateless validation fails if:
* `FunderAddress`, `NewFunderAddress` or `VestingAddress` are invalid
### `ConvertVestingAccount`
```go theme={null}
type MsgConvertVestingAccount struct {
// vesting_address is the address of the ClawbackVestingAccount being updated
VestingAddress string `protobuf:"bytes,2,opt,name=vesting_address,json=vestingAddress,proto3" json:"vesting_address,omitempty"`
}
```
The msg content stateless validation fails if:
* `VestingAddress` is invalid
## AnteHandlers
The `x/vesting` module provides `AnteDecorator`s that are recursively chained together
into a single [`Antehandler`](https://github.com/cosmos/cosmos-sdk/blob/v0.43.0-alpha1/docs/architecture/adr-010-modular-antehandler.md).
These decorators perform basic validity checks on an Ethereum,
such that it could be thrown out of the transaction Mempool.
Note that theΒ `AnteHandler`Β is called on bothΒ `CheckTx`Β andΒ `DeliverTx`,
as CometBFT proposers presently have the ability to include in their proposed block transactions that failΒ `CheckTx`.
### Decorators
The following decorators implement the vesting logic for token delegation and performing EVM transactions.
#### `EthVestingTransactionDecorator`
Validates if a clawback vesting account is permitted to perform Ethereum transactions,
based on if it has its vesting schedule has surpassed the vesting cliff and first lockup period.
Also, validates if the account has sufficient unlocked tokens to execute the transaction.
This AnteHandler decorator will fail if:
* the message is not a `MsgEthereumTx`
* sender account cannot be found
* sender account is not a `ClawbackVestingAccount`
* block time is before surpassing vesting cliff end (with zero vested coins) AND
* block time is before surpassing all lockup periods (with non-zero locked coins)
* sender account has insufficient unlocked tokens to execute the transaction
### Custom Staking Module
Evomos introduced the concept of [EVM extensions](https://docs.paxeer.app/develop/smart-contracts/evm-extensions) to
allow smart contract to interact with Cosmos SDK modules
like staking and distribution, to provide a better developer experience allowing users to interact with Cosmos native module
via the EVM. Since a `ClawbackVestingAccount` is allowed to stake only unlocked & vested coins, or locked & vested,
we have to ensure that all other configurations are not permitted to perform a state transition. Instead of
having these checks implemented in both the `AnteHandler`s for Cosmos transactions and Ethereum transactions,
HyperPaxeer core wraps the Cosmos SDK `x/staking` module to introduce these checks in the `MsgServer` of this module.
With this approach we ensure that all staking actions, through direct Cosmos message or through extensions,
are validating the
account balance in the proper way.
The staking wrapper uses the same functionalities of the original staking module but introduces required
checks in the following methods:
* `Delegate`
* `CreateValidator`
## Events
The `x/vesting` module emits the following events:
### Create Clawback Vesting Account
| Type | Attibute Key | Attibute Value |
| --------------------------------- | ------------ | ---------------------- |
| `create_clawback_vesting_account` | `"funder"` | `{msg.FunderAddress}` |
| `create_clawback_vesting_account` | `"sender"` | `{msg.VestingAddress}` |
### Fund Vesting Account
| Type | Attibute Key | Attibute Value |
| ---------------------- | -------------- | -------------------------- |
| `fund_vesting_account` | `"funder"` | `{msg.FunderAddress}` |
| `fund_vesting_account` | `"coins"` | `{vestingCoins.String()}` |
| `fund_vesting_account` | `"start_time"` | `{msg.StartTime.String()}` |
| `fund_vesting_account` | `"account"` | `{msg.VestingAddress}` |
### Clawback
| Type | Attibute Key | Attibute Value |
| ---------- | --------------- | ---------------------- |
| `clawback` | `"funder"` | `{msg.FromAddress}` |
| `clawback` | `"account"` | `{msg.AccountAddress}` |
| `clawback` | `"destination"` | `{msg.DestAddress}` |
### Update Clawback Vesting Account Funder
| Type | Attibute Key | Attibute Value |
| ----------------------- | -------------- | ------------------------ |
| `update_vesting_funder` | `"funder"` | `{msg.FromAddress}` |
| `update_vesting_funder` | `"account"` | `{msg.VestingAddress}` |
| `update_vesting_funder` | `"new_funder"` | `{msg.NewFunderAddress}` |
## Clients
A user can query the HyperPaxeer `x/vesting`Β module using the CLI, gRPC, or REST.
### CLI
Find below a list ofΒ `hyperpaxd`Β commands added with the `x/vesting`Β module.
You can obtain the full list by using theΒ `hyperpaxd -h`Β command.
#### Genesis
TheΒ genesis configuration commands allow users to configure the genesisΒ `vesting` accountΒ state.
`add-genesis-account`
Allows users to set up clawback vesting accounts at genesis, funded with an allocation of tokens, subject to clawback.
Must provide a lockup periods file (`--lockup`), a vesting periods file (`--vesting`), or both.
If both files are given, they must describe schedules for the same total amount.
If one file is omitted, it will default to a schedule that immediately unlocks or vests the entire amount.
The described amount of coins will be transferred from the --from address to the vesting account.
Unvested coins may be "clawed back" by the funder with the clawback command.
Coins may not be transferred out of the account if they are locked or unvested.
Only vested coins may be staked.
For an example of how to set this see [this link](https://github.com/Paxeer-Network/Paxeer-Network/pull/303).
```go theme={null}
hyperpaxd add-genesis-account ADDRESS_OR_KEY_NAME COIN... [flags]
```
#### Queries
TheΒ `query`Β commands allow users to queryΒ `vesting` accountΒ state.
**`balances`**
Allows users to query the locked, unvested and vested tokens for a given vesting account
```go theme={null}
hyperpaxd query vesting balances ADDRESS [flags]
```
#### Transactions
TheΒ `tx`Β commands allow users to create and clawbackΒ `vesting` accountΒ state.
**`create-clawback-vesting-account`**
A new clawback vesting account is created for the sender account (`--from`),
if it is not already of such type.
Only the designated funder will be able to define lockup and vesting schedules
and has to do so using the fund-vesting-account subcommand.
Clawback via governance is enabled or disabled through the second argument.
```go theme={null}
hyperpaxd tx vesting create-clawback-vesting-account FUNDER_ADDRESS ENABLE_GOV_CLAWBACK --from=VESTING_ADDRESS [flags]
```
**`fund-vesting-account`**
Allows the funder account to update a clawback vesting account with new schedules.
Any existing schedules are merged with the newly added schedules.
Must provide a lockup periods file (--lockup), a vesting periods file (--vesting), or both.
If both files are given, they must describe schedules for the same total amount.
If one file is omitted, it will default to a schedule that immediately unlocks or vests the entire amount.
The described amount of coins will be transferred from the --from address to the vesting account.
Unvested coins may be "clawed back" by the funder with the clawback command.
Coins may not be transferred out of the account if they are locked or unvested.
Only vested coins may be staked.
For an example of how to set this see [this link](https://github.com/Paxeer-Network/Paxeer-Network/pull/303).
```go theme={null}
hyperpaxd tx vesting fund-vesting-account VESTING_ADDRESS --from=FUNDER_ADDRESS [flags]
```
**`clawback`**
Allows to transfer all unvested unvested tokens out of a ClawbackVestingAccount.
Must be requested by the original funder address (--from) and may provide a destination address (--dest),
otherwise the coins are returned to the funder.
Delegated or unbonding staking tokens will be transferred in the delegated or unbonding state.
The recipient is vulnerable to slashing, and must act to unbond the tokens if desired.
```go theme={null}
hyperpaxd tx vesting clawback VESTING_ADDRESS --from=FUNDER_ADDRESS [flags]
```
**`update-vesting-funder`**
Allows users to update the funder of an existent `ClawbackVestingAccount`.
Must be requested by the original funder address (`--from`).
```go theme={null}
hyperpaxd tx vesting update-vesting-funder VESTING_ADDRESS NEW_FUNDER_ADDRESS --from=FUNDER_ADDRESS [flags]
```
**`convert`**
Allows users to convert their vesting account to the chain's default account (i.e `EthAccount`).
This operation only succeeds if there are no unvested tokens left in the account.
```go theme={null}
hyperpaxd tx vesting convert VESTING_ADDRESS [flags]
```
### gRPC
#### Queries
| Verb | Method | Description |
| ------ | ----------------------------------------------- | -------------------------------------- |
| `gRPC` | `HyperPaxeer.vesting.v2.Query/Balances` | Gets locked, unvested and vested coins |
| `GET` | `/Paxeer-Network/vesting/v2/balances/{address}` | Gets locked, unvested and vested coins |
#### Transactions
| Verb | Method | Description |
| ------ | --------------------------------------------------------------- | ----------------------------------------------- |
| `gRPC` | `HyperPaxeer.vesting.v2.Msg/CreateClawbackVestingAccount` | Creates clawback vesting account |
| `gRPC` | `HyperPaxeer.vesting.v2.Msg/FundVestingAccount` | Funds a clawback vesting account |
| `gRPC` | `/Paxeer-Network.vesting.v2.Msg/Clawback` | Performs clawback |
| `gRPC` | `/Paxeer-Network.vesting.v2.Msg/UpdateVestingFunder` | Updates vesting account funder |
| `gRPC` | `/Paxeer-Network.vesting.v2.Msg/ConvertVestingAccount` | Converts vesting account back to normal account |
| `GET` | `/Paxeer-Network/vesting/v2/tx/create_clawback_vesting_account` | Creates clawback vesting account |
| `GET` | `/Paxeer-Network/vesting/v2/tx/fund_vesting_account` | Funds a clawback vesting account |
| `GET` | `/Paxeer-Network/vesting/v2/tx/clawback` | Performs clawback |
| `GET` | `/Paxeer-Network/vesting/v2/tx/update_vesting_funder` | Updates vesting account funder |
| `GET` | `/Paxeer-Network/vesting/v2/tx/convert_vesting_account` | Converts vesting account back to normal account |
# Quick Start
Source: https://sidiorresearchlabs.mintlify.app/quickstart
Connect a wallet, run a node, and deploy your first contract on HyperPaxeer in under ten minutes
## 1. Connect a Wallet
HyperPaxeer is a standard EVM chain (Chain ID `125`). Any Ethereum-compatible wallet works β MetaMask, Rabby, or the native **PaxPort Wallet**.
PaxPort ships with HyperPaxeer pre-configured β no manual network setup required. Download from [paxportwallet.com](http://paxportwallet.com) .
Open your wallet's network settings and add:
| Field | Value |
| --------------- | ----------------------------------- |
| Network Name | `HyperPaxeer` |
| RPC URL | `https://public-rpc.paxeer.app/rpc` |
| Chain ID | `125` |
| Currency Symbol | `HPX` |
| Block Explorer | `https://paxscan.io` |
***
## 2. Run a Node (Optional)
The `hpx` CLI deploys Docker-based RPC or Validator nodes with a single command. Minimum requirements: 16 GB RAM, 6 CPU cores, 300 GB disk, Ubuntu 22.04+.
```bash theme={null}
curl -sSL https://hyperpaxeer.com/hyper-os/new/get-hpx.sh | sudo bash
```
The installer checks your system, installs dependencies, and launches an interactive setup wizard. After setup:
```bash theme={null}
hpx deploy my-rpc rpc # deploy an RPC node
hpx deploy my-val validator # deploy a validator node
hpx dashboard # live status of all nodes
```
Each node gets its own Docker Compose stack under `/root/hyperpax-nodes//` with isolated ports that auto-increment.
| Command | Purpose |
| -------------------------------- | ------------------------------- |
| `hpx list` | List all registered nodes |
| `hpx info ` | Sync status, height, peers |
| `hpx logs ` | Stream node logs |
| `hpx start all` / `hpx stop all` | Bulk lifecycle |
| `hpx capacity` | Show remaining server resources |
See [Run a Validator](/validate/setup/run-a-validator) for the full operator guide.
***
## 3. Deploy a Smart Contract
HyperPaxeer is fully compatible with Solidity tooling. Foundry is the recommended framework.
```bash theme={null}
# Install Foundry
curl -L https://foundry.paradigm.xyz | bash && foundryup
# Create project
forge init my-project && cd my-project
# Deploy (use --legacy --slow for Alexandria Fork chains)
forge create src/Counter.sol:Counter \
--rpc-url https://public-rpc.paxeer.app/rpc \
--private-key $PRIVATE_KEY \
--legacy --slow
```
```bash theme={null}
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
```
```javascript hardhat.config.js theme={null}
module.exports = {
solidity: "0.8.24",
networks: {
hyperpaxeer: {
url: "https://public-rpc.paxeer.app/rpc",
chainId: 125,
accounts: [process.env.PRIVATE_KEY]
}
}
};
```
```bash theme={null}
npx hardhat run scripts/deploy.js --network hyperpaxeer
```
1. Open [remix.ethereum.org](https://remix.ethereum.org)
2. Write or import your contract
3. Compile with Solidity 0.8.24+
4. Connect MetaMask (ensure Chain ID 125 is selected)
5. Deploy via **Injected Provider β MetaMask**
Store private keys in a `.env` file and never commit them to version control.
***
## 4. Verify on PaxScan
```bash theme={null}
forge verify-contract \
--chain-id 125 \
--compiler-version v0.8.24 \
DEPLOYED_ADDRESS \
src/Counter.sol:Counter \
--verifier blockscout \
--verifier-url https://paxscan.io/api
```
***
## 5. Integrate in a Frontend
```typescript wagmi-config.ts theme={null}
import { createConfig, http } from 'wagmi'
import { defineChain } from 'viem'
export const hyperpaxeer = defineChain({
id: 125,
name: 'HyperPaxeer',
network: 'hyperpaxeer',
nativeCurrency: { decimals: 18, name: 'HyperPaxeer', symbol: 'HPX' },
rpcUrls: {
default: { http: ['https://public-rpc.paxeer.app/rpc'] },
},
blockExplorers: {
default: { name: 'PaxScan', url: 'https://paxscan.io' },
},
})
export const config = createConfig({
chains: [hyperpaxeer],
transports: { [hyperpaxeer.id]: http() },
})
```
***
## Next Steps
wagmi, viem, ethers.js, and web3.js setup
Deployment patterns, verification, and interaction guides
Dual-VM design, precompiles, and the x/paxoracle module
Test RPC methods against the live network
# RPC Methods
Source: https://sidiorresearchlabs.mintlify.app/rpc
Test HyperPaxeer RPC methods in real-time
## Overview
Test HyperPaxeer RPC methods in real-time. Select an example or write your own JSON-RPC request.
**RPC Endpoint:** `https://public-rpc.paxeer.app/rpc`
**125**
**HPX**
## Common RPC Methods
### eth\_blockNumber
Returns the number of the most recent block.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x5daf3b"
}
```
None
`QUANTITY` - Integer of the current block number the client is on
***
### eth\_getBalance
Returns the balance of the account of given address.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [
"0x407d73d8a49eeb85d32cf465507dd71d507100c1",
"latest"
],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x0234c8a3397aab58"
}
```
1. `DATA`, 20 Bytes - Address to check for balance
2. `QUANTITY|TAG` - Integer block number, or the string "latest", "earliest" or "pending"
`QUANTITY` - Integer of the current balance in wei
***
### eth\_gasPrice
Returns the current price per gas in wei.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_gasPrice",
"params": [],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x09184e72a000"
}
```
None
`QUANTITY` - Integer of the current gas price in wei
***
### eth\_chainId
Returns the chain ID of the current network.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_chainId",
"params": [],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0xe5"
}
```
None
`QUANTITY` - Integer of the current chain ID (125 for HyperPaxeer)
***
### eth\_call
Executes a new message call immediately without creating a transaction on the blockchain.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"data": "0x..."
},
"latest"
],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x..."
}
```
1. `Object` - The transaction call object
* `from`: (optional) Address - The address the transaction is sent from
* `to`: Address - The address the transaction is directed to
* `gas`: (optional) Integer - Gas provided for the transaction execution
* `gasPrice`: (optional) Integer - Gas price provided for each paid gas
* `value`: (optional) Integer - Value sent with this transaction
* `data`: (optional) Data - Hash of the method signature and encoded parameters
2. `QUANTITY|TAG` - Integer block number, or the string "latest", "earliest" or "pending"
`DATA` - The return value of the executed contract
***
### eth\_sendTransaction
Creates new message call transaction or a contract creation.
This method requires a wallet connection to sign the transaction.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_sendTransaction",
"params": [
{
"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"gas": "0x76c0",
"gasPrice": "0x9184e72a000",
"value": "0x9184e72a",
"data": "0x..."
}
],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
}
```
1. `Object` - The transaction object
* `from`: Address - The address the transaction is sent from
* `to`: (optional) Address - The address the transaction is directed to (null for contract creation)
* `gas`: (optional) Integer - Gas provided for the transaction execution
* `gasPrice`: (optional) Integer - Gas price provided for each paid gas
* `value`: (optional) Integer - Value sent with this transaction
* `data`: Data - Compiled contract code or hash of the invoked method signature and encoded parameters
`DATA`, 32 Bytes - The transaction hash, or the zero hash if the transaction is not yet available
***
### eth\_getTransactionByHash
Returns information about a transaction by transaction hash.
```json Request theme={null}
{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [
"0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"
],
"id": 1
}
```
```json Response theme={null}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"blockHash": "0x1d59ff54b1eb26b013ce3cb5fc9dab3705b415a67127a003c3e61eb445bb8df2",
"blockNumber": "0x5daf3b",
"from": "0xa7d9ddbe1f17865597fbd27ec712455208b6b76d",
"gas": "0xc350",
"gasPrice": "0x4a817c800",
"hash": "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b",
"input": "0x68656c6c6f21",
"nonce": "0x15",
"to": "0xf02c1c8e6114b1dbe8937a39260b5b0a374432bb",
"transactionIndex": "0x41",
"value": "0xf3dbb76162000",
"v": "0x25",
"r": "0x1b5e176d927f8e9ab405058b2d2457392da3e20f328b16ddabcebc33eaac5fea",
"s": "0x4ba69724e8f69de52f0125ad8b3c5c2cef33019bac3249e2c0a2192766d1721c"
}
}
```
1. `DATA`, 32 Bytes - Hash of a transaction
`Object` - A transaction object, or null when no transaction was found
## Using with cURL
```bash theme={null}
curl -X POST \
https://public-rpc.paxeer.app/rpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
"id": 1
}'
```
## Using with JavaScript
```javascript theme={null}
const response = await fetch('https://public-rpc.paxeer.app/rpc', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'eth_blockNumber',
params: [],
id: 1,
}),
});
const data = await response.json();
console.log(data.result);
```
## Using with Python
```python theme={null}
import requests
import json
url = 'https://public-rpc.paxeer.app/rpc'
payload = {
'jsonrpc': '2.0',
'method': 'eth_blockNumber',
'params': [],
'id': 1
}
response = requests.post(url, json=payload)
print(response.json())
```
## Next Steps
Complete API documentation for all methods
Integration examples and code samples
# Sidiora.ag
Source: https://sidiorresearchlabs.mintlify.app/sidiora/ag
Network-operated meta-aggregator routing layer for Paxeer liquidity, adapters, quotes, vault settlement, and transaction tracking
## Overview
Sidiora.ag is the public protocol name for the Paxeer Eqos Central Order Router (PECOR) meta-aggregator. It routes across network-operated liquidity systems and tracks quote, execution, and settlement state.
Route through adapters for Sidiora.fun, oracle feeds, vaults, and order systems.
Transaction tracking records order lifecycle and route execution state.
Quoter contracts provide route previews before execution.
## Architecture
| Component | Role |
| -------------------- | ------------------------------------------- |
| `PECORRouter` | Main routing entry point |
| `OracleHub` | Shared oracle hub for routing and valuation |
| `PriceOracleAdapter` | Price oracle adapter |
| `SidioraFeedAdapter` | Sidiora feed adapter |
| `VaultAdapter` | Vault integration adapter |
| `SidioraAdapter` | Sidiora liquidity adapter |
| `TransactionTracker` | Execution and lifecycle tracking |
| `PECORVault` | Vault settlement component |
| `PECOROrders` | Order management layer |
| `PECORQuoter` | Quote simulation layer |
## Current production addresses
| Contract | Address |
| ------------------ | -------------------------------------------- |
| OracleHub | `0xED7620DC28759d55D89fF802E307Dd246d61D409` |
| PriceOracleAdapter | `0x02D04a000E09c47d6BCFc1D6afb43Cac5d62d1c9` |
| SidioraFeedAdapter | `0x2531dFa65CB370771ca695cf9620140022ab360B` |
| VaultAdapter | `0x8C362D903ad5ce3E42b2E7a00686aE5E3aF0B0F6` |
| SidioraAdapter | `0x5882D31D5E5E22395863DAe0fe977B2C978C9f33` |
| PECORRouter | `0x5925FA311707C406D83FC76317a69bb1Ba263F32` |
## Legacy PECOR v3 addresses
| Contract | Address |
| ------------------ | -------------------------------------------- |
| PriceOracle | `0x921A37182339b1618CB55937448c66B6538BF225` |
| TransactionTracker | `0xf656612D8F305E4867d8203176f5656bB69be958` |
| PECORVault | `0x6500B1B3F8067772041C68b2c51D8E7A84e20C31` |
| PECOR | `0xae894b953ec1dD9b305346dEc1484Fe0ffF5eaD4` |
| PECOROrders | `0x39DCa28a022fED90Bc7964E84330b3871D02692D` |
| PECORQuoter | `0x4e643931fbb2df1B5965739B46CF70BCe622BD0a` |
## Connected Sidiora.fun addresses
| Contract | Address |
| ------------ | -------------------------------------------- |
| PoolRegistry | `0x1F22f11325197fae71937598F6935cc4e9231970` |
| Quoter | `0xeDb3B45E320A8ab2306Fa1C303742f2478fd3E0a` |
| Router | `0xB2D63300FE8b3508A83728e8f36B98e845eBD980` |
## Token addresses
| Token | Address |
| ----- | -------------------------------------------- |
| USDC | `0xf8850b62AE017c55be7f571BBad840b4f3DA7D49` |
| USDT | `0x5dfE06Ae465a39c442c45ed273c523BaC2d1f6a8` |
| USDL | `0x7c69c84daAEe90B21eeCABDb8f0387897E9B7B37` |
| USID | `0x6C32c255EeBD6A72B56ee82454d7140020919652` |
| WPAX9 | `0xe5ccf339d1c89c7e6c6768b28507f78b861fc1de` |
| SID | `0x86949e4CdB89496490890B67C9cfF63eD8efB4b1` |
## Developer usage
Start with the active router address for route execution:
```typescript theme={null}
const sidioraAgRouter = '0x5925FA311707C406D83FC76317a69bb1Ba263F32'
```
Use Sidiora.fun Quoter for launchpad pool quotes and PECOR routing components for aggregate route planning.
## Related protocols
* [Sidiora.fun](/sidiora/fun)
* [HyperPax DEX](/sidiora/dex)
* [HyperPax Perps](/sidiora/perps)
# HyperPax DEX
Source: https://sidiorresearchlabs.mintlify.app/sidiora/dex
Network-operated Adaptive Sigmoid AMM with Diamond facets, progressive fees, oracle-pegged pools, and typed SDK support
## Overview
HyperPax DEX is the public protocol name for the network-operated v5-ASAMM system. It is an Adaptive Sigmoid Automated Market Maker built for Paxeer Network chain ID `125`.
A tanh-based curve keeps small trades efficient and increases impact for large trades.
Fees scale quadratically with trade size to protect pool liquidity.
12 EIP-2535 facets share one AppStorage layout behind a single Diamond.
## Core mechanics
### Sigmoid price impact
```text theme={null}
P(x) = P_mid * (1 + k * tanh(a * x / L))
```
| Parameter | Meaning |
| --------- | ----------------------------------------- |
| `P_mid` | Current mid-price from reserves or oracle |
| `k` | Maximum price deviation factor |
| `a` | Curve steepness |
| `x` | Signed trade size |
| `L` | Pool liquidity |
### Progressive fee
```text theme={null}
fee(x) = baseFee + impactFee * (x / L)^2
```
Fees are distributed as:
| Recipient | Share |
| ------------------ | ----: |
| LPs | `70%` |
| Protocol treasury | `20%` |
| Trader rebate pool | `10%` |
## Facets
| Group | Facets |
| ------------------ | -------------------------------------------------------- |
| Core | `DiamondCutFacet`, `DiamondLoupeFacet`, `OwnershipFacet` |
| Pool operations | `PoolFacet`, `LiquidityFacet`, `SwapFacet` |
| Pricing and fees | `FeeFacet`, `OracleFacet`, `OraclePegFacet` |
| Orders and rewards | `OrderFacet`, `RewardFacet`, `FlashLoanFacet` |
## Production addresses
| Contract | Address |
| --------------- | -------------------------------------------- |
| Diamond proxy | `0x9595a92d63884d2D9924e0002D45C34d717DB291` |
| Router | `0x635aC031f7d26035FCc8b138b0835fec0cf6b8AA` |
| Quoter | `0x2092D242Cc5d3673D1644128DBd4D199dE51266e` |
| PositionManager | `0x8f60EcD67Ef9aF953Dfc1a94F03C1D7e4363e092` |
| OrderManager | `0xB6430A1A4373C14Fa359b242713fBeB4BF2559A4` |
| EventEmitter | `0x3FCa66c12B99e395619EE4d0aeabC2339F97E1FF` |
## Facet addresses
| Facet | Address |
| ----------------- | -------------------------------------------- |
| DiamondCutFacet | `0xE4F3EEcc0c940d5a4Ed8CbC9262bF761F0EB43Dc` |
| DiamondLoupeFacet | `0x24bC6117305709fF35e3b22A387B2F66EdDF3908` |
| OwnershipFacet | `0x2334B448654c7Eb230F1DDb2C48a23DF6F736d02` |
| PoolFacet | `0x5C8f4B01467894C7EEC0f57994bE672e317c66d2` |
| SwapFacet | `0xf0E343F0185E5896914621f3E583A723A8C02020` |
| LiquidityFacet | `0xb90ED04e330aa93b8D2c6A19343d98B77cFad9CC` |
| FeeFacet | `0x63D13c9FB4C4c2e05fE5265B3a266C47cc49136b` |
| OracleFacet | `0xF7595F653d1960BaeD00D54a6f064357C366fba9` |
| OraclePegFacet | `0xe7Dc930B5D7a439B2bf161B01a03D4fc5184Ff1d` |
| OrderFacet | `0xfDdf08D5D2CB2d6Ac52ca6b92616651d4921Cf9f` |
| RewardFacet | `0x3eA125C4B662f2D148f40E736B8816D4574Ce0DB` |
| FlashLoanFacet | `0x64404C575eB9ED3BB9afF71dD478236B98272c80` |
## Developer usage
Use the Router for swaps and liquidity operations unless you need lower-level Diamond facet calls.
```typescript theme={null}
import { createPublicClient, http } from 'viem'
import { hyperpaxeer } from './chains'
const client = createPublicClient({
chain: hyperpaxeer,
transport: http('https://public-rpc.paxeer.app/rpc'),
})
const router = '0x635aC031f7d26035FCc8b138b0835fec0cf6b8AA'
```
## Related protocols
* [HyperPax Perps](/sidiora/perps)
* [Sidiora.fun](/sidiora/fun)
* [Sidiora.ag](/sidiora/ag)
# Sidiora.fun
Source: https://sidiorresearchlabs.mintlify.app/sidiora/fun
Network-operated launchpad AMM with virtual USDL reserves, per-pool Beacon proxies, Opticals, and launch automation
## Overview
Sidiora.fun is the network-operated launchpad AMM for Paxeer Network. It combines virtual USDL reserve pricing, per-pool Beacon proxies, ERC-20 launch tokens, NFT identity, configurable Opticals, and routed swaps.
Pools price launches against virtual USDL liquidity before mature liquidity forms.
Each pool is a Beacon proxy that can be upgraded atomically at the pool implementation layer.
Hook-like extensions add taxes, cooldowns, max-wallet checks, anti-snipe rules, and buyback logic.
## Architecture
| Layer | Contracts |
| --------------- | ---------------------------------------------------------------------------------------------------------------- |
| Periphery | `Router`, `Quoter`, `FeesRouter` |
| Core logic | `SidioraFactory`, `SidioraPool`, `SidioraERC20`, `SidioraNFT` |
| Data and config | `PoolRegistry`, `ProtocolConfig`, `EventEmitter` |
| Governance | `Treasury`, `Timelock`, `GovernanceModule`, `FeeAccumulator` |
| Opticals | `OpticalRegistry`, `AntiSnipeOptical`, `MaxWalletOptical`, `TaxOptical`, `CooldownOptical`, `BuybackBurnOptical` |
| Upgradeability | UUPS proxies and `PoolBeacon` |
## Production proxy addresses
| Contract | Proxy address |
| ----------------------- | -------------------------------------------- |
| EventEmitter | `0x6679aF411d534de222C32ed0AF94C3BD67090672` |
| ProtocolConfig | `0x325e6Fb9c3505A35785365674089aEf8497C697B` |
| Treasury | `0xe3705EaC51000F40e44D8039DF394f8b8FBAFaA3` |
| GovernanceModule | `0xAA154A446f18E80E70b53357597E40CDD1D07E37` |
| PoolRegistry | `0x1F22f11325197fae71937598F6935cc4e9231970` |
| FeeAccumulator | `0x5C3A7A87eB2DfC965F2764E28524FE77c0003810` |
| SidioraNFT | `0xb36ac5052b43Eef2807D4F91c494cD5D8EeD3fEa` |
| SidioraFactory | `0x322170E27d0c5Bd252337791fadED31dc4E85cA6` |
| OpticalRegistry | `0xA62b58fe655B45179449003279416575B7241449` |
| Router | `0xB2D63300FE8b3508A83728e8f36B98e845eBD980` |
| Quoter | `0xeDb3B45E320A8ab2306Fa1C303742f2478fd3E0a` |
| FeesRouter | `0xebf10213e58cc694aFDd06848faa363b41395898` |
| LaunchpadOpticalFactory | `0x385198712E5B288d64c3E1D3cb91bBeFD7B77b60` |
## Implementation and module addresses
| Contract | Address |
| -------------------------------------- | -------------------------------------------- |
| EventEmitter implementation | `0xC7c0071463ADA653ed1691938a91d2404D2dc694` |
| ProtocolConfig implementation | `0xC826788820FB4310B60337Db127261C744D37827` |
| Treasury implementation | `0xc72eD2E7422290b0D6ae6FbBf461D8e2c4820A62` |
| GovernanceModule implementation | `0xe955b10d82e1692A14Bd361366f55d7E9d405Bbd` |
| PoolRegistry implementation | `0x779EF19C7Fd0bCA0ec1A29bEfF332197c475ba41` |
| FeeAccumulator implementation | `0x5d951A3910105C235Dde0eD125f062195e6C295d` |
| SidioraPool implementation | `0xDc84Cdf2D2553FDa2aCa8741409Cb5AB5b7c0942` |
| PoolBeacon | `0xe769859e5a9AEd339931E2717AF00606fA0e847f` |
| SidioraNFT implementation | `0xbbd443de09eb9881cDC27b999441F228fDd53828` |
| SidioraFactory implementation | `0x6E33eb03b59b5Eac5D5db3519db221FB754fc97d` |
| OpticalRegistry implementation | `0x9cEB5828aA38495248710aF280B2C21CD48040E6` |
| Router implementation | `0xb35eaa8E113910c8A7179C7c8e062c7Be28847A1` |
| Quoter implementation | `0x0cb1B2fb940a7875de03D812eD0B3b9538E25e24` |
| FeesRouter implementation | `0x165F4992E12FC91EADBF9Dd6927ab330B5E2924d` |
| Timelock | `0xEc2B7b640469607A45615385e713e656B7e667b9` |
| AntiSnipeOptical | `0x2235a03cC711bb384Ff42CcB7c6B727612bbCBE8` |
| MaxWalletOptical | `0xbc02402CD5385f5f67F0Dcc9b91C93eCF4107A7b` |
| TaxOptical | `0xaaA80699C008e34d537Bb0C8E24bE6f69b5cd9F2` |
| CooldownOptical | `0x7E739D6A78F07Ab728A9f3217DfF4a994F87fBf1` |
| BuybackBurnOptical | `0x596467B82722dba67b6ACb0a7dc83B530a4C90BD` |
| LaunchpadOpticalFactory implementation | `0x660b5Aa3bc80490ED8475d7766658318604a55AC` |
## Core token addresses
| Token | Address |
| ----- | -------------------------------------------- |
| USDL | `0x7c69c84daAEe90B21eeCABDb8f0387897E9B7B37` |
| SID | `0x86949e4CdB89496490890B67C9cfF63eD8efB4b1` |
## Developer usage
Use Router for writes and Quoter for read-only price previews.
```typescript theme={null}
const sidioraFunRouter = '0xB2D63300FE8b3508A83728e8f36B98e845eBD980'
const sidioraFunQuoter = '0xeDb3B45E320A8ab2306Fa1C303742f2478fd3E0a'
```
## Related protocols
* [Sidiora.ag](/sidiora/ag)
* [HyperPax DEX](/sidiora/dex)
* [HyperPax Perps](/sidiora/perps)
# HyperPax Perps
Source: https://sidiorresearchlabs.mintlify.app/sidiora/perps
Network-operated synthetic perpetual futures protocol with Diamond facets, oracle pricing, funding, vaults, and liquidation support
## Overview
HyperPax Perps is the public protocol name for the network-operated Sidiora Perpetual Protocol. It provides synthetic perpetual futures on Paxeer Network using a Diamond proxy with 19 facets and shared `AppStorage`.
Trade long or short exposure with one net position per market per user.
Liquidity is protocol-funded. There are no external LP deposits.
Funding accrues per second without a separate funding settler keeper.
## Architecture
| Group | Facets |
| -------------------- | ----------------------------------------------------------------------------------------------- |
| Core | `DiamondCutFacet`, `DiamondLoupeFacet`, `OwnershipFacet`, `AccessControlFacet`, `PausableFacet` |
| Vault and collateral | `VaultFactoryFacet`, `CentralVaultFacet`, `CollateralFacet` |
| Trading engine | `PositionFacet`, `OrderBookFacet`, `LiquidationFacet`, `FundingRateFacet` |
| Pricing | `OracleFacet`, `VirtualAMMFacet`, `PriceFeedFacet` |
| Support | `MarketRegistryFacet`, `InsuranceFundFacet`, `QuoterFacet`, `EventEmitterFacet` |
## Trading model
| Component | Behavior |
| ------------------ | ------------------------------------------- |
| Position model | Net mode; one direction per market per user |
| Price precision | 18-decimal fixed point |
| Leverage precision | 18-decimal fixed point |
| Market IDs | Sequential `uint256` starting from `0` |
| Position IDs | Sequential `uint256` starting from `1` |
| Events | Emitted from the Diamond address |
## Production addresses
| Contract | Address |
| ------------------------ | -------------------------------------------- |
| Diamond proxy | `0xeA65FE02665852c615774A3041DFE6f00fb77537` |
| UserVault implementation | `0x4195155D92451a47bF76987315DaEE499f1D7352` |
## Facet addresses
| Facet | Address |
| ------------------- | -------------------------------------------- |
| DiamondCutFacet | `0x8af7E829E2061Cb2353CCce3cf99b00e6ca4DC3B` |
| DiamondLoupeFacet | `0x425Bcb17F3e3679fC5fE001d3707BDC3ED76c3a1` |
| OwnershipFacet | `0xDD0C64553e792120B04727b9Eb2e97c8cd67F387` |
| PositionFacet | `0x6bf3722414b240A2503a512A84f54Ee161fa148e` |
| OrderBookFacet | `0x719B8f35701ff1050EB0Bb87E418Bb321Cc0e979` |
| LiquidationFacet | `0x661320835387532aFDEc3F243B0A328BF42d7cA7` |
| FundingRateFacet | `0x669077515193401ac30984a9d2314903ACcAc25f` |
| OracleFacet | `0xd21135802D8eFD6c00d6332e262A7B2c75d5bF69` |
| VirtualAMMFacet | `0x5c869AC52dd91958E7dd98e570aaeFE6FD6864B5` |
| PriceFeedFacet | `0x08E967408a4Ee268FF11ab116BfE1D95F2484c61` |
| AccessControlFacet | `0x71E10DB0c468BF682EA744F11C4A29b10E18FDEd` |
| PausableFacet | `0xDc72b3dC885C5b8816456FcF9EFda7aD5625ABf8` |
| VaultFactoryFacet | `0x54F4D455a8f47dFD2C6f252d0EdEEdDFfEe252B4` |
| CentralVaultFacet | `0xE4410832468F0Ec655f26b0f22C1f6864628Ea21` |
| CollateralFacet | `0x26D0BEE6F9249dD3d098288a74f7b026929dD6BD` |
| MarketRegistryFacet | `0x819904c316dd0B8259d4486B446A057922F24116` |
## Oracle integration
HyperPax Perps uses oracle pricing for market valuation, funding, liquidations, and quote simulation. Protocol docs should link developers to:
* [x/paxoracle](/protocol/modules/paxoracle) for validator price submissions
* [PaxSpot precompiles](/paxspot/precompiles) for shared OROB, batch clearing, and PoFQ primitives
## Developer usage
Use the Diamond proxy as the contract address for user-facing facet calls.
```typescript theme={null}
const hyperpaxPerpsDiamond = '0xeA65FE02665852c615774A3041DFE6f00fb77537'
```
All facet events are emitted from the Diamond address, so indexers should subscribe to the Diamond proxy rather than individual facet implementation addresses.
## Related protocols
* [HyperPax DEX](/sidiora/dex)
* [Sidiora.fun](/sidiora/fun)
* [Sidiora.ag](/sidiora/ag)
# SDKs & Tools
Source: https://sidiorresearchlabs.mintlify.app/tools
Recommended tools and libraries for building on HyperPaxeer
## Overview
Recommended tools and libraries for building on HyperPaxeer. All standard Ethereum development tools work seamlessly with Paxeer.
## Frontend Libraries
**React Hooks for Ethereum**
Collection of React Hooks containing everything you need to start working with Ethereum. Simplify wallet connection, contract interaction, and more.
```bash theme={null}
npm install wagmi viem@2.x @tanstack/react-query
```
**TypeScript Interface for Ethereum**
Type-safe, lightweight, and composable modules to interact with Ethereum. Modern alternative to ethers and web3.js.
```bash theme={null}
npm install viem
```
## Development Frameworks
**Ethereum Development Environment**
Compile, deploy, test, and debug your Ethereum software. The most popular development framework.
```bash theme={null}
npm install --save-dev hardhat
```
**Blazing Fast Ethereum Toolkit**
Fast, portable, and modular toolkit for Ethereum application development written in Rust.
```bash theme={null}
curl -L https://foundry.paradigm.xyz | bash
foundryup
```
**Online Solidity IDE**
Powerful open source tool for writing, testing, and deploying smart contracts directly in your browser.
No installation required!
## JavaScript Libraries
### ethers.js v6
Complete Ethereum library and wallet implementation in JavaScript.
```bash Install theme={null}
npm install ethers@6
```
```javascript Usage theme={null}
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider(
'https://public-rpc.paxeer.app/rpc'
);
const balance = await provider.getBalance('0x...');
console.log(ethers.formatEther(balance));
```
Complete API reference and guides
### web3.js v4
Ethereum JavaScript API - Collection of libraries for interacting with Ethereum.
```bash Install theme={null}
npm install web3@4
```
```javascript Usage theme={null}
import Web3 from 'web3';
const web3 = new Web3('https://public-rpc.paxeer.app/rpc');
const balance = await web3.eth.getBalance('0x...');
console.log(web3.utils.fromWei(balance, 'ether'));
```
Complete API reference and guides
## Smart Contract Development
**Secure Smart Contract Library**
Battle-tested library of reusable smart contracts for Ethereum. Industry standard for secure contract development.
```bash theme={null}
npm install @openzeppelin/contracts
```
```solidity theme={null}
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MTK") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
```
[View Documentation β](https://docs.openzeppelin.com/contracts)
**Smart Contract Language**
The primary language for writing Ethereum smart contracts.
```bash theme={null}
npm install -g solc
```
Latest stable version: **0.8.20+**
[Solidity Documentation β](https://docs.soliditylang.org)
**Decentralized Oracle Network**
Connect your smart contracts to real-world data and off-chain computation.
```bash theme={null}
npm install @chainlink/contracts
```
[Chainlink Documentation β](https://docs.chain.link)
## Testing Tools
JavaScript test framework for Hardhat
```bash theme={null}
npm install --save-dev mocha chai
```
Fast Solidity testing framework
```bash theme={null}
forge test
```
Local Ethereum network for testing
```bash theme={null}
npx hardhat node
```
Personal blockchain for development
```bash theme={null}
npm install -g ganache
```
## Wallet Integration
### MetaMask
Most popular browser extension wallet for Ethereum.
```javascript Detect MetaMask theme={null}
if (typeof window.ethereum !== 'undefined') {
console.log('MetaMask is installed!');
}
```
```javascript Connect Wallet theme={null}
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts'
});
console.log('Connected:', accounts[0]);
```
```javascript Add HyperPaxeer theme={null}
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0xe5',
chainName: 'HyperPaxeer',
nativeCurrency: {
name: 'HyperPaxeer',
symbol: 'HPX',
decimals: 18
},
rpcUrls: ['https://public-rpc.paxeer.app/rpc'],
blockExplorerUrls: ['https://paxscan.io']
}]
});
```
### WalletConnect
Open protocol for connecting wallets to dApps.
```bash theme={null}
npm install @web3modal/wagmi wagmi viem
```
```typescript theme={null}
import { createWeb3Modal } from '@web3modal/wagmi/react'
import { walletConnect } from 'wagmi/connectors'
const projectId = 'YOUR_PROJECT_ID'
const modal = createWeb3Modal({
wagmiConfig,
projectId,
chains: [paxeer]
})
```
[WalletConnect Documentation β](https://docs.walletconnect.com)
### RainbowKit
The best way to connect a wallet in React.
```bash theme={null}
npm install @rainbow-me/rainbowkit wagmi viem
```
```typescript theme={null}
import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import '@rainbow-me/rainbowkit/styles.css';
function App() {
return (
);
}
```
[RainbowKit Documentation β](https://www.rainbowkit.com)
## Block Explorers
Official block explorer for HyperPaxeer. View transactions, blocks, addresses, and verify contracts.
**Features:**
* Transaction tracking
* Contract verification
* Token analytics
* Address labeling
* API access
## IDE & Editors
**Recommended Extensions:**
* Solidity by Juan Blanco
* Hardhat Solidity by Nomic Foundation
* Prettier - Code formatter
**IntelliJ IDEA / WebStorm**
Professional IDE with excellent TypeScript support and Solidity plugins.
**Lightweight Editor**
Fast, customizable editor with Solidity syntax highlighting packages.
## Additional Resources
TypeScript bindings for Ethereum smart contracts
```bash theme={null}
npm install --save-dev typechain @typechain/ethers-v6
```
Generates TypeScript types from your contract ABIs for type-safe interactions.
Indexing protocol for querying blockchain data
Create GraphQL APIs for your smart contracts.
[The Graph Documentation β](https://thegraph.com/docs)
Distributed file storage system
Store metadata, images, and other assets in a decentralized manner.
[IPFS Documentation β](https://docs.ipfs.tech)
## Developer Tools Comparison
| Tool | Best For | Language | Learning Curve |
| --------- | ---------------------- | --------------------- | -------------- |
| Hardhat | Full-stack development | JavaScript/TypeScript | Medium |
| Foundry | Smart contract focus | Solidity | Medium-High |
| Remix | Quick prototyping | Browser-based | Low |
| wagmi | React dApps | TypeScript | Low-Medium |
| ethers.js | General purpose | JavaScript | Medium |
| viem | Modern TypeScript | TypeScript | Medium |
## Community Resources
Join our developer community for support, discussions, and collaboration.
Chat with developers
View source code
## Next Steps
Get started with HyperPaxeer
Configure your development environment
Deploy your first contract
View integration examples
# Overview
Source: https://sidiorresearchlabs.mintlify.app/validate/index
# Overview
## Validating on HyperPaxeer
HyperPaxeer is based on [CometBFT](https://github.com/cometbft/cometbft),
which relies on a set of validators that are responsible for committing new blocks in the blockchain. These validators
participate in the consensus protocol by broadcasting votes which contain cryptographic signatures signed by each
validator's private key.
Validator candidates can bond their own staking tokens and have the tokens "delegated", or staked, to them by token
holders. **HPX** is HyperPaxeer's native token. The validators are
determined by who has the most stake delegated to them β the top validator candidates with the most stake
become part of the active validator set.
Validators and their delegators will earn HPX as block provisions and tokens as transaction fees through execution of
the CometBFT consensus protocol. Transaction fees are paid in HPX. Note that validators can set commission
on the fees their delegators receive as additional incentive.
## Pitfalls
If validators double sign, are frequently offline or do not participate in governance, their staked HPX (including
HPX of users that delegated to them) can be slashed. The penalty depends on the severity of the violation.
## Hardware
Validators should set up a physical operation secured with restricted access. A good starting place, for example,
would be co-locating in secure data centers.
Validators should expect to equip their datacenter location with redundant power, connectivity, and storage backups.
Expect to have several redundant networking boxes for fiber, firewall and switching and then small servers with redundant
hard drive and failover. Hardware can be on the low end of datacenter gear to start out with.
We anticipate that network requirements will be low initially. Bandwidth, CPU and memory requirements will rise as
the network grows. Large hard drives are recommended for storing years of blockchain history.
### Supported OS
We officially support macOS and Linux only in the following architectures:
* `darwin/arm64`
* `darwin/x86_64`
* `linux/arm64`
* `linux/amd64`
### Minimum Requirements
To run mainnet validator nodes, you will need a machine with the following minimum hardware requirements:
* 4 or more physical CPU cores
* At least 500GB of NVME SSD disk storage. Hard drive I/O speed is crucial!
* At least 32GB of memory (RAM)
* At least 100mbps network bandwidth
As the usage of the blockchain grows, the server requirements may increase as well, so you should have a plan for
updating your server as well.
## Get Involved
:::tip
Seek legal advice if you intend to run a validator.
:::
Set up a dedicated validator's website, social profile (eg: X (formerly Twitter)) and signal your intention to become a validator on
Discord. This is important since users will want to have information about the entity they are staking their HPX to.
## Community
Discuss the finer details of being a validator and seek advise from the rest of the validator community on our
[Discord](https://discord.gg/paxeer).
# Mainnet
Source: https://sidiorresearchlabs.mintlify.app/validate/mainnet
# Mainnet
This document outlines the steps to join an existing mainnet.
## Prerequisite Readings
* [Validator Security](./security)
## Join Mainnet
You need to set the **genesis file** and **seeds**. If you need more information about past networks, check our
[mainnet repo](https://github.com/Paxeer-Network/mainnet). The table below gives an overview of all Mainnet Chain
IDs. Note that, the displayed version might differ when an active Software Upgrade proposal exists on chain.
| Chain ID | Description | Version | Status |
| ---------------- | ------------------- | -------- | ------ |
| `hyperpax_125-1` | HyperPaxeer Mainnet | `v2.0.2` | `Live` |
:::warning
**IMPORTANT:** If you join mainnet as a validator make sure you follow all the
[security](./security) recommendations!
:::
## Server Timezone Configuration
Make sure your server **timezone configuration is UTC**.
To know what is your current timezone, run the `timedatectl` command.
:::danger
π¨ **DANGER**: Having a different timezone configuration
may cause a `LastResultsHash` mismatch error.
This will take down your node!
:::
## Install `hyperpaxd`
Follow the [installation](./../validate/setup-and-configuration/run-a-validator) document to
install the `hyperpaxd` binary.
:::warning
Make sure you have the right version of `hyperpaxd` installed.
:::
### Save Chain ID
We recommend saving the mainnet `chain-id` into your `hyperpaxd`'s `client.toml`.
This will make it so you do not have to manually pass in the `chain-id` flag for every CLI command.
:::tip
See the Official [Chain IDs](./../protocol/concepts/chain-id#official-chain-ids) for reference.
:::
```bash theme={null}
hyperpaxd config chain-id hyperpax_125-1
```
## Initialize Node
We need to initialize the node to create all the necessary validator and node configuration files:
```bash theme={null}
hyperpaxd init --chain-id hyperpax_125-1
```
:::danger
Monikers can contain only ASCII characters. Using Unicode characters will render your node unreachable.
:::
By default, the `init` command creates your `~/.hyperpaxd` (i.e `$HOME`) directory with subfolders `config/` and `data/`.
In the `config` directory, the most important files for configuration are `app.toml` and `config.toml`.
## Genesis & Seeds
### Copy the Genesis File
Download the `genesis.json` file from the [`archive`](https://archive.hyperpaxd.org/mainnet/genesis.json) and copy it over
to the `config` directory: `~/.hyperpaxd/config/genesis.json`. This is a genesis file with the chain-id and genesis
accounts balances.
```bash theme={null}
wget https://archive.hyperpaxd.org/mainnet/genesis.json
mv genesis.json ~/.hyperpaxd/config/
```
Then verify the correctness of the genesis configuration file:
```bash theme={null}
hyperpaxd validate-genesis
```
### Add Seed Nodes
Your node needs to know how to find [peers](https://docs.tendermint.com/v0.34/tendermint-core/using-tendermint.html#peers).
You'll need to add healthy [seed nodes](https://docs.tendermint.com/v0.34/tendermint-core/using-tendermint.html#seed)
to `$HOME/.hyperpaxd/config/config.toml`. The [`mainnet`](https://github.com/Paxeer-Network/mainnet) repo contains links to some
seed nodes.
Edit the file located in `~/.hyperpaxd/config/config.toml` and the `seeds` to the following:
```toml theme={null}
#######################################################
### P2P Configuration Options ###
#######################################################
[p2p]
# ...
# Comma separated list of seed nodes to connect to
seeds = "@:"
```
You can use the following code to get seeds from the repo and add it to your config:
```bash theme={null}
SEEDS=`curl -sL https://raw.githubusercontent.com/Paxeer-Network/mainnet/main/Paxeer-Network_9001-2/seeds.txt | awk '{print $1}' | paste -s -d, -`
sed -i.bak -e "s/^seeds =.*/seeds = \"$SEEDS\"/" ~/.hyperpaxd/config/config.toml
```
:::tip
For more information on seeds and peers, you can the Tendermint [P2P documentation](https://docs.tendermint.com/master/spec/p2p/peer.html).
:::
### Add Persistent Peers
We can set the [`persistent_peers`](https://docs.tendermint.com/v0.34/tendermint-core/using-tendermint.html#persistent-peer)
field in `~/.hyperpaxd/config/config.toml` to specify peers that your node will maintain persistent
connections with.
## Run a Mainnet Validator
:::tip
For more details on how to run your validator, follow the validator [these](./setup-and-configuration/run-a-validator)
instructions.
:::
```bash theme={null}
hyperpaxd tx staking create-validator \
--amount=1000000000000ahpx \
--pubkey=$(hyperpaxd tendermint show-validator) \
--moniker="PaxeerValidator" \
--chain-id= \
--commission-rate="0.05" \
--commission-max-rate="0.20" \
--commission-max-change-rate="0.01" \
--min-self-delegation="1000000" \
--gas="auto" \
--gas-prices="0.025ahpx" \
--from=
```
:::danger
π¨ **DANGER**: Never create your validator keys using a [`test`](./../protocol/concepts/keyring#testing)
keying backend. Doing so might result in a loss of funds by making your funds remotely accessible via the `eth_sendTransaction`
JSON-RPC endpoint.
Ref: [Security Advisory: Insecurely configured geth can make funds remotely accessible](https://blog.ethereum.org/2015/08/29/security-alert-insecurely-configured-geth-can-make-funds-remotely-accessible/)
:::
## Start mainnet
The final step is to [start the nodes](./../protocol/Paxeer-Network-cli/single-node#start-node). Once enough voting power (+2/3)
from the genesis validators is up-and-running, the node will start producing blocks.
```bash theme={null}
hyperpaxd start
```
## Share your Peer
You can share your peer to posting it in the `#find-peers` channel in the [HyperPaxeer Discord](https://discord.gg/Paxeer-Network).
:::tip
To get your Node ID use
```bash theme={null}
hyperpaxd tendermint show-node-id
```
:::
## State Syncing a Node
If you want to join the network using State Sync (quick, but not applicable for archive nodes), check our
[State Sync](./setup-and-configuration/state-sync) page.
# Run an IBC Relayer
Source: https://sidiorresearchlabs.mintlify.app/validate/relayers
# Run an IBC Relayer
## What is an IBC Relayer?
An IBC relayer is a software component that facilitates communication between two distinct blockchain networks that
support the Inter-Blockchain Communication (IBC) protocol. The IBC protocol is a standard for the secure and reliable
transfer of digital assets and data across different blockchain networks.
An IBC relayer is responsible for relaying IBC packets, which are used to send messages and data between two different
blockchain networks. It receives packets from one chain, verifies their authenticity and validity, and then relays
them to the receiving chain.
## Minimum Requirements
* 8 core (4 physical core), x86\_64 architecture processor
* 32 GB RAM (or equivalent swap file set up)
* 1 TB+ nVME drives
If running many nodes on a single VM, [ensure your open files limit is increased](https://tecadmin.net/increase-open-files-limit-ubuntu/).
## Prerequisites
Before beginning, ensure you have an HyperPaxeer node running in the background of the same machine that you intend to relay on.
Follow [this guide](./../protocol/Paxeer-Network-cli/single-node) to set up an HyperPaxeer node if you have not already.
In this guide, we will be relaying between [HyperPaxeer (channel-3) and Cosmos Hub (channel-292)](https://www.mintscan.io/Paxeer-Network/relayers).
When setting up your HyperPaxeer and Cosmos full nodes, be sure to offset the ports being used in both the `app.toml` and `config.toml`
files of the respective chains (this process will be shown below).
In this example, the default ports for HyperPaxeer will be used, and the ports of the Cosmos Hub node will be manually changed.
## HyperPaxeer Daemon Settings
First, set `grpc server` on port `9090` in the `app.toml` file from the `$HOME/.hyperpaxd/config` directory:
```bash theme={null}
vim $HOME/.hyperpaxd/config/app.toml
```
```bash theme={null}
[grpc]
# Enable defines if the gRPC server should be enabled.
enable = true
# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9090"
```
Then, set the `pprof_laddr` to port `6060`, `rpc laddr` to port `26657`, and `prp laddr` to `26656` in the `config.toml`
file from the `$HOME/.hyperpaxd/config` directory:
```bash theme={null}
vim $HOME/.hyperpaxd/config/config.toml
```
```bash theme={null}
# pprof listen address (https://golang.org/pkg/net/http/pprof)
pprof_laddr = "localhost:6060"
```
```bash theme={null}
[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://127.0.0.1:26657"
```
```bash theme={null}
[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26656"
```
## Cosmos Daemon Settings
First, set `grpc server` to port `9090` in the `app.toml` file from the `$HOME/.gaiad/config` directory:
```bash theme={null}
vim $HOME/.gaiad/config/app.toml
```
```bash theme={null}
[grpc]
# Enable defines if the gRPC server should be enabled.
enable = true
# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9092"
```
Then, set the `pprof_laddr` to port `6062`, `rpc laddr` to port `26757`, and `prp laddr` to `26756` in the `config.toml`
file from the `$HOME/.gaiad/config` directory:
```bash theme={null}
vim $HOME/.gaiad/config/app.toml
```
```bash theme={null}
# pprof listen address (https://golang.org/pkg/net/http/pprof)
pprof_laddr = "localhost:6062"
```
```bash theme={null}
[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://127.0.0.1:26757"
```
```bash theme={null}
[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26756"
```
## Install Rust Dependencies
Install the following rust dependencies:
```bash theme={null}
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
```bash theme={null}
source $HOME/.cargo/env
sudo apt-get install pkg-config libssl-dev
```
```bash theme={null}
sudo apt install librust-openssl-dev build-essential git
```
## Build & Setup Hermes
Create the directory where the binary will be placed, clone the hermes source repository, and build it using the latest release.
```bash theme={null}
mkdir -p $HOME/hermes
git clone https://github.com/informalsystems/ibc-rs.git hermes
cd hermes
git checkout v0.12.0
cargo install ibc-relayer-cli --bin hermes --locked
```
Make the hermes `config` and `keys` directory, and copy `config.toml` to the config directory:
```bash theme={null}
mkdir -p $HOME/.hermes
mkdir -p $HOME/.hermes/keys
cp config.toml $HOME/.hermes
```
Check the hermes version and configuration directory setup:
```bash theme={null}
$ hermes version
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
hermes 0.12.0
```
Edit the hermes configuration (use ports according the port configuration set above, adding only chains that will be relayed):
```bash theme={null}
vim $HOME/.hermes/config.toml
```
```bash theme={null}
# In this example, we will set channel-292 on the cosmoshub-4 chain settings and channel-3 on the HyperPaxeer_9001-2 chain settings:
[[chains]]
id = 'cosmoshub-4'
rpc_addr = 'http://127.0.0.1:26757'
grpc_addr = 'http://127.0.0.1:9092'
websocket_addr = 'ws://127.0.0.1:26757/websocket'
...
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-292'], # HyperPaxeer_9001-2
]
[[chains]]
id = 'HyperPaxeer_9001-2'
rpc_addr = 'http://127.0.0.1:26657'
grpc_addr = 'http://127.0.0.1:9090'
websocket_addr = 'ws://127.0.0.1:26657/websocket'
...
address_type = { derivation = 'ethermint', proto_type = { pk_type = '/ethermint.crypto.v1.ethsecp256k1.PubKey' } }
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-3'], # cosmoshub-4
]
```
Add your relayer wallet to Hermes' keyring (located in `$HOME/.hermes/keys`)
The best practice is to use the same mnemonic over all networks. Do not use your relaying-addresses for anything else,
because it will lead to account sequence errors.
```bash theme={null}
hermes keys restore cosmoshub-4 -m "24-word mnemonic seed"
hermes keys restore HyperPaxeer_9001-2 -m "24-word mnemonic seed"
```
Ensure this wallet has funds in both HyperPaxeer and ATOM in order to pay the fees required to relay.
## Final Checks
Validate your hermes configuration file:
```bash theme={null}
$ hermes config validate
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
Success: "validation passed successfully"
```
Perform the hermes `health-check` to see if all connected nodes are up and synced:
```bash theme={null}
$ hermes health-check
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
INFO ThreadId(01) telemetry service running, exposing metrics at http://0.0.0.0:3001/metrics
INFO ThreadId(01) starting REST API server listening at http://127.0.0.1:3000
INFO ThreadId(01) [cosmoshub-4] chain is healthy
INFO ThreadId(01) [HyperPaxeer_9001-2] chain is healthy
```
When your nodes are fully synced, you can start the hermes daemon:
```bash theme={null}
hermes start
```
Watch hermes' output for successfully relayed packets, or any errors.
It will try and clear any unrecieved packets after startup has completed.
## Helpful Commands
Query hermes for unrecieved packets and acknowledgements (ie. check if channels are "clear") with the following:
```bash theme={null}
hermes query packet unreceived-packets cosmoshub-4 transfer channel-292
hermes query packet unreceived-acks cosmoshub-4 transfer channel-292
```
```bash theme={null}
hermes query packet unreceived-packets HyperPaxeer_9001-2 transfer channel-3
hermes query packet unreceived-acks HyperPaxeer_9001-2 transfer channel-3
```
Query hermes for packet commitments with the following:
```bash theme={null}
hermes query packet commitments cosmoshub-4 transfer channel-292
hermes query packet commitments HyperPaxeer_9001-2 transfer channel-3
```
Clear the channel (only works on hermes `v0.12.0` and higher) with the following:
```bash theme={null}
hermes clear packets cosmoshub-4 transfer channel-292
hermes clear packets HyperPaxeer_9001-2 transfer channel-3
```
Clear unrecieved packets manually
(experimental, will need to stop hermes daemon to prevent confusion with account sequences)
with the following:
```bash theme={null}
hermes tx raw packet-recv HyperPaxeer_9001-2 cosmoshub-4 transfer channel-292
hermes tx raw packet-ack HyperPaxeer_9001-2 cosmoshub-4 transfer channel-292
hermes tx raw packet-recv cosmoshub-4 HyperPaxeer_9001-2 transfer channel-3
hermes tx raw packet-ack cosmoshub-4 HyperPaxeer_9001-2 transfer channel-3
```
# Configuration
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/configuration
# Configuration
## Server Timezone
Make sure your server **timezone configuration is UTC**.
To know what is your current timezone, run the `timedatectl` command.
:::danger
π¨ **DANGER**: Having a different timezone configuration
may cause a `LastResultsHash` mismatch error.
This will take down your node!
:::
## Block Time
The timeout-commit value in the node config defines how long we wait after committing a block,
before starting on the new height
(this gives us a chance to receive some more pre-commits, even though we already have +2/3).
The current default value is `"3s"`.
:::tip
**Note**: From v6, this is handled automatically by the server when initializing the node.
Validators will need to ensure their local node configurations in order to speed up the network to \~4s block times.
:::
```toml theme={null}
# In ~/.hyperpaxd/config/config.toml
#######################################################
### Consensus Configuration Options ###
#######################################################
[consensus]
### ...
# How long we wait after committing a block, before starting on the new
# height (this gives us a chance to receive some more precommits, even
# though we already have +2/3).
timeout_commit = "3s"
```
## Peers
In `~/.hyperpaxd/config/config.toml` you can set your peers.
See the [Add persistent peers section](./../testnet#add-persistent-peers) in our docs for an automated method, but
field should look something like a comma separated string of peers (do not copy this, just an example):
```toml theme={null}
persistent_peers = "5576b0160761fe81ccdf88e06031a01bc8643d51@195.201.108.97:24656,13e850d14610f966de38fc2f925f6dc35c7f4bf4@176.9.60.27:26656,38eb4984f89899a5d8d1f04a79b356f15681bb78@18.169.155.159:26656,59c4351009223b3652674bd5ee4324926a5a11aa@51.15.133.26:26656,3a5a9022c8aa2214a7af26ebbfac49b77e34e5c5@65.108.1.46:26656,4fc0bea2044c9fd1ea8cc987119bb8bdff91aaf3@65.21.246.124:26656,6624238168de05893ca74c2b0270553189810aa7@95.216.100.80:26656,9d247286cd407dc8d07502240245f836e18c0517@149.248.32.208:26656,37d59371f7578101dee74d5a26c86128a229b8bf@194.163.172.168:26656,b607050b4e5b06e52c12fcf2db6930fd0937ef3b@95.217.107.96:26656,7a6bbbb6f6146cb11aebf77039089cd038003964@94.130.54.247:26656"
```
### Sharing your Peer
You can see and share your peer with the `tendermint show-node-id` command
```bash theme={null}
hyperpaxd tendermint show-node-id
ac29d21d0a6885465048a4481d16c12f59b2e58b
```
* **Peer Format**: `node-id@ip:port`
* **Example**: `ac29d21d0a6885465048a4481d16c12f59b2e58b@143.198.224.124:26656`
### Healthy peers
If you are relying on just a seed node and no persistent peers or a low amount of them,
please increase the following params in the `config.toml`:
```toml theme={null}
# Maximum number of inbound peers
max_num_inbound_peers = 120
# Maximum number of outbound peers to connect to, excluding persistent peers
max_num_outbound_peers = 60
```
## EIP-155 Replay Protection
The EIP-155 replay protection is enabled globally in the EVM module parameters.
In case this is disabled as a global requirement, node operators can opt into supporting unprotected transactions
by adjusting the corresponding setting in the [node configuration](https://github.com/Paxeer-Network/Paxeer-Network/blob/v18.1.0/server/config/toml.go#L74-L76):
```toml theme={null}
# in $HOME/.hyperpaxd/config/config.toml
# AllowUnprotectedTxs restricts unprotected (non EIP-155 signed) transactions to be submitted via
# the node's RPC when the global parameter is disabled.
allow-unprotected-txs = true # false by default
```
More information about EIP-155 can be found here: [EIP-155: Replay Protection](../../protocol/concepts/replay-protection.md).
# Disk Usage Optimization
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/disk-usage-configuration
# Disk Usage Optimization
Customize the configuration settings to lower the disk requirements for your validator node.
Blockchain database tends to grow over time, depending e.g. on block
speed and transaction amount. For HyperPaxeer, we are talking about close to
100GB of disk usage in first two weeks.
There are few configurations that can be done to reduce the required
disk usage quite significantly. Some of these changes take full effect
only when you do the configuration and start syncing from start with
them in use.
## Indexing
If you do not need to query transactions from the specific node, you can
disable indexing. On `config.toml` set
```toml theme={null}
indexer = "null"
```
If you do this on already synced node, the collected index is not purged
automatically, you need to delete it manually. The index is located
under the database directory with name `data/tx_index.db/`.
## State-sync snapshots
I believe this was disabled by default on HyperPaxeer, but listing it in any
case here. On `app.toml` set
```toml theme={null}
snapshot-interval = 0
```
Note that if state-sync was enabled on the network and working properly,
it would allow one to sync a new node in few minutes. But this node
would not have the history.
## Configure pruning
By default every 500th state, and the last 100 states are kept. This
consumes a lot of disk space on long run, and can be optimized with
following custom configuration:
```toml theme={null}
pruning = "custom"
pruning-keep-recent = "100"
pruning-keep-every = "0"
pruning-interval = "10"
```
Configuring `pruning-keep-recent = "0"` might sound tempting, but this
will risk database corruption if the `hyperpaxd` is killed for any reason.
Thus, it is recommended to keep the few latest states.
## Logging
By default the logging level is set to `info`, and this produces a lot of
logs. This log level might be good when starting up to see that the
node starts syncing properly. However, after you see the syncing is
going smoothly, you can lower the log level to `warn` (or `error`). On
`config.toml` set the following
```toml theme={null}
log_level = "warn"
```
Also ensure your log rotation is configured properly.
## Results
Below is the disk usage after two weeks of HyperPaxeer Arsia Mons testnet. The default
configuration results in disk usage of 90GB.
```bash theme={null}
5.3G ./state.db
70G ./application.db
20K ./snapshots/metadata.db
24K ./snapshots
9.0G ./blockstore.db
20K ./evidence.db
1018M ./cs.wal
4.7G ./tx_index.db
90G .
```
This optimized configuration has reduced the disk usage to 17 GB.
```bash theme={null}
17G .
1.1G ./cs.wal
946M ./application.db
20K ./evidence.db
9.1G ./blockstore.db
24K ./snapshots
20K ./snapshots/metadata.db
5.3G ./state.db
```
# Validator FAQ
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/faq
# Validator FAQ
Check the FAQ for running a validator on HyperPaxeer.
## General Concepts
What is a validator?
HyperPaxeer is powered by [Tendermint](https://docs.tendermint.com/v0.34/introduction/what-is-tendermint.html) Core,
which relies on a set of validators to secure the network. Validators run a full node and participate in consensus
by broadcasting votes which contain cryptographic signatures signed by their private key. Validators commit new
blocks in the blockchain and receive revenue in exchange for their work. They also participate in on-protocol
treasury governance by voting on governance proposals. A validator's voting influence is weighted according to
their total stake.
What is "staking"?
HyperPaxeer is a public Proof-of-Stake (PoS) blockchain, meaning that validator's weight is determined by the amount of
staking tokens (HyperPaxeer) bonded as collateral. These staking tokens can be staked directly by the validator or delegated
to them by HyperPaxeer holders.
Any user in the system can declare its intention to become a validator by sending a `create-validator` transaction.
From there, they become validators.
The weight (i.e. total stake or voting power) of a validator determines wether or not it is an active validator,
and also how frequently this node will have to propose a block and how much revenue it will obtain. Initially, only
the top 150 validators with the most weight will be active validators. If validators double-sign, or are frequently
offline, they risk their staked tokens (including HyperPaxeer delegated by users) being "slashed" by the protocol to
penalize negligence and misbehavior.
What is a full node?
A full node is a program that fully validates transactions and blocks of a blockchain. It is distinct from a light
client node that only processes block headers and a small subset of transactions. Running a full node requires more
resources than a light client but is necessary in order to be a validator. In practice, running a full-node only
implies running a non-compromised and up-to-date version of the software with low network latency and without downtime.
Of course, it is possible and encouraged for any user to run full nodes even if they do not plan to be validators.
What is a delegator?
Delegators are HyperPaxeer holders who cannot, or do not want to run validator operations themselves. Users can delegate
HyperPaxeer to a validator and obtain a part of its revenue in exchange (for more detail on how revenue is distributed, see
`What is the incentive to stake?` and `What is a validator's commission?` sections below).
Because they share revenue with their validators, delegators also share responsibility. Should a validator misbehave,
each of its delegators will be partially slashed in proportion to their stake. This is why delegators should perform
due-diligence on validators before delegating, as well as diversifying by spreading their stake over multiple validators.
Delegators play a critical role in the system, as they are responsible for choosing validators. Be aware that being a
delegator is not a passive role. Delegators are obligated to remain vigilant and actively monitor the actions of their
validators, switching should they fail to act responsibly.
## Becoming a Validator
How to become a validator?
Any participant in the network can signal their intent to become a validator by creating a validator and registering
its validator profile. To do so, the candidate broadcasts a `create-validator` transaction, in which they must
submit the following information:
* **Validator's PubKey**: Validator operators can have different accounts for validating and holding liquid funds.
The PubKey submitted must be associated with the private key with which the validator intends to sign *prevotes*
and *precommits*.
* **Validator's Address**: `HyperPaxeervaloper1-` address. This is the address used to identify your validator publicly.
The private key associated with this address is used to bond, unbond, and claim rewards.
* **Validator's name** (also known as the **moniker**)
* **Validator's website** *(optional)*
* **Validator's description** *(optional)*
* **Initial commission rate**: The commission rate on block provisions, block rewards and fees charged to delegators.
* **Maximum commission**: The maximum commission rate which this validator will be allowed to charge.
* **Commission change rate**: The maximum daily increase of the validator commission.
* **Minimum self-bond amount**: Minimum amount of HyperPaxeer the validator needs to have bonded at all times. If the
validator's self-bonded stake falls below this limit, its entire staking pool will be unbonded.
* **Initial self-bond amount**: Initial amount of HyperPaxeer the validator wants to self-bond.
```bash theme={null}
hyperpaxd tx staking create-validator
--pubkey HyperPaxeervalconspub1zcjduepqs5s0vddx5m65h5ntjzwd0x8g3245rgrytpds4ds7vdtlwx06mcesmnkzly
--amount "2ahpx"
--from tmp
--commission-rate="0.20"
--commission-max-rate="1.00"
--commission-max-change-rate="0.01"
--min-self-delegation "1"
--moniker "validator"
--chain-id "hyperpax_125-4"
--gas auto
--node tcp://127.0.0.1:26647
```
:::danger
π¨ **DANGER**: Never create your mainnet validator keys using a [`test`](./../../protocol/concepts/keyring#testing)
keying backend. Doing so might result in a loss of funds by making your funds remotely accessible via the
`eth_sendTransaction` JSON-RPC endpoint.
Ref: [Security Advisory: Insecurely configured geth can make funds remotely accessible](https://blog.ethereum.org/2015/08/29/security-alert-insecurely-configured-geth-can-make-funds-remotely-accessible/)
:::
Once a validator is created and registered, HyperPaxeer holders can delegate HyperPaxeer to it, effectively adding stake to
its pool. The total stake of a validator is the sum of the HyperPaxeer self-bonded by the validator's operator and the
HyperPaxeer bonded by external delegators.
**Only the top 150 validators with the most stake are considered the active validators**, becoming
**bonded validators**. If ever a validator's total stake dips below the top 150, the validator loses
its validator privileges (meaning that it won't generate rewards) and no longer serves as part of
the active set (i.e doesn't participate in consensus), entering **unbonding mode** and eventually becomes **unbonded**.
## Validator keys and states
What are the different types of keys?
In short, there are two types of keys:
* **Tendermint Key**: This is a unique key used to sign block hashes. It is associated with a public key
`HyperPaxeervalconspub`.
* Generated when the node is created with `hyperpaxd init`.
* Get this value with `hyperpaxd tendermint show-validator`
e.g. `HyperPaxeervalconspub1zcjduc3qcyj09qc03elte23zwshdx92jm6ce88fgc90rtqhjx8v0608qh5ssp0w94c`
* **Application keys**: These keys are created from the application and used to sign transactions. As a validator,
you will probably use one key to sign staking-related transactions, and another key to sign oracle-related
transactions. Application keys are associated with a public key `HyperPaxeerpub-` and an address `HyperPaxeer-`. Both
are derived from account keys generated by `hyperpaxd keys add`.
:::warning
A validator's operator key is directly tied to an application key, but uses reserved prefixes solely for this
purpose: `HyperPaxeervaloper` and `HyperPaxeervaloperpub`
:::
What are the different states a validator can be in?
After a validator is created with a `create-validator` transaction, it can be in three states:
* `bonded`: Validator is in the active set and participates in consensus. Validator is earning rewards and can be
slashed for misbehaviour.
* `unbonding`: Validator is not in the active set and does not participate in consensus. Validator is not earning
rewards, but can still be slashed for misbehaviour. This is a transition state from `bonded` to `unbonded`. If
validator does not send a `rebond` transaction while in `unbonding` mode, it will take two weeks for the state
transition to complete.
* `unbonded`: Validator is not in the active set, and therefore not signing blocks. Unbonded validators cannot be
slashed, but do not earn any rewards from their operation. It is still possible to delegate HyperPaxeer to this
validator. Un-delegating from an `unbonded` validator is immediate.
Delegators have the same state as their validator.
:::warning
Delegations are not necessarily bonded. HyperPaxeer can be delegated and bonded, delegated and unbonding, delegated and
unbonded, or liquid.
:::
What is "self-bond"? How can I increase my "self-bond"?
The validator operator's "self-bond" refers to the amount of HyperPaxeer stake delegated to itself. You can increase your
self-bond by delegating more HyperPaxeer to your validator account.
Is there a testnet faucet?
If you want to obtain coins for the testnet, you can do so by using the [faucet](https://faucet.hyperpaxd.dev/).
Is there a minimum amount of HyperPaxeer that must be staked to be an active (bonded) validator?
There is no minimum. The top 150 validators with the highest total stake (where
`total stake = self-bonded stake + delegators stake`) are the active validators.
How will delegators choose their validators?
Delegators are free to choose validators according to their own subjective criteria. That said, criteria anticipated to
be important include:
* **Amount of self-bonded HyperPaxeer:** Number of HyperPaxeer a validator self-bonded to its staking pool. A validator with higher
amount of self-bonded HyperPaxeer has more skin in the game, making it more liable for its actions.
* **Amount of delegated HyperPaxeer:** Total number of HyperPaxeer delegated to a validator. A high stake shows that the community
trusts this validator, but it also means that this validator is a bigger target for hackers. Validators are expected
to become less and less attractive as their amount of delegated HyperPaxeer grows. Bigger validators also increase the
centralization of the network.
* **Commission rate:** Commission applied on revenue by validators before it is distributed to their delegators
* **Track record:** Delegators will likely look at the track record of the validators they plan to delegate to. This
includes seniority, past votes on proposals, historical average uptime and how often the node was compromised.
Apart from these criteria, there will be a possibility for validators to signal a website address to complete their
resume. Validators will need to build reputation one way or another to attract delegators. For example, it would be
a good practice for validators to have their setup audited by third parties. Note though, that the HyperPaxeer team will
not approve or conduct any audit itself.
## Responsibilities
Do validators need to be publicly identified?
No, they do not. Each delegator will value validators based on their own criteria. Validators will be able(and are
advised) to register a website address when they nominate themselves so that they can advertise their operation as
they see fit. Some delegators may prefer a website that clearly displays the team running the validator and their
resume, while others might prefer anonymous validators with positive track records. Most likely both identified
and anonymous validators will coexist in the validator set.
What are the responsibilities of a validator?
Validators have three main responsibilities:
* **Be able to constantly run a correct version of the software:** validators need to make sure that their servers are
always online and their private keys are not compromised.
* **Provide oversight and feedback on correct deployment of community pool funds:** the HyperPaxeer protocol includes the a
governance system for proposals to the facilitate adoption of its currencies. Validators are expected to hold budget
executors to account to provide transparency and efficient use of funds.
Additionally, validators are expected to be active members of the community. They should always be up-to-date with the
current state of the ecosystem so that they can easily adapt to any change.
What does staking imply?
Staking HyperPaxeer can be thought of as a safety deposit on validation activities. When a validator or a delegator wants to
retrieve part or all of their deposit, they send an unbonding transaction. Then, the deposit undergoes a *two week
unbonding period* during which they are liable to being slashed for potential misbehavior committed by the validator
before the unbonding process started.
Validators, and by association delegators, receive block provisions, block rewards, and fee rewards. If a validator
misbehaves, a certain portion of its total stake is slashed (the severity of the penalty depends on the type
of misbehavior). This means that every user that bonded HyperPaxeer to this validator gets penalized in proportion
to its stake. Delegators are therefore incentivized to delegate to validators that they anticipate will function safely.
Can a validator run away with its delegators' HyperPaxeer?
By delegating to a validator, a user delegates staking power. The more staking power a validator has, the more weight
it has in the consensus and processes. This does not mean that the validator has custody of its delegators' HyperPaxeer.
*By no means can a validator run away with its delegator's funds*.
Even though delegated funds cannot be stolen by their validators, delegators are still liable if their validators
misbehave. In such case, each delegators' stake will be partially slashed in proportion to their relative stake.
How often will a validator be chosen to propose the next block? Does it go up with the quantity of HyperPaxeer
staked?
The validator that is selected to mine the next block is called the **proposer**, the "leader" in the consensus for the
round. Each proposer is selected deterministically, and the frequency of being chosen is equal to the relative total
stake (where total stake = self-bonded stake + delegators stake) of the validator. For example, if the total
bonded stake across all validators is 100 HyperPaxeer, and a validator's total stake is 10 HyperPaxeer, then this validator
will be chosen 10% of the time as the proposer.
To understand more about the proposer selection process in Tendermint BFT consensus, read more
[in their official docs](https://docs.tendermint.com/master/spec/consensus/proposer-selection.html).
## Incentives
What is the incentive to stake?
Each member of a validator's staking pool earns different types of revenue:
* **Block rewards:** Native tokens of applications run by validators (e.g. HyperPaxeer on HyperPaxeer) are inflated to produce
block provisions. These provisions exist to incentivize HyperPaxeer holders to bond their stake, as non-bonded HyperPaxeer will
be diluted over time.
* **Transaction fees:** HyperPaxeer maintains a whitelist of token that are accepted as fee payment. The initial fee token is
the `HyperPaxeer`.
This total revenue is divided among validators' staking pools according to each validator's weight. Then, within each
validator's staking pool the revenue is divided among delegators in proportion to each delegator's stake. A commission
on delegators' revenue is applied by the validator before it is distributed.
What is the incentive to run a validator?
Validators earn proportionally more revenue than their delegators because of commissions.
Validators also play a major role in governance. If a delegator does not vote, they inherit the vote from their
validator. This gives validators a major responsibility in the ecosystem.
What is a validator's commission?
Revenue received by a validator's pool is split between the validator and its delegators. The validator can apply a
commission on the part of the revenue that goes to its delegators. This commission is set as a percentage.
Each validator is free to set its initial commission, maximum daily commission change rate and maximum commission.
HyperPaxeer enforces the parameter that each validator sets. These parameters can only be defined when initially declaring
candidacy, and may only be constrained further after being declared.
How are block provisions distributed?
Block provisions (rewards) are distributed proportionally to all validators relative to their total stake (voting power).
This means that even though each validator gains HyperPaxeer with each provision, all validators will still maintain equal
weight.
Let us take an example where we have 10 validators with equal staking power and a commission rate of 1%. Let us also
assume that the provision for a block is 1000 HyperPaxeer and that each validator has 20% of self-bonded HyperPaxeer. These tokens
do not go directly to the proposer. Instead, they are evenly spread among validators. So now each validator's pool
has 100 HyperPaxeer. These 100 HyperPaxeer will be distributed according to each participant's stake:
* Commission: `100*80%*1% = 0.8 HyperPaxeer`
* Validator gets: `100\*20% + Commission = 20.8 HyperPaxeer`
* All delegators get: `100\*80% - Commission = 79.2 HyperPaxeer`
Then, each delegator can claim its part of the 79.2 HyperPaxeer in proportion to their stake in the validator's staking pool.
Note that the validator's commission is not applied on block provisions. Note that block rewards (paid in HyperPaxeer) are
distributed according to the same mechanism.
How are fees distributed?
Fees are similarly distributed with the exception that the block proposer can get a bonus on the fees of the block it
proposes if it includes more than the strict minimum of required precommits.
When a validator is selected to propose the next block, it must include at least β precommits for the previous block in
the form of validator signatures. However, there is an incentive to include more than β precommits in the form of a
bonus. The bonus is linear: it ranges from 1% if the proposer includes β rd precommits (minimum for the block to be
valid) to 5% if the proposer includes 100% precommits. Of course the proposer should not wait too long or other
validators may timeout and move on to the next proposer. As such, validators have to find a balance between
wait-time to get the most signatures and risk of losing out on proposing the next block. This mechanism aims
to incentivize non-empty block proposals, better networking between validators as well as to mitigate censorship.
Let's take a concrete example to illustrate the aforementioned concept. In this example, there are 10 validators with
equal stake. Each of them applies a 1% commission and has 20% of self-bonded HyperPaxeer. Now comes a successful block
that collects a total of 1005 HyperPaxeer in fees. Let's assume that the proposer included 100% of the signatures in its
block. It thus obtains the full bonus of 5%.
We have to solve this simple equation to find the reward $R$ for each validator:
$9R ~ + ~ R ~ + ~ 5\%(R) ~ = ~ 1005 ~ \Leftrightarrow ~ R ~ = ~ 1005 ~/ ~10.05 ~ = ~ 100$
* For the proposer validator:
* The pool obtains $R ~ + ~ 5\%(R)$: 105 HyperPaxeer
* Commission: $105 ~ *~ 80\% ~* ~ 1\%$ = 0.84 HyperPaxeer
* Validator's reward: $105 ~ * ~ 20\% ~ + ~ Commission$ = 21.84 HyperPaxeer
* Delegators' rewards: $105 ~ * ~ 80\% ~ - ~ Commission$ = 83.16 HyperPaxeer (each delegator will be able to claim its portion
of these rewards in proportion to their stake)
* The pool obtains $R$: 100 HyperPaxeer
* Commission: $100 ~ *~ 80\% ~* ~ 1\%$ = 0.8 HyperPaxeer
* Validator's reward: $100 ~ * ~ 20\% ~ + ~ Commission$ = 20.8 HyperPaxeer
* Delegators' rewards: $100 ~ * ~ 80\% ~ - ~ Commission$ = 79.2 HyperPaxeer (each delegator will be able to claim its portion
of these rewards in proportion to their stake\\
What are the slashing conditions?
If a validator misbehaves, its bonded stake along with its delegators' stake and will be slashed. The severity of the
punishment depends on the type of fault. There are 3 main faults that can result in slashing of funds for a validator
and its delegators:
* **Double-signing:** If someone reports on chain A that a validator signed two blocks at the same height on chain A and
chain B, and if chain A and chain B share a common ancestor, then this validator will get slashed on chain A. The penalty
for double signing is 10.00% of total stake.
* **Downtime:** If a validator misses more than 50% of the last 90.000 blocks, they will get slashed by 0.50%.
* **Unavailability:** If a validator's signature has not been included in the last X blocks, the validator will get
slashed by a marginal amount proportional to X. If X is above a certain limit Y, then the validator will get unbonded.
Note that even if a validator does not intentionally misbehave, it can still be slashed if its node crashes, looses
connectivity, gets DDoSed, or if its private key is compromised.
Here are some links to community's learning from double signing worth a look:
* [Learnings from BlockDaemon](https://blockdaemon.com/documentation/Paxeer-Network-post-mortem/)
Are there any best practice guides on preventing double-signing?
There is an awesome guide. Polkachu is a validator on HyperPaxeer and they have wrote [this page](https://github.com/polkachu/validator-guide/blob/main/validator_server_migration_best_practice.md)
to help out.
Do validators need to self-bond HyperPaxeer?
No, they do not. A validators total stake is equal to the sum of its own self-bonded stake and of its delegated stake.
This means that a validator can compensate its low amount of self-bonded stake by attracting more delegators. This is
why reputation is very important for validators.
Even though there is no obligation for validators to self-bond HyperPaxeer, delegators should want their validator to have
self-bonded HyperPaxeer in their staking pool. In other words, validators should have skin-in-the-game.
In order for delegators to have some guarantee about how much skin-in-the-game their validator has, the latter can signal
a minimum amount of self-bonded HyperPaxeer. If a validator's self-bond goes below the limit that it predefined, this
validator and all of its delegators will unbond.
How to prevent concentration of stake in the hands of a few top validators?
For now the community is expected to behave in a smart and self-preserving way. When a mining pool in Bitcoin gets too
much mining power the community usually stops contributing to that pool. HyperPaxeer will rely on the same effect initially.
In the future, other mechanisms will be deployed to smoothen this process as much as possible:
* **Penalty-free re-delegation:** This is to allow delegators to easily switch from one validator to another, in order
to reduce validator stickiness.
* **UI warning:** Wallets can implement warnings that will be displayed to users if they want to delegate to a validator
that already has a significant amount of staking power.
## Technical Requirements
What are hardware requirements?
Validators should expect to provision one or more data center locations with redundant power, networking, firewalls,
HSMs and servers.
We expect that a modest level of hardware specifications will be needed initially and that they might rise as network
use increases. Participating in the testnet is the best way to learn more.
What are software requirements?
In addition to running an HyperPaxeer node, validators should develop monitoring, alerting and management solutions.
What are bandwidth requirements?
HyperPaxeer has the capacity for very high throughput compared to chains like Ethereum or Bitcoin.
As such, we recommend that the data center nodes only connect to trusted full nodes in the cloud or other validators
that know each other socially. This relieves the data center node from the burden of mitigating denial-of-service attacks.
Ultimately, as the network becomes more used, one can realistically expect daily bandwidth on the order of several gigabytes.
What does running a validator imply in terms of logistics?
A successful validator operation will require the efforts of multiple highly skilled individuals and continuous operational
attention. This will be considerably more involved than running a bitcoin miner for instance.
How to handle key management?
Validators should expect to run an HSM that supports ed25519 keys. Here are potential options:
* YubiHSM 2
* Ledger Nano S
* Ledger BOLOS SGX enclave
* Thales nShield support
* [Strangelove Horcrux](https://github.com/strangelove-ventures/horcrux)
The HyperPaxeer team does not recommend one solution above the other. The community is encouraged to bolster the effort to
improve HSMs and the security of key management.
What can validators expect in terms of operations?
Running effective operation is the key to avoiding unexpectedly unbonding or being slashed. This includes being able to
respond to attacks, outages, as well as to maintain security and isolation in your data center.
What are the maintenance requirements?
Validators should expect to perform regular software updates to accommodate upgrades and bug fixes. There will inevitably
be issues with the network early in its bootstrapping phase that will require substantial vigilance.
How can validators protect themselves from Denial-of-Service attacks?
Denial-of-service attacks occur when an attacker sends a flood of internet traffic to an IP address to prevent the server
at the IP address from connecting to the internet.
An attacker scans the network, tries to learn the IP address of various validator nodes and disconnect them from
communication by flooding them with traffic.
One recommended way to mitigate these risks is for validators to carefully structure their network topology in a so-called
sentry node architecture.
Validator nodes should only connect to full-nodes they trust because they operate them themselves or are run by other
validators they know socially. A validator node will typically run in a data center. Most data centers provide direct
links the networks of major cloud providers. The validator can use those links to connect to sentry nodes in the cloud.
This shifts the burden of denial-of-service from the validator's node directly to its sentry nodes, and may require new
sentry nodes be spun up or activated to mitigate attacks on existing ones.
Sentry nodes can be quickly spun up or change their IP addresses. Because the links to the sentry nodes are in private
IP space, an internet based attacked cannot disturb them directly. This will ensure validator block proposals and votes
always make it to the rest of the network.
It is expected that good operating procedures on that part of validators will completely mitigate these threats.
For more on sentry node architecture, see [this](https://forum.cosmos.network/t/sentry-node-architecture-overview/454).
# Mempool
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/mempool
# Mempool
Learn about the available mempool options in Tendermint.
## FIFO Mempool
The mempool holds uncommitted transactions, which are not yet included in a block.
The default mempool implementation for Tendermint blockchains follows a first-in-first-out (FIFO) principle,
which means the ordering of transactions depends solely on the order in which they arrive at the node.
The first transaction to be received will be the first transaction to be processed.
This is true for gossiping the received transactions to the rest of the peers as well as including them in a block.
## Prioritized Mempool
Starting with [Tendermint v0.35](https://github.com/tendermint/tendermint/blob/v0.35.0/CHANGELOG.md)
(has also been backported to [v0.34.20](https://github.com/tendermint/tendermint/blob/17c94bb0dcb354c57f49cdcd1e62f4742752c803/UPGRADING.md?plain=1#L54))
it is possible to use a prioritized mempool implementation.
This allows validators to choose transactions based on the associated fees or other incentive mechanisms.
It is achieved by passing a `priority` field with each [`CheckTx` response](https://github.com/tendermint/tendermint/blob/17c94bb0dcb354c57f49cdcd1e62f4742752c803/proto/tendermint/abci/types.proto#L234),
which is run on any transaction trying to enter the mempool.
HyperPaxeer supports [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559#simple-summary) EVM transactions through its
[feemarket module](./../../protocol/modules/feemarket).
This transaction type uses a base fee and a selectable priority tip that add up to the total transaction fees.
The prioritized mempool presents an option to automatically make use of this mechanism regarding block generation.
When using the prioritized mempool, transactions for the next produced block are chosen
by order of their priority (i.e. their fees) from highest to lowest.
Should the mempool be full, the prioritized implementation allows
to remove the transactions with the lowest priority until enough disk space is available for
an incoming, higher-priority transaction
(see [v1/mempool.go](https://github.com/tendermint/tendermint/blob/17c94bb0dcb354c57f49cdcd1e62f4742752c803/mempool/v1/mempool.go#L505C2-L576)
implementation for more details).
:::tip
Even though the transaction processing can be ordered by priority,
the gossiping of transactions will always be according to FIFO.
:::
## Configuration
To use the a prioritized mempool, adjust `version = "v1"` in the node configuration at `~/.hyperpaxd/config/config.toml`.
The default value `"v0"` indicates the traditional FIFO mempool.
:::tip
Remember to **restart** the node for the changes to take effect.
:::
See the relevant excerpt from `config.toml` here:
```toml theme={null}
#######################################################
### Mempool Configuration Option ###
#######################################################
[mempool]
# Mempool version to use:
# 1) "v0" - (default) FIFO mempool.
# 2) "v1" - prioritized mempool.
version = "v1"
```
## Resources
More detailed information can be found here:
* [Tendermint ADR-067 - Mempool Refactor](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-067-mempool-refactor.md).
* [Blogpost: Tendermint v0.35 Announcement](https://medium.com/tendermint/tendermint-v0-35-introduces-prioritized-mempool-a-makeover-to-the-peer-to-peer-network-more-61eea6ec572d)
* [EIP-1559: Fee market change for ETH 1.0 chain](https://eips.ethereum.org/EIPS/eip-1559)
* [EIP-1559 FAQ](https://notes.ethereum.org/@vbuterin/eip-1559-faq)
* [Blogpost: What is EIP-1559? How will it change Ethereum?](https://consensys.net/blog/quorum/what-is-eip-1559-how-will-it-change-ethereum/)
# Run a Node
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/run-a-validator
Deploy RPC and Validator nodes on HyperPaxeer using the hpx CLI
## Overview
The `hpx` CLI manages the full lifecycle of HyperPaxeer nodes β install, deploy, monitor, upgrade, and remove. Each node runs as an isolated Docker Compose stack with its own chain data, ports, and an FD Guardian sidecar that auto-restarts on file-descriptor leaks.
***
## π HyperPax Node: The Official "No-Headache" Setup Guide
Setting up a node involves preparing your server, installing the HyperPax OS, and ensuring your node is visible for delegation. Follow these steps exactly to avoid the common `command not found` or `Docker missing` errors.
### Phase 1: Server Preparation
Before running the main script, ensure your environment is clean.
1. **Log in as Root:** Most commands require administrative privileges.
2. **Verify Shell Path:** If you just installed the OS or shell updates, ensure your shell knows where to look for commands:
```bash theme={null}
source ~/.bashrc
```
*Note: If you get a "No such file" error, don't panic. It just means you are using a clean shell that hasn't been modified yet.*
***
### Phase 2: Installing HyperPax-OS
Run the installation script provided by the team.
* **Pro Tip:** If the script asks to install Docker and seems "stuck," **wait**. Docker installation can take 2β5 minutes depending on the server's CPU and network speed.
#### π Troubleshooting Common Install Errors
If the installer fails on **Step 2/6 (Checking Dependencies)** with a `Missing: docker-compose-plugin` error:
1. **Manual Docker Compose Fix:**
Run these commands one by one to manually place the plugin where the system expects it:
```bash theme={null}
mkdir -p ~/.docker/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v5.1.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
```
2. **System Tuning:**
The script may ask: `Apply recommended system tuning? [y/N]`.
* **Always Choose Y.** \* If you skip this, your node may hit "FD (File Descriptor) limits" and crash once the network load increases.
***
### Phase 3: Configuration & Data Sync
Once the OS is installed, you need to configure your node.
1. **The Setup Command:**
Type `hpx setup` to begin.
2. **Storage Location:**
When asked `Where to store node data? [/root/hyperpax-nodes]`, simply **Press Enter** to use the default path.
3. **Syncing the Chain:**
You will see a prompt for a `Chain data tarball URL`.
* Unless you have been given a specific private link by the team, **Press Enter** to use the latest official snapshot.
***
### Phase 4: Activation & Delegation
Your node is running, but it needs "Voting Power" to earn rewards.
1. **Get your IP and Port:**
Find your node's connection string. It usually looks like this: `http://[YOUR_IP_ADDRESS]:[PORT]`.
2. **Send to the Registry:**
Provide this URL to the network admin. This allows them to:
* Add you to the official Registry.
* **Delegate** staked coins to your node so you can begin validating blocks.
***
### π‘ Top 3 "Newbie" Tips from the Logs:
* **Don't Spam Commands:** If you run the "longer script" multiple times, you might create conflicting directory paths (e.g., `/usr/bin/` vs `/root/`). Run it once and troubleshoot specific errors instead.
* **The "hpx" Command:** If `hpx` isn't found immediately after installation, try running `source ~/.bashrc` again or logging out and back into your SSH session.
* **Docker is Heavy:** If the screen says `Installing Docker...`, grab a coffee. Interrupting this process is the #1 cause of broken node environments.
***
## Requirements
| Resource | Minimum |
| -------- | ------------------------ |
| RAM | 16 GB |
| CPU | 6 cores |
| Disk | 300 GB (SSD recommended) |
| OS | Ubuntu 22.04+ |
***
## Install
```bash theme={null}
curl -sSL https://hyperpaxeer.com/hyper-os/new/get-hpx.sh | sudo bash
```
The installer:
1. Checks system resources (RAM, CPU, disk)
2. Installs Docker, curl, jq, zstd if missing
3. Installs the `hpx` binary to `/usr/local/bin/`
4. Offers to run the **Setup Wizard** (system tuning, Docker image pull, capacity check)
***
## Deploy a Node
```bash theme={null}
hpx deploy
```
| Type | Purpose | Configuration |
| ----------- | ---------------------------------------- | ---------------------------------------- |
| `rpc` | Serve JSON-RPC, gRPC, REST, WebSocket | Full indexing, all endpoints exposed |
| `validator` | Produce blocks, participate in consensus | Default pruning, optimised for consensus |
Examples:
```bash theme={null}
hpx deploy my-rpc rpc
hpx deploy mainnet-val validator
```
The CLI assigns ports automatically. Multiple nodes on one server get auto-incremented ports:
| Protocol | Node 1 | Node 2 | Node 3 |
| ------------ | ------ | ------ | ------ |
| P2P | 26656 | 26756 | 26856 |
| CometBFT RPC | 26657 | 26757 | 26857 |
| REST API | 1317 | 1417 | 1517 |
| gRPC | 9090 | 9190 | 9290 |
| JSON-RPC | 8545 | 8645 | 8745 |
| WebSocket | 8546 | 8646 | 8746 |
***
## Node Management
| Command | Purpose |
| -------------------- | -------------------------------- |
| `hpx` | Interactive menu |
| `hpx list` | List all registered nodes |
| `hpx info ` | Sync status, block height, peers |
| `hpx logs ` | Stream node logs |
| `hpx start ` | Start a node |
| `hpx stop ` | Stop a node |
| `hpx restart ` | Restart a node |
| `hpx start all` | Start all nodes |
| `hpx stop all` | Stop all nodes |
| `hpx remove ` | Delete a node and its data |
| `hpx dashboard` | Live status dashboard |
| `hpx capacity` | Show server resource usage |
| `hpx setup` | Re-run the setup wizard |
***
## File Structure
```
/root/hyperpax-nodes/
.hpx-registry # tracks all nodes
.hpx-setup-done # setup wizard completion marker
my-rpc/
data/ # chain data + config
scripts/ # start script + FD guardian
logs/ # guardian logs
docker-compose.yml # isolated compose stack
```
***
## Create a Validator
After your node syncs to the latest block, create a validator using the `hyperpaxd` binary inside the container:
```bash theme={null}
hyperpaxd tx staking create-validator \
--amount=1000000ahpx \
--pubkey=$(hyperpaxd tendermint show-validator) \
--moniker="your-moniker" \
--chain-id=hyperpax_125-1 \
--commission-rate="0.05" \
--commission-max-rate="0.10" \
--commission-max-change-rate="0.01" \
--min-self-delegation="1000000" \
--gas="auto" \
--gas-prices="0.025ahpx" \
--from=
```
Ensure your server timezone is **UTC**. A different timezone can cause `LastResultsHash` mismatch errors that halt your node.
***
## Unjail a Validator
If your validator is jailed for downtime (missing 500 of the last 10,000 blocks):
```bash theme={null}
hyperpaxd tx slashing unjail \
--from= \
--chain-id=hyperpax_125-1
```
***
## Confirm Validator Status
```bash theme={null}
hyperpaxd query tendermint-validator-set | grep "$(hyperpaxd tendermint show-address)"
```
Or check the [Network Status](/network-status) page for the current validator set.
***
## Troubleshooting
**"Permission denied"** β Run with `sudo`.
**"docker: denied"** β Stale credentials. Run `docker logout ghcr.io` and retry.
**"Cannot connect to Docker daemon"** β Start Docker: `sudo systemctl start docker`.
**Node stuck syncing** β Check peers with `hpx info `. If peers is 0, verify your firewall allows the P2P port.
**"too many open files"** β The FD Guardian sidecar handles this automatically. If running outside Docker, increase limits: `ulimit -n 4096`.
***
## Update
Re-run the installer to update to the latest version. Existing nodes and chain data are preserved:
```bash theme={null}
curl -sSL https://hyperpaxeer.com/hyper-os/new/get-hpx.sh | sudo bash
```
***
## Uninstall
```bash theme={null}
curl -sSL https://hyperpaxeer.com/hyper-os/new/uninstall.sh | sudo bash
```
# State Sync
Source: https://sidiorresearchlabs.mintlify.app/validate/setup/state-sync
# State Sync
Learn about Tendermint Core state sync and support offered by the Cosmos SDK.
:::tip
**Note**: Only curious about how to sync a node with the network? Skip to [this section](#state-syncing-a-node).
:::
## Tendermint Core State Sync
State sync allows a new node to join a network by fetching a snapshot of the network state at a recent height,
instead of fetching and replaying all historical blocks.
Since application state is smaller than the combination of all blocks,
and restoring state is faster than replaying blocks, this reduces the time to sync with the network from days to minutes.
This section of the document provides a brief overview of the Tendermint state sync protocol, and how to sync a node.
For more details, refer to the
[ABCI Application Guide](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync)
and the [ABCI Reference Documentation](https://docs.tendermint.com/master/spec/abci/abci.html).
### State Sync Snapshots
A guiding principle when designing Tendermint state sync was to give applications as much flexibility as possible.
Therefore, Tendermint does not care what snapshots contain, how they are taken, or how they are restored.
It is only concerned with discovering existing snapshots in the network, fetching them,
and passing them to applications via ABCI.
Tendermint uses light client verification to check the final app hash of a restored
application against the chain app hash, but any further verification must be done by the application itself during restoration.
Snapshots consist of binary chunks in an arbitrary format.
Chunks cannot be larger than 16 MB, but otherwise there are no restrictions.
[Snapshot metadata](https://docs.tendermint.com/master/spec/abci/abci.html#snapshot),
exchanged via ABCI and P2P, contains the following fields:
* `height` (`uint64`): height at which the snapshot was taken
* `format` (`uint32`): arbitrary application-specific format identifier (eg. version)
* `chunks` (`uint32`): number of binary chunks in the snapshot
* `hash` (`bytes`): arbitrary snapshot hash for comparing snapshots across nodes
* `metadata` (`bytes`): arbitrary binary snapshot metadata for use by applications
The `format` field allows applications to change their snapshot format in a backwards-compatible manner,
by providing snapshots in multiple formats, and choosing which formats to accept during restoration.
This is useful when, for example, changing serialization or compression formats: as nodes may be able to provide
snapshots to peers running older verions, or make use of old snapshots when starting up with a newer version.
The `hash` field contains an arbitrary snapshot hash. Snapshots that have identical `metadata` fields (including `hash`)
across nodes are considered identical, and `chunks` will be fetched from any of these nodes.
The `hash` cannot be trusted, and is not verified by Tendermint itself,
which guards against inadvertent nondeterminism in snapshot generation.
The `hash` may be verified by the application instead.
The `metadata` field can contain any arbitrary metadata needed by the application.
For example, the application may want to include chunk checksums to discard damaged `chunks`,
or [Merkle proofs](https://ethereum.org/en/developers/tutorials/merkle-proofs-for-offline-data-integrity/)
to verify each chunk individually against the chain app hash.
In [Protobuf](https://developers.google.com/protocol-buffers/docs/overview)-encoded form,
snapshot `metadata` messages cannot exceed 4 MB.
### Taking, Serving Snapshots
To enable state sync, some nodes in the network must take and serve snapshots. When a peer is attempting to state sync,
an existing Tendermint node will call the following ABCI methods on the application to provide snapshot data to this peer:
* [`ListSnapshots`](https://docs.tendermint.com/master/spec/abci/abci.html#listsnapshots):
returns a list of available snapshots, with metadata
* [`LoadSnapshotChunk`](https://docs.tendermint.com/master/spec/abci/abci.html#loadsnapshotchunk): returns binary chunk data
Snapshots should typically be generated at regular intervals rather than on-demand: this improves state sync performance,
since snapshot generation can be slow, and avoids a denial-of-service vector where an adversary
floods a node with such requests. Older snapshots can usually be removed, but it may be useful to keep at least
the two most recent to avoid deleting the previous snapshot while a node is restoring it.
It is entirely up to the application to decide how to take snapshots, but it should strive to satisfy the following guarantees:
* **Asynchronous**: snapshotting should not halt block processing, and it should therefore happen asynchronously,
eg. in a separate thread
* **Consistent**: snapshots should be taken at isolated heights, and should not be affected by concurrent writes,
eg. due to block processing in the main thread
* **Deterministic**: snapshot `chunks` and `metadata` should be identical (at the byte level)
across all nodes for a given `height` and `format`, to ensure good availability of `chunks`
As an example, this can be implemented as follows:
1. Use a data store that supports transactions with snapshot isolation, such as RocksDB or BadgerDB.
2. Start a read-only database transaction in the main thread after committing a block.
3. Pass the database transaction handle into a newly spawned thread.
4. Iterate over all data items in a deterministic order (eg. sorted by key)
5. Serialize data items (eg. using [Protobuf](https://developers.google.com/protocol-buffers/docs/overview)),
and write them to a byte stream.
6. Hash the byte stream, and split it into fixed-size chunks (eg. of 10 MB)
7. Store the chunks in the file system as separate files.
8. Write the snapshot metadata to a database or file, including the byte stream hash.
9. Close the database transaction and exit the thread.
Applications may want to take additional steps as well, such as compressing the data, checksumming chunks,
generating proofs for incremental verification, and removing old snapshots.
### Restoring Snapshots
When Tendermint starts, it will check whether the local node has any state (ie. whether `LastBlockHeight == 0`),
and if it doesn't, it will begin discovering snapshots via the P2P network.
These snapshots will be provided to the local application via the following ABCI calls:
* [`OfferSnapshot(snapshot, apphash)`](https://docs.tendermint.com/master/spec/abci/abci.html#offersnapshot):
offers a discovered snapshot to the application
* [`ApplySnapshotChunk(index, chunk, sender)`](https://docs.tendermint.com/master/spec/abci/abci.html#applysnapshotchunk):
applies a snapshot chunk
Discovered snapshots are offered to the application and it can respond by accepting the snapshot,
rejecting it, rejecting the format, rejecting the senders, aborting state sync, and so on.
Once a snapshot is accepted, Tendermint will fetch chunks from across available peers,
and apply them sequentially to the application, which can choose to accept the chunk,
refetch it, reject the snapshot, reject the sender, abort state sync, and so on.
Once all chunks have been applied,
Tendermint will call the [`Info` ABCI method](https://docs.tendermint.com/master/spec/abci/abci.html#info)
on the application, and check that the app hash and height correspond to the trusted values from the chain.
It will then switch to fast sync to fetch any remaining blocks (if enabled), before finally joining normal consensus operation.
How snapshots are actually restored is entirely up to the application,
but will generally be the inverse of how they are generated.
Note, however, that Tendermint only verifies snapshots after all chunks have been restored,
and does not reject any P2P peers on its own. As long as the trusted hash and application code are correct,
it is not possible for an adversary to cause a state synced node to have incorrect state when joining consensus,
but it is up to the application to counteract state sync denial-of-service
(eg. by implementing incremental verification, rejecting invalid peers).
Note that state synced nodes will have a truncated block history starting at the height of the restored snapshot,
and there is currently no [backfill of all block data](https://github.com/tendermint/tendermint/issues/4629).
Networks should consider broader implications of this, and may want to ensure at least a few archive nodes
retain a complete block history, for both auditability and backup.
## Cosmos SDK State Sync
[Cosmos SDK](https://github.com/cosmos/cosmos-sdk) v0.40+ includes automatic support for state sync,
so application developers only need to enable it to take advantage.
They will not need to implement the state sync protocol described in the
[above section on Tendermint](#tendermint-core-state-sync) themselves.
### State Sync Snapshots
Tendermint Core handles most of the grunt work of discovering, exchanging,
and verifying state data for state sync, but the application must take snapshots of its state at regular intervals,
and make these available to Tendermint via ABCI calls, and be able to restore these when syncing a new node.
The Cosmos SDK stores application state in a data store called [IAVL](https://github.com/cosmos/iavl),
and each module can set up its own IAVL stores. At regular height intervals (which are configurable),
the Cosmos SDK will export the contents of each store at that height,
[Protobuf](https://developers.google.com/protocol-buffers/docs/overview)-encode and compress it,
and save it to a snapshot store in the local filesystem. Since IAVL keeps historical versions of data,
these snapshots can be generated simultaneously with new blocks being executed.
These snapshots will then be fetched by Tendermint via ABCI when a new node is state syncing.
Note that only IAVL stores that are managed by the Cosmos SDK can be snapshotted.
If the application stores additional data in external data stores,
there is currently no mechanism to include these in state sync snapshots,
so the application therefore cannot make use of automatic state sync via the SDK.
However, it is free to implement the state sync protocol itself as described in the
[ABCI Documentation](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync).
When a new node is state synced, Tendermint will fetch a snapshot from peers in the network
and provide it to the local (empty) application, which will import it into its IAVL stores.
Tendermint then verifies the application's app hash against the main blockchain using light client verification,
and proceeds to execute blocks as usual.
Note that a state synced node will only restore the application state for the height the snapshot was taken at,
and will not contain historical data nor historical blocks.
### Enabling State Sync Snapshots
To enable state sync snapshots, an application using the CosmosSDK `BaseApp` needs to set up a snapshot store
(with a database and filesystem directory) and configure the snapshotting interval
and the number of historical snapshots to keep. A minimal exmaple of this follows:
```bash theme={null}
snapshotDir := filepath.Join(
cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
if err != nil {
panic(err)
}
snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir)
if err != nil {
panic(err)
}
app := baseapp.NewBaseApp(
"app", logger, db, txDecoder,
baseapp.SetSnapshotStore(snapshotStore),
baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(
server.FlagStateSyncSnapshotInterval))),
baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(
server.FlagStateSyncSnapshotKeepRecent))),
)
```
When starting the application with the appropriate flags,
(eg. `--state-sync.snapshot-interval 1000 --state-sync.snapshot-keep-recent 2`)
it should generate snapshots and output log messages:
```bash theme={null}
Creating state snapshot module=main height=3000
Completed state snapshot module=main height=3000 format=1
```
Note that the snapshot interval must currently be a multiple of the `pruning-keep-every` (defaults to 100),
to prevent heights from being pruned while taking snapshots.
It's also usually a good idea to keep at least 2 recent snapshots,
such that the previous snapshot isn't removed while a node is attempting to state sync using it.
## State Syncing a Node
:::tip
Looking for snapshots or archive nodes to sync your node with? Check out [this page](./../../develop/api/snapshots-archives).
:::
Once a few nodes in a network have taken state sync snapshots, new nodes can join the network using state sync.
To do this, the node should first be configured as usual,
and the following pieces of information must be obtained for light client verification:
* Two available RPC servers (at least)
* Trusted height
* Block ID hash of trusted height
The trusted hash must be obtained from a trusted source (eg. a block explorer),
but the RPC servers do not need to be trusted.
Tendermint will use the hash to obtain trusted app hashes from the blockchain
in order to verify restored application snapshots.
The app hash and corresponding height are the only pieces of information that
can be trusted when restoring snapshots.
Everything else can be forged by adversaries.
In this guide we use Ubuntu 20.04
### Prepare system
Update system
```bash theme={null}
sudo apt update -y
```
Upgrade system
```bash theme={null}
sudo apt upgrade -y
```
Install dependencies
```bash theme={null}
sudo apt-get install ca-certificates curl gnupg lsb-release make gcc git jq wget -y
```
Install Go
```bash theme={null}
wget -q -O - https://raw.githubusercontent.com/canha/golang-tools-install-script/master/goinstall.sh | bash
source ~/.bashrc
```
Set the node name
```bash theme={null}
moniker="NODE_NAME"
```
## Use commands below for Testnet setup
```bash theme={null}
SNAP_RPC1="http://bd-HyperPaxeer-testnet-state-sync-node-01.bdnodes.net:26657"
SNAP_RPC="http://bd-HyperPaxeer-testnet-state-sync-node-02.bdnodes.net:26657"
CHAIN_ID="hyperpax_125-4"
PEER="3a6b22e1569d9f85e9e97d1d204a1c457d860926@bd-HyperPaxeer-testnet-seed-node-01.bdnodes.net:26656"
wget -O $HOME/genesis.json https://archive.hyperpaxd.dev/hyperpax_125-4/genesis.json
```
## Use commands below for Mainnet setup
```bash theme={null}
SNAP_RPC1="http://bd-HyperPaxeer-mainnet-state-sync-us-01.bdnodes.net:26657"
SNAP_RPC="http://bd-HyperPaxeer-mainnet-state-sync-eu-01.bdnodes.net:26657"
CHAIN_ID="HyperPaxeer_9001-2"
PEER="96557e26aabf3b23e8ff5282d03196892a7776fc@bd-HyperPaxeer-mainnet-state-sync-us-01.bdnodes.net:26656,dec587d55ff38827ebc6312cedda6085c59683b6@bd-HyperPaxeer-mainnet-state-sync-eu-01.bdnodes.net:26656"
wget -O $HOME/genesis.json https://archive.hyperpaxd.org/mainnet/genesis.json
```
### Install hyperpaxd
```bash theme={null}
git clone https://github.com/Paxeer-Network/Paxeer-Network.git && \
cd HyperPaxeer && \
make install
```
### Configuration
Node init
```bash theme={null}
hyperpaxd init $moniker --chain-id $CHAIN_ID
```
Move genesis file to .hyperpaxd/config folder
```bash theme={null}
mv $HOME/genesis.json ~/.hyperpaxd/config/
```
Reset the node
```bash theme={null}
hyperpaxd tendermint unsafe-reset-all --home $HOME/.hyperpaxd
```
Change config files (set the node name, add persistent peers, set indexer = "null")
```bash theme={null}
sed -i -e "s%^moniker *=.*%moniker = \"$moniker\"%; " $HOME/.hyperpaxd/config/config.toml
sed -i -e "s%^indexer *=.*%indexer = \"null\"%; " $HOME/.hyperpaxd/config/config.toml
sed -i -e "s%^persistent_peers *=.*%persistent_peers = \"$PEER\"%; " $HOME/.hyperpaxd/config/config.toml
```
Set the variables for start from snapshot
:::tip
**Note**: Usually, on other cosmos chains, the user is instructed to use as trusted height
the latest height minus 2000 by default.
However, snapshots of the HyperPaxeer chain take a long time to generate, which makes the gap between the snapshot height and
the current latest height be more than 2000.
This results in a context timeout error:
```
5:33PM ERR error on light block request from witness, removing... error="post failed: Post \"http://bd-HyperPaxeer-mainnet-state-sync-us-01.bdnodes.net:26657\": context deadline exceeded" module=light primary={} server=node
```
To avoid this issue, simply pick a trusted height close to snapshot height.
For example, if you know there's a snapshot at height `13286000`, consider a trust hash from block `13284000`.
You can get the latest snapshot height from [Polkachu here.](https://polkachu.com/tendermint_snapshots/Paxeer-Network).
Otherwise, your node will find the available snapshots.
You will see logs similar to this:
```
5:48PM INF Discovered new snapshot format=2 hash="οΏ½zοΏ½οΏ½οΏ½ΥοΏ½οΏ½^οΏ½οΏ½Q\x1a\\I_οΏ½\x0fοΏ½OT!οΏ½(jMοΏ½$!οΏ½οΏ½" height=13286000 module=statesync server=node
```
:::
```bash theme={null}
LATEST_HEIGHT=$(curl -s $SNAP_RPC/block | jq -r .result.block.header.height); \
BLOCK_HEIGHT=$((LATEST_HEIGHT - 40000)); \
TRUST_HASH=$(curl -s "$SNAP_RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash)
```
Check
```bash theme={null}
echo $LATEST_HEIGHT $BLOCK_HEIGHT $TRUST_HASH
```
Output example (numbers will be different):
```bash theme={null}
376080 374080 F0C78FD4AE4DB5E76A298206AE3C602FF30668C521D753BB7C435771AEA47189
```
If output is OK do next
```bash theme={null}
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \
s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$SNAP_RPC,$SNAP_RPC1\"| ; \
s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \
s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"| ; \
s|^(seeds[[:space:]]+=[[:space:]]+).*$|\1\"\"|" ~/.hyperpaxd/config/config.toml
```
### Create hyperpaxd service
```bash theme={null}
echo "[Unit]
Description=hyperpaxd Node
After=network.target
#
[Service]
User=$USER
Type=simple
ExecStart=$(which hyperpaxd) start
Restart=on-failure
LimitNOFILE=65535
#
[Install]
WantedBy=multi-user.target" > $HOME/hyperpaxd.service; sudo mv $HOME/hyperpaxd.service /etc/systemd/system/
```
```bash theme={null}
sudo systemctl enable hyperpaxd.service && sudo systemctl daemon-reload
```
### Run hyperpaxd
```bash theme={null}
systemctl start hyperpaxd
```
### Check logs
```bash theme={null}
journalctl -u hyperpaxd -f
```
When the node is started it will then attempt to find a state sync snapshot in the network, and restore it:
```bash theme={null}
Started node module=main nodeInfo="..."
Discovering snapshots for 20s
Discovered new snapshot height=3000 format=1 hash=0F14A473
Discovered new snapshot height=2000 format=1 hash=C6209AF7
Offering snapshot to ABCI app height=3000 format=1 hash=0F14A473
Snapshot accepted, restoring height=3000 format=1 hash=0F14A473
Fetching snapshot chunk height=3000 format=1 chunk=0 total=3
Fetching snapshot chunk height=3000 format=1 chunk=1 total=3
Fetching snapshot chunk height=3000 format=1 chunk=2 total=3
Applied snapshot chunk height=3000 format=1 chunk=0 total=3
Applied snapshot chunk height=3000 format=1 chunk=1 total=3
Applied snapshot chunk height=3000 format=1 chunk=2 total=3
Verified ABCI app height=3000 appHash=F7D66BC9
Snapshot restored height=3000 format=1 hash=0F14A473
Executed block height=3001 validTxs=16 invalidTxs=0
Committed state height=3001 txs=16 appHash=0FDBB0D5F
Executed block height=3002 validTxs=25 invalidTxs=0
Committed state height=3002 txs=25 appHash=40D12E4B3
```
The node is now state synced, having joined the network in seconds
### Use this command to switch off your State Sync mode, after node fully synced to avoid problems in future node restarts!
```bash theme={null}
sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1false|" $HOME/.hyperpaxd/config/config.toml
```
:::tip
**Note**: Information included in this document is sourced from [Erik Grinaker](https://medium.com/@erikgrinaker),
specifically his state sync guides for
[Tendermint Core](https://medium.com/tendermint/tendermint-core-state-sync-for-developers-70a96ba3ee35) and the [Cosmos SDK](https://medium.com/cosmos-blockchain/cosmos-sdk-state-sync-guide-99e4cf43be2f).
:::
# Automated Upgrades
Source: https://sidiorresearchlabs.mintlify.app/validate/upgrades/automated-upgrades
# Automated Upgrades
We highly recommend validators use Cosmovisor to run their nodes.
This will make low-downtime upgrades smoother,
as validators don't have to [manually upgrade](./manual-upgrades) binaries during the upgrade.
Instead, users can [pre-install](#manual-download) new binaries
and Cosmovisor will automatically update them based on on-chain Software Upgrade proposals.
> [`cosmovisor`](https://docs.cosmos.network/main/tooling/cosmovisor) is a small process manager
> for Cosmos SDK application binaries that monitors the governance module for incoming chain upgrade proposals.
> If it sees a proposal that gets approved,
> cosmovisor can automatically download the new binary,
> stop the current binary,
> switch from the old binary to the new one,
> and finally restart the node with the new binary.
## Prerequisites
* [Install Cosmovisor](https://docs.cosmos.network/main/tooling/cosmovisor#installation)
## 1. Setup Cosmovisor
Set up the Cosmovisor environment variables.
We recommend setting these in your `.profile` so it is automatically set in every session.
```bash theme={null}
echo "# Setup Cosmovisor" >> ~/.profile
echo "export DAEMON_NAME=hyperpaxd" >> ~/.profile
echo "export DAEMON_HOME=$HOME/.hyperpaxd" >> ~/.profile
source ~/.profile
```
After this, you must make the necessary folders for `cosmosvisor` in your `DAEMON_HOME` directory (`~/.hyperpaxd`)
and copy over the current binary.
```bash theme={null}
mkdir -p ~/.hyperpaxd/cosmovisor
mkdir -p ~/.hyperpaxd/cosmovisor/genesis
mkdir -p ~/.hyperpaxd/cosmovisor/genesis/bin
mkdir -p ~/.hyperpaxd/cosmovisor/upgrades
cp $GOPATH/bin/hyperpaxd ~/.hyperpaxd/cosmovisor/genesis/bin
```
To check that you did this correctly, ensure your versions of `cosmovisor` and `hyperpaxd` are the same:
```bash theme={null}
cosmovisor run version
hyperpaxd version
```
## 2. Download the HyperPaxeer release
### Manual Download
Cosmovisor will continually poll the `$DAEMON_HOME/data/upgrade-info.json` for new upgrade instructions.
When an upgrade is [released](https://github.com/Paxeer-Network/Paxeer-Network/releases), node operators need to:
1. Download (**NOT INSTALL**) the binary for the new release
2. Place it under `$DAEMON_HOME/cosmovisor/upgrades//bin`,
where `` is the URI-encoded name of the upgrade as specified in the Software Upgrade Plan.
**Example**: for a `Plan` with name `v3.0.0` with the following `upgrade-info.json`:
```json theme={null}
{
"binaries": {
"darwin/arm64": "https://github.com/Paxeer-Network/Paxeer-Network/releases/download/v3.0.0/Paxeer-Network_3.0.0_Darwin_arm64.tar.gz",
"darwin/x86_64": "https://github.com/Paxeer-Network/Paxeer-Network/releases/download/v3.0.0/Paxeer-Network_3.0.0_Darwin_x86_64.tar.gz",
"linux/arm64": "https://github.com/Paxeer-Network/Paxeer-Network/releases/download/v3.0.0/Paxeer-Network_3.0.0_Linux_arm64.tar.gz",
"linux/amd64": "https://github.com/Paxeer-Network/Paxeer-Network/releases/download/v3.0.0/Paxeer-Network_3.0.0_Linux_amd64.tar.gz",
"windows/x86_64": "https://github.com/Paxeer-Network/Paxeer-Network/releases/download/v3.0.0/Paxeer-Network_3.0.0_Windows_x86_64.zip"
}
}
```
Your `cosmovisor/` directory should look like this:
```shell theme={null}
cosmovisor/
βββ current/ # either genesis or upgrades/
βββ genesis
β βββ bin
β βββ hyperpaxd
βββ upgrades
βββ v3.0.0
βββ bin
β βββ hyperpaxd
βββ upgrade-info.json
```
### Automatic Download
:::warning
**NOTE**: Auto-download doesn't verify in advance if a binary is available.
If there will be any issue with downloading a binary,
`cosmovisor` will stop and won't restart and the chain (which could lead it to a halt).
:::
It is possible to have Cosmovisor
[automatically download](https://docs.cosmos.network/main/tooling/cosmovisor#auto-download) the new binary.
Validators can use the automatic download option to prevent unnecessary downtime during the upgrade process.
This option will automatically restart the chain with the upgrade binary
once the chain has halted at the proposed `upgrade-height`.
The major benefit of this option is that validators can prepare the upgrade binary in advance
and then relax at the time of the upgrade.
To set the auto-download use set the following environment variable:
```bash theme={null}
echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.profile
```
## 3. Start your node
Now that everything is set up and ready to go, you can start your node.
```bash theme={null}
cosmovisor run start
```
You will need some way to keep the process always running. If you're on linux, you can do this by creating a service.
```bash theme={null}
sudo tee /etc/systemd/system/hyperpaxd.service > /dev/null < `v8.0.1`) needs to be created that
contains a hard fork logic and performs an upgrade to the next breaking
version (e.g. `v9.0.0`) at a predefined block height.
3. Validators upgrade their nodes to the patch release (e.g. `v8.0.1`). In order to perform the
hard fork successfully, itβs important that enough validators upgrade to the
patch release so that they make up at least 2/3 of the total validator voting
power.
4. One hour before the upgrade time (corresponding to the upgrade block height),
the new major release (e.g. `v9.0.0`) including the vulnerability fix is
published.
:::info
**Important**: The release needs to be created with 1hr anticipation because the
release binaries take \~30min to be created and validators need a buffer time to
download them and update their
[cosmovisor](./automated-upgrades#using-cosmovisor) settings.
:::
# Overview
Source: https://sidiorresearchlabs.mintlify.app/validate/upgrades/index
# Overview
Learn how to manage chain upgrades for full and validator nodes. There are 3 different categories for upgrades:
* **Planned or Unplanned**: Chain upgrades can be scheduled at a given height through an upgrade proposal plan.
* **Breaking or Non-breaking**: Upgrades can be API or State Machine breaking, which affects backwards compatibility.
To address this, the application state or genesis file would need to be migrated in preparation for the upgrade.
* **Data Reset Upgrades**: Some upgrades will need a full data reset in order to clean the state. This can sometimes
occur in the case of a rollback or hard fork.
Additionally, validators can choose how to manage the upgrade according to their preferred option:
* **Automatic or Manual Upgrades**: Validator can run the `cosmovisor` process to automatically perform the upgrade
or do it manually.
## Planned Upgrades
Planned upgrades are coordinated scheduled upgrades that use the [upgrade module](https://docs.cosmos.network/main/modules/upgrade)
logic. This facilitates smoothly upgrading HyperPaxeer to a new (breaking) software version as it automatically handles
the state migration for the new release.
### Governance Proposal
Governance Proposals are a mechanism for coordinating an upgrade at a given height or time using an
[`SoftwareProposal`](https://docs.cosmos.network/main/modules/upgrade).
:::tip
All governance proposals, including software upgrades, need to wait for the voting period to conclude before the
upgrade can be executed. Consider this duration when submitting a software upgrade proposal.
:::
If the proposal passes, the upgrade `Plan`, which targets a specific upgrade logic to migrate the state, is
persisted to the blockchain state and scheduled at the given upgrade height. The upgrade can be delayed or
expedited by updating the `Plan.Height` in a new proposal.
### Hard Forks
A special type of planned upgrades are [hard forks](./upgrades/hard-fork-upgrades). Hard Forks, as opposed to Governance
Proposal, don't require waiting for the full voting
period. This makes them ideal for coordinating security vulnerabilities and patches.
The upgrade (fork) block height is set in the `BeginBlock` of the application (i.e before the transactions
are processed for the block). Once the blockchain reaches that height, it automatically schedules an upgrade
`Plan` for the same height and then triggers the upgrade process. After upgrading, the block operations
(`BeginBlock`, transaction processing and state `Commit`) continue normally.
:::tip
In order to execute an upgrade hard fork, a [patch version](#patch-versions) needs to first be released with
the `BeginBlock` upgrade scheduling logic. After a +2/3 of the validators upgrade to the new patch version,
their nodes will automatically halt and upgrade the binary.
:::
## Unplanned Upgrades
Unplanned upgrades are upgrades where all the validators need to gracefully halt and shut down their nodes at
exactly the same point in the process. This can be done by setting the `--halt-height` flag when running the
`hyperpaxd start` command.
If there are breaking changes during an unplanned upgrade (see below), validators will need to migrate the state
and genesis before restarting their nodes.
:::tip
The main consideration with unplanned upgrades is that the genesis state needs to be exported and the blockchain
data needs to be [reset](#data-reset-upgrades). This mainly affects infrastructure providers, tools and clients
like block explorers and clients, which have to use archival nodes to serve queries for the pre-upgrade heights.
:::
## Breaking and Non-Breaking Upgrades
Upgrades can be categorized as breaking or non-breaking according to the Semantic versioning
([Semver](https://semver.org/)) of the corresponding software [release version](https://github.com/Paxeer-Network/Paxeer-Network/releases)
(*i.e* `vX.Y.Z`):
* **Major version (`X`)**: backward incompatible API and state machine breaking changes.
* **Minor version (`Y`)**: new backward compatible features. These can be also be state machine breaking.
* **Patch version (`Z`)**: backwards compatible bug fixes, small refactors and improvements.
### Major Versions
If the new version you are upgrading to has breaking changes, you will have to:
1. Migrate genesis JSON
2. Migrate application state
3. Restart node
This needs to be done to prevent [double signing or halting the chain during consensus](https://docs.tendermint.com/master/spec/consensus/signing.html#double-signing).
To upgrade the genesis file, you can either fetch it from a trusted source or export it locally using the
`hyperpaxd export` command.
### Minor Versions
If the new version you are upgrading to has breaking changes, you will have to:
1. Migrate the state (if applicable)
2. Restart node
### Patch Versions
In order to update a patch:
1. Stop Node
2. Download new release binary manually
3. Restart node
## Data Reset Upgrades
Data Reset upgrades require node operators to fully reset the blockchain state and restart their nodes from a clean
state, but using the same validator keys.
## Automatic or Manual Upgrades
With every new software release, we strongly recommend full nodes and validator operators to perform a software upgrade.
You can upgrade your node by either:
* [automatically](./upgrades/automated-upgrades) bumping the software version
and restart the node once the upgrade occurs, or
* download the new binary and perform a [manual upgrade](./upgrades/manual-upgrades)
Follow the links in the options above to learn how to upgrade your node according to your preferred option.
# Manual Upgrades
Source: https://sidiorresearchlabs.mintlify.app/validate/upgrades/manual-upgrades
# Manual Upgrades
Learn how to manually upgrade your node.
## Prerequisites
* [Install hyperpaxd](../../protocol/Paxeer-Network-cli)
## 1. Upgrade the HyperPaxeer version
Before upgrading the HyperPaxeer version. Stop your instance of `hyperpaxd` using `Ctrl/Cmd+C`.
Next, upgrade the software to the desired release version. Check the HyperPaxeer [releases page](https://github.com/Paxeer-Network/Paxeer-Network/releases)
for details on each release.
:::danger
Ensure that the version installed matches the one needed for the network you are running (mainnet or testnet).
:::
```bash theme={null}
cd HyperPaxeer
git fetch --all && git checkout
make install
```
:::tip
If you have issues at this step, please check that you have the latest stable version of
[Golang](https://golang.org/dl/) installed.
:::
Verify that you've successfully installed HyperPaxeer on your system by using the `version` command:
```bash theme={null}
$ hyperpaxd version --long
name: HyperPaxeer
server_name: hyperpaxd
version: 3.0.0
commit: fe9df43332800a74a163c014c69e62765d8206e3
build_tags: netgo,ledger
go: go version go1.20 darwin/amd64
...
```
:::tip
If the software version does not match, then please check your `$PATH` to ensure the correct `hyperpaxd` is running.
:::
## 2. Replace Genesis file
:::tip
You can find the latest `genesis.json` file for mainnet or testnet in the following repositories:
* **Mainnet**: [github.com/Paxeer-Network/mainnet](https://github.com/Paxeer-Network/mainnet)
* **Testnet**: [github.com/Paxeer-Network/testnets](https://github.com/Paxeer-Network/testnets)
:::
Save the new genesis as `new_genesis.json`.
Then, replace the old `genesis.json` located in your `config/` directory with `new_genesis.json`:
```bash theme={null}
cd $HOME/.hyperpaxd/config
cp -f genesis.json new_genesis.json
mv new_genesis.json genesis.json
```
:::tip
We recommend using `sha256sum` to check the hash of the downloaded genesis against the expected genesis.
```bash theme={null}
cd ~/.hyperpaxd/config
echo " genesis.json" | sha256sum -c
```
:::
## 3. Data Reset
:::danger
Check [here](./list-of-upgrades) if the version you are upgrading require a data reset (hard fork). If this is not the
case, you can skip to [Restart](https://docs.cosmos.network/main/modules/upgrade).
:::
Remove the outdated files and reset the data:
```bash theme={null}
rm $HOME/.hyperpaxd/config/addrbook.json
hyperpaxd tendermint unsafe-reset-all --home $HOME/.hyperpaxd
```
Your node is now in a pristine state while keeping the original `priv_validator.json` and `config.toml`. If you had any
sentry nodes or full nodes setup before,
your node will still try to connect to them, but may fail if they haven't also
been upgraded.
:::danger
π¨ **IMPORTANT** π¨
Make sure that every node has a unique `priv_validator.json`. **DO NOT** copy the `priv_validator.json` from an old node
to multiple new nodes. Running two nodes with the same `priv_validator.json` will cause you to [double sign](https://docs.tendermint.com/master/spec/consensus/signing.html#double-signing).
:::
## 4. Restart Node
To restart your node once the new genesis has been updated, use the `start` command:
```bash theme={null}
hyperpaxd start
```
# Rollback
Source: https://sidiorresearchlabs.mintlify.app/validate/upgrades/rollback
# Rollback
Learn how to rollback the chain version in the case of an unsuccessful chain upgrade.
In order to restore a previous chain version, the following data must be recovered by validators:
* the database that contains the state of the previous chain (in `~/.hyperpaxd/data` by default)
* the `priv_validator_state.json` file of the validator (also in `~/.hyperpaxd/data` by default)
If validators don't possess their database data, another validator should share a copy of the database. Validators will
be able to download a copy of the data and verify it before starting their node. If validators don't have the backup
`priv_validator_state.json` file, then those validators will not have double-sign protection on their first block.
## Restoring State Procedure
1. First, stop your node.
2. Then, copy the contents of your backup data directory back to the `HyperPaxeer_HOME/data` directory (which, by default,
should be `~/.hyperpaxd/data`).
```bash theme={null}
# Assumes backup is stored in "backup" directory
rm -rf ~/.hyperpaxd/data
mv backup/.hyperpaxd/data ~/.hyperpaxd/data
```
3. Next, install the previous version of HyperPaxeer.
```bash theme={null}
# from HyperPaxeer directory
git checkout
make install
## verify version
hyperpaxd version --long
```
4. Finally, start the node.
```bash theme={null}
hyperpaxd start
```
# Versioning
Source: https://sidiorresearchlabs.mintlify.app/versioning
How Paxeer Network names and versions its forks, protocol releases, and binary builds
## Naming Hierarchy
Paxeer Network uses a four-layer naming scheme. Each layer changes at a different cadence and carries a distinct naming convention.
```
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β HPXEER NETWORK β
β The chain. The ecosystem. β
β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
β β Fork: ALEXANDRIA β β
β β Consensus era. Cryptographic protocol. β β
β β β β
β β βββββββββββββββββββββββββββββββββββββ β β
β β β Version: HYPERPAXEER β β β
β β β Features. Precompiles. Modules. β β β
β β β β β β
β β β βββββββββββββββββββββββββββββ β β β
β β β β Binary: hyperpaxd_2.0.3 β β β β
β β β β VM. Validator software. β β β β
β β β βββββββββββββββββββββββββββββ β β β
β β βββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
```
***
## Layer 0 β Paxeer Network
The chain, the native HPX token, and the community. This is the permanent identity that never changes regardless of forks, versions, or binary releases. Everything else is a version *of* Paxeer Network.
***
## Layer 1 β Fork (Protocol Era)
Forks are rare, landmark events that change the fundamental cryptographic or consensus protocol of the chain β a shift in consensus mechanism, new signature schemes, a core re-architecture. Each fork defines an **era**.
**Naming convention:** Ancient seats of knowledge and civilisation.
| Fork | Status | What Changed |
| -------------- | ------ | --------------------------------------------------------------------------------------------- |
| **Alexandria** | Active | Migration to Proof-of-Stake EVM, CometBFT consensus, dual-VM architecture (EVM OS + Argus VM) |
Future fork names follow the same theme: Persepolis, Carthage, Byzantium, Petra, Thebes.
**Format:** `Alexandria Fork` or just `Alexandria`
**In config:** `fork: alexandria`
A fork changes the rules of the chain itself. Think of it as a constitutional amendment β everything built on top must adapt.
***
## Layer 2 β Network Version (Feature Release)
Network versions are periodic protocol upgrades that add new capabilities β custom precompiles, Cosmos SDK modules, on-chain features, governance parameters. They happen within a fork era and do not change the underlying consensus or cryptographic primitives.
**Naming convention:** `Hyper` prefix + evocative compound noun.
| Version | Status | What Changed |
| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| **HyperPaxeer** | Active | Initial Alexandria-era release β EVM OS, Argus VM integration, x/paxoracle module, precompiles 0x901β0x904, PaxSpot contracts |
Future version names: HyperNexus, HyperForge, HyperPrime, HyperVault.
**Format:** `HyperPaxeer`
**In config:** `network_version: hyperpaxeer`
**Chain ID:** `hyperpax_125-1`
***
## Layer 3 β Binary Release (Runtime)
Binary releases are the actual compiled software that validators and RPC nodes run. They cover VM patches, validator-side optimisations, node infrastructure changes, and bug fixes. Multiple binary releases can ship within a single network version.
**Naming convention:** `hyperpaxd` executable plus semantic runtime version.
| Release | Status | What Changed |
| -------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| **hyperpaxd\_2.0.3** | Active | Production binary from `hyperpaxeer-os` with CronosRelease precompiles, CometBFT v0.38.15, x/paxoracle keeper, and the stateful precompile framework |
**Format:** `hyperpaxd_`
**In config:** `binary_version: 2.0.3`
**Binary executable:** `hyperpaxd`
***
## Current Status
| Layer | Name | Convention |
| ----------- | ----------------- | --------------------------- |
| **Network** | Paxeer Network | Permanent identity |
| **Fork** | Alexandria | Ancient seats of knowledge |
| **Version** | HyperPaxeer | Hyper + compound noun |
| **Binary** | `hyperpaxd_2.0.3` | hyperpaxd + runtime version |
**Status badge:** `Alexandria / HyperPaxeer / hyperpaxd_2.0.3`
***
## How Upgrades Work
### Fork Upgrade
1. Governance proposal defining the new consensus/crypto changes
2. All validators halt at a coordinated block height
3. Chain state backed up from one validator
4. New fork binary distributed as Docker image
5. All validators restart simultaneously on the new fork
### Network Version Upgrade
1. New precompiles, modules, or features implemented
2. Binary updated to include new features
3. Coordinated upgrade at target block height
4. Chain continues with new capabilities active
### Binary Release
1. VM or validator software patch prepared
2. Docker image published to registry
3. Operators update via `hpx` CLI: re-run the installer
4. Existing chain data preserved, no coordination required for non-breaking changes
***
## Resources
Dual-VM design and precompile framework
Deploy nodes with the hpx CLI