> ## 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.

# OP Stack에서 permissionless 결함 증명으로 마이그레이션하기

> OP Stack 체인을 permissioned 결함 증명에서 permissionless 결함 증명으로 마이그레이션합니다. 분쟁 구성 요소를 구성하고, OPCM으로 컨트랙트를 배포하고, 오프체인 에이전트를 테스트한 다음, respected game type을 전환합니다.

이 가이드는 OP Stack 체인을 permissioned 결함 증명(fault proof)에서 permissionless 결함 증명으로 전환하는 방법을 보여 줍니다.
체인 운영자를 위해 네 가지 마이그레이션 단계, 즉 분쟁 구성 요소 구성, OPCM을 사용한 스마트 컨트랙트 배포, 오프체인 에이전트 테스트, respected game type 전환을 차례로 안내합니다.

## 개요

OP Stack 아키텍처는 결함 증명을 사용하여 L2에서 L1으로의 출금이 유효한지 보장합니다.
permissioned 증명에서 permissionless 증명으로 전환하는 것은 중요한 보안 업그레이드로, 모든 참여자가 상태 output root를 제안하고 이의를 제기할 수 있게 됩니다.
기존 permissioned 게임은 신뢰할 수 있는 단일 검증자에 의존했습니다. 이 검증자는 일반적으로 PermissionedDisputeGame에 구성된 proposer이며, 대개 네트워크의 유일한 sequencer입니다.

이 마이그레이션에는 다음과 같은 주요 구성 요소가 포함됩니다.

