> ## Documentation Index
> Fetch the complete documentation index at: https://docs.optimism.io/llms.txt
> Use this file to discover all available pages before exploring further.

# proposer 실행하기

> L2 상태 루트를 게시하도록 OP Stack proposer를 설정하고 구성하는 방법을 알아봅니다.

sequencer와 batcher를 실행한 후에는 L2 상태 루트 데이터를 L1에 다시 게시하는 proposer를 연결해야 합니다. 이를 통해 출금의 유효성을 증명할 수 있습니다. proposer는 신뢰가 필요 없는(trustless) L2-L1 메시징을 가능하게 하고, L1 관점에서 L2 상태에 대한 권위 있는 뷰를 생성하는 핵심 구성 요소입니다.

> [!NOTE]
>
> **5단계 중 4단계**: 이 튜토리얼은 단계별로 따라 하도록 구성되어 있습니다. 각 단계는 이전 단계를 기반으로 합니다.

> [!NOTE]
>
> **자동화된 설정 제공**
>
> 모든 구성 요소가 포함된 완전한 작동 설정은 코드 디렉터리의 [자동화된 방식](https://github.com/ethereum-optimism/optimism/tree/develop/docs/public-docs/create-l2-rollup-example/)을 확인하십시오.

이 가이드는 정상적으로 작동하는 sequencer와 batcher가 이미 있고, [`op-deployer`](./op-deployer-setup)를 사용하여 필요한 L1 컨트랙트를 배포했다고 가정합니다. 아직 sequencer와 batcher를 설정하지 않았다면 먼저 [sequencer 가이드](https://docs.optimism.io/ko/chain-operators/tutorials/create-l2-rollup/op-reth-setup.md)와 [batcher 가이드](https://docs.optimism.io/ko/chain-operators/tutorials/create-l2-rollup/op-batcher-setup.md)를 참조하십시오.

proposer의 구성 정보는 [구성 페이지](https://docs.optimism.io/ko/chain-operators/guides/configuration/proposer.md)를 확인하십시오.

## proposer의 역할 이해하기

proposer(`op-proposer`)는 L2 체인과 L1 사이를 잇는 중요한 다리 역할을 합니다. 주요 책임은 다음과 같습니다.

* **상태 커밋먼트**: 일정한 간격으로 L2 상태 루트를 L1에 제안합니다
* **출금 지원**: 사용자가 출금을 증명하고 최종 확정하는 데 필요한 커밋먼트를 제공합니다

proposer는 `DisputeGameFactory` 컨트랙트를 통해 분쟁 게임(dispute game)을 생성합니다.

## 사전 요구 사항

proposer를 설정하기 전에 다음을 준비했는지 확인하십시오.

**실행 중인 인프라:**

* 작동 중인 sequencer node
* L1 RPC 엔드포인트에 대한 접근 권한

**네트워크 정보:**

* L2 체인 ID 및 네트워크 구성
* L1 네트워크 세부 정보(체인 ID, RPC 엔드포인트)

proposer를 설정할 때는 일관되고 격리된 환경을 제공하는 Docker 사용을 권장합니다. 소스에서 빌드하는 방법도 선택할 수 있습니다.

> [tab] Docker 사용
>
> 컨테이너 기반 배포를 선호한다면 공식 Docker 이미지를 사용하여 다음과 같이 진행할 수 있습니다.
>
> **1. 디렉터리 구조 설정 및 구성 파일 복사**
>
> ```bash theme={null}
> # Create a proposer directory inside rollup
> cd ../    # Go back to rollup directory if you're in batcher
> mkdir proposer
> cd proposer
> # inside the proposer directory, copy the state.json file from the op-deployer setup
> # Copy configuration files from deployer
> cp ../deployer/.deployer/state.json .
>
> # Extract the DisputeGameFactory address
> GAME_FACTORY_ADDRESS=$(cat state.json | jq -r '.opChainDeployments[0].DisputeGameFactoryProxy')
> echo "DisputeGameFactory Address: $GAME_FACTORY_ADDRESS"
> ```
>
> **2. 환경 변수 파일 생성**
>
> > [!NOTE]
> >
> > **OP Stack 표준 변수**
> >
> > proposer는 OP Stack 규칙을 따르는 OP Stack 표준 환경 변수를 사용합니다. proposer 전용 설정에는 `OP_PROPOSER_` 접두사가 붙습니다.
>
> ```bash theme={null}
> # Create .env file with your actual values
> cat > .env << 'EOF'
> #  L1 Configuration - Replace with your actual RPC URLs
> OP_PROPOSER_L1_RPC_URL=https://sepolia.infura.io/v3/YOUR_ACTUAL_INFURA_KEY
>
> # L2 Configuration - Should match your sequencer setup
> OP_PROPOSER_ROLLUP_RPC=http://op-node:8547
>
> # Contract addresses - Extract from your op-deployer output
> OP_PROPOSER_GAME_FACTORY_ADDRESS=YOUR_ACTUAL_GAME_FACTORY_ADDRESS
>
> # Private key - Replace with your actual private key
> OP_PROPOSER_PRIVATE_KEY=YOUR_ACTUAL_PRIVATE_KEY
>
> # OP Stack proposer configuration (optional - defaults provided)
> OP_PROPOSER_PROPOSAL_INTERVAL=3600s
> OP_PROPOSER_GAME_TYPE=0
> OP_PROPOSER_POLL_INTERVAL=20s
> OP_PROPOSER_ALLOW_NON_FINALIZED=true
> OP_PROPOSER_WAIT_NODE_SYNC=true
> EOF
> ```
>
> **중요**: 모든 플레이스홀더 값(`YOUR_ACTUAL_*`)을 실제 구성 값으로 바꾸십시오.
>
> **3. docker-compose.yml 생성**
>
> > [!NOTE]
> >
> > "failed to dial address" 오류가 발생하면 proposer가 sequencer와 동일한 Docker 네트워크에 있는지 확인하십시오.
> >
> > 일반적인 해결 방법:
> >
> > * proposer의 docker-compose.yml에 `networks: - sequencer-node_default`를 추가합니다
> > * `.env` 파일에서 `op-reth:8545`, `op-node:8547`과 같은 서비스 이름을 사용합니다
> > * `docker network ls`로 sequencer 네트워크 이름을 확인합니다
>
> ```yaml theme={null}
>
> services:
>   op-proposer:
>     image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-proposer:v1.16.3
>     volumes:
>       - .:/workspace
>     working_dir: /workspace
>     ports:
>       - "8560:8560"
>     env_file:
>       - .env
>     command: >
>       op-proposer
>       --rpc.port=8560
>       --log.level=info
>       --log.format=json
>     restart: unless-stopped
>     networks:
>       - sequencer-node_default
>
> networks:
>   sequencer-node_default:
>     external: false
>
> ```
>
> **4. proposer 서비스 시작**
>
> ```bash theme={null}
> # Make sure your sequencer network exists
> docker network create op-stack 2>/dev/null || true
>
> # Start the proposer
> docker-compose up -d
>
> # View logs
> docker-compose logs -f op-proposer
> ```
>
> **5. proposer 실행 확인**
>
> ```bash theme={null}
> # Check container status
> docker-compose ps
> ```
>
> **6. 최종 디렉터리 구조**
>
> ```bash theme={null}
> rollup/
> ├── deployer/            # From previous step
> │   └── .deployer/      # Contains state.json
> ├── sequencer/          # From previous step
> ├── batcher/           # From previous step
> └── proposer/         # You are here
>     ├── state.json    # Copied from deployer
>     ├── .env          # Environment variables
>     └── docker-compose.yml # Docker configuration
> ```
>
> > [accordion] proposer 시작 로그 이해하기
> >
> > proposer를 처음 시작하면 여러 유형의 로그 메시지가 표시됩니다.
> >
> > 1. **초기화 메시지**(정상):
> >    ```
> >    lvl=info msg="Initializing L2Output Submitter"
> >    lvl=info msg="Connected to DisputeGameFactory"
> >    lvl=info msg="Starting JSON-RPC server"
> >    ```
> >
> > 2. **동기화 상태 메시지**(시작 중 예상되는 메시지):
> >    ```
> >    msg="rollup current L1 block still behind target, retrying"
> >    current_l1=...:9094035 target_l1=9132815
> >    ```
> >    이는 정상입니다. 의미는 다음과 같습니다.
> >    * rollup이 아직 L1(예: Sepolia)과 동기화 중입니다
> >    * proposer는 동기화가 L1 최신 블록(tip)에 가까워질 때까지 대기합니다
> >    * 따라잡는 동안 `current_l1` 숫자가 증가하는 것을 확인할 수 있습니다
> >    * 따라잡고 나면 proposer가 제안 제출을 시작합니다
> >
> > "retrying" 메시지는 걱정하지 않아도 됩니다. 이는 rollup이 최신 L1 블록을 따라잡으며 정상적으로 진행되고 있음을 보여 줍니다.
> >
> > **일반적인 로그 패턴:**
> >
> > * 시작: 서비스가 시작되면서 초기화 메시지가 표시됩니다
> > * 동기화: 따라잡는 동안 "block still behind target" 메시지가 표시됩니다
> > * 정상 작동: 동기화가 완료되면 정기적으로 제안이 제출됩니다
> > * 네트워크: L1/L2 엔드포인트에 대한 연결 메시지가 표시됩니다
> >
> > "failed to dial" 오류나 연결 문제가 표시되는 경우:
> >
> > * 소스 빌드의 경우: localhost 포트와 서비스를 확인하십시오
>
> 이제 proposer가 작동하며 상태 루트를 L1에 지속적으로 제출합니다!

> [tab] 소스에서 빌드
>
> ### 현재 안정 릴리스 찾기
>
> 호환되는 최신 버전의 OP Stack 구성 요소를 사용하려면 항상 공식 [릴리스 페이지](https://github.com/ethereum-optimism/optimism/releases)를 확인하십시오.
>
> sequencer 설정과 호환되는 최신 `op-proposer/v*` 릴리스를 찾으십시오.
>
> > [!NOTE]
> >
> > 이 가이드는 작성 시점의 최신 릴리스인 `op-proposer/v1.16.3`을 sequencer 설정의 op-node/v1.19.3 및 op-reth/v2.4.0과 함께 사용합니다.
> > 호환성 정보는 항상 [릴리스 노트](https://github.com/ethereum-optimism/optimism/releases)를 확인하십시오.
>
> 소스에서 빌드하면 바이너리를 완전히 제어할 수 있습니다.
>
> **1. op-proposer 클론 및 빌드**
>
> ```bash theme={null}
> # If you don't already have the optimism repository from the sequencer setup
> git clone https://github.com/ethereum-optimism/optimism.git
> cd optimism
>
> # Checkout the latest release tag
> git checkout op-proposer/v1.16.3
>
> # Build op-proposer
> cd op-proposer
> just
>
> # Binary will be available at ./bin/op-proposer
> ```
>
> **2. 설치 확인**
>
> 다음 명령을 실행하여 설치를 확인합니다.
>
> ```bash theme={null}
> ./bin/op-proposer --version
> ```
>
> ## 구성 설정
>
> > [!NOTE]
> >
> > 이 가이드의 나머지 부분은 **소스에서 빌드** 방식을 사용한다고 가정합니다.
> > Docker를 선택했다면 필요한 모든 구성은 위의 Docker 탭에서 다루었습니다.
>
> **1. 작업 공간 정리**
>
> sequencer와 같은 수준에 proposer 작업 디렉터리를 생성합니다.
>
> ```bash theme={null}
> # Create proposer directory inside rollup
> cd ../    # Go back to rollup directory
> mkdir proposer
> cd proposer
>
> # Create scripts directory
> mkdir scripts
> ```
>
> **2. DisputeGameFactory 주소 추출**
>
> op-deployer 출력에서 `DisputeGameFactory` 컨트랙트 주소를 추출합니다.
>
> ```bash theme={null}
> # Make sure you're in the rollup/proposer directory
> cd rollup/proposer
>
> # Copy the state.json from deployer
> cp ../deployer/.deployer/state.json .
>
> # Extract the DisputeGameFactory address
> GAME_FACTORY_ADDRESS=$(cat state.json | jq -r '.opChainDeployments[0].disputeGameFactoryProxyAddress')
> echo "DisputeGameFactory Address: $GAME_FACTORY_ADDRESS"
> ```
>
> > [!NOTE]
> >
> > proposer가 제안을 제출하는 데 필요한 것은 `DisputeGameFactory` 주소뿐입니다.
> > `GAME_TYPE=0`은 표준 결함 증명(fault proof) 게임 유형을 나타냅니다.
>
> **3. 환경 변수 설정**
>
> 실제 값으로 `.env` 파일을 생성합니다.
>
> ```bash theme={null}
> # Create .env file with your actual values
> # L1 Configuration - Replace with your actual RPC URL
> L1_RPC_URL=https://sepolia.infura.io/v3/YOUR_ACTUAL_INFURA_KEY
>
> # L2 Configuration - Should match your sequencer setup
>       L2_RPC_URL=http://localhost:8545
>     ROLLUP_RPC_URL=http://localhost:8547
>
> # Contract addresses - Extract from your op-deployer output
> GAME_FACTORY_ADDRESS=YOUR_ACTUAL_GAME_FACTORY_ADDRESS
>
> # Private key - Replace with your actual private key
> PRIVATE_KEY=YOUR_ACTUAL_PRIVATE_KEY
>
> # Proposer configuration
> PROPOSAL_INTERVAL=3600s
> GAME_TYPE=0
> POLL_INTERVAL=20s
>
> # RPC configuration
> PROPOSER_RPC_PORT=8560
> ```
>
> **중요**: 모든 플레이스홀더 값(`YOUR_ACTUAL_*`)을 실제 구성 값으로 바꾸십시오!
>
> **4. 개인 키 준비**
>
> L1에 제안을 제출하는 데 사용할 개인 키를 지갑에서 가져옵니다. 이 계정에는 L1 gas 비용을 지불할 충분한 ETH가 있어야 합니다.
>
> > [!NOTE]
> >
> > proposer 계정에는 제안 제출 트랜잭션 비용을 지불하기 위해 L1의 ETH가 충전되어 있어야 합니다. 제안을 제출할 때마다 ETH가 소모되므로 이 계정의 잔액을 정기적으로 모니터링하십시오.
>
> ## proposer 구성
>
> `scripts/start-proposer.sh`를 생성합니다.
>
> ```bash theme={null}
> #!/bin/bash
>
> source .env
>
> # Path to the op-proposer binary we built
> ../../optimism/op-proposer/bin/op-proposer \
>   --poll-interval=$POLL_INTERVAL \
>   --rpc.port=$PROPOSER_RPC_PORT \
>   --rpc.enable-admin \
>   --rollup-rpc=$ROLLUP_RPC_URL \
>   --l1-eth-rpc=$L1_RPC_URL \
>   --private-key=$PRIVATE_KEY \
>   --game-factory-address=$GAME_FACTORY_ADDRESS \
>   --game-type=$GAME_TYPE \
>   --proposal-interval=$PROPOSAL_INTERVAL \
>   --num-confirmations=1 \
>   --resubmission-timeout=30s \
>   --wait-node-sync=true \
>   --log.level=info
> ```
>
> 최종 디렉터리 구조는 다음과 같아야 합니다.
>
> ```bash theme={null}
> rollup/
> ├── deployer/              # From previous step
> │   └── .deployer/        # Contains state.json
> ├── optimism/             # Contains op-proposer binary
> ├── sequencer/           # From previous step
> ├── batcher/            # From previous step
> └── proposer/          # You are here
>     ├── state.json     # Copied from deployer
>     ├── .env          # Environment variables
>     └── scripts/      # Startup scripts
>         └── start-proposer.sh
> ```
>
> ## proposer 시작하기
>
> **1. proposer 시작**
>
> ```bash theme={null}
> # Make the script executable
> chmod +x scripts/start-proposer.sh
>
> # Start the proposer
> ./scripts/start-proposer.sh
> ```
>
> > [accordion] proposer 시작 로그 이해하기
> >
> > proposer를 처음 시작하면 여러 유형의 로그 메시지가 표시됩니다.
> >
> > 1. **초기화 메시지**(정상):
> >    ```
> >    lvl=info msg="Initializing L2Output Submitter"
> >    lvl=info msg="Connected to DisputeGameFactory"
> >    lvl=info msg="Starting JSON-RPC server"
> >    ```
> >
> > 2. **동기화 상태 메시지**(시작 중 예상되는 메시지):
> >    ```
> >    msg="rollup current L1 block still behind target, retrying"
> >    current_l1=...:9094035 target_l1=9132815
> >    ```
> >    이는 정상입니다. 의미는 다음과 같습니다.
> >    * rollup이 아직 L1(예: Sepolia)과 동기화 중입니다
> >    * proposer는 동기화가 L1 최신 블록(tip)에 가까워질 때까지 대기합니다
> >    * 따라잡는 동안 `current_l1` 숫자가 증가하는 것을 확인할 수 있습니다
> >    * 따라잡고 나면 proposer가 제안 제출을 시작합니다
> >
> > "retrying" 메시지는 걱정하지 않아도 됩니다. 이는 rollup이 최신 L1 블록을 따라잡으며 정상적으로 진행되고 있음을 보여 줍니다.
> >
> > **일반적인 로그 패턴:**
> >
> > * 시작: 서비스가 시작되면서 초기화 메시지가 표시됩니다
> > * 동기화: 따라잡는 동안 "block still behind target" 메시지가 표시됩니다
> > * 정상 작동: 동기화가 완료되면 정기적으로 제안이 제출됩니다
> > * 네트워크: L1/L2 엔드포인트에 대한 연결 메시지가 표시됩니다
> >
> > "failed to dial" 오류나 연결 문제가 표시되는 경우:
> >
> > * Docker의 경우: 네트워크 구성과 서비스 이름을 확인하십시오
>
> 이제 proposer가 작동합니다!

## 다음 단계

잘하셨습니다! proposer가 상태 루트를 L1에 제출하고 있습니다. 마지막 단계는 분쟁을 모니터링하고 대응하는 challenger를 설정하는 것입니다.

> [card] [challenger 실행하기 →](https://docs.optimism.io/ko/chain-operators/tutorials/create-l2-rollup/op-challenger-setup.md)
>
> **다음**: 분쟁을 모니터링하고 rollup의 보안을 유지하도록 op-challenger를 구성하고 시작합니다.

***

## 도움이 필요하신가요?

* **proposer 구성**: [op-proposer 구성 레퍼런스](https://docs.optimism.io/ko/chain-operators/guides/configuration/proposer.md)
* **분쟁 게임**: [OPCM으로 분쟁 게임 배포하기](https://docs.optimism.io/ko/chain-operators/tutorials/dispute-games.md)
