资讯动态

WTF Solidity 超シンプル入門:抽象コントラクト(abstract)とインターフェース(interface)を実例でマスターする

发布时间:2026/9/15 22:44:39 来源:尧图企业网站定制
WTF Solidity 超シンプル入門抽象コントラクトabstractとインターフェースinterfaceを実例でマスターする【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity本稿は WTF-Solidity 入門コースの第14講を基に、Solidity における**抽象コントラクトabstractとインターフェースinterface**の設計思想・文法規則・実践用法を解説する技術ガイドです。ERC721 トークン標準のIERC721インターフェースと、実際の NFT プロジェクト「Bored Ape Yacht ClubBAYC」との対話例を題材に、コントラクトの「雛形テンプレート」を書くことでコードの冗長性を減らし、他コントラクトと安全に連携する方法を学びます。読了後は、抽象コントラクトの宣言規則、インターフェースの5大ルール、インターフェース経由で任意の実装コントラクトを呼び出すスキルを身につけられます。抽象コントラクトabstract contractスマートコントラクト内に未実装の関数関数本体{}の中身が空が1つ以上存在する場合、そのコントラクトは必ずabstractと宣言しなければなりません。宣言しないままコンパイルするとエラーになります。さらに、未実装の関数にはvirtualキーワードを付与し、子コントラクトがオーバーライドできるようにしておく必要があります。例として、本コースの挿入ソートコントラクトを考えます。挿入ソートの具体的な実装方法がまだ決まっていない段階でも、以下のように契約をabstractと宣言しておけば、将来ほかの開発者に実装を委ねることができます。abstract contract InsertionSort{ function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory); }抽象コントラクトの実例リポジトリのソースからリポジトリ内の AbstractDemo.sol には、抽象コントラクトを継承して実装する最小限のデモが収録されています。// SPDX-License-Identifier: MIT pragma solidity ^0.8.34; abstract contract Base{ string public name Base; function getAlias() public pure virtual returns(string memory); } contract BaseImpl is Base{ function getAlias() public pure override returns(string memory){ return BaseImpl; } }ポイントは次の通りです。抽象コントラクトBaseは状態変数nameを持つことができますインターフェースとの大きな違い。未実装関数getAlias()はvirtual宣言され、本体を持ちません。継承するコントラクトBaseImplはoverrideキーワードでgetAlias()を実装しています。このデモは Solidity^0.8.34を前提としており、uint[]など旧来の書き方もそのまま利用できます。インターフェースinterfaceinterfaceは抽象コントラクトと似ていますが、関数を一切実装しないことが求められます。インターフェースを宣言する際のルールは次の5つです。状態変数を含むことができないコンストラクタを含むことができないインターフェース以外のコントラクトを継承することができないinterface IERC721 is IERC165のように、インターフェース同士の継承は可能すべての関数はexternalでなければならず、関数本体{ }を持ってはならないインターフェースを継承する非抽象コントラクトは、定義されたすべての関数を実装しなければならないインターフェースが提供する2つの重要な情報インターフェースは実際の機能を実装しませんが、スマートコントラクトの「骨格スケルトン」として極めて重要です。あるコントラクトがインターフェースERC20やERC721などを実装していれば、他の Dapps やスマートコントラクトは、その詳細な内部実装を知らなくても対話方法を理解できます。その理由は、インターフェースが次の2つの情報を提供するためです。関数セレクターと関数シグネチャコントラクト内の各関数について、関数名(各パラメータの型)という関数シグネチャと、それをハッシュ化して先頭4バイトを取り出したbytes4セレクター。インターフェースIDinterface idERC165 仕様EIP-165に基づく識別子。詳細はリポジトリ内の IERC165.sol を参照してください。IERC165はsupportsInterface(bytes4 interfaceId)という関数を宣言しており、コントラクトがどのインターフェースを実装しているかを他のコントラクトが問い合わせられるようにします。インターフェースと ABI の等価性インターフェースはコントラクトのABIApplication Binary Interfaceと等価であり、相互に変換できます。インターフェースコントラクトをコンパイルするとその ABI が得られ、逆に ABI JSON ファイルからインターフェースの Solidity ファイルを復元することも可能です。IERC721ERC721 トークン標準のインターフェース具体例として、ERC721トークン標準を定義するIERC721インターフェースを見てみましょう。これは3つのイベントと9つの関数を持ち、すべてのERC721標準 NFT が実装しなければならない内容です。通常のコントラクトとの違いは、各関数の宣言が関数本体{ }ではなく;で終わる点です。また、インターフェース内の関数はすべてデフォルトでvirtualとみなされるため、明示的にvirtualを付ける必要はありません。interface IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) external view returns (uint256 balance); function ownerOf(uint256 tokenId) external view returns (address owner); function safeTransferFrom(address from, address to, uint256 tokenId) external; function transferFrom(address from, address to, uint256 tokenId) external; function approve(address to, uint256 tokenId) external; function getApproved(uint256 tokenId) external view returns (address operator); function setApprovalForAll(address operator, bool _approved) external; function isApprovedForAll(address owner, address operator) external view returns (bool); function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data) external; }この完全版の実装は 34_ERC721/IERC721.sol に収録されています。同ディレクトリの IERC721Receiver.sol には、安全転送時に受信側コントラクトが実装すべきonERC721Received()が宣言されています。IERC721 の3つのイベントTransferイベント転送の際に発火します。送信元アドレスfrom、受信アドレスto、tokenIdを記録します。Approvalイベント単体承認の際に発火します。トークン所有者owner、承認先アドレスapproved、tokenIdを記録します。ApprovalForAllイベントバッチ承認の際に発火します。バッチ承認を発行した所有者owner、承認先operator、承認が有効か否かを示すapprovedを記録します。IERC721 の9つの関数balanceOf引数のアドレスが保有する NFT の数量balanceを返します。ownerOftokenIdに対応する NFT の所有者ownerを返します。transferFromtokenIdの所有権をfromからtoへ移す通常の転送です。safeTransferFrom安全転送です。受信先がコントラクトアドレスの場合、IERC721Receiverインターフェースを実装していることを確認します受け取り関数の戻り値がonERC721Received.selectorと一致しない場合、リポジトリ実装では ERC721.sol の_checkOnERC721ReceivedがERC721InvalidReceiverエラーでリバートします。approve他のアドレスに特定 NFT の管理権限を付与・解除します。getApproved単一のtokenIdに対して承認されているアドレスを照会します。setApprovalForAllこのコントラクト内の全 NFT を管理する権限を第三者operatorに対して一括で有効化・無効化します。isApprovedForAllあるアドレスが別のアドレスの承認済みオペレーターバッチ承認先かどうかを照会します。safeTransferFromオーバーロード版パラメータにdataを含む安全転送用の重載関数です。なお、これらの関数がどのように実装されるかは、本コースのERC721 完全実装34_ERC721/ERC721.solで確認できます。balanceOfは_balancesマッピング、ownerOfは_ownersマッピング、approveは_tokenApprovalsマッピングを参照するなど、インターフェース宣言が内部の状態変数とどう対応するかをソースレベルで追跡できます。インターフェースはいつ使うのかBAYC との対話あるコントラクトがIERC721インターフェースを実装していると分かっていれば、その具体的なコード実装を知らなくても対話できます。「Bored Ape Yacht ClubBAYC」はERC721規格の NFT であり、IERC721インターフェースのすべての関数を実装しています。BAYC のソースコードを知らなくても、コントラクトアドレスとIERC721インターフェースさえ分かれば、balanceOf()でアドレスの BAYC 保有数を照会したり、safeTransferFrom()で BAYC を転送したりできます。contract interactBAYC { // BAYCアドレスを使ってインターフェース型のコントラクト変数を作成ETHメインネット IERC721 BAYC IERC721(0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D); // インターフェース経由で BAYC の balanceOf() を呼び出し、保有数を照会 function balanceOfBAYC(address owner) external view returns (uint256 balance){ return BAYC.balanceOf(owner); } // インターフェース経由で BAYC の safeTransferFrom() を呼び出し、安全に転送 function safeTransferFromBAYC(address from, address to, uint256 tokenId) external{ BAYC.safeTransferFrom(from, to, tokenId); } }このデモコードは Languages/ja/14_Interface_ja/Interface.sol に収録されています同ファイル冒頭には抽象コントラクトのInsertionSort例も含まれています。インターフェースを「型」として使うことで、実装の詳細に依存しない疎結合な設計が可能になることが分かります。インターフェースと実装の対応例リポジトリの InterfaceDemo.sol には、インターフェースを実装する最小デモもあります。// SPDX-License-Identifier: MIT pragma solidity ^0.8.34; interface Base { function getFirstName() external pure returns(string memory); function getLastName() external pure returns(string memory); } contract BaseImpl is Base{ function getFirstName() external pure override returns(string memory){ return Amazing; } function getLastName() external pure override returns(string memory){ return Ang; } }インターフェースに宣言されたすべての関数を、継承側でoverride付きで実装している点がルール5非抽象コントラクトは全関数の実装が必須の具体例です。Remix での検証方法本講のコードは Remix IDE 上ですぐに検証できます。抽象コントラクトの例Base抽象とBaseImpl実装をコンパイル・デプロイし、BaseImpl.getAlias()がBaseImplを返すことを確認します。下図の通り、未実装関数を含むコントラクトはabstract宣言によりコンパイルが通ります。インターフェースの例IERC721インターフェースをコンパイルし、interactBAYCコントラクトをデプロイしてbalanceOfBAYC()やsafeTransferFromBAYC()を呼び出します。インターフェースの関数が;で終わる構文と、インターフェース経由の外部コールが動作する様子を確認できます。まとめこの講では、Solidity の**抽象コントラクトabstractとインターフェースinterface**を紹介しました。いずれも「コントラクトの雛形」を書き、ソースコードの冗長性を低減するために使われます。未実装関数を含むコントラクトはabstract宣言が必須で、未実装関数にはvirtualを付けます。interfaceは状態変数・コンストラクタを持てず、全関数がexternalかつ本体なし、という5つのルールに従います。ERC721標準のインターフェースIERC7213イベント・9関数は NFT コントラクト相互運用の共通言語です。インターフェースを型として利用すれば、BAYC のような既存プロジェクトの詳細実装を知らなくても安全に対話できます。さらに深く学びたい方は、本リポジトリの第14講の readme日本語版、インターフェース関連のソース一式、そして実際の ERC721 コントラクト実装34_ERC721/ERC721.sol をあわせて読むことで、宣言と実装の対応関係をより確実に理解できます。【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价