Build POA Entreprise Blockchains With Ignite

In this tutorial, you'll learn how to wire a Proof of Authority (POA) module for your blockchain using the Ignite CLI. POA is a consensus mechanism designed for private and enterprise blockchains, where only pre-approved validators are allowed to produce blocks. This makes it ideal for organizations that prioritize speed, control, and privacy over decentralization.
What is Proof of Authority (POA)?
Proof of Authority (POA) is a consensus algorithm in which validators are selected based on their identity and reputation rather than computational power or stake. Unlike Proof of Stake (PoS), where validators are chosen based on the amount of cryptocurrency they lock up, POA relies on trusted entities—often known and verified individuals or organizations—to maintain the network.
In a POA system:
- Only authorized validators can propose and vote on new blocks.
- Validators are typically pre-approved by the network’s governing body.
- The network achieves fast finality and high throughput, making it perfect for enterprise use cases.
How POA Differs from Proof of Stake (PoS)
Feature | Proof of Stake (PoS) | Proof of Authority (POA) |
---|---|---|
Validator Selection | Based on staked tokens | Based on identity and trust |
Decentralization | High | Low to moderate |
Finality | Fast, but can vary | Very fast and deterministic |
Use Case | Public, permissionless blockchains | Private, permissioned networks |
Security Model | Economic incentives | Identity and reputation |
While PoS is ideal for public blockchains like Ethereum, POA shines in enterprise environments where control and regulatory compliance are key.
How to Wire the POA Module into Your Ignite Blockchain
To implement POA in your Ignite blockchain, we recommend using the open-source implementation by Strangelove Ventures , which provides a robust and battle-tested POA module compatible with Cosmos SDK.
🔗 GitHub: https://github.com/strangelove-ventures/poa
Follow these steps to integrate the POA module into your existing Ignite project.
Step 1: Initialize Your Blockchain (if not already done)
ignite scaffold chain gm --skip-module
This creates a new blockchain project with a default module structure.
Step 2: Add the POA Module as a Dependency
An Ignite chain comes by default with the x/staking
module, which implements POS.
To use the POA module, a few tweaks are necessary to the default template:
cd gm
go get github.com/strangelove-ventures/poa
Download the module
Note, there is a bug in that POA implementation the forces cosmossdk.io/core
to update while it should not. Make sure to revert it by adding the following replace to your go.mod
replace cosmossdk.io/core => cosmossdk.io/core v0.11.3
Once the module is downloaded, wire it as a Cosmos SDK module.
- Modify the
app.go
to add the keeper to theApp
struct and inject the keeper:
diff --git a/app/app.go b/app/app.go
index f5947c4..1760711 100644
--- a/app/app.go
+++ b/app/app.go
@@ -47,6 +47,8 @@ import (
"gm/docs"
+
+ poakeeper "github.com/strangelove-ventures/poa/keeper"
)
const (
@@ -91,6 +93,7 @@ type App struct {
ConsensusParamsKeeper consensuskeeper.Keeper
CircuitBreakerKeeper circuitkeeper.Keeper
ParamsKeeper paramskeeper.Keeper
+ POAKeeper poakeeper.Keeper
// ibc keepers
IBCKeeper *ibckeeper.Keeper
@@ -174,6 +177,7 @@ func New(
&app.CircuitBreakerKeeper,
&app.ParamsKeeper,
+ &app.POAKeeper,
); err != nil {
panic(err)
}
app.go changes
- Modify the
app_config.go
to write the module in he app configuration. Make sure the poa module is defined before the staking module:
diff --git a/app/app_config.go b/app/app_config.go
index 96a565b..0e2cd33 100644
--- a/app/app_config.go
+++ b/app/app_config.go
@@ -69,6 +69,9 @@ import (
icatypes "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/types"
ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types"
ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported"
+ "github.com/strangelove-ventures/poa"
+ poamodulev1 "github.com/strangelove-ventures/poa/api/module/v1"
+ _ "github.com/strangelove-ventures/poa/module" // import for side-effects
"google.golang.org/protobuf/types/known/durationpb"
)
@@ -119,6 +122,7 @@ var (
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
+ poa.ModuleName,
stakingtypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
@@ -130,6 +134,7 @@ var (
},
EndBlockers: []string{
govtypes.ModuleName,
+ poa.ModuleName,
stakingtypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
@@ -171,7 +176,7 @@ var (
ibctransfertypes.ModuleName,
icatypes.ModuleName,
// chain modules
+ poa.ModuleName,
// this line is used by starport scaffolding # stargate/app/initGenesis
},
}),
@@ -272,6 +277,10 @@ var (
Name: epochstypes.ModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
},
+ {
+ Name: poa.ModuleName,
+ Config: appconfig.WrapAny(&poamodulev1.Module{}),
+ },
// this line is used by starport scaffolding # stargate/app/moduleConfig
},
})
app_config.go changes
- Finally, adding ante handlers is required to make sure
x/staking
operations are restricted.
If you are using the wasm app or evm, simply add the following to the ante.go
:
anteDecorators := []sdk.AnteDecorator{
...
poaante.NewPOADisableStakingDecorator(),
poaante.NewPOADisableWithdrawDelegatorRewardsDecorator(),
...
}
ante.go changes
Those two ante handlers are disabling the following messages: Redelegate, Cancel Unbonding, Delegate, and Undelegate in x/staking
and MsgWithdrawDelegatorReward in x/distribution
.
Step 3: Configure the genesis
As the Cosmos SDK uses PoS by default, the x/slashing
and x/slashing
module parameters may not align with your wishes. With Ignite you can modify them easily by defining genesis configuration the config.yaml
.
genesis:
app_state:
staking:
params:
max_validators: "12"
min_commission_rate: "0.0"
slashing:
params:
slash_fraction_double_sign: "0.0"
slash_fraction_downtime: "0.0"
signed_blocks_window: "10000"
min_signed_per_window: "0.0001"
downtime_jail_duration: 60s
config.yaml exension
Step 4: Start your node with POA
Build and start your node:
ignite chain serve --skip-proto
Now, your blockchain is running with a POA consensus mechanism. Only the validators listed in the genesis file can produce blocks by default. After launch, governance, or a defined address (via the POA_ADMIN_ADDRESS
environment variable), can modify the validator set:
Usage:
gmd tx poa [flags]
gmd tx poa [command]
Available Commands:
create-validator create new validator for POA (anyone)
remove remove a validator from the active set
remove-pending remove a validator from the pending set queue
set-power set the consensus power of a validator in the active set
update-staking-params update the staking module params
poa transactions.
Conclusion
You are now using a Proof of Authority (POA) module using Ignite CLI and integrated it with the trusted strangelove-ventures/poa
implementation. This setup is perfect for enterprise blockchains where control, speed, and compliance are critical.
POA isn’t for every use case—but when you need a secure, permissioned network with fast finality, it’s one of the best choices available.