IPcl.pclProxy
pclProxy(address proxy) external view returns (PclProxyEntry memory) PCL 래핑 프록시 주소의 온체인 레지스트리 항목을 반환합니다. PclProxyEntry 튜플은 프록시 변형(kind), 현재 바인딩된 정책 admin(admin), 등록된 프록시 주소(proxy)를 담습니다. proxy가 등록되어 있지 않으면 반환 항목의 모든 필드가 0입니다(kind = Unspecified, admin = 0x0, proxy = 0x0). 호출은 revert되지 않습니다. admin 필드는 표준 컨트랙트 admin 레코드의 투영이며, deployPclProxy 실행 시점에 설정되고 이후 changeContractPolicies가 admin을 회전하면 함께 갱신됩니다. 따라서 클라이언트가 이 뷰만 읽어도 contractPolicies를 추가로 조회하지 않고 현재 게이트키퍼를 확인할 수 있습니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
proxy | address | ✓ | PCL 프록시 레지스트리에서 조회할 프록시 주소입니다. 사용자가 규제 경로로 트랜잭션을 보낼 때 호출하는 주소이며, 그 뒤에 있는 구현체 주소가 아닙니다. |
반환값
PclProxyEntry (PclProxyKind kind, address admin, address proxy) 튜플입니다. kind는 Unspecified | Transparent | UUPS | Beacon 중 하나입니다. admin은 이 프록시에 대해 changeContractPolicies와 removeContractPolicies를 호출할 권한을 가진 현재 주소입니다. proxy는 등록된 프록시 주소 자체로, 클라이언트에서 여러 항목을 순회할 때 편의를 위해 함께 반환됩니다. 등록되지 않은 주소를 조회하면 세 필드 모두 0입니다.
예제
viem으로 프록시 레지스트리 항목 조회
등록되지 않은 주소에 대해서는 모든 필드가 0인 항목을 반환합니다. revert를 잡는 대신 kind === Unspecified(0)로 미등록 여부를 분기 처리합니다.
import { createPublicClient, http } from "viem";
const PCL = "0x1000000000000000000000000000000000000005" as const;
const pclAbi = [{
name: "pclProxy", type: "function", stateMutability: "view",
inputs: [{ name: "proxy", type: "address" }],
outputs: [{
type: "tuple",
components: [
{ name: "kind", type: "uint8" },
{ name: "admin", type: "address" },
{ name: "proxy", type: "address" },
],
}],
}] as const;
const client = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
// TODO: replace with the real proxy address before production.
const proxyAddress = "0x8f3aC2b1D9e74C05a6B18Fe27dC4913E5A0f7b62";
const entry = await client.readContract({
address: PCL,
abi: pclAbi,
functionName: "pclProxy",
args: [proxyAddress],
});
if (entry.kind === 0) {
console.log("not a registered PCL proxy");
} else {
const kindName = ["Unspecified", "Transparent", "UUPS", "Beacon"][entry.kind];
console.log(`kind=${kindName} admin=${entry.admin} proxy=${entry.proxy}`);
} changeContractPolicies 호출자가 여전히 등록된 admin인지 확인
admin 필드가 컨트랙트 admin 바인딩을 그대로 반영하므로, 온체인 자동화 로직이 contractPolicies를 추가로 조회하지 않고도 후속 정책 갱신 전에 현재 admin을 검증할 수 있습니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.22;
import { IPcl, PclProxyEntry, PclProxyKind } from "@maroo-chain/contracts/precompiles/pcl/IPcl.sol";
contract AdminGuard {
IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);
/// @notice Reverts unless `expectedAdmin` is currently the admin recorded
/// in the PCL proxy registry for `proxy`.
function requireProxyAdmin(address proxy, address expectedAdmin) external view {
PclProxyEntry memory entry = PCL.pclProxy(proxy);
require(entry.kind != PclProxyKind.Unspecified, "not a registered PCL proxy");
require(entry.admin == expectedAdmin, "admin rotated");
}
}