IOkrw.mint
mint(address recipient, uint256 amount) external returns (bool) amount만큼의 OKRW를 발행하여 recipient에게 입금합니다. 금액 단위는 소수점 18자리 base denom인 aokrw입니다. x/okrw 모듈 파라미터에 지정된 발행자 주소만 호출에 성공하며, 그 외 호출자는 UnauthorizedMinter 커스텀 오류로 revert됩니다. recipient가 0 주소이거나 amount가 0이면 각각 InvalidAddress(address)와 InvalidAmount(uint256) 커스텀 오류로 revert되므로, 클라이언트 dApp이 트랜잭션 영수증에서 4바이트 selector로 실패 원인을 구분할 수 있습니다. amount가 음수이거나 nil인 경우(저수준 ABI 조작으로만 도달)는 커스텀 오류가 아니라 일반 문자열 revert로 처리됩니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
recipient | address | ✓ | 새로 발행된 OKRW를 받을 주소입니다. 0 주소여서는 안 되며, 0x0을 전달하면 타입 지정 커스텀 오류 InvalidAddress(recipient)로 revert됩니다. |
amount | uint256 | ✓ | 발행할 수량으로 aokrw(소수점 18자리, 1 OKRW = 10^18 aokrw — okrw-precompile-overview 참고) 단위입니다. 반드시 0보다 커야 합니다. 0을 전달하면 InvalidAmount(amount)로 revert됩니다. nil이거나 음수 big.Int 입력(저수준 ABI 조작으로만 도달 가능)은 디코딩 가능한 커스텀 오류가 아니라 "amount must not be nil" 또는 "amount must not be negative"라는 일반 문자열로 revert됩니다. |
반환값
bool 성공 시 true를 반환합니다. 실패는 false 반환이 아니라 커스텀 오류로 revert됩니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
UnauthorizedMinter | UnauthorizedMinter | msg.sender가 지정된 발행자 주소가 아닐 때 revert됩니다. UnauthorizedMinter(address caller, address authorizedMinter) 형태로 인코딩되어 있어, 클라이언트가 실패한 호출자와 현재 지정된 발행자를 함께 표시할 수 있습니다. |
InvalidAddress | InvalidAddress | recipient가 0 주소일 때 revert됩니다. InvalidAddress(address addr) 형태로 인코딩되며, 문제가 된 주소(이 경우 0x0000…0000)를 함께 전달합니다. |
InvalidAmount | InvalidAmount | amount가 정확히 0일 때 revert됩니다. InvalidAmount(uint256 amount) 형태로 인코딩됩니다. nil이거나 음수 big.Int 입력(저수준 ABI 조작으로만 도달 가능)은 이 커스텀 오류가 아니라 일반 문자열("amount must not be nil" 또는 "amount must not be negative")로 처리됩니다. |
예제
지정된 발행자 컨트랙트에서 기본 발행
프리컴파일 측 권한 검사가 msg.sender와 지정된 발행자를 비교하므로, 이 호출이 성공하려면 Treasury 자신의 주소가 발행자로 지정되어 있어야 합니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;
import "@maroo-chain/contracts/precompiles/okrw/IOkrw.sol";
contract Treasury {
address constant OKRW_PRECOMPILE = 0x1000000000000000000000000000000000000001;
IOkrw okrw = IOkrw(OKRW_PRECOMPILE);
/// @notice Mint OKRW to `to`. This contract's address must be the
/// authorized minter in the x/okrw module parameters.
function mintTo(address to, uint256 amount) external {
// 10_000_000 OKRW == 10_000_000 * 10**18 aokrw when caller passes ether units.
bool ok = okrw.mint(to, amount);
require(ok, "OKRW mint returned false");
}
} viem으로 클라이언트에서 커스텀 오류 처리
문서화된 세 실패 유형은 모두 커스텀 오류 형태로 통일되어 있어, decodeErrorResult가 반환하는 errorName으로 실패 원인을 구분해 dApp의 사용자 메시지 처리를 분기할 수 있습니다. 0 금액과 0 주소는 커스텀 오류로 처리되며, nil이거나 음수인 amount 입력(Solidity에서는 도달 불가, 수동 ABI 인코딩으로만 가능)은 여전히 일반 문자열 revert로 처리됩니다.
import { createWalletClient, http, parseEther, decodeErrorResult } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const OKRW = "0x1000000000000000000000000000000000000001" as const;
const okrwAbi = [
{ type: "function", name: "mint", stateMutability: "nonpayable",
inputs: [{ name: "recipient", type: "address" }, { name: "amount", type: "uint256" }],
outputs: [{ type: "bool" }] },
{ type: "error", name: "UnauthorizedMinter",
inputs: [{ name: "caller", type: "address" }, { name: "authorizedMinter", type: "address" }] },
{ type: "error", name: "InvalidAddress", inputs: [{ name: "addr", type: "address" }] },
{ type: "error", name: "InvalidAmount", inputs: [{ name: "amount", type: "uint256" }] },
] as const;
const wallet = createWalletClient({
account: privateKeyToAccount(process.env.MINTER_KEY as `0x${string}`),
transport: http("https://rpc-testnet.maroo.io"),
});
try {
await wallet.writeContract({
address: OKRW,
abi: okrwAbi,
functionName: "mint",
// TODO: replace with the real treasury recipient before production.
args: ["0x8f3aC2b1D9e74C05a6B18Fe27dC4913E5A0f7b62", parseEther("10000000")],
});
} catch (err: any) {
if (err?.data) {
const decoded = decodeErrorResult({ abi: okrwAbi, data: err.data });
// decoded.errorName is one of UnauthorizedMinter | InvalidAddress | InvalidAmount
console.error(`OKRW.mint reverted: ${decoded.errorName}`, decoded.args);
} else {
// Plain string reverts (nil/negative amount) land here.
throw err;
}
} Solidity의 try/catch로 커스텀 오류 처리
문서화된 세 실패 유형(UnauthorizedMinter, InvalidAddress, InvalidAmount)이 모두 안정적인 4바이트 selector를 갖고 있으므로, 컨트랙트가 catch (bytes memory) 안에서 selector로 분기 처리할 수 있습니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;
import "@maroo-chain/contracts/precompiles/okrw/IOkrw.sol";
contract SafeMinter {
IOkrw constant okrw = IOkrw(0x1000000000000000000000000000000000000001);
event MintFailed(bytes4 selector);
function safeMint(address to, uint256 amount) external {
try okrw.mint(to, amount) returns (bool ok) {
require(ok, "mint returned false");
} catch (bytes memory raw) {
bytes4 sel;
assembly { sel := mload(add(raw, 32)) }
if (sel == IOkrw.UnauthorizedMinter.selector) {
emit MintFailed(sel);
} else if (sel == IOkrw.InvalidAddress.selector) {
emit MintFailed(sel);
} else if (sel == IOkrw.InvalidAmount.selector) {
emit MintFailed(sel);
} else {
// Unknown revert (e.g. plain-string revert on nil amount) — bubble up.
assembly { revert(add(raw, 32), mload(raw)) }
}
}
}
}