IPcl.runOnPcl
runOnPcl(address contractAddress, bytes calldata data, uint256 value) external returns (bytes memory) PCL의 규제 컨텍스트 안에서 대상 컨트랙트에 대한 호출을 실행합니다. 이 함수는 '규제 트랙'의 진입점입니다. 먼저 발신자, 대상 컨트랙트, 호출 데이터를 기준으로 적용 대상이 되는 전역 및 컨트랙트별 정책 검사를 모두 실행합니다. 모든 검사가 통과하면 저수준 call을 사용하여 대상 컨트랙트에서 제공된 호출 데이터를 실행합니다. 검사 중 하나라도 실패하면 트랜잭션이 해당 오류로 revert됩니다.
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
contractAddress | address | ✓ | PCL 검사가 통과한 후 호출할 대상 컨트랙트의 주소입니다. |
data | bytes | ✓ | 대상 컨트랙트에서 실행할 함수의 ABI 인코딩 콜데이터입니다. |
value | uint256 | ✓ | 호출과 함께 전달할 aokrw(기본 단위, 소수점 18자리) 금액입니다. 대상 컨트랙트에서 msg.value로 전달됩니다. |
반환값
타입:
bytes memory 대상 컨트랙트 호출이 성공적으로 실행되어 돌려준 반환 데이터입니다.
에러
| 코드 | 이름 | 설명 |
|---|---|---|
InDenylist | InDenylist | 발신자 주소가 활성 거부 목록 정책에 포함되어 있으면 revert됩니다. |
EasAttestationRequired | EasAttestationRequired | 발신자가 필요한 EAS 증명(예: KYC)이 없는 경우 revert됩니다. |
VolumeAboveMaxLimit | VolumeAboveMaxLimit | 트랜잭션 금액이 구성된 거래량 한도를 초과하면 revert됩니다. |
예제
ERC20 전송 래핑
이 예제는 public transfer 함수를 재정의하는 토큰 컨트랙트를 보여줍니다. 로직을 직접 실행하지 않고, address(this)(자기 자신)를 대상으로 자신의 internal 전송 로직을 인코딩한 콜데이터를 넘겨 runOnPcl을 호출합니다. 이렇게 하면 이 토큰에 등록된 PCL 검사를 통과해야만 전송이 일어나도록 강제할 수 있습니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IPcl } from "@maroo-chain/contracts/IPcl.sol";
contract CompliantToken is IERC20 {
IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);
// ... 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) {
bytes memory data = abi.encodeWithSelector(
this._transfer.selector,
msg.sender,
to,
amount
);
// Execute via PCL — this contract calls itself through the PCL gate.
PCL.runOnPcl(address(this), data, 0);
return true;
}
} 에러 처리를 포함한 다른 컨트랙트 호출
이 예제는 try/catch 블록으로 runOnPcl에서 발생할 수 있는 revert를 처리하는 방법을 보여줍니다. 특히 InDenylist 커스텀 에러를 식별해 더 사용자 친화적인 메시지를 보여줍니다.
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;
import { IPcl } from "@maroo-chain/contracts/IPcl.sol";
contract PclCaller {
IPcl constant PCL = IPcl(0x1000000000000000000000000000000000000005);
function callCompliantService(address service, uint256 value) external {
bytes memory data = abi.encodeWithSignature("deposit(uint256)", value);
try PCL.runOnPcl(service, data, 0) returns (bytes memory) {
// Success path
} catch (bytes memory reason) {
// bytes memory slicing isn't supported in Solidity — read the
// 4-byte error selector via assembly.
bytes4 selector;
assembly { selector := mload(add(reason, 32)) }
if (selector == IPcl.InDenylist.selector) {
// Strip the selector and decode the arg.
bytes memory args = new bytes(reason.length - 4);
for (uint i = 0; i < args.length; i++) args[i] = reason[i + 4];
address sender = abi.decode(args, (address));
revert("Caller is on the denylist");
}
// Bubble up unknown reverts.
revert(string(reason));
}
}
}