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)constl2NativeTokenContract=newethers.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 L1constdepositTx=awaitportals.depositTransaction({ to:l2Wallet.address, value:BigNumber.from(amount), gasLimit:BigNumber.from('200000'),// It will be greater than data.length * 16 + 21000 data:'0x',})constdepositReceipt=awaitdepositTx.wait()console.log('depositTx:',depositReceipt.transactionHash)
입금 확인: 입금이 성공적으로 처리되었는지 확인하기 위해 portals.waitingDepositTransactionRelayed 함수를 사용합니다. 이 함수는 트랜잭션이 L2에 도달하고 최종적으로 처리되었는지 확인 후 관련된 트랜잭션 해시를 반환합니다. getTransactionReceipt를 통해 입금이 올바르게 처리되었는지 확인합니다.
// get relayedTxHash in L2constrelayedTxHash=awaitportals.waitingDepositTransactionRelayed( depositReceipt, {})console.log('relayedTxHash:', relayedTxHash)constdepositedTxReceipt=awaitl2Provider.getTransactionReceipt( relayedTxHash)
출금 (Withdrawal)
출금 시작: 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)consttransferTx=awaitl2NativeTokenContract.transferFrom(l1Contracts.OptimismPortal,l1Wallet.address, amount)awaittransferTx.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에서 성공적으로 릴레이되었는지 확인합니다.