* 보안상 중요한 분쟁 [모니터링 서비스](https://docs.optimism.io/ko/chain-operators/tools/chain-monitoring.md) 구성
* [op-deployer](https://docs.optimism.io/ko/chain-operators/tools/op-deployer/overview.md)를 사용한 스마트 컨트랙트 배포 및 구성
* 활성화 전 새 시스템 테스트
* respected game type을 permissionless 결함 증명, 구체적으로 [`FaultDisputeGame`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/dispute/FaultDisputeGame.sol)으로 설정

## 사전 요구 사항

이 전환을 시작하기 전에 체인은 다음 조건을 갖추어야 합니다.

* 표준 OP Stack 구현을 실행하고 있어야 합니다.
* 최신 컨트랙트 버전 사용을 권장하며, 최소 요구 버전은 [**v5.0.0**](https://github.com/ethereum-optimism/optimism/releases/tag/op-contracts%2Fv5.0.0)입니다.
* [`op-challenger`](https://docs.optimism.io/ko/op-stack/fault-proofs/challenger)와 [`op-dispute-mon`](https://docs.optimism.io/ko/chain-operators/tools/chain-monitoring#dispute-mon)을 포함한 필수 인프라 서비스를 운영하고 있어야 합니다.

## 마이그레이션 단계

permissioned 결함 증명에서 permissionless 결함 증명으로 마이그레이션하는 과정은 네 가지 주요 단계로 구성됩니다. 오프체인 분쟁 구성 요소 구성, 필요한 스마트 컨트랙트 배포, 시스템의 철저한 테스트, 마지막으로 체인이 permissionless 증명을 사용하도록 전환하는 단계입니다. 각 단계는 이전 단계를 기반으로 하여 원활하고 안전한 전환을 보장합니다.

먼저 새 permissionless 게임과 상호작용할 분쟁 구성 요소를 구성하는 것부터 시작하겠습니다.

## 1. 분쟁 구성 요소 구성

`op-challenger`와 `op-dispute-mon` 서비스는 분쟁 게임(dispute game) 프로세스에 참여하여 잘못된 제안에 이의를 제기하고 진행 중인 게임을 모니터링하는, 보안상 중요한 구성 요소입니다.

### 최신 `op-challenger`로 업그레이드

업그레이드 과정을 단순화하는 중요한 개선 사항이 포함된 [최신 릴리스](https://github.com/ethereum-optimism/optimism/releases)로 업그레이드하십시오.

안정성과 배포 편의성을 위해 공식 Docker 이미지를 사용할 수 있습니다.

```bash theme={null}
# Pull a specific stable release version
docker pull us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:<latest_version>
```

그런 다음 이미지를 실행합니다. 예를 들면 다음과 같습니다.

```bash theme={null}
# Run with all required flags
docker run -d --name op-challenger \
  -e OP_CHALLENGER_GAME_TYPES=permissioned,cannon-kona \
  -e OP_CHALLENGER_PRESTATES_URL=<YOUR_PRESTATES_URL> \
  -e OP_CHALLENGER_L1_ETH_RPC=<YOUR_L1_RPC_URL> \
  -e OP_CHALLENGER_GAME_FACTORY_ADDRESS=<YOUR_DISPUTE_GAME_FACTORY> \
  -e OP_CHALLENGER_PRIVATE_KEY=<YOUR_PRIVATE_KEY_OR_USE_WALLET_SIGNER> \
  -e OP_CHALLENGER_NETWORK=<YOUR_NETWORK> \
  -v /path/to/local/prestates:/prestates \
  us-docker.pkg.dev/oplabs-tools-artifacts/images/op-challenger:latest

# Replace all placeholder values with your actual configuration

```

`<YOUR_PRESTATES_URL>`을 실제 prestates URL로 바꾸십시오.

배포 시 소스에서 빌드해야 한다면 다음 방법을 대신 사용할 수 있습니다.

```bash theme={null}
git clone https://github.com/ethereum-optimism/optimism -b op-challenger/<latest_version> --recurse-submodules
cd optimism
make op-challenger
```

### 네트워크 구성 업데이트

체인 구성을 로드하도록 `op-challenger`를 구성합니다.
체인이 [superchain-registry](https://docs.optimism.io/ko/op-stack/protocol/superchain-registry.md)에 포함되어 있지 않더라도 사용자 지정 구성을 지정할 수 있습니다.

```bash theme={null}
# For chains in the registry
--network <chain-name>

# For chains not in the registry, provide a path to your rollup configuration
- `rollup.json` - Your rollup configuration
- `genesis-l2.json` - Your L2 genesis file
```

### cannon-kona game type 활성화

Karst 업그레이드부터는 `cannon-kona`(Cannon VM 내부에서 실행되는 kona-client 프로그램)가 op-program을 대체하여 respected permissionless game type이 됩니다. 다음을 설정하여 `op-challenger`가 permissioned 게임과 permissionless 게임을 모두 지원하도록 구성합니다.

```bash theme={null}
--game-types permissioned,cannon-kona
```

또는 환경 변수를 설정합니다.

```bash theme={null}
OP_CHALLENGER_GAME_TYPES=permissioned,cannon-kona
```

### prestate 접근 구성

`--cannon-kona-prestate` 플래그를 필요한 모든 prestate가 들어 있는 소스를 가리키는 `--prestates-url`로 바꿉니다.

```bash theme={null}
--prestates-url <URL_TO_PRESTATES_DIRECTORY>
```

URL에는 `http`, `https`, `file` 프로토콜을 사용할 수 있습니다. 각 prestate의 이름은 `<PRESTATE_HASH>.bin.gz` 형식이어야 합니다.

### superchain-registry에 없는 체인을 위한 필수 prestate 빌드

`FaultDisputeGame` 및 `PermissionedDisputeGame`에 등록할 새 absolute prestate가 필요합니다([2절](#2-deploy-and-configure-smart-contracts-using-opcm) 참조).

> [!NOTE]
>
> permissioned 게임에 사용되는 초기 prestate에는 결함 증명 시스템(Fault Proof System)에 필요한 체인 구성이 포함되어 있지 않습니다. 유일한 permissioned 주체인 체인 운영자가 자신의 게임에 이의를 제기하지 않는다고 가정하기 때문입니다. 따라서 초기 `PermissionedDisputeGame`의 absolute prestate는 절대 사용되지 않습니다.
> 새 체인을 배포할 때는 먼저 L1 컨트랙트를 배포한 다음 체인 genesis 파일과 rollup 구성 파일을 생성해야 합니다.
> 이 파일들은 absolute prestate 생성의 입력값이며, 이러한 순환 의존성 때문에 체인을 permissionless 결함 증명 시스템에 바로 배포할 수 없습니다.

superchain-registry에 없는 체인의 경우, 체인 구성을 포함한 사용자 지정 prestate를 빌드해야 합니다.

`just reproducible-prestate-kona`로 kona-client absolute prestate를 빌드합니다([absolute prestate 튜토리얼](https://docs.optimism.io/ko/chain-operators/tutorials/absolute-prestate.md) 참조). 아티팩트는 다음 위치에 기록됩니다.

* `rust/kona/prestate-artifacts-cannon/prestate-proof.json` — 증명 파일이며, `pre` 필드가 absolute prestate 해시입니다(`jq -r .pre ...`).
* `rust/kona/prestate-artifacts-cannon/<PRESTATE_HASH>.bin.gz` — `op-challenger`가 로드하는 preimage 파일입니다.

> [!NOTE]
>
> kona-client absolute prestate를 `FaultDisputeGame` 및 `PermissionedDisputeGame`에 등록하십시오. challenger는 온체인 absolute prestate가 자신이 가진 것과 일치하지 않는 게임과는 상호작용하지 않으므로, 해시가 정확히 일치해야 합니다.

### 본드를 위한 충분한 자금 확보

본드는 permissioned 게임과 permissionless 게임 모두에 필요합니다.
그러나 permissioned 게임에서는 일반적으로 클레임을 정기적으로 게시하지 않으므로 본드 요구 사항이 크게 드러나지 않습니다.
반면 permissionless 게임의 challenger는 클레임을 게시할 때마다 본드를 게시해야 하는 경우가 많습니다.
따라서 challenger에 충분한 자금이 있는지 확인하십시오.

일반적인 지침은 다음과 같습니다.

* 최소 50 ETH의 잔액을 유지하십시오.
* 잠재적인 공격 시나리오에 대비해 대규모 ETH 풀에 접근할 수 있도록 하십시오.
* 항상 충분한 자금이 확보되어 있도록 모니터링을 구현하십시오.

### challenger가 사용할 디스크 공간 확보

`op-challenger`, 특히 permissionless 모드의 `op-challenger`는 디스크에 접근할 수 있어야 합니다. 약 50GB면 `invalid_ games` 몇 개를 처리하기에 충분합니다. 다만 challenger가 더 많은 잘못된 분쟁 게임에 대응해야 하는 경우 스토리지 요구 사항이 늘어납니다.
원칙적으로 잘못된 제안이 없는 한 challenger는 디스크 공간을 사용하지 않습니다.

op-challenger가 올바르게 구성되었는지 더 확신할 수 있는 한 가지 방법은 op-challenger를 "runner" 모드로 운영하는 것입니다.
동일한 op-challenger 구성을 사용하여 `op-challenger run-trace --run cannon-kona` 하위 명령을 실행합니다.
이렇게 하면 op-challenger가 실제 L2 블록에 대해 Cannon VM에서 kona-client 프로그램을 실행하는 모드로 동작하여, 올바르게 구성되었는지 확인합니다.
이 명령은 몇 개의 L2 블록마다 검사를 수행하며 계속 실행됩니다. 하지만 한 번의 루프를 완료할 때까지 실행한 후 종료해도 충분합니다.
종료하기 전에 로그에서 `Successfully verified output root`가 나타날 때까지 기다리십시오.
오류가 발생하면 구성이 잘못되었음을 의미합니다.

### `op-dispute-mon` 설정

문서의 [단계](https://docs.optimism.io/ko/chain-operators/tools/chain-monitoring.md#dispute-mon)에 따라 `op-dispute-mon`이 올바르게 구성되어 있는지 확인하십시오.

## 2. OPCM을 사용한 스마트 컨트랙트 배포 및 구성

이 섹션에서는 `ProxyAdminOwner`와 `Guardian` 역할의 권한 있는 작업이 필요합니다.

### ProxyAdmin Owner 및 Guardian 역할 이해

이 마이그레이션에는 시스템에서 권한 있는 역할의 작업이 필요합니다.

* **ProxyAdmin Owner**는 proxy 컨트랙트를 업그레이드할 권한을 가집니다.
* **Guardian**은 출금 일시 중지, respected game type 변경 등의 긴급 권한을 가집니다.

권한 있는 역할과 그 보안상 영향에 대한 자세한 내용은 [권한 있는 역할 문서](https://docs.optimism.io/ko/op-stack/protocol/privileged-roles.md)를 참조하십시오.

### 체인에 PermissionlessDisputeGame 추가

permissionless 분쟁 게임을 활성화하려면 적절한 `DisputeGameConfig` 항목과 함께 `OPContractsManagerV2`(OPCM) 컨트랙트의 `upgrade()` 함수를 호출합니다. ProxyAdmin owner가 이를 delegatecall해야 하며, 일반적으로 [superchain-ops](https://github.com/ethereum-optimism/superchain-ops) task를 통해 수행합니다.

업그레이드는 다음을 수행합니다.

1. 올바른 게임 인자(absolute prestate, VM, anchor state registry, delayed WETH, chain ID)와 함께 `FaultDisputeGame` 구현을 `DisputeGameFactory`에 등록합니다.
2. 새 game type의 초기 본드를 설정합니다.

상위 수준의 구현은 이 [문서](https://docs.optimism.io/ko/chain-operators/tutorials/dispute-games.md) 또는 [이 superchain-ops 템플릿](https://github.com/ethereum-optimism/superchain-ops/blob/main/src/template/AddGameTypeTemplate.sol)을 참조하십시오.

## 3. 오프체인 에이전트 테스트

`DisputeGameFactory`에 permissionless `FaultDisputeContract` 구현을 설정한 후, respected game type을 이것(game type 0)으로 설정하기 전에 `op-challenger`와 `op-dispute-mon`이 permissionless 게임에서 올바르게 동작하는지 테스트할 수 있습니다.

테스트에 사용할 수 있는 유용한 `op-challenger` 하위 명령이 여러 개 있으며, 특히 `list-games`, `list-claims`, `create-game`이 유용합니다. 자세한 내용은 [README](https://github.com/ethereum-optimism/optimism/tree/develop/op-challenger#subcommands)와 `op-challenger --help` 출력을 참조하십시오. 아래 두 테스트는 기본적인 정상 동작 확인 테스트입니다.

### 유효한 제안 방어 테스트

permissionless game type `0`을 사용하여 유효한 제안을 생성합니다.

1. 제안이 `safe` head 이하의 블록에서 나온 것인지 확인합니다.

   ```bash theme={null}
   cast block --rpc-url <OP_GETH_ENDPOINT> safe

   ```

2. (op-node에서) 유효한 output root를 가져옵니다.

   ```bash theme={null}
   cast rpc --rpc-url <OP_NODE_ENDPOINT> optimism_outputAtBlock \
     $(cast 2h <BLOCK_NUMBER>) | jq -r .outputRoot

   ```

3. 테스트 게임을 생성합니다.

   ```bash theme={null}
   ./op-challenger/bin/op-challenger create-game \
     --l1-eth-rpc=<L1_RPC_ENDPOINT> \
     --game-factory-address <DISPUTE_GAME_FACTORY_ADDR> \
     --l2-block-num <BLOCK_NUMBER> \
     --output-root <OUTPUT_ROOT> \
     <SIGNER_OPTIONS>

   ```

4. 다음을 확인합니다.
   * `op-challenger`가 게임이 진행 중임을 나타내는 메시지를 로그에 기록합니다.
   * `op-challenger`가 반박 클레임을 게시하지 않습니다(유효한 제안이므로).
   * `dispute-mon`이 새 게임을 `status="agree_defender_ahead"`로 포함합니다.

### 잘못된 클레임 반박 테스트

위에서 생성한 유효한 제안에 대해 잘못된 반박 클레임을 게시합니다.

```bash theme={null}
./op-challenger/bin/op-challenger move \
  --l1-eth-rpc <L1_RPC_ENDPOINT> \
  --game-address <GAME_ADDR> \
  --attack \
  --parent-index 0 \
  --claim 0x0000000000000000000000000000000000000000000000000000000000000000 \
  <SIGNER_OPTIONS>

```

`op-challenger`가 잘못된 클레임에 대해 반박 클레임을 게시하는지 확인합니다. 다음 명령으로 클레임을 확인할 수 있습니다.

```bash theme={null}
./op-challenger/bin/op-challenger list-claims \
  --l1-eth-rpc <L1_RPC_ENDPOINT> \
  --game-address <GAME_ADDR>

```

이 테스트 후 게임에는 3개의 클레임이 있어야 합니다.

## permissionless 증명으로 전환

이전 단계를 모두 완료하고 정상적으로 동작하는지 확인한 후, `AnchorStateRegistry`의 `respectedGameType`을 업데이트해야 합니다. 이 작업은 적절한 권한 있는 역할(일반적으로 Guardian)을 통해 실행해야 합니다.

이 단계를 실행하는 방법은 두 가지가 있습니다.

### 옵션 1: 멀티시그를 사용하여 실행

권한 있는 역할(예: Guardian)이 멀티시그 또는 DAO 거버넌스 시스템으로 제어되는 경우, 제공된 JSON 페이로드(`input.json`)를 사용합니다.

> [accordion] `respectedGameType`을 업데이트하는 트랜잭션이 담긴 `input.json` 파일을 생성합니다:
>
> ```json theme={null}
> {
>   "chainId": "<YOUR_L1_CHAIN_ID>",
>   "metadata": {
>     "name": "Deputy Guardian - Enable Permissionless Dispute Game",
>     "description": "This task updates the `respectedGameType` in the `AnchorStateRegistry` to `CANNON` (game type 0), enabling users to permissionlessly propose outputs as well as for anyone to participate in the dispute of these proposals. This action requires all in-progress withdrawals to be re-proven against a new `FaultDisputeGame` that was created after this update occurs."
>   },
>   "transactions": [
>     {
>       "metadata": {
>         "name": "Update `respectedGameType` in the `AnchorStateRegistry`",
>         "description": "Updates the `respectedGameType` to `CANNON` in the `AnchorStateRegistry`, enabling permissionless proposals and challenging."
>       },
>       "to": "<ASR_ADDRESS>",
>       "value": "0x0",
>       "data": "0x7fc485040000000000000000000000000000000000000000000000000000000000000000",
>       "contractMethod": {
>         "type": "function",
>         "name": "setRespectedGameType",
>         "inputs": [
>           {
>             "name": "_gameType",
>             "type": "uint32"
>           }
>         ],
>         "outputs": [],
>         "stateMutability": "nonpayable"
>       },
>       "contractInputsValues": {
>         "_gameType": "0"
>       }
>     }
>   ]
> }
>
> ```

* 사용하는 인터페이스(예: Safe transaction builder)를 통해 **이 JSON 페이로드를 제출**합니다.
* 실행 전에 Tenderly를 사용하여 이 트랜잭션을 **시뮬레이션**하고 예상한 상태 변경이 일어나는지 확인합니다.
  * `AnchorStateRegistry`의 `respectedGameType`이 `1`(PERMISSIONED)에서 `0`(CANNON)으로 변경되어야 합니다.

***

### 옵션 2: `cast`(Forge CLI)를 통한 직접 실행

또는 권한이 있는 단일 지갑에서 직접 실행하거나 더 빠르게 실행하려는 경우, 다음 `cast` 명령을 사용합니다.

1. 먼저 `cast calldata`를 사용하여 트랜잭션 calldata를 인코딩합니다.

```bash theme={null}
CALLDATA=$(cast calldata "setRespectedGameType(uint32)" 0)
```

2. 트랜잭션을 전송합니다.

```bash theme={null}
# Execute the transaction
cast send --rpc-url <YOUR_RPC_URL> --private-key <YOUR_PRIVATE_KEY> <ASR_ADDRESS> "$CALLDATA"
```

3. 실행 후 respected game type을 확인합니다.

```bash theme={null}
cast call --rpc-url <YOUR_RPC_URL> <ASR_ADDRESS> "respectedGameType()(uint32)"
# The value should now be 0 (CANNON)

```

### 실행 후 구성:

업데이트 후 permissionless `CANNON` game type을 사용하여 제안을 생성하도록 `op-proposer`를 구성합니다.

명령줄 인자 사용:

```bash theme={null}
--game-type 0
```

또는 환경 변수 사용:

```bash theme={null}
OP_PROPOSER_GAME_TYPE=0
```

> [!NOTE]
>
> 이 작업을 수행하면 진행 중인 모든 출금을 이 업데이트 이후에 생성된 새 `FaultDisputeGame`을 기준으로 다시 증명해야 합니다.

## 다음 단계

* OPCM으로 새 분쟁 게임을 배포하는 방법에 대한 자세한 내용은 [문서](https://docs.optimism.io/ko/chain-operators/tutorials/dispute-games.md)를 참조하십시오.
* [이 튜토리얼](https://docs.optimism.io/ko/chain-operators/tutorials/dispute-games.md)을 통해 OPCM으로 새 분쟁 게임을 배포하십시오.
* [absolute prestate 가이드](https://docs.optimism.io/ko/chain-operators/tutorials/absolute-prestate.md)를 사용하여 absolute prestate를 생성하십시오.
* [결함 증명 설명](https://docs.optimism.io/ko/op-stack/fault-proofs/explainer.md)에서 결함 증명에 대해 알아보십시오.
