runOnPcl로 컴플라이언스 검사를 시뮬레이션하는 방법

integration intermediate

PCL의 runOnPcl 함수를 사용하여 사전 트랜잭션 검사를 수행하고, dApp 사용자 경험을 개선하며, 가스 낭비를 방지하는 방법에 대한 집중 가이드입니다.

사전 요구사항

  • 함수 콜데이터 인코딩 방법을 알고 있을 것.
  • Ethers.js 또는 유사 라이브러리로 클라이언트 측을 설정해 둔 상태입니다.

1. 목표: 사전 검사

사용자가 규제된 토큰을 대량으로 전송하려는 상황을 가정해 봅시다. 트랜잭션을 제출했는데 PCL 정책(예: 전송 한도)으로 실패하면, 가스는 그대로 소비됩니다. 이는 사용자 경험을 해칩니다. 따라서 runOnPcl로 트랜잭션을 먼저 확인하고 즉시 피드백을 제공해, 자금을 낭비하지 않고도 금액을 조정하거나 작업을 중단할 수 있게 합니다.

2. 계약 설정

클라이언트 측 코드에는 두 개의 계약 인스턴스가 필요합니다. 하나는 PCL 프리컴파일용, 다른 하나는 상호작용할 대상 계약(예: ERC20 토큰)용입니다.
import { ethers } from 'ethers';
import PCL_ABI from './PclAbi.json';
import TOKEN_ABI from './TokenAbi.json';

const PCL_ADDRESS = '0x1000000000000000000000000000000000000005';
const TOKEN_ADDRESS = '0x...'; // 정책이 적용된 토큰의 주소

// 'provider'가 ethers Provider 인스턴스라고 가정
const pclContract = new ethers.Contract(PCL_ADDRESS, PCL_ABI, provider);
const tokenContract = new ethers.Contract(TOKEN_ADDRESS, TOKEN_ABI, provider);

3. 트랜잭션 콜데이터 인코딩

runOnPcl의 두 번째 인수는 시뮬레이션하려는 함수에 대한 인코딩된 data입니다. 이는 계약의 인터페이스 객체에서 얻을 수 있습니다.
const recipient = '0x...';
const amount = ethers.parseEther('50000'); // 실패할 수 있는 금액

const calldata = tokenContract.interface.encodeFunctionData('transfer', [
  recipient,
  amount
]);

// calldata는 '0xa9059cbb0000...'과 같은 16진수 문자열이 됩니다.

4. 정적 호출 수행

트랜잭션을 시뮬레이션하기 위해 정적 호출을 사용합니다. 정적 호출은 트랜잭션을 생성하거나 상태를 변경하지 않고 노드에서 함수를 실행합니다. PCL 정책은 발신자를 기준으로 평가되므로 호출 옵션에 from 주소를 반드시 전달해야 합니다.
// ethers v6 — v5의 contract.callStatic.x(...) 대신 메서드의 .staticCall 호출
async function isTransferAllowed(userAddress, tokenAddress, calldata) {
  try {
    await pclContract.runOnPcl.staticCall(
      tokenAddress,
      calldata,
      0n, // 호출의 'value', ERC20 전송은 0
      { from: userAddress } // 가장 중요한 부분!
    );
    console.log('시뮬레이션 통과. 트랜잭션이 허용됩니다.');
    return true;
  } catch (error) {
    console.error('시뮬레이션 실패. 트랜잭션이 차단됩니다.');
    // PCL 커스텀 에러는 error.data에 ABI 인코딩됨; IPcl ABI로 디코드.
    if (error.data) {
        console.error('Revert 사유:', error.data);
    }
    return false;
  }
}

// 사용법:
isTransferAllowed(user.address, TOKEN_ADDRESS, calldata);
참고: `<method>.staticCall(...)` (ethers v6) 또는 JSON-RPC `eth_call` 사용합니다. ethers v5의 `contract.callStatic.x(...)`는 v6에서 제거되었으므로, 신규 dApp은 v6 형식을 사용합니다.
소스: maroo
ESC
검색어를 입력하세요