Simapp - Change cosmos AddressCodec
this article is a record of modifying addresscodec of cosmos-sdk SimApp.
What is SimApp
SimApp is an application built using the Cosmos SDK for testing and educational purposes.
prerequisite
dependency injection (DI) framework for the Cosmos SDK
cosmos simapp
clone the cosmos-sdk
change to simapp dir and build with go
change AddressCodec
All the module configs are located in simapp/app_config.go.
we can change app module config in simapp/app_config.go
change the addresscodec
appConfig = appconfig.Compose(&appv1alpha1.Config{
...
Modules: []*appv1alpha1.ModuleConfig{
{
Name: authtypes.ModuleName,
Config: appconfig.WrapAny(&authmodulev1.Module{
Bech32Prefix: "zen",
ModuleAccountPermissions: moduleAccPerms,
}),
},
}
...
{
Name: stakingtypes.ModuleName,
Config: appconfig.WrapAny(&stakingmodulev1.Module{
Bech32PrefixValidator: "zenvaloper",
Bech32PrefixConsensus: "zenvalcons",
}),
},
})
but we get an error when create the genesis transaction with the following command
simd genesis gentx alice 1000000000stake --chain-id zen-1
failed to validate genesis state: hrp does not match bech32 prefix: expected 'cosmos' got 'zen': internal logic error [/home/kkk/cosmos-sdk/codec/address/bech32_codec.go:89]
Enable debug log for dependency injection
enable log in simapp/simd/cmd/root_di.go
@@ -35,7 +35,7 @@ func NewRootCmd() *cobra.Command {
clientCtx client.Context
)
- if err := depinject.Inject(
+ if err := depinject.InjectDebug(depinject.StdoutLogger(),
depinject.Configs(simapp.AppConfig(),
depinject.Supply(log.NewNopLogger()),
depinject.Provide(
then execute the command again we can see the dependency tree
from the log we found that
Supplying *modulev1.Module from cosmossdk.io/depinject/appconfig.Compose (/home/kkk/cosmos-sdk/depinject/appconfig/config.go:110) to cosmossdk.io/x/auth.ProvideModule
Providing keeper.AccountKeeper from cosmossdk.io/x/auth.ProvideModule (/home/kkk/cosmos-sdk/x/auth/depinject.go:48) to cosmossdk.io/x/bank.ProvideModule
after checked all the provider, I found that all is fine.
Debug simd
start gdb to debug simd set break point to the line of code where the error occur
func (bc Bech32Codec) StringToBytes(text string) ([]byte, error) {
...
if hrp != bc.Bech32Prefix {
//set breakpoint here then use bt command
return nil, errorsmod.Wrapf(sdkerrors.ErrLogic, "hrp does not match bech32 prefix: expected '%s' got '%s'", bc.Bech32Prefix, hrp)
}
...
}
after bt
command
we can see the backtrace
#0 github.com/cosmos/cosmos-sdk/codec/address.Bech32Codec.StringToBytes (bc=..., text=..., ~r0=..., ~r1=...)
at /home/kkk/cosmos-sdk/codec/address/bech32_codec.go:89
#1 0x0000000000f77d0e in github.com/cosmos/cosmos-sdk/types.AccAddressFromBech32 (address=..., addr=..., err=...)
at /home/kkk/cosmos-sdk/types/address.go:196
...
#13 0x0000000002874593 in main.main () at /home/kkk/cosmos-sdk/simapp/simd/main.go:15
from the second call AccAddressFromBech32 we can find that is the Bech32AccountAddrPrefix not modify here
func AccAddressFromBech32(address string) (addr AccAddress, err error) {
bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix()
addrCdc := addresscodec.NewBech32Codec(bech32PrefixAccAddr)
return addrCdc.StringToBytes(address)
}
because bech32PrefixAccAddr here is stil cosmos
, so we need to update this prefix to zen
Modify bech32PrefixAccAddr of app_config
we can find the app_config is set in simapp/simd/cmd/commands.go
func initRootCmd(
rootCmd *cobra.Command,
txConfig client.TxConfig,
moduleManager *module.Manager,
) {
cfg := sdk.GetConfig()
cfg.Seal()
...
}
now we add those prefix here
func initRootCmd(
rootCmd *cobra.Command,
client client.Context,
moduleManager *module.Manager,
) {
cfg := sdk.GetConfig()
cfg.SetBech32PrefixForAccount(client.AddressPrefix, client.AddressPrefix+sdk.PrefixPublic)
cfg.SetBech32PrefixForValidator(
client.AddressPrefix+sdk.PrefixValidator+sdk.PrefixOperator,
client.AddressPrefix+sdk.PrefixValidator+sdk.PrefixOperator+sdk.PrefixPublic,
)
cfg.SetBech32PrefixForConsensusNode(
client.AddressPrefix+sdk.PrefixValidator+sdk.PrefixConsensus,
client.AddressPrefix+sdk.PrefixValidator+sdk.PrefixConsensus+sdk.PrefixPublic,
)
cfg.Seal()
...
}
for some convenient, I change the function signature here, don’t forget to modify the caller of initRootCmd
Genesis Transaction Created Successfully
Successfully create the genesis transaction after modifying the addresscodec and bech32PrefixAccAddr
$ simd genesis gentx alice 1000000000stake --chain-id zen-1
$
No output mean that genesis transaction is created successfully