Solanaプログラム開発でCargoがblakeクレートのバージョン競合を起こした場合、まずCargo.lockを更新し、依存関係を明示的に指定して解決するのが最短だ。競合の相手を特定できれば、数分で解消できる。
なぜCargoでblakeのバージョン競合が起きるのか

blakeとは、ブロックチェーンでよく使われるハッシュ関数の実装をまとめたRustクレート群だ。SolanaのSDKやAnchorフレームワークは、トランザクションの署名検証やデータの整合性確認にblake系クレートを内部で利用している。
競合が起きる典型的な原因は、プロジェクト内の複数のクレートが、互換性のない異なるバージョンのblakeを要求することだ。たとえば、あるクレートがblake3 1.0を要求し、別のクレートがblake3 1.5を要求した場合、Cargoは両方を同時に解決できずエラーを返す。
これはCargoのバグではなく、依存解決の仕組みとして正しい動作だ。Semantic Versioning(セマンティックバージョニング)のルール上、メジャーバージョンが異なるクレートは互換性がないとみなされる。要は、プロジェクト内で「同じ名前のクレートの複数バージョンを同時に使いたい」という矛盾した要求が生まれているということだ。
競合している相手を特定する手順

まず、どのクレートがどのバージョンのblakeを要求しているのかを正確に把握する。闇雲に依存関係を書き換えても、別の競合を引き起こすだけだ。
最初に実行すべきは、依存関係ツリーの表示だ。ターミナルで以下を実行する。
cargo tree -i blake3このコマンドは、blake3に依存しているすべてのクレートと、その要求バージョンを逆引きで表示してくれる。blake2bで競合しているなら cargo tree -i blake2b_simd のように、実際に競合しているクレート名に置き換えること。
出力を見れば、競合の相手がSolana SDKなのか、Anchorなのか、あるいは別のライブラリなのかが判明する。競合相手が特定できたら、解決策を選べる状態になる。
Cargo.lockを更新して解決する手順

最も簡単で効果的なのは、ロックファイルの再生成だ。Cargo.lockが古いバージョンのblakeを固定しているケースでは、更新するだけで解決することが多い。
次のコマンドを順番に実行する。
cargo update -p blake3でblake3単体を更新する- それでも解決しない場合は
cargo updateで全依存関係を更新する - 最後に
cargo buildでビルドが通るか確認する
競合の内容によっては、blake3を最新版に更新するだけでは解決しない。相手のクレートが古いバージョンを要求し続けるためだ。その場合は次に進む。
Cargo.tomlで依存関係を明示的に固定する

ロックファイルの更新で解決しない場合、Cargo.tomlにblakeのバージョンを明示的に指定する。これにより、Cargoがどのバージョンで解決すべきかの判断材料が増える。
競合の相手が「blake3 1.0系を要求するクレート」と「blake3 1.5系を要求する別のクレート」だと仮定する。この場合、自分のCargo.tomlに以下のように記述して、両方が受け入れられるバージョン帯を指示する。
[dependencies]
blake3 = "1.5"バージョン指定は "1.5" のようにメジャーとマイナーまで書くのが安全だ。単に "1" と書くと、Cargoが利用可能な最新の1系を選ぶ。執筆時点ではblake3 1系が広く使われているが、最新の安定版はcrates.ioで確認してほしい。
blake2系で競合している場合は、blake2b_simdやblake2のクレート名で同様に指定する。Solana SDKはblake3への依存が中心なので、まずblake3を疑うのが現実的だ。
それでも解決しない時の対処法

ここまでの手順で解決しない場合、原因は依存関係の深い位置にある。競合相手のクレート自体が古いblakeを要求し続けており、自分のCargo.tomlからは制御できない状態だ。
この場合、競合相手のクレートをアップデートすることで解決する。Anchorを使っているならAnchorのバージョンを最新にする。Solana SDKならsolana-programのバージョンを上げる。どちらもCargo.tomlの該当行を書き換えて cargo update を実行すればよい。
どうしても解消できない場合は、GitHubの該当リポジトリのissueを確認する。blake系のバージョン競合は一過性の問題であることが多く、既知のissueとして解決策が載っているケースがある。
再発を防ぐための依存関係管理

一度解決しても、依存関係の更新を繰り返すうちに再発する可能性はある。再発を防ぐには、Cargo.lockをリポジトリにコミットしておくのが基本だ。
Solanaプログラムのようなバイナリプロジェクトでは、Cargo.lockのコミットが推奨される。ロックファイルを共有することで、開発者全員が同じバージョンの依存関係を使い、環境による差異を防げる。
加えて、依存関係を更新する際は cargo update を一括で実行せず、関連するクレートを個別に更新する習慣をつける。更新後にビルドが通るかを確認すれば、競合が起きた原因を特定しやすくなる。
よくある質問
Cargo.lockを削除して再生成してもよいのか
最終手段としては有効だが、最初に試すべきではない。Cargo.lockを削除すると全依存関係が最新版に更新され、別の競合を引き起こす可能性がある。まず cargo update -p で対象を絞って更新するのが安全だ。
blake2とblake3は互換性があるのか
ない。blake2とblake3は別のアルゴリズムで、クレートも別物だ。どちらを使うかは依存元のクレートが決めるため、勝手に置き換えると署名検証やハッシュ値が一致しなくなる。競合しているクレート名を正確に特定してから対処する必要がある。
Anchorを使っている場合に特に注意することはあるか
Anchorはバージョンによって依存するblake3のバージョンが異なる。Anchorをアップデートする際は、リリースノートで依存関係の変更を確認してから行うと、競合の発生を未然に防げる。また、AnchorとSolana SDKの両方を同時に最新にすると、互換性の問題が起きにくい。
エラーメッセージに「failed to select a version for the requirement」と出る
このエラーは、Cargoが依存関係を解決できなかったことを示す。blake以外のクレートでも同じエラーが出る。解決の手順は共通で、cargo tree -i クレート名 で競合相手を特定し、バージョンを明示指定するのが基本だ。
この記事のポイント
- blakeの競合は複数クレートが異なるバージョンを要求するのが原因
- まず
cargo tree -i blake3で競合相手を特定する cargo update -p blake3で対象を絞って更新する- 解決しない場合はCargo.tomlでblake3のバージョンを明示指定する
- Cargo.lockはコミットして再発を防ぐ

「エミリーズ・クリプト・インサイダー」のリサーチ担当として、暗号資産の現場で日々生まれる疑問や悩みを丹念に追いかける。
Reddit や海外フォーラムに寄せられる声を読み解き、「初心者がつまずきやすいポイント」「経験者でも見落としがちな落とし穴
」を一つずつ記事として整理している。
専門的な話を誰もが理解できる言葉に置き換えることに全力を注ぐ。情報の正確さと読みやすさの両立を信条としている。
