Layer2とは
Layer2(L2)は、Ethereumメインネット(Layer1)の上に構築されるスケーリングソリューションです。トランザクションをオフチェーンで処理し、その結果のみをメインネットに記録することで、処理速度の向上とガス代の大幅削減を実現します。2025年、Layer2エコシステムはDeFi、NFT、ゲームなど幅広い分野で本格的に普及しています。
2025年のLayer2市場動向
TVL(Total Value Locked)の急成長
2025年初頭時点で、主要Layer2のTVLは合計500億ドルを超え、2024年から約2倍に成長しました。特にArbitrumとBaseが牽引役となっています。
| Layer2 | TVL (2025年1月) | 前年比成長率 |
|---|---|---|
| Arbitrum One | 200億ドル | +85% |
| Base | 120億ドル | +250% |
| Optimism | 80億ドル | +60% |
| zkSync Era | 50億ドル | +120% |
| Polygon zkEVM | 30億ドル | +180% |
トランザクション数の推移
主要L2は1日あたり数百万トランザクションを処理しており、Ethereumメインネットを大幅に上回る処理能力を示しています。
Rollupの仕組み
Layer2の中核技術はRollupです。複数のトランザクションを「巻き上げて(Roll up)」1つのバッチにまとめ、圧縮してLayer1に記録します。
Optimistic Rollup
Optimistic Rollupは「楽観的(Optimistic)」にトランザクションが正当であると仮定して処理を進めます。
// Optimistic Rollup の基本的な仕組み(概念コード)
contract OptimisticRollup {
uint256 public constant CHALLENGE_PERIOD = 7 days;
struct Batch {
bytes32 stateRoot;
uint256 timestamp;
bool finalized;
}
mapping(uint256 => Batch) public batches;
uint256 public latestBatchIndex;
// バッチを提出
function submitBatch(bytes32 stateRoot, bytes calldata txData) external {
batches[++latestBatchIndex] = Batch({
stateRoot: stateRoot,
timestamp: block.timestamp,
finalized: false
});
emit BatchSubmitted(latestBatchIndex, stateRoot);
}
// 不正証明(Fraud Proof)を提出
function submitFraudProof(
uint256 batchIndex,
bytes calldata proof
) external {
Batch storage batch = batches[batchIndex];
require(!batch.finalized, "Batch already finalized");
require(
block.timestamp < batch.timestamp + CHALLENGE_PERIOD,
"Challenge period ended"
);
// 不正証明を検証
require(verifyFraudProof(proof), "Invalid fraud proof");
// バッチを無効化してスラッシング
delete batches[batchIndex];
emit BatchChallenged(batchIndex);
}
// チャレンジ期間後にファイナライズ
function finalizeBatch(uint256 batchIndex) external {
Batch storage batch = batches[batchIndex];
require(
block.timestamp >= batch.timestamp + CHALLENGE_PERIOD,
"Challenge period not ended"
);
batch.finalized = true;
emit BatchFinalized(batchIndex);
}
}
Optimistic Rollupの特徴:
- EVM完全互換(既存のSolidityコードをそのままデプロイ可能)
- 7日間のチャレンジ期間(出金に時間がかかる)
- 不正行為があった場合のみ検証が発生
- 代表例: Arbitrum、Optimism、Base
ZK Rollup(Zero-Knowledge Rollup)
ZK Rollupは暗号学的証明(ZKプルーフ)を使用して、全てのトランザクションの正当性を数学的に証明します。
// ZK Rollup のトランザクション検証フロー(概念コード)
interface ZKProof {
pi_a: [bigint, bigint];
pi_b: [[bigint, bigint], [bigint, bigint]];
pi_c: [bigint, bigint];
publicInputs: bigint[];
}
interface ZKBatch {
transactions: Transaction[];
oldStateRoot: string;
newStateRoot: string;
proof: ZKProof;
}
class ZKRollupVerifier {
private verificationKey: VerificationKey;
constructor(vk: VerificationKey) {
this.verificationKey = vk;
}
// ZK証明を検証
async verifyBatch(batch: ZKBatch): Promise<boolean> {
const { proof, publicInputs } = batch;
// Groth16またはPLONK証明を検証
const isValid = await this.verifyProof(
this.verificationKey,
proof,
publicInputs
);
if (!isValid) {
throw new Error("Invalid ZK proof");
}
// 状態遷移の検証
const expectedNewRoot = this.computeStateRoot(
batch.oldStateRoot,
batch.transactions
);
return expectedNewRoot === batch.newStateRoot;
}
// 証明生成(Prover側)
async generateProof(
transactions: Transaction[],
witness: Witness
): Promise<ZKProof> {
// 回路を実行して証明を生成
// 計算コストは高いがオンチェーン検証は安価
return await snarkjs.groth16.fullProve(
witness,
"circuit.wasm",
"circuit_final.zkey"
);
}
}
ZK Rollupの特徴:
- 即時ファイナリティ(証明検証後すぐに確定)
- 出金が高速(数時間以内)
- 証明生成に計算リソースが必要
- EVM互換性の実現が技術的に困難(zkEVM開発が進行中)
- 代表例: zkSync Era、Polygon zkEVM、StarkNet、Scroll
Optimistic vs ZK 比較
| 項目 | Optimistic Rollup | ZK Rollup |
|---|---|---|
| ファイナリティ | 7日間 | 数時間 |
| EVM互換性 | 完全互換 | zkEVM(開発進行中) |
| 計算コスト | 低い | 高い(証明生成) |
| ガス効率 | 良好 | 非常に良好 |
| 成熟度 | 高い | 中〜高(急速に改善中) |
主要Layer2プラットフォーム比較
Arbitrum One
最大のTVLを誇るOptimistic Rollup。DeFiエコシステムが最も充実しています。
// Arbitrum への接続(ethers.js v6)
import { ethers } from "ethers";
const ARBITRUM_CONFIG = {
chainId: 42161,
name: "Arbitrum One",
rpcUrl: "https://arb1.arbitrum.io/rpc",
blockExplorer: "https://arbiscan.io",
nativeCurrency: {
name: "Ethereum",
symbol: "ETH",
decimals: 18
}
};
async function connectToArbitrum() {
const provider = new ethers.JsonRpcProvider(ARBITRUM_CONFIG.rpcUrl);
// ネットワーク情報を取得
const network = await provider.getNetwork();
console.log(`Connected to ${network.name} (chainId: ${network.chainId})`);
// 現在のガス価格を取得
const feeData = await provider.getFeeData();
console.log(`Gas Price: ${ethers.formatUnits(feeData.gasPrice!, "gwei")} Gwei`);
return provider;
}
// Arbitrum でのトークン転送
async function transferOnArbitrum(
signer: ethers.Signer,
to: string,
amount: bigint
) {
const tx = await signer.sendTransaction({
to,
value: amount,
// Arbitrum は EIP-1559 をサポート
maxFeePerGas: ethers.parseUnits("0.1", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("0.01", "gwei")
});
const receipt = await tx.wait();
console.log(`Transaction confirmed: ${receipt?.hash}`);
return receipt;
}
Arbitrumの特徴:
- Nitro: 最新の実行エンジンで高速・低コスト
- Stylus: RustやC++でスマートコントラクト開発が可能
- Arbitrum Orbit: 独自のL3チェーンを構築可能
- GMX、Uniswap、Aaveなど主要DeFiが稼働
Optimism(OP Mainnet)
OP Stackを基盤とした「Superchain」ビジョンを推進。
// Optimism への接続と OP Stack の活用
import { ethers } from "ethers";
import { CrossChainMessenger, MessageStatus } from "@eth-optimism/sdk";
const OP_CONFIG = {
chainId: 10,
name: "OP Mainnet",
rpcUrl: "https://mainnet.optimism.io",
l1ChainId: 1,
l1RpcUrl: "https://mainnet.infura.io/v3/YOUR_KEY"
};
// L1 <-> L2 メッセージング
async function setupCrossChainMessenger(
l1Signer: ethers.Signer,
l2Signer: ethers.Signer
) {
const messenger = new CrossChainMessenger({
l1ChainId: OP_CONFIG.l1ChainId,
l2ChainId: OP_CONFIG.chainId,
l1SignerOrProvider: l1Signer,
l2SignerOrProvider: l2Signer
});
return messenger;
}
// L1 から L2 への ETH 入金
async function depositETH(
messenger: CrossChainMessenger,
amount: bigint
) {
console.log("Depositing ETH to L2...");
const tx = await messenger.depositETH(amount);
await tx.wait();
console.log("Deposit initiated, waiting for L2 confirmation...");
// L2 での確認を待つ
await messenger.waitForMessageStatus(
tx.hash,
MessageStatus.RELAYED
);
console.log("Deposit complete!");
}
// L2 から L1 への ETH 出金
async function withdrawETH(
messenger: CrossChainMessenger,
amount: bigint
) {
console.log("Initiating withdrawal from L2...");
// Step 1: L2 で出金を開始
const withdrawTx = await messenger.withdrawETH(amount);
await withdrawTx.wait();
// Step 2: 状態ルートの公開を待つ
console.log("Waiting for state root publication...");
await messenger.waitForMessageStatus(
withdrawTx.hash,
MessageStatus.READY_TO_PROVE
);
// Step 3: 出金を証明
console.log("Proving withdrawal...");
const proveTx = await messenger.proveMessage(withdrawTx.hash);
await proveTx.wait();
// Step 4: チャレンジ期間を待つ(7日間)
console.log("Waiting for challenge period (7 days)...");
await messenger.waitForMessageStatus(
withdrawTx.hash,
MessageStatus.READY_FOR_RELAY
);
// Step 5: L1 で出金を完了
console.log("Finalizing withdrawal...");
const finalizeTx = await messenger.finalizeMessage(withdrawTx.hash);
await finalizeTx.wait();
console.log("Withdrawal complete!");
}
Optimismの特徴:
- OP Stack: オープンソースのL2構築フレームワーク
- Superchain: 相互運用可能なL2ネットワーク群
- RetroPGF: 公共財への遡及的資金提供
- ガバナンストークン: $OP
Base
Coinbaseが運営するOP Stack基盤のLayer2。2025年最も成長したL2の一つ。
// Base での NFT ミント(ERC-721)
import { ethers } from "ethers";
const BASE_CONFIG = {
chainId: 8453,
name: "Base",
rpcUrl: "https://mainnet.base.org",
blockExplorer: "https://basescan.org"
};
// ERC-721 コントラクト ABI(抜粋)
const NFT_ABI = [
"function mint(address to) external payable returns (uint256)",
"function totalSupply() view returns (uint256)",
"function tokenURI(uint256 tokenId) view returns (string)",
"event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)"
];
async function mintNFTOnBase(
signer: ethers.Signer,
nftContractAddress: string
) {
const provider = new ethers.JsonRpcProvider(BASE_CONFIG.rpcUrl);
const connectedSigner = signer.connect(provider);
const nftContract = new ethers.Contract(
nftContractAddress,
NFT_ABI,
connectedSigner
);
// ミント価格を取得(例: 0.001 ETH)
const mintPrice = ethers.parseEther("0.001");
// ガス見積もり
const gasEstimate = await nftContract.mint.estimateGas(
await signer.getAddress(),
{ value: mintPrice }
);
console.log(`Estimated gas: ${gasEstimate.toString()}`);
// ミント実行
const tx = await nftContract.mint(
await signer.getAddress(),
{
value: mintPrice,
gasLimit: gasEstimate * 120n / 100n // 20% バッファ
}
);
const receipt = await tx.wait();
// Transfer イベントから tokenId を取得
const transferEvent = receipt?.logs.find(
(log: any) => log.topics[0] === ethers.id("Transfer(address,address,uint256)")
);
if (transferEvent) {
const tokenId = BigInt(transferEvent.topics[3]);
console.log(`Minted NFT with tokenId: ${tokenId}`);
}
return receipt;
}
Baseの特徴:
- Coinbaseとのシームレスな統合
- 低いガス代(Ethereumの約100分の1)
- 急速に成長するDeFi・NFTエコシステム
- Friend.tech、Aerodrome等の人気dApps
zkSync Era
Matter Labsが開発するzkEVM。ネイティブアカウント抽象化をサポート。
// zkSync Era でのアカウント抽象化(Paymaster)
import { Provider, Wallet, utils } from "zksync-ethers";
import { ethers } from "ethers";
const ZKSYNC_CONFIG = {
chainId: 324,
name: "zkSync Era",
rpcUrl: "https://mainnet.era.zksync.io",
blockExplorer: "https://explorer.zksync.io"
};
async function connectToZkSync() {
const provider = new Provider(ZKSYNC_CONFIG.rpcUrl);
// zkSync 固有の情報を取得
const l1BatchNumber = await provider.getL1BatchNumber();
console.log(`Current L1 batch: ${l1BatchNumber}`);
return provider;
}
// Paymaster を使用したガスレス取引
async function executeGaslessTransaction(
wallet: Wallet,
contractAddress: string,
data: string,
paymasterAddress: string
) {
// Paymaster のパラメータを設定
const paymasterParams = utils.getPaymasterParams(paymasterAddress, {
type: "General",
innerInput: new Uint8Array()
});
// トランザクションを作成
const tx = await wallet.sendTransaction({
to: contractAddress,
data: data,
// Paymaster がガスを支払う
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
paymasterParams
}
});
const receipt = await tx.wait();
console.log(`Gasless transaction confirmed: ${receipt.hash}`);
return receipt;
}
// zkSync でのコントラクトデプロイ
async function deployOnZkSync(
wallet: Wallet,
bytecode: string,
abi: any[],
constructorArgs: any[]
) {
const factory = new ethers.ContractFactory(abi, bytecode, wallet);
// zkSync 用のデプロイオプション
const contract = await factory.deploy(...constructorArgs, {
customData: {
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
factoryDeps: [] // 依存するファクトリコントラクト
}
});
await contract.waitForDeployment();
const address = await contract.getAddress();
console.log(`Contract deployed at: ${address}`);
return contract;
}
zkSync Eraの特徴:
- ネイティブアカウント抽象化(AA)
- Paymaster によるガスレス取引
- zkPorter(オフチェーンデータ可用性オプション)
- Boojum: 高効率なZK証明システム
Polygon zkEVM
Polygonが開発するType 2 zkEVM。高いEVM互換性を実現。
// Polygon zkEVM への接続
import { ethers } from "ethers";
const POLYGON_ZKEVM_CONFIG = {
chainId: 1101,
name: "Polygon zkEVM",
rpcUrl: "https://zkevm-rpc.com",
blockExplorer: "https://zkevm.polygonscan.com",
bridgeAddress: "0x2a3DD3EB832aF982ec71669E178424b10Dca2EDe"
};
// Polygon zkEVM ブリッジコントラクトの ABI
const BRIDGE_ABI = [
"function bridgeAsset(uint32 destinationNetwork, address destinationAddress, uint256 amount, address token, bool forceUpdateGlobalExitRoot, bytes permitData) external payable",
"function claimAsset(bytes32[32] smtProof, uint32 index, bytes32 mainnetExitRoot, bytes32 rollupExitRoot, uint32 originNetwork, address originTokenAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata) external",
"event BridgeEvent(uint8 leafType, uint32 originNetwork, address originAddress, uint32 destinationNetwork, address destinationAddress, uint256 amount, bytes metadata, uint32 depositCount)"
];
// L1 から Polygon zkEVM へのブリッジ
async function bridgeToPolygonZkEVM(
signer: ethers.Signer,
amount: bigint,
destinationAddress: string
) {
const bridge = new ethers.Contract(
POLYGON_ZKEVM_CONFIG.bridgeAddress,
BRIDGE_ABI,
signer
);
// ETH をブリッジ(token = address(0))
const tx = await bridge.bridgeAsset(
1, // destinationNetwork: Polygon zkEVM
destinationAddress,
amount,
ethers.ZeroAddress, // ETH
true, // forceUpdateGlobalExitRoot
"0x", // permitData
{ value: amount }
);
const receipt = await tx.wait();
console.log(`Bridge transaction: ${receipt?.hash}`);
return receipt;
}
Polygon zkEVMの特徴:
- Type 2 zkEVM(高いEVM同等性)
- LxLy Bridge: 高速なクロスチェーンブリッジ
- Polygonエコシステムとの統合
- 既存のEthereumツールチェーンがそのまま利用可能
ガス代・速度比較
トランザクションコスト比較(2025年1月時点)
| ネットワーク | ETH転送 | ERC-20転送 | Uniswap Swap |
|---|---|---|---|
| Ethereum L1 | $2.50 | $5.00 | $15.00 |
| Arbitrum One | $0.02 | $0.05 | $0.15 |
| Optimism | $0.02 | $0.05 | $0.15 |
| Base | $0.01 | $0.03 | $0.10 |
| zkSync Era | $0.03 | $0.06 | $0.20 |
| Polygon zkEVM | $0.02 | $0.04 | $0.12 |
トランザクション速度
// 各 L2 のブロック時間とファイナリティ
const L2_PERFORMANCE = {
arbitrum: {
blockTime: "0.25秒",
softFinality: "即時",
hardFinality: "約7日間(L1へのファイナリティ)",
tps: "40,000+ TPS(理論値)"
},
optimism: {
blockTime: "2秒",
softFinality: "即時",
hardFinality: "約7日間",
tps: "2,000+ TPS"
},
base: {
blockTime: "2秒",
softFinality: "即時",
hardFinality: "約7日間",
tps: "2,000+ TPS"
},
zkSync: {
blockTime: "数秒",
softFinality: "数分(ZK証明生成後)",
hardFinality: "数時間",
tps: "2,000+ TPS"
},
polygonZkEVM: {
blockTime: "数秒",
softFinality: "数分",
hardFinality: "数時間",
tps: "2,000+ TPS"
}
};
ブリッジとセキュリティ
ブリッジの種類
// ブリッジの分類と特徴
interface BridgeType {
name: string;
trustModel: "trustless" | "trusted" | "hybrid";
speed: string;
security: string;
examples: string[];
}
const BRIDGE_TYPES: BridgeType[] = [
{
name: "ネイティブブリッジ",
trustModel: "trustless",
speed: "遅い(7日間 for Optimistic)",
security: "最高(L1セキュリティを継承)",
examples: ["Arbitrum Bridge", "Optimism Bridge", "zkSync Bridge"]
},
{
name: "流動性ネットワーク",
trustModel: "hybrid",
speed: "速い(数分)",
security: "中(流動性プロバイダーに依存)",
examples: ["Across", "Stargate", "Hop Protocol"]
},
{
name: "メッセージングプロトコル",
trustModel: "hybrid",
speed: "中(数十分)",
security: "中〜高(オラクルに依存)",
examples: ["LayerZero", "Chainlink CCIP", "Axelar"]
}
];
セキュリティのベストプラクティス
// L2 利用時のセキュリティチェックリスト
class L2SecurityChecker {
// 1. コントラクトの検証
async verifyContract(
provider: ethers.Provider,
contractAddress: string
): Promise<boolean> {
// ソースコード検証を確認
const code = await provider.getCode(contractAddress);
if (code === "0x") {
throw new Error("Contract not deployed");
}
// Block explorer での検証状態を確認
// (実際には API を使用)
console.log("Verify contract on block explorer");
return true;
}
// 2. ブリッジ前のアドレス確認
validateBridgeAddress(address: string, expectedNetwork: number): boolean {
// チェックサム検証
if (!ethers.isAddress(address)) {
throw new Error("Invalid address format");
}
// ネットワーク間でアドレスが同一か確認
// (一部のトークンは異なるアドレスを持つ)
console.log(`Bridging to ${address} on network ${expectedNetwork}`);
return true;
}
// 3. スマートコントラクトウォレットの互換性確認
async checkSmartWalletCompatibility(
address: string,
l1Provider: ethers.Provider,
l2Provider: ethers.Provider
): Promise<{ compatible: boolean; reason?: string }> {
const l1Code = await l1Provider.getCode(address);
const l2Code = await l2Provider.getCode(address);
if (l1Code !== "0x" && l2Code === "0x") {
return {
compatible: false,
reason: "Smart wallet not deployed on L2. Deploy first or use EOA."
};
}
return { compatible: true };
}
}
出金時の注意点
// Optimistic Rollup からの出金フロー
async function safeWithdrawal(
messenger: CrossChainMessenger,
amount: bigint
) {
// 1. 出金前の残高確認
const l2Balance = await messenger.l2Provider.getBalance(
await messenger.l2Signer.getAddress()
);
if (l2Balance < amount) {
throw new Error("Insufficient balance on L2");
}
// 2. L1 のガス価格を確認
const l1FeeData = await messenger.l1Provider.getFeeData();
console.log(`L1 gas price: ${ethers.formatUnits(l1FeeData.gasPrice!, "gwei")} Gwei`);
// 3. 出金には複数の L1 トランザクションが必要
// - proveMessage: 約200,000 gas
// - finalizeMessage: 約100,000 gas
const estimatedL1Cost = (l1FeeData.gasPrice! * 300000n);
console.log(`Estimated L1 cost: ${ethers.formatEther(estimatedL1Cost)} ETH`);
// 4. 7日間のチャレンジ期間を考慮
const challengePeriodEnd = new Date();
challengePeriodEnd.setDate(challengePeriodEnd.getDate() + 7);
console.log(`Withdrawal available after: ${challengePeriodEnd.toISOString()}`);
// 5. 実行
return await messenger.withdrawETH(amount);
}
開発者向け実装ガイド
マルチチェーン対応アプリケーション
// マルチL2対応のDAppアーキテクチャ
import { ethers } from "ethers";
interface ChainConfig {
chainId: number;
name: string;
rpcUrl: string;
nativeCurrency: string;
blockExplorer: string;
}
const SUPPORTED_L2S: Record<string, ChainConfig> = {
arbitrum: {
chainId: 42161,
name: "Arbitrum One",
rpcUrl: "https://arb1.arbitrum.io/rpc",
nativeCurrency: "ETH",
blockExplorer: "https://arbiscan.io"
},
optimism: {
chainId: 10,
name: "OP Mainnet",
rpcUrl: "https://mainnet.optimism.io",
nativeCurrency: "ETH",
blockExplorer: "https://optimistic.etherscan.io"
},
base: {
chainId: 8453,
name: "Base",
rpcUrl: "https://mainnet.base.org",
nativeCurrency: "ETH",
blockExplorer: "https://basescan.org"
},
zksync: {
chainId: 324,
name: "zkSync Era",
rpcUrl: "https://mainnet.era.zksync.io",
nativeCurrency: "ETH",
blockExplorer: "https://explorer.zksync.io"
}
};
class MultiChainProvider {
private providers: Map<number, ethers.JsonRpcProvider> = new Map();
getProvider(chainId: number): ethers.JsonRpcProvider {
if (!this.providers.has(chainId)) {
const config = Object.values(SUPPORTED_L2S).find(c => c.chainId === chainId);
if (!config) {
throw new Error(`Unsupported chain: ${chainId}`);
}
this.providers.set(chainId, new ethers.JsonRpcProvider(config.rpcUrl));
}
return this.providers.get(chainId)!;
}
async getBalance(address: string, chainId: number): Promise<bigint> {
const provider = this.getProvider(chainId);
return provider.getBalance(address);
}
async getAllBalances(address: string): Promise<Map<string, bigint>> {
const balances = new Map<string, bigint>();
await Promise.all(
Object.entries(SUPPORTED_L2S).map(async ([name, config]) => {
try {
const balance = await this.getBalance(address, config.chainId);
balances.set(name, balance);
} catch (error) {
console.error(`Failed to get balance on ${name}:`, error);
balances.set(name, 0n);
}
})
);
return balances;
}
}
// 使用例
async function main() {
const multiChain = new MultiChainProvider();
const address = "0x...";
const balances = await multiChain.getAllBalances(address);
for (const [chain, balance] of balances) {
console.log(`${chain}: ${ethers.formatEther(balance)} ETH`);
}
}
Hardhat でのL2デプロイ
// hardhat.config.ts
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
arbitrum: {
url: "https://arb1.arbitrum.io/rpc",
accounts: [process.env.PRIVATE_KEY!],
chainId: 42161
},
optimism: {
url: "https://mainnet.optimism.io",
accounts: [process.env.PRIVATE_KEY!],
chainId: 10
},
base: {
url: "https://mainnet.base.org",
accounts: [process.env.PRIVATE_KEY!],
chainId: 8453
},
zksync: {
url: "https://mainnet.era.zksync.io",
accounts: [process.env.PRIVATE_KEY!],
chainId: 324,
// zkSync 用の追加設定
zksync: true,
ethNetwork: "mainnet"
}
},
etherscan: {
apiKey: {
arbitrumOne: process.env.ARBISCAN_API_KEY!,
optimisticEthereum: process.env.OPTIMISM_API_KEY!,
base: process.env.BASESCAN_API_KEY!
}
}
};
export default config;
# デプロイコマンド
npx hardhat run scripts/deploy.ts --network arbitrum
npx hardhat run scripts/deploy.ts --network optimism
npx hardhat run scripts/deploy.ts --network base
# コントラクト検証
npx hardhat verify --network arbitrum CONTRACT_ADDRESS
2025年の主要トレンド
1. Superchain の台頭
Optimism の OP Stack を基盤とした相互運用可能なL2群が拡大。Base、Mode、Zora などが参加。
2. zkEVM の成熟
zkSync Era、Polygon zkEVM、Scroll、Linea などのzkEVMが本番利用に耐えうる成熟度に到達。
3. ネイティブアカウント抽象化
zkSync Era に続き、他のL2もネイティブAAをサポート開始。Paymasterによるガスレス取引が一般化。
4. データ可用性レイヤーの多様化
Celestia、EigenDA などの専用DAレイヤーを活用した「Validium」や「Optimium」が登場。
5. L3(Layer 3)の台頭
Arbitrum Orbit、OP Stack を使った特定用途向けL3チェーンが増加。ゲーム、DeFi特化型など。
Layer2選択ガイド
| ユースケース | 推奨L2 | 理由 |
|---|---|---|
| DeFi(大規模) | Arbitrum | 最大のTVLと流動性 |
| NFT・ゲーム | Base、Arbitrum | 低コスト、高速 |
| エンタープライズ | zkSync Era | ネイティブAA、プライバシー |
| 既存Ethereumアプリ移植 | Polygon zkEVM | 高いEVM互換性 |
| Coinbaseユーザー向け | Base | シームレスな統合 |
まとめ
2025年、Layer2は Ethereum エコシステムの中核として確立されました。Optimistic Rollup は成熟度と EVM 互換性で優位性を保ちつつ、ZK Rollup が急速にキャッチアップしています。開発者は複数のL2をサポートするマルチチェーンアプローチを採用し、ユーザーは用途に応じて最適なL2を選択できる時代になりました。
今後は Superchain 構想による L2 間の相互運用性向上、zkEVM のさらなる成熟、そして L3 の台頭により、Ethereum のスケーラビリティは新たなフェーズに入ると予想されます。
← 一覧に戻る参考リンク