메인 콘텐츠로 건너뛰기
이 튜토리얼에서는 @eth-optimism/viem과 viem을 사용하여 L1(Ethereum 또는 Sepolia)과 L2(OP Mainnet 또는 OP Sepolia) 간에 ERC-20 토큰을 브리징하는 방법을 설명합니다. @eth-optimism/viem 및 viem 패키지를 사용하면 JavaScript 기반 애플리케이션에 브리징 기능을 쉽게 추가할 수 있습니다. 또한 토큰에 접근할 수 없게 만드는 일반적인 실수를 방지하기 위한 몇 가지 안전장치도 제공합니다. 내부적으로 @eth-optimism/viem 패키지는 Standard Bridge 컨트랙트를 사용하여 토큰을 전송합니다. bridge가 내부적으로 어떻게 동작하는지 자세히 알아보려면 Standard Bridge 가이드를 꼭 확인하십시오.
Standard Bridge는 bridge 회계 오류를 일으킬 수 있으므로 전송 수수료 토큰(fee on transfer tokens)이나 리베이싱 토큰(rebasing tokens)을 지원하지 않습니다.

지원되는 네트워크

Viem은 모든 OP Stack 네트워크를 지원합니다. 기본적으로 포함되지 않은 네트워크를 사용하려면 Viem의 체인 구성에 추가할 수 있습니다.

의존성

데모 프로젝트 생성

이 튜토리얼에서는 @eth-optimism/viem 라이브러리를 사용합니다. @eth-optimism/viem는 Node.js 라이브러리이므로, 이를 사용하려면 Node.js 프로젝트를 생성해야 합니다.
1

프로젝트 폴더 만들기

2

프로젝트 초기화

3

의존성 설치

Sepolia 및 OP Sepolia에서 ETH 받기

이 튜토리얼에서는 Sepolia에서 OP Sepolia로 토큰을 브리징하는 방법을 설명합니다. 두 testnet 모두에서 약간의 ETH가 필요합니다.

환경에 개인 키 추가

트랜잭션에 서명하려면 개인 키가 필요합니다. export 명령으로 개인 키를 환경 변수로 설정하십시오. 이 개인 키가 both Sepolia and OP Sepolia에서 ETH를 보유한 주소에 해당하는지 확인하십시오.
이 튜토리얼을 위해 새 지갑을 만들고 싶으신가요? cast가 설치되어 있다면 터미널에서 cast wallet new를 실행하여 새 지갑을 만들고 개인 키를 얻을 수 있습니다.

Node REPL 시작

Node REPL을 사용하여 @eth-optimism/viem와 상호작용합니다. Node REPL을 시작하려면 터미널에서 다음 명령을 실행하십시오.
그러면 JavaScript 코드를 실행할 수 있는 Node REPL 프롬프트가 열립니다.

의존성 가져오기

Node REPL 세션에 몇 가지 의존성을 가져와야 합니다. @eth-optimism/viem 패키지는 ESM 모듈을 사용하므로, Node.js REPL에서 사용하려면 await와 함께 동적 import를 사용해야 합니다. 방법은 다음과 같습니다.
1

@eth-optimism/viem 패키지 가져오기

세션 변수 설정

이 튜토리얼 전반에 걸쳐 몇 가지 변수가 필요합니다. 지금 설정해 보겠습니다.
1

개인 키 불러오기

이 단계에서는 앞서 설정한 환경 변수에서 개인 키를 가져와 Viem이 트랜잭션 서명에 사용할 수 있는 계정 객체로 변환합니다.개인 키는 L1 및 L2 네트워크 모두에서 트랜잭션을 승인하는 데 필수적입니다. 보안상의 이유로 하드코딩하지 않고 환경 변수에서 가져옵니다.
2

RPC provider 및 지갑 생성

여기서는 네 가지 클라이언트를 생성하여 두 네트워크에 대한 연결을 설정합니다.
  1. L1 Public Client: Sepolia 네트워크에서 데이터를 읽기 위한 클라이언트
  2. L1 Wallet Client: Sepolia에서 트랜잭션에 서명하고 전송하기 위한 클라이언트
  3. L2 Public Client: OP Sepolia에서 데이터를 읽기 위한 클라이언트
  4. L2 Wallet Client: OP Sepolia에서 트랜잭션에 서명하고 전송하기 위한 클라이언트
각 클라이언트는 적절한 체인 정보와 RPC 엔드포인트로 구성됩니다. 이러한 이중 네트워크 설정을 통해 동일한 계정으로 두 레이어와 원활하게 상호작용할 수 있습니다. <YOUR_API_KEY>를 RPC provider에서 발급받은 API 키로 바꾸십시오.
3

L1 및 L2 ERC-20 주소 설정

