IPcl.deployPclProxy

deployPclProxy(PclProxyKind kind, uint256 value, bytes calldata initData) external returns (address proxy)

체인 바이너리에 내장된 표준 프록시 bytecode로 PCL 래핑 프록시를 배포하고, PCL 프록시 레지스트리에 등록하며, 배포 호출자(msg.sender)를 그 프록시 주소의 초기 PCL 컨트랙트 admin으로 바인딩합니다. 이 모든 작업은 호출이 반환되기 전에 완료됩니다. 초기 admin이 msg.sender로 바인딩되므로, 팩토리 컨트랙트를 통해 배포하면 최종 사용자가 아니라 팩토리가 admin이 됩니다. PclProxyKind.Transparent의 경우 initDataabi.encode(logic, initialOwner, initializer)입니다.

파라미터

이름 타입 필수 설명
kind PclProxyKind 배포할 프록시 종류입니다. PclProxyKind enum에는 현재 Unspecified(0, 유효하지 않음)와 Transparent(1) 두 멤버만 있습니다. PclProxyKind.Transparent를 전달하며, 다른 프록시 종류는 현재 enum에 없습니다.
value uint256 프록시 생성자/이니셜라이저로 전달되는 네이티브 aokrw 값이며, base denom(소수점 18자리) 단위입니다. 배포 시 자금이 필요하지 않으면 0을 전달합니다.
initData bytes ABI 인코딩된 생성자 인자입니다. Transparent의 경우 abi.encode(address logic, address initialOwner, bytes initializer)이며, initializer는 배포 후 logic에 호출할 calldata입니다(호출을 건너뛰려면 빈 bytes를 전달합니다).

반환값

타입: address

배포된 프록시의 주소를 반환합니다. 호출 이후 IPcl.pclProxy(proxy)는 non-zero PclProxyEntry를 반환하며, IPcl.contractPolicies(proxy).admin은 아직 부착된 PolicySet이 없어도 msg.sender와 동일합니다. 초기 정책 세트를 부착할 때는 registerContractPolicies가 아니라 changeContractPolicies를 사용합니다.

에러

코드 이름 설명
AbiDecodeFailed AbiDecodeFailed initData를 해당 kind의 예상 레이아웃으로 디코드할 수 없을 때 revert됩니다.
PolicyAlreadyRegistered PolicyAlreadyRegistered admin 바인딩 단계에서, 배포된 프록시 주소에 이미 다른 배포자로 PCL admin이 기록되어 있으면 revert됩니다. 예를 들어 다른 주소가 수행한 CREATE2 사전 등록이 이에 해당합니다. 동일 주소의 사전 등록은 idempotent하며 revert되지 않습니다.

예제

Transparent 프록시 배포 후 정책 부착

배포 호출은 이 컨트랙트를 새 프록시의 PCL admin으로 자동 바인딩합니다. 이후 정책 부착은 admin 슬롯이 이미 초기화되었으므로 changeContractPolicies를 사용합니다.

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.22;

import {
    IPcl, PclProxyKind, ContractPolicyConfig, PolicySet
} from "@maroo-chain/contracts/precompiles/pcl/IPcl.sol";

contract DeployAndConfigure {
    IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);

    // Replace with the actual token logic contract address before production.
    address constant LOGIC = 0x000000000000000000000000000000000000dEaD;

    function deployAndAttach(PolicySet[] calldata policies)
        external
        returns (address proxy)
    {
        bytes memory initializer = abi.encodeWithSignature(
            "initialize(address)", msg.sender
        );
        bytes memory initData = abi.encode(LOGIC, msg.sender, initializer);

        // deployPclProxy binds msg.sender (this contract) as PCL admin of `proxy`.
        proxy = PCL.deployPclProxy(PclProxyKind.Transparent, 0, initData);

        // Slot is already bound → use changeContractPolicies, NOT register.
        PCL.changeContractPolicies(ContractPolicyConfig({
            _contract: proxy,
            admin:     address(this),   // keep, or replace to hand over
            policies:  policies
        }));
    }
}

viem으로 EOA에서 배포

deployPclProxy를 제출한 EOA가 결과 프록시의 PCL admin으로 바인딩됩니다. 별도의 등록 단계가 필요하지 않습니다.

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

const PCL = "0x1000000000000000000000000000000000000005" as const;

// Replace with a real testnet key before running.
const account = privateKeyToAccount("0xREPLACE_ME_TESTNET_KEY");
const walletClient = createWalletClient({
  account,
  transport: http("https://rpc-testnet.maroo.io"),
});

const logic        = "0x000000000000000000000000000000000000dEaD"; // replace
const initialOwner = account.address;
const initializer  = "0x"; // no initializer call

const initData = encodeAbiParameters(
  [
    { type: "address" },
    { type: "address" },
    { type: "bytes"   },
  ],
  [logic, initialOwner, initializer]
);

const hash = await walletClient.writeContract({
  address: PCL,
  abi: pclAbi,
  functionName: "deployPclProxy",
  args: [1 /* PclProxyKind.Transparent */, 0n, initData],
});
// After the tx is mined:
//   pcl.contractPolicies(proxy).admin === account.address
// Follow up with changeContractPolicies to attach policies.
ESC
검색어를 입력하세요