IPcl.registerContractPolicies
registerContractPolicies(ContractPolicyConfig calldata policy) external ContractPolicyConfig의 레거시 최초 등록 진입점입니다. policy.admin을 policy._contract의 PCL admin으로 바인딩하고 초기 정책 세트를 저장합니다. 이 진입점은 deprecated 상태입니다. admin 슬롯이 이미 바인딩된 경우 현재 바인딩된 admin만 호출할 수 있고, 이때 호출은 전체 재등록을 수행합니다(정책 세트가 교체되고 슬롯이 policy.admin으로 설정되므로 현재 admin이 슬롯을 넘겨줄 수도 있습니다). 바인딩된 admin이 아닌 호출자는 PolicyAlreadyRegistered로 revert됩니다. 새 코드는 changeContractPolicies를 사용합니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
policy | ContractPolicyConfig | ✓ | 등록할 설정입니다. (address _contract, address admin, PolicySet[] policies) 형식이며, admin이 컨트랙트의 admin 슬롯에 기록되어 이후 changeContractPolicies / removeContractPolicies를 호출할 수 있는 유일한 키가 됩니다. |
반환값
타입:
void 반환값이 없습니다. 유효성 검증이나 권한 검사에 실패하면 트랜잭션이 revert됩니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
PolicyAlreadyRegistered | PolicyAlreadyRegistered | 컨트랙트의 admin 슬롯이 이미 바인딩되어 있고 호출자가 그 admin이 아닐 때 revert됩니다(검사 기준은 policy.admin이 아니라 호출자입니다). deployPclProxy로 배포한 컨트랙트는 배포 시점에 admin 슬롯이 배포 호출자로 바인딩되므로, 다른 계정이 이후 registerContractPolicies를 호출하면 이 오류가 발생합니다. |
UnknownPolicyType | UnknownPolicyType | PolicySet.templateId 중 하나라도 이 네트워크가 아는 정책 타입으로 해석되지 않으면 revert됩니다. |
InvalidParameter | InvalidParameter | PolicySet.policy 바이트가 해당 템플릿의 예상 파라미터 struct로 디코드되지 않을 때 revert됩니다. |
예제
프록시가 아닌 컨트랙트의 레거시 등록
IPcl.contractPolicies(target).admin이 0 주소일 때만 registerContractPolicies를 사용합니다. deployPclProxy로 생성된 프록시는 배포 시점에 슬롯이 이미 바인딩되어 있으므로 이 호출이 필요하지 않습니다.
import {
IPcl, ContractPolicyConfig, PolicySet, DenylistPolicy
} from "@maroo-chain/contracts/precompiles/pcl/IPcl.sol";
IPcl pcl = IPcl(0x1000000000000000000000000000000000000005);
address[] memory blocked = new address[](1);
blocked[0] = 0x000000000000000000000000000000000000dEaD; // replace before production
PolicySet[] memory policies = new PolicySet[](1);
policies[0] = PolicySet({
templateId: "DENYLIST_POLICY",
policy: abi.encode(DenylistPolicy({ addresses: blocked })),
selector: ""
});
// Unbound slot: binds `admin`. If the slot is already bound, only the
// current admin may call this (and it performs a full re-registration).
pcl.registerContractPolicies(ContractPolicyConfig({
_contract: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F, // replace
admin: msg.sender,
policies: policies
})); 클라이언트에서 register와 change 중 선택
이식성 있는 클라이언트 로직입니다. contractPolicies(target).admin을 읽어 0 주소이면 슬롯이 아직 바인딩되지 않은 상태이므로 레거시 registerContractPolicies가 유효합니다. 그렇지 않으면 changeContractPolicies를 사용합니다.
import { createPublicClient, createWalletClient, http, zeroAddress } from "viem";
const PCL = "0x1000000000000000000000000000000000000005" as const;
const publicClient = createPublicClient({
transport: http("https://rpc-testnet.maroo.io"),
});
async function attachPolicies(target: `0x${string}`, config: any) {
const existing = await publicClient.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPolicies",
args: [target],
});
const fnName = existing.admin === zeroAddress
? "registerContractPolicies" // legacy path (deprecated)
: "changeContractPolicies"; // proxy-deployed or already-bound path
return walletClient.writeContract({
address: PCL,
abi: pclAbi,
functionName: fnName,
args: [config],
});
}