testnet
GitHub EN

IPcl.runOnPcl

runOnPcl(address contractAddress, bytes calldata data, uint256 value) external returns (bytes memory)

PCL의 규제된 컨텍스트 내에서 대상 컨트랙트에 대한 호출을 실행합니다. 이 함수는 '규제 트랙'의 진입점입니다. 먼저 발신자, 대상 컨트랙트 및 호출 데이터를 기반으로 적용 가능한 모든 전역 및 컨트랙트별 정책 검사를 트리거합니다. 모든 검사가 통과하면 저수준 call을 사용하여 대상 컨트랙트에서 제공된 호출 데이터를 실행합니다. 검사 중 하나라도 실패하면 트랜잭션은 특정 오류와 함께 되돌려집니다.

파라미터

이름 타입 필수 설명
contractAddress address PCL 검사가 통과한 후 호출할 대상 컨트랙트의 주소입니다.
data bytes 대상 컨트랙트에서 실행될 함수에 대한 ABI 인코딩된 콜데이터입니다.
value uint256 호출과 함께 보낼 OKRW의 양 (msg.value) 입니다.

반환값

타입: bytes memory

대상 컨트랙트 호출의 성공적인 실행으로부터의 반환 데이터입니다.

에러

코드 이름 설명
InDenylist InDenylist 발신자의 주소가 활성 거부 목록 정책에서 발견되면 되돌립니다.
EasAttestationRequired EasAttestationRequired 발신자가 필요한 EAS 증명(예: KYC)이 없는 경우 되돌립니다.
VolumeAboveMaxLimit VolumeAboveMaxLimit 트랜잭션 금액이 구성된 거래량 한도를 초과하면 되돌립니다.

예제

ERC20 전송 래핑

이 예제는 공개 `transfer` 함수를 재정의하는 토큰 컨트랙트를 보여줍니다. 로직을 직접 실행하는 대신, 자신(`address(this)`)을 대상으로 하고 자신의 `internal` 전송 로직에 대한 인코딩된 콜데이터를 제공하여 `runOnPcl`을 호출합니다. 이를 통해 이 토큰에 등록된 PCL 검사를 통과하지 않고는 어떠한 전송도 발생할 수 없도록 보장합니다.

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IPcl, PCL_CONTRACT } from "./IPcl.sol";

contract CompliantToken is IERC20 {
    // ... other ERC20 implementation ...

    function _transfer(address from, address to, uint256 amount) internal {
        // ... core transfer logic ...
    }

    // Public transfer function enforces PCL checks
    function transfer(address to, uint256 amount) public override returns (bool) {
        // Encode the call to the internal transfer function
        bytes memory data = abi.encodeWithSelector(
            this._transfer.selector,
            msg.sender,
            to,
            amount
        );

        // Execute via PCL. This contract calls itself through the PCL gate.
        PCL_CONTRACT.runOnPcl(address(this), data, 0);
        return true;
    }
}

에러 처리를 포함한 다른 컨트랙트 호출

이 예제는 `try/catch` 블록을 사용하여 `runOnPcl`에서 발생할 수 있는 되돌림을 처리하는 방법을 보여줍니다. 특히 `InDenylist` 커스텀 에러를 확인하고 더 사용자 친화적인 메시지를 제공합니다.

import { IPcl, PCL_CONTRACT } from "./IPcl.sol";

contract PclCaller {
    function callCompliantService(address service, uint256 value) external {
        bytes memory data = abi.encodeWithSignature("deposit(uint256)", value);

        try PCL_CONTRACT.runOnPcl(service, data, 0) {
            // Success
        } catch (bytes memory reason) {
            // Attempt to decode a PCL custom error
            if (reason.length == 36) { // selector + 1 argument (e.g., address)
                bytes4 selector = bytes4(reason[:4]);
                if (selector == IPcl.InDenylist.selector) {
                    address sender = abi.decode(reason[4:], (address));
                    // Handle denylist error specifically
                    revert("Caller is on the denylist");
                }
            }
            // Revert with the original reason if it's not a known PCL error
            revert(string(reason));
        }
    }
}
ESC
검색어를 입력하세요