두 네트워크에 있는 ERC-20 토큰의 주소를 정의합니다. 이 토큰들은 L1(Sepolia)과 L2(OP Sepolia) 모두에 대응하는 구현이 있도록 특별히 배포된 테스트 토큰입니다.L2 토큰은 L1 대응 토큰으로부터의 입금(디파짓)을 인식하도록 구성되어 있습니다. 또한 입금 및 출금 작업을 단순화하기 위해 전체 단위(10^18 wei)를 나타내는 상수 oneToken을 정의합니다.
Standard Bridge용 L2 토큰 생성 튜토리얼에서 넘어왔다면 여기에 직접 만든 ERC-20 토큰의 주소를 대신 사용할 수 있습니다.

L1 토큰 받기

L2로 브리징할 수 있는 L1 토큰이 필요합니다. 0x5589BB8228C07c4e15558875fAf2B859f678d129에 있는 L1 테스트 토큰에는 토큰을 쉽게 받을 수 있는 faucet 함수가 있습니다.
1

ERC20 ABI 설정

ABI(Application Binary Interface)는 스마트 컨트랙트 함수와 상호작용하는 방법을 정의합니다. 이 ERC-20 ABI에는 다음과 같은 몇 가지 중요한 함수가 포함되어 있습니다.
  • balanceOf: 임의의 주소에 대한 토큰 잔액을 확인할 수 있습니다
  • faucet: 이 테스트 토큰에 있는 특수 함수로, 호출자에게 새 토큰을 발행합니다
  • approve: bridge가 사용자를 대신하여 토큰을 전송할 수 있도록 권한을 부여하는 데 필요합니다
  • allowance: bridge에 승인한 토큰 수량을 확인합니다
  • decimals 및 symbol: 토큰 메타데이터를 제공합니다
이 포괄적인 ABI는 L1과 L2 모두에서 토큰을 관리하는 데 필요한 모든 것을 제공합니다.
2

토큰 요청

이제 L1 테스트 토큰 컨트랙트의 faucet 함수를 호출하여 테스트용 무료 토큰을 받습니다. 이 트랜잭션은 지갑 주소로 새 토큰을 직접 발행합니다.이 함수는 매개변수가 필요하지 않으며, 호출한 사람에게 미리 정해진 수량을 지급합니다. 나중에 참조할 수 있도록 트랜잭션 해시를 저장하고 트랜잭션이 확인될 때까지 기다립니다.
3

토큰 잔액 확인

faucet을 사용한 후 L1 토큰 컨트랙트의 balanceOf 함수를 호출하여 토큰 잔액을 확인합니다.이 단계는 브리징 과정을 진행하기 전에 토큰을 성공적으로 받았는지 확인합니다. 잔액은 가장 작은 단위(wei)로 반환되지만, 이 토큰은 소수점 18자리를 사용하므로 viem의 formatEther 유틸리티 함수를 사용하여 더 읽기 쉬운 형태로 변환합니다.

토큰 입금하기

이제 L1에 토큰이 있으므로 해당 토큰을 L1StandardBridge 컨트랙트에 입금할 수 있습니다. 그러면 그 대가로 L2에서 같은 수량의 토큰을 받게 됩니다.
1

입금할 수량 정의

기본 단위(wei)로 1개의 전체 토큰을 나타내는 변수 oneToken을 정의합니다. ERC-20 토큰은 일반적으로 소수점 18자리를 사용하므로 1 토큰은 10^18 wei와 같습니다.이 상수를 사용하면 트랜잭션에서 정확한 토큰 수량을 다룰 수 있어 반올림 오류를 피하고 정확한 값을 전송할 수 있습니다. 이 값은 입금과 출금 모두에 사용합니다.
2

Standard Bridge가 토큰에 접근하도록 허용

ERC-20 토큰은 사용자를 대신하여 토큰을 전송하려면 2단계 과정이 필요합니다. 먼저 토큰 컨트랙트의 approve 함수를 호출하여 bridge 컨트랙트가 토큰을 사용할 수 있도록 권한을 부여해야 합니다.체인 구성에서 가져온 bridge 주소와 브리징하려는 정확한 수량을 지정합니다. bridge가 토큰을 이동하려면 먼저 이 승인 트랜잭션이 확인되어야 합니다.
3

승인 대기

승인 트랜잭션을 제출한 후 L1에서 확인될 때까지 기다려야 합니다. waitForTransactionReceipt 함수를 사용하여 트랜잭션이 블록에 포함될 때까지 모니터링합니다.영수증(receipt)은 트랜잭션이 포함된 블록 등 확인 세부 정보를 제공합니다. 이 단계를 통해 토큰을 브리징하기 전에 승인이 확정되었는지 확인합니다.
4

토큰 입금

이제 @eth-optimism/viem 패키지의 depositERC20 함수를 사용하여 실제 브리징 작업을 실행할 수 있습니다.이 함수는 L1StandardBridge 컨트랙트와의 모든 복잡한 상호작용을 대신 처리합니다. 다음을 제공합니다.
  • L1 및 L2 토큰의 주소
  • 브리징할 수량
  • 대상 체인(OP Sepolia)
  • L2에서의 수신자로서 지갑 주소
  • L2 트랜잭션의 최소 gas 한도
