Thanos에서 Portal은 L1의 OptimismPortal 컨트랙트와 L2의 L2ToL1MessagePasser 컨트랙트를 사용하여 네트워크 간 자산의 입출금을 지원합니다. 단, Portal을 통해 전송할 수 있는 자산은 NativeToken으로 한정되며 CrossChainMessenger를 사용하는 것보다 더 낮은 가스비로 거래를 처리할 수 있습니다.
본 문서에서는 입금과 출금 시에 사용되는 Portal의 함수들을 살펴보고 Portal을 import하여 NativeToken을 L1과 L2 간에 입출금하는 방법을 예제를 통해 단계별로 설명합니다.
여기를 통해 Portal에 대한 자세한 코드를 확인할 수 있습니다. Thanos SDK를 활용하여 L1과 L2 간에 NativeToken을 입출금하는 예제 코드는 여기에서 확인할 수 있습니다.
생성자 (Constructor)
생성자는 CrossChainProvider 인스턴스를 초기화하는 데 필요한 정보를 설정합니다. 각 생성자는 L1과 L2 간의 상호작용을 원활하게 처리하기 위해 필수적인 요소들로 구성됩니다.
l1SignerOrProvider: L1과 상호작용하기 위한 서명자 또는 제공자
l2SignerOrProvider: L2와 상호작용하기 위한 서명자 또는 제공자
l1ChainId: L1 체인의 고유 식별자
l2ChainId: L2 체인의 고유 식별자
depositConfirmationBlocks: 입금이 확인되기까지 필요한 블록 수
l1BlockTimeSeconds: L1 체인의 블록 생성 시간 (초)
contracts: 오버라이드할 수 있는 특정 계약 주소
/**
* Creates a new CrossChainProvider instance.
*
* @param opts Options for the provider.
* @param opts.l1SignerOrProvider Signer or Provider for the L1 chain, or a JSON-RPC url.
* @param opts.l2SignerOrProvider Signer or Provider for the L2 chain, or a JSON-RPC url.
* @param opts.l1ChainId Chain ID for the L1 chain.
* @param opts.l2ChainId Chain ID for the L2 chain.
* @param opts.depositConfirmationBlocks Optional number of blocks before a deposit is confirmed.
* @param opts.l1BlockTimeSeconds Optional estimated block time in seconds for the L1 chain.
* @param opts.contracts Optional contract address overrides.
*/
constructor(opts: {
l1SignerOrProvider: SignerOrProviderLike
l2SignerOrProvider: SignerOrProviderLike
l1ChainId: NumberLike
l2ChainId: NumberLike
depositConfirmationBlocks?: NumberLike
l1BlockTimeSeconds?: NumberLike
contracts?: DeepPartial<OEContractsLike>
})
NativeToken 생성: L1에서 NativeToken 컨트랙트와 상호작용하기 위한 인스턴스를 생성합니다. 해당 인스턴스를 사용하여 이후 토큰의 승인 및 전송 작업을 수행할 수 있습니다. 컨트랙트의 주소와 ERC20 표준 ABI를 사용하여 NativeToken 컨트랙트 객체를 생성하며 이를 기반으로 OptimismPortal 컨트랙트와의 상호작용이 가능해집니다.
// NativeTokenContract in L1 (like TON)
const l2NativeTokenContract = new ethers.Contract(
l2NativeToken,
erc20ABI,
l1Wallet
)
사전 승인: L1에서 NativeToken을 입금하기 전, OptimismPortal 컨트랙트가 해당 토큰을 사용할 수 있도록 사전에 승인을 받아야 합니다. 이를 위해 approve 함수를 호출하여 지정된 수량만큼의 토큰을 OptimismPortal에서 처리할 수 있도록 허용합니다. 이 절차는 입금 과정에서 필수이며 승인 이후에 입금 트랜잭션이 성공적으로 진행됩니다.
입금 실행: portals.depositTransaction함수를 사용하여 L2로 NativeToken을 입금합니다. 이 과정에서 to, value, gasLimit, data와 같은 매개변수를 설정하여 트랜잭션을 실행합니다. 트랜잭션이 블록에 포함되면 depositReceipt을 통해 트랜잭션 해시를 확인할 수 있습니다.
to: 입금을 진행할 L2 주소
value: 입금 금액
gasLimit: 트랜잭션 실행 시 필요한 가스 한도 설정, data.length * 16 + 21000 보다 커야합니다.
data: 추가로 전달한 데이터 (기본 값은 0x)
// deposit NativeToken in L1
const depositTx = await portals.depositTransaction({
to: l2Wallet.address,
value: BigNumber.from(amount),
gasLimit: BigNumber.from('200000'), // It will be greater than data.length * 16 + 21000
data: '0x',
})
const depositReceipt = await depositTx.wait()
console.log('depositTx:', depositReceipt.transactionHash)
입금 확인: 입금이 성공적으로 처리되었는지 확인하기 위해 portals.waitingDepositTransactionRelayed 함수를 사용합니다. 이 함수는 트랜잭션이 L2에 도달하고 최종적으로 처리되었는지 확인 후 관련된 트랜잭션 해시를 반환합니다. getTransactionReceipt를 통해 입금이 올바르게 처리되었는지 확인합니다.
출금 시작: portals.initiateWithdrawal함수를 사용하여 L2에서 L1으로 출금을 시작합니다. 이 함수는 출금 트랜잭션을 생성하고 target, value, gasLimit, data와 같은 매개변수를 사용하여 출금을 요청합니다. withdrawalReceipt을 통해 트랜잭션이 완료될 때까지 대기합니다.
출금 증명: 출금 트랜잭션이 L2에서 L1으로 릴레이될 준비가 되었음을 확인한 후 portals.proveWithdrawalTransactionUsingL2Tx 함수를 통해 L2 트랜잭션 해시를 기반으로 출금 트랜잭션을 증명합니다. 이 단계에서는 출금 트랜잭션의 유효성을 확인하기 위해 증명 트랜잭션을 제출합니다.
출금 확정: portals.finalizeWithdrawalTransactionUsingL2Tx함수를 사용하여 L2 트랜잭션 해시를 기반으로 출금 트랜잭션을 확정합니다. 이 단계에서 출금 트랜잭션의 최종 처리가 완료되며 finalizedTransactionReceipt을 확인합니다.
토큰 전송: 출금이 확정된 후 OptimismPortal 컨트랙트를 이용하여 사용자의 지갑 주소로 토큰을 전송합니다. 이 과정은 확정된 출금 트랜잭션에 따라 L1으로 토큰을 전송하는 작업을 수행합니다.
// Transferfrom (after finalization, user have to transferFrom to get his token)
const transferTx = await l2NativeTokenContract.transferFrom(
l1Contracts.OptimismPortal,
l1Wallet.address,
amount
)
await transferTx.wait()
트랜잭션 상태 확인 (getMessageStatus)
getMessageStatus는 OptimismPortal 및 L2ToL1MessagePasser를 사용할 때 L1과 L2 간의 입출금 트랜잭션의 상태를 확인하는 데 사용됩니다.
OptimismPortal
트랜잭션 생성: portals.depositTransaction 함수를 사용하여 L1에서 L2로 NativeToken 입금 트랜잭션을 생성합니다.
릴레이 해시: 트랜잭션이 L1에서 성공적으로 처리한 후 해당 트랜잭션이 L2로 릴레이될 때까지 기다려야 합니다. portals.waitingDepositTransactionRelayed 함수를 사용하여 L1에서 제출된 트랜잭션이 L2에 성공적으로 릴레이되었는지 확인하고 relayedTxHash를 가져옵니다. 이 해시는 L2에서 발생한 트랜잭션을 추적하는 데 사용됩니다.
출금 트랜잭션 확정 및 상태 확인: portals.finalizeWithdrawalTransaction을 사용하여 출금 트랜잭션을 확정합니다. 이 과정은 트랜잭션이 성공적으로 완료되었음을 나타냅니다. 마지막으로 getMessageStatus를 호출하여 출금 트랜잭션이 L1에서 성공적으로 릴레이되었는지 확인합니다.