Build POA Entreprise Blockchains With Ignite

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.

  1. Modify the app.go to add the keeper to the App 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

  1. 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

  1. 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.