Skip to content
On this page

S2C11: Pre-Mint + RLP

1. 問題

S1C12 と同様に、RLP エンコードされたブロックヘッダーを提供する必要があります。しかし preMintFlag メカニズムが追加されています — 事前にコミットメントを提出し、指定された時間枠内にブロックヘッダーを提出する必要があります。

2. 原因

コントラクトは Commit-Reveal パターンを実装しています:最初に preMintFlag を呼び出して意図をロックし、その後一定時間内(256 ブロック以内)に正しい RLP ブロックヘッダーを提出して、指定されたブロック数「待機」したことを証明します。

3. 解決策

  1. preMintFlag を複数回呼び出します(成功率を最大化するために 10 回推奨)
  2. 2 ブロック以上が採掘されるのを待ちます
  3. 現在のブロック番号の 2 つ前のブロックの完全なヘッダー情報を取得します
  4. 正しい RLP エンコードを使用します
  5. 256 ブロックのウィンドウ内に提出します
bash
# 事前コミット(複数回)
for i in $(seq 1 10); do
  cast send $CHALLENGE "preMintFlag()" --private-key $PK --rpc-url $RPC
done

# 2 ブロック待機
sleep 10

# ブロックヘッダーを提出
BLOCK_NUM=$(($CURRENT_BLOCK - 2))
BLOCK_HEADER=$(cast rlp $BLOCK_NUM --rpc-url $RPC)
cast send $CHALLENGE "mintFlag(bytes)" $BLOCK_HEADER --private-key $PK

4. 遭遇した落とし穴

RLP エンコードの正確性: OP Mainnet のブロックヘッダー RLP エンコードは Bedrock アップグレードにより、標準のイーサリアムと異なる可能性があります。

Commit-Reveal 時間枠: 256 ブロック以内に完了し、かつ最低 2 ブロック待機する必要があります。

Pre-mint 回数: 1 回の preMintFlag では正しいブロック範囲をロックするのに不十分な可能性があり、複数回の呼び出しで成功率を高めます。

5. 落とし穴の原因

OP のブロック構造はイーサリアムメインネットと若干の違いがあります(例えば difficulty フィールドが OP では異なる可能性があります)。RLP エンコーダーは OP ブロックの 15 以上のフィールドすべてを正しく処理できる必要があります。

6. 解決方法

  • RLP エンコードには ethers.utils.RLP.encode() または cast rlp を使用します
  • ブロックが [block.number - 256, block.number - 2] の範囲内にあることを確認します
  • preMintFlag を 10 回呼び出して十分な時間枠をカバーします

7. 技術的ポイント

ポイント説明
Commit-Reveal二段階提出パターン、前方計算攻撃を防止
RLP エンコードイーサリアムの標準シリアライゼーション、ブロックヘッダーの 15 以上のフィールドを正確にエンコードする必要あり
OP Bedrock ブロックOptimism の Bedrock アップグレードによりブロック形式が変更
時間枠管理preMint + 待機 + mint を正しいブロック範囲内で実行する必要あり

Built with AiAda