IPcl.contractPolicies / removeContractPolicies
contractPolicies(
address contractAddress
) external view returns (ContractPolicyConfig memory);
removeContractPolicies(address contractAddress) external; 컨트랙트 범위 정책 바인딩에 대한 두 작업입니다. contractPolicies(address)는 현재 바인딩된 ContractPolicyConfig를 반환하는 view입니다. 바인딩이 없으면 0으로 채운 struct가 반환됩니다. removeContractPolicies(address)는 PCL 래핑 프록시의 PolicySet[]을 비웁니다. 컨트랙트 admin 바인딩 자체는 제거하지 않으므로, admin은 이후 changeContractPolicies로 다시 정책을 붙일 수 있습니다. 보호 장치가 두 가지 있습니다. (1) 현재 컨트랙트 admin만 제거할 수 있습니다. (2) 정책 인지 프리컴파일(PclParams.PolicyAwarePrecompiles에 등재된 주소)은 이 방식으로 비울 수 없습니다. 이 경우 CannotEmpty("policy-aware precompile policies")로 revert됩니다. 정책 인지 프리컴파일의 규칙을 완화하려면 대신 changeContractPolicies로 허용형 PolicySet을 설정합니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
contractAddress | address | ✓ | 대상 컨트랙트입니다. view에서는 어떤 주소든 허용됩니다(바인딩이 없으면 0으로 채운 struct가 반환됩니다). 제거에서는 반드시 PCL 래핑 프록시여야 하며, 정책 인지 프리컴파일 주소는 revert됩니다. |
반환값
ContractPolicyConfig | void contractPolicies는 ContractPolicyConfig(즉 _contract, admin, policies)를 반환합니다. removeContractPolicies는 반환값이 없으며, 성공 시 ContractPoliciesRemoved(contractAddress)를 발행합니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
Unauthorized | Unauthorized | removeContractPolicies에 적용됩니다. msg.sender가 대상의 현재 컨트랙트 admin이 아닐 때 revert됩니다. |
CannotEmpty | CannotEmpty | removeContractPolicies에 적용됩니다. contractAddress가 PclParams.PolicyAwarePrecompiles의 정책 인지 프리컴파일 중 하나이면 CannotEmpty("policy-aware precompile policies")로 revert됩니다. 이 대상들은 항상 최소 하나의 활성 PolicySet을 유지해야 합니다. |
PclProxyNotRegistered | PclProxyNotRegistered | removeContractPolicies에 적용됩니다. 대상이 PCL 래핑 프록시가 아닐 때 revert됩니다(정책 인지 프리컴파일은 앞서 CannotEmpty에서 걸러집니다). |
예제
viem으로 현재 바인딩 읽기
바인딩이 있으면 완전한 ContractPolicyConfig가 반환되고, 없으면 모든 필드가 0으로 채워집니다.
import { createPublicClient, http } from "viem";
const PCL = "0x1000000000000000000000000000000000000005" as const;
// TODO: replace with the real proxy address.
const PROXY = "0x8F3ac2B1d9E74c05A6B18FE27Dc4913e5A0F7b62" as const;
const publicClient = createPublicClient({ transport: http("https://rpc-testnet.maroo.io") });
const cfg = await publicClient.readContract({
address: PCL,
abi: pclAbi,
functionName: "contractPolicies",
args: [PROXY],
});
console.log(cfg.admin, cfg.policies.length); 정책 인지 프리컴파일의 정책 제거 거부
정책 인지 프리컴파일이 정책 없이 동작하는 상황을 막기 위해 removeContractPolicies는 의도적으로 차단됩니다. 대신 changeContractPolicies로 새 PolicySet(필요하면 허용형)을 제출합니다.
import { createWalletClient, http, decodeErrorResult } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const PCL = "0x1000000000000000000000000000000000000005" as const;
// Privacy precompile — a policy-aware precompile on Maroo.
const PRIVACY = "0x100000000000000000000000000000000000000b" as const;
const wallet = createWalletClient({
account: privateKeyToAccount(process.env.PRECOMPILE_ADMIN_KEY as `0x${string}`),
transport: http("https://rpc-testnet.maroo.io"),
});
try {
await wallet.writeContract({
address: PCL,
abi: pclAbi,
functionName: "removeContractPolicies",
args: [PRIVACY],
});
} catch (err: any) {
const decoded = decodeErrorResult({ abi: pclAbi, data: err.data });
// decoded.errorName === "CannotEmpty"
// decoded.args === ["policy-aware precompile policies"]
console.error("cannot clear policies on a policy-aware precompile:", decoded.args[0]);
}