OKRW 프리컴파일
OKRW는 안정적인 두 개의 EVM 진입점을 노출합니다. 0x1000…0001의 IOkrw 프리컴파일은 마루 고유 작업(mint, getParams)을 제공하고, 0xEeeE…EEeE의 네이티브 ERC20 표현은 표준 ERC20 호출(transfer, approve, balanceOf)을 제공합니다.
OKRW는 마루의 KRW 페그 스테이블코인이자 체인의 네이티브 가스 토큰입니다. Solidity 호출자 관점에서 OKRW는 모든 네트워크에서 고정된 두 주소로 노출됩니다. IOkrw 프리컴파일(0x1000000000000000000000000000000000000001)은 mint, getParams 등 마루 고유 작업을 제공하고, 네이티브 ERC20 표현(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)은 제네시스에서 aokrw base denom의 기본 토큰 페어로 등록된 표준 ERC20 진입점입니다. 표준 지갑·DEX·볼트 연동에는 ERC20 주소를 사용하고, 마루 확장 작업에만 IOkrw 프리컴파일을 사용합니다.
아키텍처
flowchart LR
SC["Your Solidity Contract"] -->|"IOkrw.mint(recipient, amount)"| OKRW["OKRW Precompile<br/>0x...001"]
OKRW --> XOK["x/okrw module<br/>(checks minter authorization)"]
XOK -->|"on success"| XBK["x/bank module<br/>(credits recipient with aokrw)"]
XOK -->|"emit event"| EV["Mint event<br/>(EVM log)"]
XOK -.->|"on failure"| Err["Revert: UnauthorizedMinter"]
classDef evm fill:#0096AA,stroke:#0096AA,color:#fff;
classDef precompile fill:#FF8C50,stroke:#FF8C50,color:#fff;
classDef module fill:#8CC3C3,stroke:#8CC3C3,color:#fff;
classDef bad fill:#AA0019,stroke:#AA0019,color:#fff;
class SC,EV evm;
class OKRW precompile;
class XOK,XBK module;
class Err bad; IOkrw.mint를 호출하면 프리컴파일이 권한 검증을 위해 x/okrw로 연결되고, 성공 시 x/bank가 recipient에게 aokrw를 입금하며 Mint 이벤트가 발행됩니다.
두 주소, 하나의 토큰
OKRW는 상호 보완적인 두 EVM 진입점을 가진 하나의 토큰입니다. 두 주소 모두 테스트넷과 메인넷에서 동일하므로 하드코딩하거나
ERC20 표현은 제네시스에서
@maroo-chain/contracts에서 읽어옵니다.| 진입점 | 주소 | 용도 |
|---|---|---|
| IOkrw 프리컴파일 | 0x1000000000000000000000000000000000000001 | mint, getParams, 마루 고유 확장 |
| 네이티브 ERC20 표현 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE | 표준 transfer, approve, transferFrom, balanceOf, totalSupply, Approval / Transfer 이벤트 |
ERC20 표현은 제네시스에서
aokrw(18자리 소수점 base denom)를 ERC20 컨트랙트 주소에 매핑하는 토큰 페어로 등록되며 컨트랙트 소유자는 OWNER_MODULE입니다. 표준 ERC20 ABI가 그대로 동작합니다.// 표준 ERC20 경로 — 지갑, DEX, 볼트
IERC20 okrw = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
okrw.transfer(recipient, 10_000_000 ether); // 10,000,000 OKRW
okrw.approve(spender, 10_000_000 ether);
// 마루 확장 경로 — 발행자 전용 작업
import "@maroo-chain/contracts/precompiles/okrw/IOkrw.sol";
IOkrw extn = IOkrw(0x1000000000000000000000000000000000000001);
extn.mint(recipient, 10_000_000 ether); // 지정된 발행자만 단위 표기와 변환
OKRW는 이더리움 스타일의 18자리 소수점 회계를 사용합니다. Base denom은
aokrw(1 OKRW = 10^18 aokrw)이고 display denom은 okrw입니다. aokrw는 가스·수수료 denom이며 스테이킹은 별도 denom(amaroo)을 사용한다는 점에 유의합니다. Solidity 리터럴 1_000_000 ether는 1,000,000 OKRW를 의미합니다.// 10,000,000 OKRW — 실제 전송 상한 예시 수량
uint256 amount = 10_000_000 ether; // 10_000_000 * 10**18 aokrw
okrw.transfer(recipient, amount); 두 진입점이 함께 존재하는 이유
네이티브 ERC20 표현은 EVM 도구가 기본적으로 기대하는 형태입니다. 지갑은 이 주소로 잔액을 조회하고, DEX 라우터는 이 주소를 유동성 한쪽으로 추가하며, 회계 도구는 이 주소의
Transfer 이벤트를 색인합니다. IOkrw 프리컴파일은 ERC20 인터페이스에 들어맞지 않는 마루 고유 작업(지정 발행자에 의한 통제된 mint, getParams를 통한 파라미터 조회)을 담당합니다. 두 진입점 모두 결국 동일한 aokrw 잔액을 이동시키며, 어느 주소를 쓸지는 호출이 필요한 API 표면에 따라 결정합니다.통제된 발행 권한
오픈 mint ERC20과 달리, 설정된 지정 발행자 주소만
IOkrw.mint 호출에 성공할 수 있습니다. 다른 호출자는 UnauthorizedMinter(caller, authorizedMinter)로 revert됩니다. 발행자 교체는 컨소시엄 거버넌스 작업이며 외부 dApp이 수행하지 않습니다. 현재 발행자는 IOkrw.getParams()로 조회하고, 그 결과를 mint 요청 라우팅의 권위 있는 답으로 취급합니다.import "@maroo-chain/contracts/precompiles/okrw/IOkrw.sol";
IOkrw okrw = IOkrw(0x1000000000000000000000000000000000000001);
address minter = okrw.getParams().minter;
require(msg.sender == minter, "not authorized to mint"); 오프체인 코드에서 잔액 조회
viem, ethers, cast 등 표준 리더에서 ERC20 주소를 그대로 사용합니다.
https://explorer-testnet.maroo.io의 블록 익스플로러도 동일한 주소를 ERC20 형태의 계정으로 보여줍니다.import { createPublicClient, http, parseAbi } from "viem";
const OKRW_ERC20 = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
const erc20Abi = parseAbi([
"function balanceOf(address) view returns (uint256)",
"function totalSupply() view returns (uint256)",
]);
const client = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const balance = await client.readContract({
address: OKRW_ERC20,
abi: erc20Abi,
functionName: "balanceOf",
args: ["0xUserAddress..."], // 프로덕션 전 교체합니다
});