이 간소화된 과정을 통해 토큰이 L2로 안전하게 전송됩니다.
스마트 컨트랙트 지갑을 사용하고 있습니까? 안전 조치로서, recipient를 지정하지 않고 스마트 컨트랙트 지갑에서 ETH를 입금하려고 하면 depositERC20이 실패합니다. 이 문제를 해결하려면 depositERC20 호출에 recipient 옵션을 추가하십시오. depositERC20에 전달할 수 있는 옵션에 대한 자세한 내용은 @eth-optimism/viem 문서를 확인하십시오.
5

입금이 릴레이될 때까지 대기

입금을 시작한 후 L1 트랜잭션이 확인될 때까지 기다려야 합니다. 이 함수는 트랜잭션이 L1 블록에 포함될 때까지 추적합니다.이를 통해 L1에서 입금이 수락되었음을 확인할 수 있지만, 트랜잭션이 Optimism sequencer에 의해 처리되어야 하므로 토큰이 L2에 표시되기까지 약간의 지연(일반적으로 몇 분)이 여전히 있다는 점에 유의하십시오.
6

L1에서 토큰 잔액 확인

입금 트랜잭션이 확인된 후 L1에서 토큰 잔액을 다시 확인하여 토큰이 차감되었는지 확인합니다.해당 토큰은 이제 L1StandardBridge 컨트랙트에 에스크로되어 있으므로, 잔액은 브리징한 수량만큼 줄어들어야 합니다. 이 단계는 브리징 과정의 첫 번째 부분이 성공적으로 완료되었는지 확인하는 데 도움이 됩니다.
7

L2에서 토큰 잔액 확인

L2 트랜잭션이 처리될 때까지 잠시 기다린 후 L2에서 토큰 잔액을 확인하여 브리징된 토큰을 받았는지 확인합니다.새로 발행된 L2 토큰은 L1에서 사용한 것과 동일한 주소의 지갑에 표시되어야 합니다. 이 단계는 L1에서 L2로의 bridge 작업이 완전히 성공했음을 확인합니다.

토큰 출금하기

방금 L1에서 L2로 토큰을 브리징했습니다. 잘하셨습니다! 이제 과정을 반대로 반복하여 L2에서 L1로 토큰을 브리징합니다.
1

출금 시작

토큰을 L1으로 다시 옮기려면 @eth-optimism/viem 패키지의 withdrawOptimismERC20 함수를 사용합니다. 이 함수는 L2StandardBridge 컨트랙트와 상호작용하여 출금 과정을 시작합니다. 다음을 지정합니다.
  • L2 토큰 주소
  • 출금할 수량(이 튜토리얼에서는 토큰 절반을 사용합니다)
  • L1에서의 수신자로서 사용자 주소
  • 트랜잭션의 최소 gas 한도
입금과 달리 L2에서 L1으로의 출금은 즉시 이루어지지 않으며, 보안상의 이유로 7일간의 챌린지 기간을 포함한 여러 단계의 과정이 필요합니다.
2

트랜잭션 영수증 대기

입금과 마찬가지로 출금 트랜잭션이 L2에서 확인될 때까지 기다립니다. 이 영수증은 출금이 시작되었음을 확인해 줍니다.트랜잭션 로그에는 이후 출금 검증 과정에서 사용될 중요한 정보가 담겨 있습니다. 이것은 출금의 첫 번째 단계일 뿐이며, 토큰은 이제 L2에서 잠겨 있지만 아직 L1에서 사용할 수는 없습니다.
이 단계는 몇 분 정도 걸릴 수 있습니다. 기다리는 동안 잠시 쉬어도 좋습니다.
3

L2에서 토큰 잔액 확인

출금 트랜잭션이 확인된 후 L2에서 토큰 잔액을 다시 확인하여 토큰이 차감되었는지 확인합니다. 이제 L2 잔액은 출금을 시작한 수량만큼 줄어들어야 합니다.이 시점에서 출금 과정은 시작되었지만 토큰은 아직 L1에서 사용할 수 없습니다. “증명(prove)” 및 “최종 확정(finalize)” 출금 단계를 계속 진행하려면 ETH 출금을 참조하십시오.

다음 단계

축하합니다! 방금 @eth-optimism/viem 패키지를 사용하여 토큰을 입금하고 출금했습니다. 이제 @eth-optimism/viem 패키지를 사용하여 L1과 L2 간에 ERC-20 토큰을 전송하는 애플리케이션을 작성할 수 있을 것입니다. 이 튜토리얼에서는 Sepolia와 OP Sepolia를 사용했지만, Ethereum과 OP Mainnet에서도 동일한 과정이 적용됩니다.