IPcl.changeContractPolicies

changeContractPolicies(ContractPolicyConfig calldata policy) external

컨트랙트의 정책 설정 전체를 교체하며, 동일한 호출에서 admin 권한을 이전할 수도 있습니다. 호출자는 policy._contract의 현재 admin이어야 합니다. 성공 시 저장된 PolicySet[]policy.policies로 완전히 교체되고 admin 바인딩은 policy.admin으로 설정됩니다. 현재 admin을 유지하려면 policy.admin에 동일한 주소를 전달합니다. 권한을 이전하려면 새 admin의 주소를 전달합니다. 이것이 지원되는 유일한 admin 이전 경로이며, 별도의 transfer 메서드는 없습니다.

파라미터

이름 타입 필수 설명
policy ContractPolicyConfig 교체할 전체 설정입니다. _contract는 대상 컨트랙트를 지정합니다(기존 설정이 있어야 합니다). admin은 이 호출 이후의 admin이 될 주소입니다. 현재 admin과 동일한 주소를 지정하면 권한이 유지되고, 다른 주소를 지정하면 권한이 이전됩니다. policies는 새로운 완전한 PolicySet[] 배열이며, 병합이나 delta가 아닌 통째 교체입니다.

반환값

타입: void

반환값이 없습니다. 실패 시 revert됩니다.

에러

코드 이름 설명
Unauthorized Unauthorized 호출자가 policy._contract의 현재 admin이 아니면 revert됩니다.
PolicyNotRegistered PolicyNotRegistered policy._contract에 기존 정책 설정이 없으면 revert됩니다. 최초 등록에는 registerContractPolicies를 사용합니다.
InvalidAddress InvalidAddress _contract 또는 admin을 유효한 체인 측 계정으로 정규화할 수 없으면 revert됩니다.
UnknownPolicyType UnknownPolicyType policiesPolicySet.templateId 중 어느 하나라도 이 네트워크에 등록된 정책 템플릿과 일치하지 않으면 revert됩니다.
InvalidParameter InvalidParameter PolicySet.policy 바이트가 템플릿의 예상 파라미터 struct로 ABI 디코드되지 않으면 revert됩니다.

예제

admin을 유지한 채 정책 갱신

표준 정책 갱신 흐름입니다. 현재 admin이 교체용 PolicySet[]을 제출하고 admin에 자기 주소를 그대로 넣어 권한을 유지합니다.

import { createWalletClient, http, encodeAbiParameters } from "viem";
import { privateKeyToAccount } from "viem/accounts";

const PCL = "0x1000000000000000000000000000000000000005";
const tokenAddress   = "0x1234567890123456789012345678901234567890"; // replace before production
const currentAdmin   = "0xAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAaAa"; // replace before production

const denylistBytes = encodeAbiParameters(
  [{ type: "address[]", name: "addresses" }],
  [["0xBbbBBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBbBb"]],
);

const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.ADMIN_KEY as `0x${string}`),
  transport: http(process.env.MAROO_RPC),
});

await wallet.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "changeContractPolicies",
  args: [{
    _contract: tokenAddress,
    admin:     currentAdmin,        // same address → no handover
    policies: [{
      templateId: "DENYLIST_POLICY",
      policy:     denylistBytes,
      selector:   "0x",
    }],
  }],
});

동일한 호출에서 admin 권한 이전

권한 이전 흐름입니다. 현재 admin이 admin에 다른 주소를 지정합니다. 트랜잭션이 확정되면 새 admin만이 해당 컨트랙트의 정책을 변경하거나 제거할 수 있습니다. 권한 이전과 정책 교체는 동일한 호출에서 원자적으로 이루어집니다.

// Called by the CURRENT admin. After this transaction lands, `newAdmin`
// becomes the sole address able to call changeContractPolicies /
// removeContractPolicies for tokenAddress.
const newAdmin = "0xCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCcCc"; // replace before production

await wallet.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "changeContractPolicies",
  args: [{
    _contract: tokenAddress,
    admin:     newAdmin,            // handover: authority transfers to newAdmin
    policies:  existingPolicySets,  // keep policies as-is, or replace at the same time
  }],
});

// A subsequent call from the old admin would now revert with Unauthorized.

정책 하나만 조정할 때 read-modify-write

changeContractPoliciesPolicySet[] 전체를 교체하므로, 반드시 현재 설정을 먼저 읽어 로컬에서 배열을 재구성한 뒤 제출합니다.

import { createPublicClient, http } from "viem";

const publicClient = createPublicClient({ transport: http(process.env.MAROO_RPC) });

// Read the current config first — the call is a wholesale replacement,
// so anything you omit gets dropped.
const current = await publicClient.readContract({
  address: PCL,
  abi: pclAbi,
  functionName: "contractPolicies",
  args: [tokenAddress],
});

// Rebuild the array with your edit; here we append a new PolicySet.
const nextPolicies = [...current.policies, additionalPolicySet];

await wallet.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "changeContractPolicies",
  args: [{
    _contract: tokenAddress,
    admin:     current.admin,   // preserve current admin
    policies:  nextPolicies,
  }],
});
ESC
검색어를 입력하세요