마루 주소 형식 이해하기
마루 계정은 EVM hex (0x…) 와 Bech32 (maroo1…) 두 가지 동등한 문자열 표현을 가집니다. 각각 언제 필요한지, JS/TS에서 어떻게 변환하는지를 함께 안내합니다.
사전 요구사항
- EVM hex 주소 (이더리움 등)에 대한 기본 이해.
EVM hex (기본 surface)
표준 42자
예:
0x… 주소입니다. 메타마스크가 표시하고, Solidity가 사용하고, JSON-RPC가 반환하고, 마루 블록 탐색기가 표시하며, 모든 viem / ethers / Hardhat / Foundry 도구가 기대하는 형식입니다.예:
0x71C7656EC7ab88b098defB751B7401B5f6d8976FBech32
동일한 20바이트 계정 ID를 네트워크 식별 HRP(마루의 경우
예:
같은 키를 다른 문자열로 표현한 것일 뿐입니다.
maroo)와 체크섬으로 인코딩한 형식입니다. 다음 경우에 등장합니다:- validator / staking / governance 모듈 쿼리 (Bech32 입력을 받습니다),
- 비-EVM 쿼리 결과 검사,
- IBC 인터페이스에서 상대 체인 주소로 사용됩니다.
예:
maroo1g9aher02v4dmf49m26de25d2n0a2th8g3z4x9a같은 키를 다른 문자열로 표현한 것일 뿐입니다.
JS/TS로 변환
양방향 모두 O(1)이며 네트워크 호출이 필요 없습니다. Bech32는
@cosmjs/encoding을 사용하고(가볍고 많은 지갑 스택에 이미 포함되어 있습니다), 0x 형식은 ethers/viem의 hex helper를 사용합니다.import { fromBech32, toBech32 } from "@cosmjs/encoding";
import { getAddress, hexToBytes, bytesToHex } from "viem"; // 또는 ethers 동등물
const HRP = "maroo";
// hex -> bech32
export function hexToBech32(hex: `0x${string}`): string {
const bytes = hexToBytes(hex);
return toBech32(HRP, bytes);
}
// bech32 -> hex (체크섬 적용)
export function bech32ToHex(addr: string): `0x${string}` {
const { data } = fromBech32(addr);
return getAddress(`0x${bytesToHex(data).slice(2)}`);
}
// 라운드트립 예시
const hex = "0x71C7656EC7ab88b098defB751B7401B5f6d8976F";
const bech32 = hexToBech32(hex);
// 'maroo1g9aher02v4dmf49m26de25d2n0a2th8g3z4x9a'
const andBack = bech32ToHex(bech32);
// '0x71C7656EC7ab88b098defB751B7401B5f6d8976F' 참고: Bech32는 체크섬이 내장되어 있어 `fromBech32`가 오타가 있으면 예외를 발생시킵니다. `0x` 형식은 자체 체크섬이 없으므로 viem의 `getAddress`(또는 ethers의 `getAddress`)로 EIP-55 mixed-case 체크섬을 적용합니다.
특수 접두사
Bech32에는 계정 외 용도로 사용하는 접두사 변형이 있습니다. validator / governance 모듈과 상호작용할 때만 등장합니다:
계정 레벨 dApp 작업에서는 사실상 필요하지 않습니다.
maroovaloper1…— validator 운영자 주소로, staking 모듈 메시지에서 사용합니다.maroovalcons1…— validator 합의 주소입니다.maroopub1…/maroovaloperpub1…— 공개키 인코딩 형식 (앱 코드에서는 거의 사용하지 않습니다).
계정 레벨 dApp 작업에서는 사실상 필요하지 않습니다.