CINXE.COM

Contracts — Solidity 0.8.29 documentation

<!DOCTYPE html> <html class="writer-html5" lang="en"> <head> <meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Contracts &mdash; Solidity 0.8.29 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css" /> <link rel="stylesheet" type="text/css" href="_static/a4_railroad_diagram.css" /> <link rel="stylesheet" type="text/css" href="_static/css/fonts.css" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css" /> <link rel="stylesheet" type="text/css" href="_static/css/custom-dark.css" /> <link rel="stylesheet" type="text/css" href="_static/css/pygments.css" /> <link rel="stylesheet" type="text/css" href="_static/css/toggle.css" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <!--[if lt IE 9]> <script src="_static/js/html5shiv.min.js"></script> <![endif]--> <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script> <script src="_static/jquery.js"></script> <script src="_static/underscore.js"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js"></script> <script src="_static/doctools.js"></script> <script src="_static/sphinx_highlight.js"></script> <script src="_static/js/constants.js"></script> <script src="_static/js/initialize.js"></script> <script src="_static/js/toggle.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" /> <link rel="next" title="Inline Assembly" href="assembly.html" /> <link rel="prev" title="Expressions and Control Structures" href="control-structures.html" /> <script async type="text/javascript" src="/_/static/javascript/readthedocs-addons.js"></script><meta name="readthedocs-project-slug" content="solidity" /><meta name="readthedocs-version-slug" content="latest" /><meta name="readthedocs-resolver-filename" content="/contracts.html" /><meta name="readthedocs-http-status" content="200" /></head> <body class="wy-body-for-nav"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search" > <a href="index.html"> </a> <div class="version"> 0.8.29 </div> <div role="search"> <form id="rtd-search-form" class="wy-form" action="search.html" method="get"> <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> <p class="caption" role="heading"><span class="caption-text">Basics</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="introduction-to-smart-contracts.html">Introduction to Smart Contracts</a></li> <li class="toctree-l1"><a class="reference internal" href="solidity-by-example.html">Solidity by Example</a></li> <li class="toctree-l1"><a class="reference internal" href="installing-solidity.html">Installing the Solidity Compiler</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Language Description</span></p> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="layout-of-source-files.html">Layout of a Solidity Source File</a></li> <li class="toctree-l1"><a class="reference internal" href="structure-of-a-contract.html">Structure of a Contract</a></li> <li class="toctree-l1"><a class="reference internal" href="types.html">Types</a></li> <li class="toctree-l1"><a class="reference internal" href="units-and-global-variables.html">Units and Globally Available Variables</a></li> <li class="toctree-l1"><a class="reference internal" href="control-structures.html">Expressions and Control Structures</a></li> <li class="toctree-l1 current"><a class="current reference internal" href="#">Contracts</a><ul> <li class="toctree-l2"><a class="reference internal" href="#creating-contracts">Creating Contracts</a></li> <li class="toctree-l2"><a class="reference internal" href="#visibility-and-getters">Visibility and Getters</a><ul> <li class="toctree-l3"><a class="reference internal" href="#state-variable-visibility">State Variable Visibility</a></li> <li class="toctree-l3"><a class="reference internal" href="#function-visibility">Function Visibility</a></li> <li class="toctree-l3"><a class="reference internal" href="#getter-functions">Getter Functions</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#function-modifiers">Function Modifiers</a></li> <li class="toctree-l2"><a class="reference internal" href="#transient-storage">Transient Storage</a></li> <li class="toctree-l2"><a class="reference internal" href="#composability-of-smart-contracts-and-the-caveats-of-transient-storage">Composability of Smart Contracts and the Caveats of Transient Storage</a></li> <li class="toctree-l2"><a class="reference internal" href="#constant-and-immutable-state-variables">Constant and Immutable State Variables</a><ul> <li class="toctree-l3"><a class="reference internal" href="#constant">Constant</a></li> <li class="toctree-l3"><a class="reference internal" href="#immutable">Immutable</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#functions">Functions</a><ul> <li class="toctree-l3"><a class="reference internal" href="#function-parameters-and-return-variables">Function Parameters and Return Variables</a><ul> <li class="toctree-l4"><a class="reference internal" href="#function-parameters">Function Parameters</a></li> <li class="toctree-l4"><a class="reference internal" href="#return-variables">Return Variables</a></li> <li class="toctree-l4"><a class="reference internal" href="#returning-multiple-values">Returning Multiple Values</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#state-mutability">State Mutability</a><ul> <li class="toctree-l4"><a class="reference internal" href="#view-functions">View Functions</a></li> <li class="toctree-l4"><a class="reference internal" href="#pure-functions">Pure Functions</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#special-functions">Special Functions</a><ul> <li class="toctree-l4"><a class="reference internal" href="#receive-ether-function">Receive Ether Function</a></li> <li class="toctree-l4"><a class="reference internal" href="#fallback-function">Fallback Function</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#function-overloading">Function Overloading</a><ul> <li class="toctree-l4"><a class="reference internal" href="#overload-resolution-and-argument-matching">Overload resolution and Argument matching</a></li> </ul> </li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#events">Events</a><ul> <li class="toctree-l3"><a class="reference internal" href="#members-of-events">Members of Events</a></li> <li class="toctree-l3"><a class="reference internal" href="#example">Example</a></li> <li class="toctree-l3"><a class="reference internal" href="#additional-resources-for-understanding-events">Additional Resources for Understanding Events</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#custom-errors">Custom Errors</a><ul> <li class="toctree-l3"><a class="reference internal" href="#members-of-errors">Members of Errors</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#inheritance">Inheritance</a><ul> <li class="toctree-l3"><a class="reference internal" href="#function-overriding">Function Overriding</a></li> <li class="toctree-l3"><a class="reference internal" href="#modifier-overriding">Modifier Overriding</a></li> <li class="toctree-l3"><a class="reference internal" href="#constructors">Constructors</a></li> <li class="toctree-l3"><a class="reference internal" href="#arguments-for-base-constructors">Arguments for Base Constructors</a></li> <li class="toctree-l3"><a class="reference internal" href="#multiple-inheritance-and-linearization">Multiple Inheritance and Linearization</a></li> <li class="toctree-l3"><a class="reference internal" href="#inheriting-different-kinds-of-members-of-the-same-name">Inheriting Different Kinds of Members of the Same Name</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#abstract-contracts">Abstract Contracts</a></li> <li class="toctree-l2"><a class="reference internal" href="#interfaces">Interfaces</a></li> <li class="toctree-l2"><a class="reference internal" href="#libraries">Libraries</a><ul> <li class="toctree-l3"><a class="reference internal" href="#function-signatures-and-selectors-in-libraries">Function Signatures and Selectors in Libraries</a></li> <li class="toctree-l3"><a class="reference internal" href="#call-protection-for-libraries">Call Protection For Libraries</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="#using-for">Using For</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="assembly.html">Inline Assembly</a></li> <li class="toctree-l1"><a class="reference internal" href="cheatsheet.html">Cheatsheet</a></li> <li class="toctree-l1"><a class="reference internal" href="grammar.html">Language Grammar</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Compiler</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="using-the-compiler.html">Using the Compiler</a></li> <li class="toctree-l1"><a class="reference internal" href="analysing-compilation-output.html">Analysing the Compiler Output</a></li> <li class="toctree-l1"><a class="reference internal" href="ir-breaking-changes.html">Solidity IR-based Codegen Changes</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Internals</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="internals/layout_in_storage.html">Layout of State Variables in Storage and Transient Storage</a></li> <li class="toctree-l1"><a class="reference internal" href="internals/layout_in_memory.html">Layout in Memory</a></li> <li class="toctree-l1"><a class="reference internal" href="internals/layout_in_calldata.html">Layout of Call Data</a></li> <li class="toctree-l1"><a class="reference internal" href="internals/variable_cleanup.html">Cleaning Up Variables</a></li> <li class="toctree-l1"><a class="reference internal" href="internals/source_mappings.html">Source Mappings</a></li> <li class="toctree-l1"><a class="reference internal" href="internals/optimizer.html">The Optimizer</a></li> <li class="toctree-l1"><a class="reference internal" href="metadata.html">Contract Metadata</a></li> <li class="toctree-l1"><a class="reference internal" href="abi-spec.html">Contract ABI Specification</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Advisory content</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="security-considerations.html">Security Considerations</a></li> <li class="toctree-l1"><a class="reference internal" href="bugs.html">List of Known Bugs</a></li> <li class="toctree-l1"><a class="reference internal" href="050-breaking-changes.html">Solidity v0.5.0 Breaking Changes</a></li> <li class="toctree-l1"><a class="reference internal" href="060-breaking-changes.html">Solidity v0.6.0 Breaking Changes</a></li> <li class="toctree-l1"><a class="reference internal" href="070-breaking-changes.html">Solidity v0.7.0 Breaking Changes</a></li> <li class="toctree-l1"><a class="reference internal" href="080-breaking-changes.html">Solidity v0.8.0 Breaking Changes</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Additional Material</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="natspec-format.html">NatSpec Format</a></li> <li class="toctree-l1"><a class="reference internal" href="smtchecker.html">SMTChecker and Formal Verification</a></li> <li class="toctree-l1"><a class="reference internal" href="yul.html">Yul</a></li> <li class="toctree-l1"><a class="reference internal" href="path-resolution.html">Import Path Resolution</a></li> </ul> <p class="caption" role="heading"><span class="caption-text">Resources</span></p> <ul> <li class="toctree-l1"><a class="reference internal" href="style-guide.html">Style Guide</a></li> <li class="toctree-l1"><a class="reference internal" href="common-patterns.html">Common Patterns</a></li> <li class="toctree-l1"><a class="reference internal" href="resources.html">Resources</a></li> <li class="toctree-l1"><a class="reference internal" href="contributing.html">Contributing</a></li> <li class="toctree-l1"><a class="reference internal" href="language-influences.html">Language Influences</a></li> <li class="toctree-l1"><a class="reference internal" href="brand-guide.html">Solidity Brand Guide</a></li> </ul> <ul> <li> <a href="genindex.html">Keyword Index</a> </li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="index.html">Solidity</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="Page navigation"> <ul class="wy-breadcrumbs"> <li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li> <li class="breadcrumb-item active">Contracts</li> <li class="wy-breadcrumbs-aside"> <a href="https://github.com/ethereum/solidity/blob/latest/docs/contracts.rst" class="fa fa-github"> Edit on GitHub</a> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <section id="contracts"> <span id="index-0"></span><span id="id1"></span><h1>Contracts<a class="headerlink" href="#contracts" title="Permalink to this heading"></a></h1> <p>Contracts in Solidity are similar to classes in object-oriented languages. They contain persistent data in state variables, and functions that can modify these variables. Calling a function on a different contract (instance) will perform an EVM function call and thus switch the context such that state variables in the calling contract are inaccessible. A contract and its functions need to be called for anything to happen. There is no “cron” concept in Ethereum to call a function at a particular event automatically.</p> <section id="creating-contracts"> <span id="index-1"></span><h2>Creating Contracts<a class="headerlink" href="#creating-contracts" title="Permalink to this heading"></a></h2> <p>Contracts can be created “from outside” via Ethereum transactions or from within Solidity contracts.</p> <p>IDEs, such as <a class="reference external" href="https://remix.ethereum.org/">Remix</a>, make the creation process seamless using UI elements.</p> <p>One way to create contracts programmatically on Ethereum is via the JavaScript API <a class="reference external" href="https://github.com/web3/web3.js">web3.js</a>. It has a function called <a class="reference external" href="https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract">web3.eth.Contract</a> to facilitate contract creation.</p> <p>When a contract is created, its <a class="reference internal" href="#constructor"><span class="std std-ref">constructor</span></a> (a function declared with the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> keyword) is executed once.</p> <p>A constructor is optional. Only one constructor is allowed, which means overloading is not supported.</p> <p>After the constructor has executed, the final code of the contract is stored on the blockchain. This code includes all public and external functions and all functions that are reachable from there through function calls. The deployed code does not include the constructor code or internal functions only called from the constructor.</p> <p id="index-2">Internally, constructor arguments are passed <a class="reference internal" href="abi-spec.html#abi"><span class="std std-ref">ABI encoded</span></a> after the code of the contract itself, but you do not have to care about this if you use <code class="docutils literal notranslate"><span class="pre">web3.js</span></code>.</p> <p>If a contract wants to create another contract, the source code (and the binary) of the created contract has to be known to the creator. This means that cyclic creation dependencies are impossible.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjIyIDwwLjkuMDsKCgpjb250cmFjdCBPd25lZFRva2VuIHsKICAgIC8vIGBUb2tlbkNyZWF0b3JgIGlzIGEgY29udHJhY3QgdHlwZSB0aGF0IGlzIGRlZmluZWQgYmVsb3cuCiAgICAvLyBJdCBpcyBmaW5lIHRvIHJlZmVyZW5jZSBpdCBhcyBsb25nIGFzIGl0IGlzIG5vdCB1c2VkCiAgICAvLyB0byBjcmVhdGUgYSBuZXcgY29udHJhY3QuCiAgICBUb2tlbkNyZWF0b3IgY3JlYXRvcjsKICAgIGFkZHJlc3Mgb3duZXI7CiAgICBieXRlczMyIG5hbWU7CgogICAgLy8gVGhpcyBpcyB0aGUgY29uc3RydWN0b3Igd2hpY2ggcmVnaXN0ZXJzIHRoZQogICAgLy8gY3JlYXRvciBhbmQgdGhlIGFzc2lnbmVkIG5hbWUuCiAgICBjb25zdHJ1Y3RvcihieXRlczMyIG5hbWVfKSB7CiAgICAgICAgLy8gU3RhdGUgdmFyaWFibGVzIGFyZSBhY2Nlc3NlZCB2aWEgdGhlaXIgbmFtZQogICAgICAgIC8vIGFuZCBub3QgdmlhIGUuZy4gYHRoaXMub3duZXJgLiBGdW5jdGlvbnMgY2FuCiAgICAgICAgLy8gYmUgYWNjZXNzZWQgZGlyZWN0bHkgb3IgdGhyb3VnaCBgdGhpcy5mYCwKICAgICAgICAvLyBidXQgdGhlIGxhdHRlciBwcm92aWRlcyBhbiBleHRlcm5hbCB2aWV3CiAgICAgICAgLy8gdG8gdGhlIGZ1bmN0aW9uLiBFc3BlY2lhbGx5IGluIHRoZSBjb25zdHJ1Y3RvciwKICAgICAgICAvLyB5b3Ugc2hvdWxkIG5vdCBhY2Nlc3MgZnVuY3Rpb25zIGV4dGVybmFsbHksCiAgICAgICAgLy8gYmVjYXVzZSB0aGUgZnVuY3Rpb24gZG9lcyBub3QgZXhpc3QgeWV0LgogICAgICAgIC8vIFNlZSB0aGUgbmV4dCBzZWN0aW9uIGZvciBkZXRhaWxzLgogICAgICAgIG93bmVyID0gbXNnLnNlbmRlcjsKCiAgICAgICAgLy8gV2UgcGVyZm9ybSBhbiBleHBsaWNpdCB0eXBlIGNvbnZlcnNpb24gZnJvbSBgYWRkcmVzc2AKICAgICAgICAvLyB0byBgVG9rZW5DcmVhdG9yYCBhbmQgYXNzdW1lIHRoYXQgdGhlIHR5cGUgb2YKICAgICAgICAvLyB0aGUgY2FsbGluZyBjb250cmFjdCBpcyBgVG9rZW5DcmVhdG9yYCwgdGhlcmUgaXMKICAgICAgICAvLyBubyByZWFsIHdheSB0byB2ZXJpZnkgdGhhdC4KICAgICAgICAvLyBUaGlzIGRvZXMgbm90IGNyZWF0ZSBhIG5ldyBjb250cmFjdC4KICAgICAgICBjcmVhdG9yID0gVG9rZW5DcmVhdG9yKG1zZy5zZW5kZXIpOwogICAgICAgIG5hbWUgPSBuYW1lXzsKICAgIH0KCiAgICBmdW5jdGlvbiBjaGFuZ2VOYW1lKGJ5dGVzMzIgbmV3TmFtZSkgcHVibGljIHsKICAgICAgICAvLyBPbmx5IHRoZSBjcmVhdG9yIGNhbiBhbHRlciB0aGUgbmFtZS4KICAgICAgICAvLyBXZSBjb21wYXJlIHRoZSBjb250cmFjdCBiYXNlZCBvbiBpdHMKICAgICAgICAvLyBhZGRyZXNzIHdoaWNoIGNhbiBiZSByZXRyaWV2ZWQgYnkKICAgICAgICAvLyBleHBsaWNpdCBjb252ZXJzaW9uIHRvIGFkZHJlc3MuCiAgICAgICAgaWYgKG1zZy5zZW5kZXIgPT0gYWRkcmVzcyhjcmVhdG9yKSkKICAgICAgICAgICAgbmFtZSA9IG5ld05hbWU7CiAgICB9CgogICAgZnVuY3Rpb24gdHJhbnNmZXIoYWRkcmVzcyBuZXdPd25lcikgcHVibGljIHsKICAgICAgICAvLyBPbmx5IHRoZSBjdXJyZW50IG93bmVyIGNhbiB0cmFuc2ZlciB0aGUgdG9rZW4uCiAgICAgICAgaWYgKG1zZy5zZW5kZXIgIT0gb3duZXIpIHJldHVybjsKCiAgICAgICAgLy8gV2UgYXNrIHRoZSBjcmVhdG9yIGNvbnRyYWN0IGlmIHRoZSB0cmFuc2ZlcgogICAgICAgIC8vIHNob3VsZCBwcm9jZWVkIGJ5IHVzaW5nIGEgZnVuY3Rpb24gb2YgdGhlCiAgICAgICAgLy8gYFRva2VuQ3JlYXRvcmAgY29udHJhY3QgZGVmaW5lZCBiZWxvdy4gSWYKICAgICAgICAvLyB0aGUgY2FsbCBmYWlscyAoZS5nLiBkdWUgdG8gb3V0LW9mLWdhcyksCiAgICAgICAgLy8gdGhlIGV4ZWN1dGlvbiBhbHNvIGZhaWxzIGhlcmUuCiAgICAgICAgaWYgKGNyZWF0b3IuaXNUb2tlblRyYW5zZmVyT0sob3duZXIsIG5ld093bmVyKSkKICAgICAgICAgICAgb3duZXIgPSBuZXdPd25lcjsKICAgIH0KfQoKCmNvbnRyYWN0IFRva2VuQ3JlYXRvciB7CiAgICBmdW5jdGlvbiBjcmVhdGVUb2tlbihieXRlczMyIG5hbWUpCiAgICAgICAgcHVibGljCiAgICAgICAgcmV0dXJucyAoT3duZWRUb2tlbiB0b2tlbkFkZHJlc3MpCiAgICB7CiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGBUb2tlbmAgY29udHJhY3QgYW5kIHJldHVybiBpdHMgYWRkcmVzcy4KICAgICAgICAvLyBGcm9tIHRoZSBKYXZhU2NyaXB0IHNpZGUsIHRoZSByZXR1cm4gdHlwZQogICAgICAgIC8vIG9mIHRoaXMgZnVuY3Rpb24gaXMgYGFkZHJlc3NgLCBhcyB0aGlzIGlzCiAgICAgICAgLy8gdGhlIGNsb3Nlc3QgdHlwZSBhdmFpbGFibGUgaW4gdGhlIEFCSS4KICAgICAgICByZXR1cm4gbmV3IE93bmVkVG9rZW4obmFtZSk7CiAgICB9CgogICAgZnVuY3Rpb24gY2hhbmdlTmFtZShPd25lZFRva2VuIHRva2VuQWRkcmVzcywgYnl0ZXMzMiBuYW1lKSBwdWJsaWMgewogICAgICAgIC8vIEFnYWluLCB0aGUgZXh0ZXJuYWwgdHlwZSBvZiBgdG9rZW5BZGRyZXNzYCBpcwogICAgICAgIC8vIHNpbXBseSBgYWRkcmVzc2AuCiAgICAgICAgdG9rZW5BZGRyZXNzLmNoYW5nZU5hbWUobmFtZSk7CiAgICB9CgogICAgLy8gUGVyZm9ybSBjaGVja3MgdG8gZGV0ZXJtaW5lIGlmIHRyYW5zZmVycmluZyBhIHRva2VuIHRvIHRoZQogICAgLy8gYE93bmVkVG9rZW5gIGNvbnRyYWN0IHNob3VsZCBwcm9jZWVkCiAgICBmdW5jdGlvbiBpc1Rva2VuVHJhbnNmZXJPSyhhZGRyZXNzIGN1cnJlbnRPd25lciwgYWRkcmVzcyBuZXdPd25lcikKICAgICAgICBwdWJsaWMKICAgICAgICBwdXJlCiAgICAgICAgcmV0dXJucyAoYm9vbCBvaykKICAgIHsKICAgICAgICAvLyBDaGVjayBhbiBhcmJpdHJhcnkgY29uZGl0aW9uIHRvIHNlZSBpZiB0cmFuc2ZlciBzaG91bGQgcHJvY2VlZAogICAgICAgIHJldHVybiBrZWNjYWsyNTYoYWJpLmVuY29kZVBhY2tlZChjdXJyZW50T3duZXIsIG5ld093bmVyKSlbMF0gPT0gMHg3ZjsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.22</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">OwnedToken</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// `TokenCreator` is a contract type that is defined below.</span> <span class="w"> </span><span class="c1">// It is fine to reference it as long as it is not used</span> <span class="w"> </span><span class="c1">// to create a new contract.</span> <span class="w"> </span>TokenCreator<span class="w"> </span>creator<span class="p">;</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">owner</span><span class="p">;</span> <span class="w"> </span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name</span><span class="p">;</span> <span class="w"> </span><span class="c1">// This is the constructor which registers the</span> <span class="w"> </span><span class="c1">// creator and the assigned name.</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name_</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// State variables are accessed via their name</span> <span class="w"> </span><span class="c1">// and not via e.g. `this.owner`. Functions can</span> <span class="w"> </span><span class="c1">// be accessed directly or through `this.f`,</span> <span class="w"> </span><span class="c1">// but the latter provides an external view</span> <span class="w"> </span><span class="c1">// to the function. Especially in the constructor,</span> <span class="w"> </span><span class="c1">// you should not access functions externally,</span> <span class="w"> </span><span class="c1">// because the function does not exist yet.</span> <span class="w"> </span><span class="c1">// See the next section for details.</span> <span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.sender</span><span class="p">;</span> <span class="w"> </span><span class="c1">// We perform an explicit type conversion from `address`</span> <span class="w"> </span><span class="c1">// to `TokenCreator` and assume that the type of</span> <span class="w"> </span><span class="c1">// the calling contract is `TokenCreator`, there is</span> <span class="w"> </span><span class="c1">// no real way to verify that.</span> <span class="w"> </span><span class="c1">// This does not create a new contract.</span> <span class="w"> </span>creator<span class="w"> </span><span class="o">=</span><span class="w"> </span>TokenCreator<span class="p">(</span><span class="k">msg.sender</span><span class="p">);</span> <span class="w"> </span>name<span class="w"> </span><span class="o">=</span><span class="w"> </span>name_<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">changeName</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">newName</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Only the creator can alter the name.</span> <span class="w"> </span><span class="c1">// We compare the contract based on its</span> <span class="w"> </span><span class="c1">// address which can be retrieved by</span> <span class="w"> </span><span class="c1">// explicit conversion to address.</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kt">address</span><span class="p">(</span>creator<span class="p">))</span> <span class="w"> </span>name<span class="w"> </span><span class="o">=</span><span class="w"> </span>newName<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">transfer</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">newOwner</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Only the current owner can transfer the token.</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span>owner<span class="p">)</span><span class="w"> </span><span class="kt">return</span><span class="p">;</span> <span class="w"> </span><span class="c1">// We ask the creator contract if the transfer</span> <span class="w"> </span><span class="c1">// should proceed by using a function of the</span> <span class="w"> </span><span class="c1">// `TokenCreator` contract defined below. If</span> <span class="w"> </span><span class="c1">// the call fails (e.g. due to out-of-gas),</span> <span class="w"> </span><span class="c1">// the execution also fails here.</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>creator<span class="p">.</span>isTokenTransferOK<span class="p">(</span>owner<span class="p">,</span><span class="w"> </span>newOwner<span class="p">))</span> <span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span>newOwner<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">TokenCreator</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">createToken</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>OwnedToken<span class="w"> </span>tokenAddress<span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Create a new `Token` contract and return its address.</span> <span class="w"> </span><span class="c1">// From the JavaScript side, the return type</span> <span class="w"> </span><span class="c1">// of this function is `address`, as this is</span> <span class="w"> </span><span class="c1">// the closest type available in the ABI.</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span>OwnedToken<span class="p">(</span>name<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">changeName</span><span class="p">(</span>OwnedToken<span class="w"> </span>tokenAddress<span class="p">,</span><span class="w"> </span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Again, the external type of `tokenAddress` is</span> <span class="w"> </span><span class="c1">// simply `address`.</span> <span class="w"> </span>tokenAddress<span class="p">.</span>changeName<span class="p">(</span>name<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// Perform checks to determine if transferring a token to the</span> <span class="w"> </span><span class="c1">// `OwnedToken` contract should proceed</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">isTokenTransferOK</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">currentOwner</span><span class="p">,</span><span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">newOwner</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span>pure <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="nv">ok</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Check an arbitrary condition to see if transfer should proceed</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="nb">keccak256</span><span class="p">(</span>abi<span class="p">.</span>encodePacked<span class="p">(</span>currentOwner<span class="p">,</span><span class="w"> </span>newOwner<span class="p">))[</span><span class="m m-Decimal">0</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mh">0x7f</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <span class="target" id="index-3"></span></section> <section id="visibility-and-getters"> <span id="id2"></span><h2>Visibility and Getters<a class="headerlink" href="#visibility-and-getters" title="Permalink to this heading"></a></h2> <section id="state-variable-visibility"> <h3>State Variable Visibility<a class="headerlink" href="#state-variable-visibility" title="Permalink to this heading"></a></h3> <dl class="simple"> <dt><code class="docutils literal notranslate"><span class="pre">public</span></code></dt><dd><p>Public state variables differ from internal ones only in that the compiler automatically generates <a class="reference internal" href="#getter-functions"><span class="std std-ref">getter functions</span></a> for them, which allows other contracts to read their values. When used within the same contract, the external access (e.g. <code class="docutils literal notranslate"><span class="pre">this.x</span></code>) invokes the getter while internal access (e.g. <code class="docutils literal notranslate"><span class="pre">x</span></code>) gets the variable value directly from storage. Setter functions are not generated so other contracts cannot directly modify their values.</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">internal</span></code></dt><dd><p>Internal state variables can only be accessed from within the contract they are defined in and in derived contracts. They cannot be accessed externally. This is the default visibility level for state variables.</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">private</span></code></dt><dd><p>Private state variables are like internal ones but they are not visible in derived contracts.</p> </dd> </dl> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>Making something <code class="docutils literal notranslate"><span class="pre">private</span></code> or <code class="docutils literal notranslate"><span class="pre">internal</span></code> only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain.</p> </div> </section> <section id="function-visibility"> <h3>Function Visibility<a class="headerlink" href="#function-visibility" title="Permalink to this heading"></a></h3> <p>Solidity knows two kinds of function calls: external ones that do create an actual EVM message call and internal ones that do not. Furthermore, internal functions can be made inaccessible to derived contracts. This gives rise to four types of visibility for functions.</p> <dl class="simple"> <dt><code class="docutils literal notranslate"><span class="pre">external</span></code></dt><dd><p>External functions are part of the contract interface, which means they can be called from other contracts and via transactions. An external function <code class="docutils literal notranslate"><span class="pre">f</span></code> cannot be called internally (i.e. <code class="docutils literal notranslate"><span class="pre">f()</span></code> does not work, but <code class="docutils literal notranslate"><span class="pre">this.f()</span></code> works).</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">public</span></code></dt><dd><p>Public functions are part of the contract interface and can be either called internally or via message calls.</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">internal</span></code></dt><dd><p>Internal functions can only be accessed from within the current contract or contracts deriving from it. They cannot be accessed externally. Since they are not exposed to the outside through the contract’s ABI, they can take parameters of internal types like mappings or storage references.</p> </dd> <dt><code class="docutils literal notranslate"><span class="pre">private</span></code></dt><dd><p>Private functions are like internal ones but they are not visible in derived contracts.</p> </dd> </dl> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>Making something <code class="docutils literal notranslate"><span class="pre">private</span></code> or <code class="docutils literal notranslate"><span class="pre">internal</span></code> only prevents other contracts from reading or modifying the information, but it will still be visible to the whole world outside of the blockchain.</p> </div> <p>The visibility specifier is given after the type for state variables and between parameter list and return parameter list for functions.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IEMgewogICAgZnVuY3Rpb24gZih1aW50IGEpIHByaXZhdGUgcHVyZSByZXR1cm5zICh1aW50IGIpIHsgcmV0dXJuIGEgKyAxOyB9CiAgICBmdW5jdGlvbiBzZXREYXRhKHVpbnQgYSkgaW50ZXJuYWwgeyBkYXRhID0gYTsgfQogICAgdWludCBwdWJsaWMgZGF0YTsKfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="kt">private</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">setData</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="kt">internal</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>data<span class="w"> </span><span class="o">=</span><span class="w"> </span>a<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">public </span><span class="nv">data</span><span class="p">;</span> <span class="p">}</span> </pre></div> </div> <p>In the following example, <code class="docutils literal notranslate"><span class="pre">D</span></code>, can call <code class="docutils literal notranslate"><span class="pre">c.getData()</span></code> to retrieve the value of <code class="docutils literal notranslate"><span class="pre">data</span></code> in state storage, but is not able to call <code class="docutils literal notranslate"><span class="pre">f</span></code>. Contract <code class="docutils literal notranslate"><span class="pre">E</span></code> is derived from <code class="docutils literal notranslate"><span class="pre">C</span></code> and, thus, can call <code class="docutils literal notranslate"><span class="pre">compute</span></code>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IEMgewogICAgdWludCBwcml2YXRlIGRhdGE7CgogICAgZnVuY3Rpb24gZih1aW50IGEpIHByaXZhdGUgcHVyZSByZXR1cm5zKHVpbnQgYikgeyByZXR1cm4gYSArIDE7IH0KICAgIGZ1bmN0aW9uIHNldERhdGEodWludCBhKSBwdWJsaWMgeyBkYXRhID0gYTsgfQogICAgZnVuY3Rpb24gZ2V0RGF0YSgpIHB1YmxpYyB2aWV3IHJldHVybnModWludCkgeyByZXR1cm4gZGF0YTsgfQogICAgZnVuY3Rpb24gY29tcHV0ZSh1aW50IGEsIHVpbnQgYikgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50KSB7IHJldHVybiBhICsgYjsgfQp9CgovLyBUaGlzIHdpbGwgbm90IGNvbXBpbGUKY29udHJhY3QgRCB7CiAgICBmdW5jdGlvbiByZWFkRGF0YSgpIHB1YmxpYyB7CiAgICAgICAgQyBjID0gbmV3IEMoKTsKICAgICAgICB1aW50IGxvY2FsID0gYy5mKDcpOyAvLyBlcnJvcjogbWVtYmVyIGBmYCBpcyBub3QgdmlzaWJsZQogICAgICAgIGMuc2V0RGF0YSgzKTsKICAgICAgICBsb2NhbCA9IGMuZ2V0RGF0YSgpOwogICAgICAgIGxvY2FsID0gYy5jb21wdXRlKDMsIDUpOyAvLyBlcnJvcjogbWVtYmVyIGBjb21wdXRlYCBpcyBub3QgdmlzaWJsZQogICAgfQp9Cgpjb250cmFjdCBFIGlzIEMgewogICAgZnVuY3Rpb24gZygpIHB1YmxpYyB7CiAgICAgICAgQyBjID0gbmV3IEMoKTsKICAgICAgICB1aW50IHZhbCA9IGNvbXB1dGUoMywgNSk7IC8vIGFjY2VzcyB0byBpbnRlcm5hbCBtZW1iZXIgKGZyb20gZGVyaXZlZCB0byBwYXJlbnQgY29udHJhY3QpCiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">private </span><span class="nv">data</span><span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="kt">private</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">setData</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>data<span class="w"> </span><span class="o">=</span><span class="w"> </span>a<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">getData</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>data<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">compute</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="kt">internal</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span>b<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="c1">// This will not compile</span> <span class="k">contract</span><span class="w"> </span><span class="ni">D</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">readData</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>C<span class="w"> </span>c<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span>C<span class="p">();</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">local</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>c<span class="p">.</span>f<span class="p">(</span><span class="m m-Decimal">7</span><span class="p">);</span><span class="w"> </span><span class="c1">// error: member `f` is not visible</span> <span class="w"> </span>c<span class="p">.</span>setData<span class="p">(</span><span class="m m-Decimal">3</span><span class="p">);</span> <span class="w"> </span>local<span class="w"> </span><span class="o">=</span><span class="w"> </span>c<span class="p">.</span>getData<span class="p">();</span> <span class="w"> </span>local<span class="w"> </span><span class="o">=</span><span class="w"> </span>c<span class="p">.</span>compute<span class="p">(</span><span class="m m-Decimal">3</span><span class="p">,</span><span class="w"> </span><span class="m m-Decimal">5</span><span class="p">);</span><span class="w"> </span><span class="c1">// error: member `compute` is not visible</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">E</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>C<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">g</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>C<span class="w"> </span>c<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span>C<span class="p">();</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>compute<span class="p">(</span><span class="m m-Decimal">3</span><span class="p">,</span><span class="w"> </span><span class="m m-Decimal">5</span><span class="p">);</span><span class="w"> </span><span class="c1">// access to internal member (from derived to parent contract)</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="getter-functions"> <span id="index-4"></span><span id="id3"></span><h3>Getter Functions<a class="headerlink" href="#getter-functions" title="Permalink to this heading"></a></h3> <p>The compiler automatically creates getter functions for all <strong>public</strong> state variables. For the contract given below, the compiler will generate a function called <code class="docutils literal notranslate"><span class="pre">data</span></code> that does not take any arguments and returns a <code class="docutils literal notranslate"><span class="pre">uint</span></code>, the value of the state variable <code class="docutils literal notranslate"><span class="pre">data</span></code>. State variables can be initialized when they are declared.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IEMgewogICAgdWludCBwdWJsaWMgZGF0YSA9IDQyOwp9Cgpjb250cmFjdCBDYWxsZXIgewogICAgQyBjID0gbmV3IEMoKTsKICAgIGZ1bmN0aW9uIGYoKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIGMuZGF0YSgpOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">public </span><span class="nv">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">42</span><span class="p">;</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Caller</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>C<span class="w"> </span>c<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span>C<span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>c<span class="p">.</span>data<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>The getter functions have external visibility. If the symbol is accessed internally (i.e. without <code class="docutils literal notranslate"><span class="pre">this.</span></code>), it evaluates to a state variable. If it is accessed externally (i.e. with <code class="docutils literal notranslate"><span class="pre">this.</span></code>), it evaluates to a function.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjAgPDAuOS4wOwoKY29udHJhY3QgQyB7CiAgICB1aW50IHB1YmxpYyBkYXRhOwogICAgZnVuY3Rpb24geCgpIHB1YmxpYyByZXR1cm5zICh1aW50KSB7CiAgICAgICAgZGF0YSA9IDM7IC8vIGludGVybmFsIGFjY2VzcwogICAgICAgIHJldHVybiB0aGlzLmRhdGEoKTsgLy8gZXh0ZXJuYWwgYWNjZXNzCiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">public </span><span class="nv">data</span><span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">x</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>data<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">3</span><span class="p">;</span><span class="w"> </span><span class="c1">// internal access</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">this</span><span class="p">.</span>data<span class="p">();</span><span class="w"> </span><span class="c1">// external access</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>If you have a <code class="docutils literal notranslate"><span class="pre">public</span></code> state variable of array type, then you can only retrieve single elements of the array via the generated getter function. This mechanism exists to avoid high gas costs when returning an entire array. You can use arguments to specify which individual element to return, for example <code class="docutils literal notranslate"><span class="pre">myArray(0)</span></code>. If you want to return an entire array in one call, then you need to write a function, for example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IGFycmF5RXhhbXBsZSB7CiAgICAvLyBwdWJsaWMgc3RhdGUgdmFyaWFibGUKICAgIHVpbnRbXSBwdWJsaWMgbXlBcnJheTsKCiAgICAvLyBHZXR0ZXIgZnVuY3Rpb24gZ2VuZXJhdGVkIGJ5IHRoZSBjb21waWxlcgogICAgLyoKICAgIGZ1bmN0aW9uIG15QXJyYXkodWludCBpKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIG15QXJyYXlbaV07CiAgICB9CiAgICAqLwoKICAgIC8vIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBlbnRpcmUgYXJyYXkKICAgIGZ1bmN0aW9uIGdldEFycmF5KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludFtdIG1lbW9yeSkgewogICAgICAgIHJldHVybiBteUFycmF5OwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">arrayExample</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// public state variable</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>myArray<span class="p">;</span> <span class="w"> </span><span class="c1">// Getter function generated by the compiler</span> <span class="w"> </span><span class="cm">/*</span> <span class="cm"> function myArray(uint i) public view returns (uint) {</span> <span class="cm"> return myArray[i];</span> <span class="cm"> }</span> <span class="cm"> */</span> <span class="w"> </span><span class="c1">// function that returns entire array</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">getArray</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span><span class="kt">memory</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>myArray<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Now you can use <code class="docutils literal notranslate"><span class="pre">getArray()</span></code> to retrieve the entire array, instead of <code class="docutils literal notranslate"><span class="pre">myArray(i)</span></code>, which returns a single element per call.</p> <p>The next example is more complex:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjAgPDAuOS4wOwoKY29udHJhY3QgQ29tcGxleCB7CiAgICBzdHJ1Y3QgRGF0YSB7CiAgICAgICAgdWludCBhOwogICAgICAgIGJ5dGVzMyBiOwogICAgICAgIG1hcHBpbmcodWludCA9PiB1aW50KSBtYXA7CiAgICAgICAgdWludFszXSBjOwogICAgICAgIHVpbnRbXSBkOwogICAgICAgIGJ5dGVzIGU7CiAgICB9CiAgICBtYXBwaW5nKHVpbnQgPT4gbWFwcGluZyhib29sID0+IERhdGFbXSkpIHB1YmxpYyBkYXRhOwp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Complex</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">struct</span><span class="w"> </span><span class="nv">Data</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">;</span> <span class="w"> </span>bytes3<span class="w"> </span>b<span class="p">;</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span>map<span class="p">;</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[</span><span class="m m-Decimal">3</span><span class="p">]</span><span class="w"> </span>c<span class="p">;</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span>d<span class="p">;</span> <span class="w"> </span><span class="kt">bytes</span><span class="w"> </span><span class="nv">e</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span>Data<span class="p">[]))</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>data<span class="p">;</span> <span class="p">}</span> </pre></div> </div> <p>It generates a function of the following form. The mapping and arrays (with the exception of byte arrays) in the struct are omitted because there is no good way to select individual struct members or provide a key for the mapping:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=ZnVuY3Rpb24gZGF0YSh1aW50IGFyZzEsIGJvb2wgYXJnMiwgdWludCBhcmczKQogICAgcHVibGljCiAgICByZXR1cm5zICh1aW50IGEsIGJ5dGVzMyBiLCBieXRlcyBtZW1vcnkgZSkKewogICAgYSA9IGRhdGFbYXJnMV1bYXJnMl1bYXJnM10uYTsKICAgIGIgPSBkYXRhW2FyZzFdW2FyZzJdW2FyZzNdLmI7CiAgICBlID0gZGF0YVthcmcxXVthcmcyXVthcmczXS5lOwp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="kt">function</span><span class="w"> </span><span class="nv">data</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">arg1</span><span class="p">,</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="nv">arg2</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">arg3</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span>bytes3<span class="w"> </span>b<span class="p">,</span><span class="w"> </span><span class="kt">bytes</span><span class="w"> </span><span class="nv">memory</span><span class="w"> </span>e<span class="p">)</span> <span class="p">{</span> <span class="w"> </span>a<span class="w"> </span><span class="o">=</span><span class="w"> </span>data<span class="p">[</span>arg1<span class="p">][</span>arg2<span class="p">][</span>arg3<span class="p">].</span>a<span class="p">;</span> <span class="w"> </span>b<span class="w"> </span><span class="o">=</span><span class="w"> </span>data<span class="p">[</span>arg1<span class="p">][</span>arg2<span class="p">][</span>arg3<span class="p">].</span>b<span class="p">;</span> <span class="w"> </span>e<span class="w"> </span><span class="o">=</span><span class="w"> </span>data<span class="p">[</span>arg1<span class="p">][</span>arg2<span class="p">][</span>arg3<span class="p">].</span>e<span class="p">;</span> <span class="p">}</span> </pre></div> </div> </section> </section> <section id="function-modifiers"> <span id="modifiers"></span><span id="index-5"></span><h2>Function Modifiers<a class="headerlink" href="#function-modifiers" title="Permalink to this heading"></a></h2> <p>Modifiers can be used to change the behavior of functions in a declarative way. For example, you can use a modifier to automatically check a condition prior to executing the function.</p> <p>Modifiers are inheritable properties of contracts and may be overridden by derived contracts, but only if they are marked <code class="docutils literal notranslate"><span class="pre">virtual</span></code>. For details, please see <a class="reference internal" href="#modifier-overriding"><span class="std std-ref">Modifier Overriding</span></a>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjEgPDAuOS4wOwoKY29udHJhY3Qgb3duZWQgewogICAgY29uc3RydWN0b3IoKSB7IG93bmVyID0gcGF5YWJsZShtc2cuc2VuZGVyKTsgfQogICAgYWRkcmVzcyBwYXlhYmxlIG93bmVyOwoKICAgIC8vIFRoaXMgY29udHJhY3Qgb25seSBkZWZpbmVzIGEgbW9kaWZpZXIgYnV0IGRvZXMgbm90IHVzZQogICAgLy8gaXQ6IGl0IHdpbGwgYmUgdXNlZCBpbiBkZXJpdmVkIGNvbnRyYWN0cy4KICAgIC8vIFRoZSBmdW5jdGlvbiBib2R5IGlzIGluc2VydGVkIHdoZXJlIHRoZSBzcGVjaWFsIHN5bWJvbAogICAgLy8gYF87YCBpbiB0aGUgZGVmaW5pdGlvbiBvZiBhIG1vZGlmaWVyIGFwcGVhcnMuCiAgICAvLyBUaGlzIG1lYW5zIHRoYXQgaWYgdGhlIG93bmVyIGNhbGxzIHRoaXMgZnVuY3Rpb24sIHRoZQogICAgLy8gZnVuY3Rpb24gaXMgZXhlY3V0ZWQgYW5kIG90aGVyd2lzZSwgYW4gZXhjZXB0aW9uIGlzCiAgICAvLyB0aHJvd24uCiAgICBtb2RpZmllciBvbmx5T3duZXIgewogICAgICAgIHJlcXVpcmUoCiAgICAgICAgICAgIG1zZy5zZW5kZXIgPT0gb3duZXIsCiAgICAgICAgICAgICJPbmx5IG93bmVyIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24uIgogICAgICAgICk7CiAgICAgICAgXzsKICAgIH0KfQoKY29udHJhY3QgcHJpY2VkIHsKICAgIC8vIE1vZGlmaWVycyBjYW4gcmVjZWl2ZSBhcmd1bWVudHM6CiAgICBtb2RpZmllciBjb3N0cyh1aW50IHByaWNlKSB7CiAgICAgICAgaWYgKG1zZy52YWx1ZSA+PSBwcmljZSkgewogICAgICAgICAgICBfOwogICAgICAgIH0KICAgIH0KfQoKY29udHJhY3QgUmVnaXN0ZXIgaXMgcHJpY2VkLCBvd25lZCB7CiAgICBtYXBwaW5nKGFkZHJlc3MgPT4gYm9vbCkgcmVnaXN0ZXJlZEFkZHJlc3NlczsKICAgIHVpbnQgcHJpY2U7CgogICAgY29uc3RydWN0b3IodWludCBpbml0aWFsUHJpY2UpIHsgcHJpY2UgPSBpbml0aWFsUHJpY2U7IH0KCiAgICAvLyBJdCBpcyBpbXBvcnRhbnQgdG8gYWxzbyBwcm92aWRlIHRoZQogICAgLy8gYHBheWFibGVgIGtleXdvcmQgaGVyZSwgb3RoZXJ3aXNlIHRoZSBmdW5jdGlvbiB3aWxsCiAgICAvLyBhdXRvbWF0aWNhbGx5IHJlamVjdCBhbGwgRXRoZXIgc2VudCB0byBpdC4KICAgIGZ1bmN0aW9uIHJlZ2lzdGVyKCkgcHVibGljIHBheWFibGUgY29zdHMocHJpY2UpIHsKICAgICAgICByZWdpc3RlcmVkQWRkcmVzc2VzW21zZy5zZW5kZXJdID0gdHJ1ZTsKICAgIH0KCiAgICAvLyBUaGlzIGNvbnRyYWN0IGluaGVyaXRzIHRoZSBgb25seU93bmVyYCBtb2RpZmllciBmcm9tCiAgICAvLyB0aGUgYG93bmVkYCBjb250cmFjdC4gQXMgYSByZXN1bHQsIGNhbGxzIHRvIGBjaGFuZ2VQcmljZWAgd2lsbAogICAgLy8gb25seSB0YWtlIGVmZmVjdCBpZiB0aGV5IGFyZSBtYWRlIGJ5IHRoZSBzdG9yZWQgb3duZXIuCiAgICBmdW5jdGlvbiBjaGFuZ2VQcmljZSh1aW50IHByaWNlXykgcHVibGljIG9ubHlPd25lciB7CiAgICAgICAgcHJpY2UgPSBwcmljZV87CiAgICB9Cn0KCmNvbnRyYWN0IE11dGV4IHsKICAgIGJvb2wgbG9ja2VkOwogICAgbW9kaWZpZXIgbm9SZWVudHJhbmN5KCkgewogICAgICAgIHJlcXVpcmUoCiAgICAgICAgICAgICFsb2NrZWQsCiAgICAgICAgICAgICJSZWVudHJhbnQgY2FsbC4iCiAgICAgICAgKTsKICAgICAgICBsb2NrZWQgPSB0cnVlOwogICAgICAgIF87CiAgICAgICAgbG9ja2VkID0gZmFsc2U7CiAgICB9CgogICAgLy8vIFRoaXMgZnVuY3Rpb24gaXMgcHJvdGVjdGVkIGJ5IGEgbXV0ZXgsIHdoaWNoIG1lYW5zIHRoYXQKICAgIC8vLyByZWVudHJhbnQgY2FsbHMgZnJvbSB3aXRoaW4gYG1zZy5zZW5kZXIuY2FsbGAgY2Fubm90IGNhbGwgYGZgIGFnYWluLgogICAgLy8vIFRoZSBgcmV0dXJuIDdgIHN0YXRlbWVudCBhc3NpZ25zIDcgdG8gdGhlIHJldHVybiB2YWx1ZSBidXQgc3RpbGwKICAgIC8vLyBleGVjdXRlcyB0aGUgc3RhdGVtZW50IGBsb2NrZWQgPSBmYWxzZWAgaW4gdGhlIG1vZGlmaWVyLgogICAgZnVuY3Rpb24gZigpIHB1YmxpYyBub1JlZW50cmFuY3kgcmV0dXJucyAodWludCkgewogICAgICAgIChib29sIHN1Y2Nlc3MsKSA9IG1zZy5zZW5kZXIuY2FsbCgiIik7CiAgICAgICAgcmVxdWlyZShzdWNjZXNzKTsKICAgICAgICByZXR1cm4gNzsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.1</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">owned</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">payable</span><span class="p">(</span><span class="k">msg.sender</span><span class="p">);</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">payable</span><span class="w"> </span>owner<span class="p">;</span> <span class="w"> </span><span class="c1">// This contract only defines a modifier but does not use</span> <span class="w"> </span><span class="c1">// it: it will be used in derived contracts.</span> <span class="w"> </span><span class="c1">// The function body is inserted where the special symbol</span> <span class="w"> </span><span class="c1">// `_;` in the definition of a modifier appears.</span> <span class="w"> </span><span class="c1">// This means that if the owner calls this function, the</span> <span class="w"> </span><span class="c1">// function is executed and otherwise, an exception is</span> <span class="w"> </span><span class="c1">// thrown.</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>onlyOwner<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span> <span class="w"> </span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">,</span> <span class="w"> </span><span class="s2">&quot;Only owner can call this function.&quot;</span> <span class="w"> </span><span class="p">);</span> <span class="w"> </span>_<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">priced</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Modifiers can receive arguments:</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>costs<span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">price</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.value</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span>price<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>_<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Register</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>priced<span class="p">,</span><span class="w"> </span>owned<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span>registeredAddresses<span class="p">;</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">price</span><span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">initialPrice</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>price<span class="w"> </span><span class="o">=</span><span class="w"> </span>initialPrice<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// It is important to also provide the</span> <span class="w"> </span><span class="c1">// `payable` keyword here, otherwise the function will</span> <span class="w"> </span><span class="c1">// automatically reject all Ether sent to it.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">register</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="kt">payable</span><span class="w"> </span>costs<span class="p">(</span>price<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>registeredAddresses<span class="p">[</span><span class="k">msg.sender</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// This contract inherits the `onlyOwner` modifier from</span> <span class="w"> </span><span class="c1">// the `owned` contract. As a result, calls to `changePrice` will</span> <span class="w"> </span><span class="c1">// only take effect if they are made by the stored owner.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">changePrice</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">price_</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>onlyOwner<span class="w"> </span><span class="p">{</span> <span class="w"> </span>price<span class="w"> </span><span class="o">=</span><span class="w"> </span>price_<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Mutex</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="nv">locked</span><span class="p">;</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>noReentrancy<span class="p">()</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span> <span class="w"> </span><span class="o">!</span>locked<span class="p">,</span> <span class="w"> </span><span class="s2">&quot;Reentrant call.&quot;</span> <span class="w"> </span><span class="p">);</span> <span class="w"> </span>locked<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span>_<span class="p">;</span> <span class="w"> </span>locked<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">/// This function is protected by a mutex, which means that</span> <span class="w"> </span><span class="c1">/// reentrant calls from within `msg.sender.call` cannot call `f` again.</span> <span class="w"> </span><span class="c1">/// The `return 7` statement assigns 7 to the return value but still</span> <span class="w"> </span><span class="c1">/// executes the statement `locked = false` in the modifier.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>noReentrancy<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="nv">success</span><span class="p">,)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.sender</span><span class="p">.</span>call<span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">);</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="m m-Decimal">7</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>If you want to access a modifier <code class="docutils literal notranslate"><span class="pre">m</span></code> defined in a contract <code class="docutils literal notranslate"><span class="pre">C</span></code>, you can use <code class="docutils literal notranslate"><span class="pre">C.m</span></code> to reference it without virtual lookup. It is only possible to use modifiers defined in the current contract or its base contracts. Modifiers can also be defined in libraries but their use is limited to functions of the same library.</p> <p>Multiple modifiers are applied to a function by specifying them in a whitespace-separated list and are evaluated in the order presented.</p> <p>Modifiers cannot implicitly access or change the arguments and return values of functions they modify. Their values can only be passed to them explicitly at the point of invocation.</p> <p>In function modifiers, it is necessary to specify when you want the function to which the modifier is applied to be run. The placeholder statement (denoted by a single underscore character <code class="docutils literal notranslate"><span class="pre">_</span></code>) is used to denote where the body of the function being modified should be inserted. Note that the placeholder operator is different from using underscores as leading or trailing characters in variable names, which is a stylistic choice.</p> <p>Explicit returns from a modifier or function body only leave the current modifier or function body. Return variables are assigned and control flow continues after the <code class="docutils literal notranslate"><span class="pre">_</span></code> in the preceding modifier.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>In an earlier version of Solidity, <code class="docutils literal notranslate"><span class="pre">return</span></code> statements in functions having modifiers behaved differently.</p> </div> <p>An explicit return from a modifier with <code class="docutils literal notranslate"><span class="pre">return;</span></code> does not affect the values returned by the function. The modifier can, however, choose not to execute the function body at all and in that case the return variables are set to their <a class="reference internal" href="control-structures.html#default-value"><span class="std std-ref">default values</span></a> just as if the function had an empty body.</p> <p>The <code class="docutils literal notranslate"><span class="pre">_</span></code> symbol can appear in the modifier multiple times. Each occurrence is replaced with the function body, and the function returns the return value of the final occurrence.</p> <p>Arbitrary expressions are allowed for modifier arguments and in this context, all symbols visible from the function are visible in the modifier. Symbols introduced in the modifier are not visible in the function (as they might change by overriding).</p> </section> <section id="transient-storage"> <span id="index-6"></span><span id="id4"></span><h2>Transient Storage<a class="headerlink" href="#transient-storage" title="Permalink to this heading"></a></h2> <p>Transient storage is another data location besides memory, storage, calldata (and return-data and code) which was introduced alongside its respective opcodes <code class="docutils literal notranslate"><span class="pre">TSTORE</span></code> and <code class="docutils literal notranslate"><span class="pre">TLOAD</span></code> by <a class="reference external" href="https://eips.ethereum.org/EIPS/eip-1153">EIP-1153</a>. This new data location behaves as a key-value store similar to storage with the main difference being that data in transient storage is not permanent, but is scoped to the current transaction only, after which it will be reset to zero. Since the content of transient storage has very limited lifetime and size, it does not need to be stored permanently as a part of state and the associated gas costs are much lower than in case of storage. EVM version <code class="docutils literal notranslate"><span class="pre">cancun</span></code> or newer is required for transient storage to be available.</p> <p>Transient storage variables cannot be initialized in place, i.e., they cannot be assigned to upon declaration, since the value would be cleared at the end of the creation transaction, rendering the initialization ineffective. Transient variables will be <a class="reference internal" href="control-structures.html#default-value"><span class="std std-ref">default value</span></a> initialized depending on their underlying type. <code class="docutils literal notranslate"><span class="pre">constant</span></code> and <code class="docutils literal notranslate"><span class="pre">immutable</span></code> variables conflict with transient storage, since their values are either inlined or directly stored in code.</p> <p>Transient storage variables have completely independent address space from storage, so that the order of transient state variables does not affect the layout of storage state variables and vice-versa. They do need distinct names though because all state variables share the same namespace. It is also important to note that the values in transient storage are packed in the same fashion as those in persistent storage. See <a class="reference internal" href="internals/layout_in_storage.html#storage-inplace-encoding"><span class="std std-ref">Storage Layout</span></a> for more information.</p> <p>Besides that, transient variables can have visibility as well and <code class="docutils literal notranslate"><span class="pre">public</span></code> ones will have a getter function generated automatically as usual.</p> <p>Note that, currently, such use of <code class="docutils literal notranslate"><span class="pre">transient</span></code> as a data location is only allowed for <a class="reference internal" href="types.html#value-types"><span class="std std-ref">value type</span></a> state variable declarations. Reference types, such as arrays, mappings and structs, as well as local or parameter variables are not yet supported.</p> <p>An expected canonical use case for transient storage is cheaper reentrancy locks, which can be readily implemented with the opcodes as showcased next.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMjg7Cgpjb250cmFjdCBHZW5lcm9zaXR5IHsKICAgIG1hcHBpbmcoYWRkcmVzcyA9PiBib29sKSBzZW50R2lmdHM7CiAgICBib29sIHRyYW5zaWVudCBsb2NrZWQ7CgogICAgbW9kaWZpZXIgbm9uUmVlbnRyYW50IHsKICAgICAgICByZXF1aXJlKCFsb2NrZWQsICJSZWVudHJhbmN5IGF0dGVtcHQiKTsKICAgICAgICBsb2NrZWQgPSB0cnVlOwogICAgICAgIF87CiAgICAgICAgLy8gVW5sb2NrcyB0aGUgZ3VhcmQsIG1ha2luZyB0aGUgcGF0dGVybiBjb21wb3NhYmxlLgogICAgICAgIC8vIEFmdGVyIHRoZSBmdW5jdGlvbiBleGl0cywgaXQgY2FuIGJlIGNhbGxlZCBhZ2FpbiwgZXZlbiBpbiB0aGUgc2FtZSB0cmFuc2FjdGlvbi4KICAgICAgICBsb2NrZWQgPSBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBjbGFpbUdpZnQoKSBub25SZWVudHJhbnQgcHVibGljIHsKICAgICAgICByZXF1aXJlKGFkZHJlc3ModGhpcykuYmFsYW5jZSA+PSAxIGV0aGVyKTsKICAgICAgICByZXF1aXJlKCFzZW50R2lmdHNbbXNnLnNlbmRlcl0pOwogICAgICAgIChib29sIHN1Y2Nlc3MsICkgPSBtc2cuc2VuZGVyLmNhbGx7dmFsdWU6IDEgZXRoZXJ9KCIiKTsKICAgICAgICByZXF1aXJlKHN1Y2Nlc3MpOwoKICAgICAgICAvLyBJbiBhIHJlZW50cmFudCBmdW5jdGlvbiwgZG9pbmcgdGhpcyBsYXN0IHdvdWxkIG9wZW4gdXAgdGhlIHZ1bG5lcmFiaWxpdHkKICAgICAgICBzZW50R2lmdHNbbXNnLnNlbmRlcl0gPSB0cnVlOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.28</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Generosity</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span>sentGifts<span class="p">;</span> <span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="nv">transient</span><span class="w"> </span>locked<span class="p">;</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>nonReentrant<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span><span class="o">!</span>locked<span class="p">,</span><span class="w"> </span><span class="s2">&quot;Reentrancy attempt&quot;</span><span class="p">);</span> <span class="w"> </span>locked<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span>_<span class="p">;</span> <span class="w"> </span><span class="c1">// Unlocks the guard, making the pattern composable.</span> <span class="w"> </span><span class="c1">// After the function exits, it can be called again, even in the same transaction.</span> <span class="w"> </span>locked<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">claimGift</span><span class="p">()</span><span class="w"> </span>nonReentrant<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span><span class="kt">address</span><span class="p">(</span><span class="kt">this</span><span class="p">).</span>balance<span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="w"> </span>ether<span class="p">);</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span><span class="o">!</span>sentGifts<span class="p">[</span><span class="k">msg.sender</span><span class="p">]);</span> <span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="nv">success</span><span class="p">,</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.sender</span><span class="p">.</span>call<span class="p">{</span>value<span class="o">:</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="w"> </span>ether<span class="p">}(</span><span class="s2">&quot;&quot;</span><span class="p">);</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="c1">// In a reentrant function, doing this last would open up the vulnerability</span> <span class="w"> </span>sentGifts<span class="p">[</span><span class="k">msg.sender</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Transient storage is private to the contract that owns it, in the same way as persistent storage. Only owning contract frames may access their transient storage, and when they do, all the frames access the same transient store.</p> <p>Transient storage is part of the EVM state and is subject to the same mutability enforcements as persistent storage. As such, any read access to it is not <code class="docutils literal notranslate"><span class="pre">pure</span></code> and writing access is not <code class="docutils literal notranslate"><span class="pre">view</span></code>.</p> <p>If the <code class="docutils literal notranslate"><span class="pre">TSTORE</span></code> opcode is called within the context of a <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code>, it will result in an exception instead of performing the modification. <code class="docutils literal notranslate"><span class="pre">TLOAD</span></code> is allowed within the context of a <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code>.</p> <p>When transient storage is used in the context of <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> or <code class="docutils literal notranslate"><span class="pre">CALLCODE</span></code>, then the owning contract of the transient storage is the contract that issued <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> or <code class="docutils literal notranslate"><span class="pre">CALLCODE</span></code> instruction (the caller) as with persistent storage. When transient storage is used in the context of <code class="docutils literal notranslate"><span class="pre">CALL</span></code> or <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code>, then the owning contract of the transient storage is the contract that is the target of the <code class="docutils literal notranslate"><span class="pre">CALL</span></code> or <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> instruction (the callee).</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>In the case of <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code>, since references to transient storage variables are currently not supported, it is not possible to pass those into library calls. In libraries, access to transient storage is only possible using inline assembly.</p> </div> <p>If a frame reverts, all writes to transient storage that took place between entry to the frame and the return are reverted, including those that took place in inner calls. The caller of an external call may employ a <code class="docutils literal notranslate"><span class="pre">try</span> <span class="pre">...</span> <span class="pre">catch</span></code> block to prevent reverts bubbling up from the inner calls.</p> </section> <section id="composability-of-smart-contracts-and-the-caveats-of-transient-storage"> <h2>Composability of Smart Contracts and the Caveats of Transient Storage<a class="headerlink" href="#composability-of-smart-contracts-and-the-caveats-of-transient-storage" title="Permalink to this heading"></a></h2> <p>Given the caveats mentioned in the specification of EIP-1153, in order to preserve the composability of your smart contract, utmost care is recommended for more advanced use cases of transient storage.</p> <p>For smart contracts, composability is a very important design principle to achieve self-contained behaviour, such that multiple calls into individual smart contracts can be composed to more complex applications. So far the EVM largely guaranteed composable behaviour, since multiple calls into a smart contract within a complex transaction are virtually indistinguishable from multiple calls to the contract stretched over several transactions. However, transient storage allows a violation of this principle, and incorrect use may lead to complex bugs that only surface when used across several calls.</p> <p>Let’s illustrate the problem with a simple example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMjg7Cgpjb250cmFjdCBNdWxTZXJ2aWNlIHsKICAgIHVpbnQgdHJhbnNpZW50IG11bHRpcGxpZXI7CiAgICBmdW5jdGlvbiBzZXRNdWx0aXBsaWVyKHVpbnQgbXVsKSBleHRlcm5hbCB7CiAgICAgICAgbXVsdGlwbGllciA9IG11bDsKICAgIH0KCiAgICBmdW5jdGlvbiBtdWx0aXBseSh1aW50IHZhbHVlKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKHVpbnQpIHsKICAgICAgICByZXR1cm4gdmFsdWUgKiBtdWx0aXBsaWVyOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.28</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">MulService</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">transient</span><span class="w"> </span>multiplier<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">setMultiplier</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">mul</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>multiplier<span class="w"> </span><span class="o">=</span><span class="w"> </span>mul<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">multiply</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>value<span class="w"> </span><span class="o">*</span><span class="w"> </span>multiplier<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>and a sequence of external calls:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=c2V0TXVsdGlwbGllcig0Mik7Cm11bHRpcGx5KDEpOwptdWx0aXBseSgyKTs=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span>setMultiplier<span class="p">(</span><span class="m m-Decimal">42</span><span class="p">);</span> multiply<span class="p">(</span><span class="m m-Decimal">1</span><span class="p">);</span> multiply<span class="p">(</span><span class="m m-Decimal">2</span><span class="p">);</span> </pre></div> </div> <p>If the example used memory or storage to store the multiplier, it would be fully composable. It would not matter whether you split the sequence into separate transactions or grouped them in some way. You would always get the same result: after <code class="docutils literal notranslate"><span class="pre">multiplier</span></code> is set to <code class="docutils literal notranslate"><span class="pre">42</span></code>, the subsequent calls would return <code class="docutils literal notranslate"><span class="pre">42</span></code> and <code class="docutils literal notranslate"><span class="pre">84</span></code> respectively. This enables use cases such as batching calls from multiple transactions together to reduce gas costs. Transient storage potentially breaks such use cases since composability can no longer be taken for granted. In the example, if the calls are not executed in the same transaction, then <code class="docutils literal notranslate"><span class="pre">multiplier</span></code> is reset and the next calls to function <code class="docutils literal notranslate"><span class="pre">multiply</span></code> would always return <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p> <p>As another example, since transient storage is constructed as a relatively cheap key-value store, a smart contract author may be tempted to use transient storage as a replacement for in-memory mappings without keeping track of the modified keys in the mapping and thereby without clearing the mapping at the end of the call. This, however, can easily lead to unexpected behaviour in complex transactions, in which values set by a previous call into the contract within the same transaction remain.</p> <p>The use of transient storage for reentrancy locks that are cleared at the end of the call frame into the contract, is safe. However, be sure to resist the temptation to save the 100 gas used for resetting the reentrancy lock, since failing to do so, will restrict your contract to only one call within a transaction, preventing its use in complex composed transactions, which have been a cornerstone for complex applications on chain.</p> <p>It is recommend to generally always clear transient storage completely at the end of a call into your smart contract to avoid these kinds of issues and to simplify the analysis of the behaviour of your contract within complex transactions. Check the <a class="reference external" href="https://eips.ethereum.org/EIPS/eip-1153#security-considerations">Security Considerations section of EIP-1153</a> for further details.</p> </section> <section id="constant-and-immutable-state-variables"> <span id="constants"></span><span id="index-7"></span><h2>Constant and Immutable State Variables<a class="headerlink" href="#constant-and-immutable-state-variables" title="Permalink to this heading"></a></h2> <p>State variables can be declared as <code class="docutils literal notranslate"><span class="pre">constant</span></code> or <code class="docutils literal notranslate"><span class="pre">immutable</span></code>. In both cases, the variables cannot be modified after the contract has been constructed. For <code class="docutils literal notranslate"><span class="pre">constant</span></code> variables, the value has to be fixed at compile-time, while for <code class="docutils literal notranslate"><span class="pre">immutable</span></code>, it can still be assigned at construction time.</p> <p>It is also possible to define <code class="docutils literal notranslate"><span class="pre">constant</span></code> variables at the file level.</p> <p>Every occurrence of such a variable in the source is replaced by its underlying value and the compiler does not reserve a storage slot for it. It cannot be assigned a slot in transient storage using the <code class="docutils literal notranslate"><span class="pre">transient</span></code> keyword either.</p> <p>Compared to regular state variables, the gas costs of constant and immutable variables are much lower. For a constant variable, the expression assigned to it is copied to all the places where it is accessed and also re-evaluated each time. This allows for local optimizations. Immutable variables are evaluated once at construction time and their value is copied to all the places in the code where they are accessed. For these values, 32 bytes are reserved, even if they would fit in fewer bytes. Due to this, constant values can sometimes be cheaper than immutable values.</p> <p>Not all types for constants and immutables are implemented at this time. The only supported types are <a class="reference internal" href="types.html#strings"><span class="std std-ref">strings</span></a> (only for constants) and <a class="reference internal" href="types.html#value-types"><span class="std std-ref">value types</span></a>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMjE7Cgp1aW50IGNvbnN0YW50IFggPSAzMioqMjIgKyA4OwoKY29udHJhY3QgQyB7CiAgICBzdHJpbmcgY29uc3RhbnQgVEVYVCA9ICJhYmMiOwogICAgYnl0ZXMzMiBjb25zdGFudCBNWV9IQVNIID0ga2VjY2FrMjU2KCJhYmMiKTsKICAgIHVpbnQgaW1tdXRhYmxlIGRlY2ltYWxzID0gMTg7CiAgICB1aW50IGltbXV0YWJsZSBtYXhCYWxhbmNlOwogICAgYWRkcmVzcyBpbW11dGFibGUgb3duZXIgPSBtc2cuc2VuZGVyOwoKICAgIGNvbnN0cnVjdG9yKHVpbnQgZGVjaW1hbHNfLCBhZGRyZXNzIHJlZikgewogICAgICAgIGlmIChkZWNpbWFsc18gIT0gMCkKICAgICAgICAgICAgLy8gSW1tdXRhYmxlcyBhcmUgb25seSBpbW11dGFibGUgd2hlbiBkZXBsb3llZC4KICAgICAgICAgICAgLy8gQXQgY29uc3RydWN0aW9uIHRpbWUgdGhleSBjYW4gYmUgYXNzaWduZWQgdG8gYW55IG51bWJlciBvZiB0aW1lcy4KICAgICAgICAgICAgZGVjaW1hbHMgPSBkZWNpbWFsc187CgogICAgICAgIC8vIEFzc2lnbm1lbnRzIHRvIGltbXV0YWJsZXMgY2FuIGV2ZW4gYWNjZXNzIHRoZSBlbnZpcm9ubWVudC4KICAgICAgICBtYXhCYWxhbmNlID0gcmVmLmJhbGFuY2U7CiAgICB9CgogICAgZnVuY3Rpb24gaXNCYWxhbmNlVG9vSGlnaChhZGRyZXNzIG90aGVyKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIG90aGVyLmJhbGFuY2UgPiBtYXhCYWxhbmNlOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.21</span><span class="p">;</span> <span class="kt">uint</span><span class="w"> </span><span class="nv">constant</span><span class="w"> </span>X<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">32</span><span class="o">**</span><span class="m m-Decimal">22</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">8</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="nv">constant</span><span class="w"> </span>TEXT<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;abc&quot;</span><span class="p">;</span> <span class="w"> </span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">constant</span><span class="w"> </span>MY_HASH<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">keccak256</span><span class="p">(</span><span class="s2">&quot;abc&quot;</span><span class="p">);</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">immutable</span><span class="w"> </span>decimals<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">18</span><span class="p">;</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">immutable</span><span class="w"> </span>maxBalance<span class="p">;</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">immutable</span><span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.sender</span><span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">decimals_</span><span class="p">,</span><span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">ref</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>decimals_<span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">)</span> <span class="w"> </span><span class="c1">// Immutables are only immutable when deployed.</span> <span class="w"> </span><span class="c1">// At construction time they can be assigned to any number of times.</span> <span class="w"> </span>decimals<span class="w"> </span><span class="o">=</span><span class="w"> </span>decimals_<span class="p">;</span> <span class="w"> </span><span class="c1">// Assignments to immutables can even access the environment.</span> <span class="w"> </span>maxBalance<span class="w"> </span><span class="o">=</span><span class="w"> </span>ref<span class="p">.</span>balance<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">isBalanceTooHigh</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">other</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>other<span class="p">.</span>balance<span class="w"> </span><span class="o">&gt;</span><span class="w"> </span>maxBalance<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <section id="constant"> <h3>Constant<a class="headerlink" href="#constant" title="Permalink to this heading"></a></h3> <p>For <code class="docutils literal notranslate"><span class="pre">constant</span></code> variables, the value has to be a constant at compile time and it has to be assigned where the variable is declared. Any expression that accesses storage, blockchain data (e.g. <code class="docutils literal notranslate"><span class="pre">block.timestamp</span></code>, <code class="docutils literal notranslate"><span class="pre">address(this).balance</span></code> or <code class="docutils literal notranslate"><span class="pre">block.number</span></code>) or execution data (<code class="docutils literal notranslate"><span class="pre">msg.value</span></code> or <code class="docutils literal notranslate"><span class="pre">gasleft()</span></code>) or makes calls to external contracts is disallowed. Expressions that might have a side-effect on memory allocation are allowed, but those that might have a side-effect on other memory objects are not. The built-in functions <code class="docutils literal notranslate"><span class="pre">keccak256</span></code>, <code class="docutils literal notranslate"><span class="pre">sha256</span></code>, <code class="docutils literal notranslate"><span class="pre">ripemd160</span></code>, <code class="docutils literal notranslate"><span class="pre">ecrecover</span></code>, <code class="docutils literal notranslate"><span class="pre">addmod</span></code> and <code class="docutils literal notranslate"><span class="pre">mulmod</span></code> are allowed (even though, with the exception of <code class="docutils literal notranslate"><span class="pre">keccak256</span></code>, they do call external contracts).</p> <p>The reason behind allowing side-effects on the memory allocator is that it should be possible to construct complex objects like e.g. lookup-tables. This feature is not yet fully usable.</p> </section> <section id="immutable"> <h3>Immutable<a class="headerlink" href="#immutable" title="Permalink to this heading"></a></h3> <p>Variables declared as <code class="docutils literal notranslate"><span class="pre">immutable</span></code> are a bit less restricted than those declared as <code class="docutils literal notranslate"><span class="pre">constant</span></code>: Immutable variables can be assigned a value at construction time. The value can be changed at any time before deployment and then it becomes permanent.</p> <p>One additional restriction is that immutables can only be assigned to inside expressions for which there is no possibility of being executed after creation. This excludes all modifier definitions and functions other than constructors.</p> <p>There are no restrictions on reading immutable variables. The read is even allowed to happen before the variable is written to for the first time because variables in Solidity always have a well-defined initial value. For this reason it is also allowed to never explicitly assign a value to an immutable.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>When accessing immutables at construction time, please keep the <a class="reference internal" href="ir-breaking-changes.html#state-variable-initialization-order"><span class="std std-ref">initialization order</span></a> in mind. Even if you provide an explicit initializer, some expressions may end up being evaluated before that initializer, especially when they are at a different level in inheritance hierarchy.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Before Solidity 0.8.21 initialization of immutable variables was more restrictive. Such variables had to be initialized exactly once at construction time and could not be read before then.</p> </div> <p>The contract creation code generated by the compiler will modify the contract’s runtime code before it is returned by replacing all references to immutables with the values assigned to them. This is important if you are comparing the runtime code generated by the compiler with the one actually stored in the blockchain. The compiler outputs where these immutables are located in the deployed bytecode in the <code class="docutils literal notranslate"><span class="pre">immutableReferences</span></code> field of the <a class="reference internal" href="using-the-compiler.html#compiler-api"><span class="std std-ref">compiler JSON standard output</span></a>.</p> </section> </section> <section id="functions"> <span id="index-8"></span><span id="id5"></span><h2>Functions<a class="headerlink" href="#functions" title="Permalink to this heading"></a></h2> <p>Functions can be defined inside and outside of contracts.</p> <p>Functions outside of a contract, also called “free functions”, always have implicit <code class="docutils literal notranslate"><span class="pre">internal</span></code> <a class="reference internal" href="#visibility-and-getters"><span class="std std-ref">visibility</span></a>. Their code is included in all contracts that call them, similar to internal library functions.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjEgPDAuOS4wOwoKZnVuY3Rpb24gc3VtKHVpbnRbXSBtZW1vcnkgYXJyKSBwdXJlIHJldHVybnMgKHVpbnQgcykgewogICAgZm9yICh1aW50IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKQogICAgICAgIHMgKz0gYXJyW2ldOwp9Cgpjb250cmFjdCBBcnJheUV4YW1wbGUgewogICAgYm9vbCBmb3VuZDsKICAgIGZ1bmN0aW9uIGYodWludFtdIG1lbW9yeSBhcnIpIHB1YmxpYyB7CiAgICAgICAgLy8gVGhpcyBjYWxscyB0aGUgZnJlZSBmdW5jdGlvbiBpbnRlcm5hbGx5LgogICAgICAgIC8vIFRoZSBjb21waWxlciB3aWxsIGFkZCBpdHMgY29kZSB0byB0aGUgY29udHJhY3QuCiAgICAgICAgdWludCBzID0gc3VtKGFycik7CiAgICAgICAgcmVxdWlyZShzID49IDEwKTsKICAgICAgICBmb3VuZCA9IHRydWU7CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.1</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="kt">function</span><span class="w"> </span><span class="nv">sum</span><span class="p">(</span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span><span class="kt">memory</span><span class="w"> </span>arr<span class="p">)</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">s</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">for</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span><span class="w"> </span>i<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>arr<span class="p">.</span>length<span class="p">;</span><span class="w"> </span>i<span class="o">++</span><span class="p">)</span> <span class="w"> </span>s<span class="w"> </span><span class="o">+=</span><span class="w"> </span>arr<span class="p">[</span>i<span class="p">];</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">ArrayExample</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="nv">found</span><span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span><span class="kt">memory</span><span class="w"> </span>arr<span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// This calls the free function internally.</span> <span class="w"> </span><span class="c1">// The compiler will add its code to the contract.</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">s</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>sum<span class="p">(</span>arr<span class="p">);</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>s<span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="m m-Decimal">10</span><span class="p">);</span> <span class="w"> </span>found<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Functions defined outside a contract are still always executed in the context of a contract. They still can call other contracts, send them Ether and destroy the contract that called them, among other things. The main difference to functions defined inside a contract is that free functions do not have direct access to the variable <code class="docutils literal notranslate"><span class="pre">this</span></code>, storage variables and functions not in their scope.</p> </div> <section id="function-parameters-and-return-variables"> <span id="function-parameters-return-variables"></span><h3>Function Parameters and Return Variables<a class="headerlink" href="#function-parameters-and-return-variables" title="Permalink to this heading"></a></h3> <p>Functions take typed parameters as input and may, unlike in many other languages, also return an arbitrary number of values as output.</p> <section id="function-parameters"> <h4>Function Parameters<a class="headerlink" href="#function-parameters" title="Permalink to this heading"></a></h4> <p>Function parameters are declared the same way as variables, and the name of unused parameters can be omitted.</p> <p>For example, if you want your contract to accept one kind of external call with two integers, you would use something like the following:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IFNpbXBsZSB7CiAgICB1aW50IHN1bTsKICAgIGZ1bmN0aW9uIHRha2VyKHVpbnQgYSwgdWludCBiKSBwdWJsaWMgewogICAgICAgIHN1bSA9IGEgKyBiOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Simple</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">sum</span><span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">taker</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>sum<span class="w"> </span><span class="o">=</span><span class="w"> </span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span>b<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Function parameters can be used as any other local variable and they can also be assigned to.</p> </section> <section id="return-variables"> <span id="index-9"></span><h4>Return Variables<a class="headerlink" href="#return-variables" title="Permalink to this heading"></a></h4> <p>Function return variables are declared with the same syntax after the <code class="docutils literal notranslate"><span class="pre">returns</span></code> keyword.</p> <p>For example, suppose you want to return two results: the sum and the product of two integers passed as function parameters, then you use something like:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IFNpbXBsZSB7CiAgICBmdW5jdGlvbiBhcml0aG1ldGljKHVpbnQgYSwgdWludCBiKQogICAgICAgIHB1YmxpYwogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zICh1aW50IHN1bSwgdWludCBwcm9kdWN0KQogICAgewogICAgICAgIHN1bSA9IGEgKyBiOwogICAgICAgIHByb2R1Y3QgPSBhICogYjsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Simple</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">arithmetic</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span>pure <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">sum</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">product</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span>sum<span class="w"> </span><span class="o">=</span><span class="w"> </span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span>b<span class="p">;</span> <span class="w"> </span>product<span class="w"> </span><span class="o">=</span><span class="w"> </span>a<span class="w"> </span><span class="o">*</span><span class="w"> </span>b<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>The names of return variables can be omitted. Return variables can be used as any other local variable and they are initialized with their <a class="reference internal" href="control-structures.html#default-value"><span class="std std-ref">default value</span></a> and have that value until they are (re-)assigned.</p> <p>You can either explicitly assign to return variables and then leave the function as above, or you can provide return values (either a single or <a class="reference internal" href="#multi-return"><span class="std std-ref">multiple ones</span></a>) directly with the <code class="docutils literal notranslate"><span class="pre">return</span></code> statement:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IFNpbXBsZSB7CiAgICBmdW5jdGlvbiBhcml0aG1ldGljKHVpbnQgYSwgdWludCBiKQogICAgICAgIHB1YmxpYwogICAgICAgIHB1cmUKICAgICAgICByZXR1cm5zICh1aW50IHN1bSwgdWludCBwcm9kdWN0KQogICAgewogICAgICAgIHJldHVybiAoYSArIGIsIGEgKiBiKTsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Simple</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">arithmetic</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span>pure <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">sum</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">product</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="p">(</span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span>b<span class="p">,</span><span class="w"> </span>a<span class="w"> </span><span class="o">*</span><span class="w"> </span>b<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>If you use an early <code class="docutils literal notranslate"><span class="pre">return</span></code> to leave a function that has return variables, you must provide return values together with the return statement.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>You cannot return some types from non-internal functions. This includes the types listed below and any composite types that recursively contain them:</p> <ul class="simple"> <li><p>mappings,</p></li> <li><p>internal function types,</p></li> <li><p>reference types with location set to <code class="docutils literal notranslate"><span class="pre">storage</span></code>,</p></li> <li><p>multi-dimensional arrays (applies only to <a class="reference internal" href="layout-of-source-files.html#abi-coder"><span class="std std-ref">ABI coder v1</span></a>),</p></li> <li><p>structs (applies only to <a class="reference internal" href="layout-of-source-files.html#abi-coder"><span class="std std-ref">ABI coder v1</span></a>).</p></li> </ul> <p>This restriction does not apply to library functions because of their different <a class="reference internal" href="#library-selectors"><span class="std std-ref">internal ABI</span></a>.</p> </div> </section> <section id="returning-multiple-values"> <span id="multi-return"></span><h4>Returning Multiple Values<a class="headerlink" href="#returning-multiple-values" title="Permalink to this heading"></a></h4> <p>When a function has multiple return types, the statement <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">(v0,</span> <span class="pre">v1,</span> <span class="pre">...,</span> <span class="pre">vn)</span></code> can be used to return multiple values. The number of components must be the same as the number of return variables and their types have to match, potentially after an <a class="reference internal" href="types.html#types-conversion-elementary-types"><span class="std std-ref">implicit conversion</span></a>.</p> </section> </section> <section id="state-mutability"> <span id="id6"></span><h3>State Mutability<a class="headerlink" href="#state-mutability" title="Permalink to this heading"></a></h3> <section id="view-functions"> <span id="index-10"></span><span id="id7"></span><h4>View Functions<a class="headerlink" href="#view-functions" title="Permalink to this heading"></a></h4> <p>Functions can be declared <code class="docutils literal notranslate"><span class="pre">view</span></code> in which case they promise not to modify the state.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>If the compiler’s EVM target is Byzantium or newer (default) the opcode <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> is used when <code class="docutils literal notranslate"><span class="pre">view</span></code> functions are called, which enforces the state to stay unmodified as part of the EVM execution. For library <code class="docutils literal notranslate"><span class="pre">view</span></code> functions <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> is used, because there is no combined <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> and <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code>. This means library <code class="docutils literal notranslate"><span class="pre">view</span></code> functions do not have run-time checks that prevent state modifications. This should not impact security negatively because library code is usually known at compile-time and the static checker performs compile-time checks.</p> </div> <p>The following statements are considered modifying the state:</p> <ol class="arabic simple"> <li><p>Writing to state variables (storage and transient storage).</p></li> <li><p><a class="reference internal" href="#events"><span class="std std-ref">Emitting events</span></a>.</p></li> <li><p><a class="reference internal" href="control-structures.html#creating-contracts"><span class="std std-ref">Creating other contracts</span></a>.</p></li> <li><p>Using <code class="docutils literal notranslate"><span class="pre">selfdestruct</span></code>.</p></li> <li><p>Sending Ether via calls.</p></li> <li><p>Calling any function not marked <code class="docutils literal notranslate"><span class="pre">view</span></code> or <code class="docutils literal notranslate"><span class="pre">pure</span></code>.</p></li> <li><p>Using low-level calls.</p></li> <li><p>Using inline assembly that contains certain opcodes.</p></li> </ol> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC41LjAgPDAuOS4wOwoKY29udHJhY3QgQyB7CiAgICBmdW5jdGlvbiBmKHVpbnQgYSwgdWludCBiKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIGEgKiAoYiArIDQyKSArIGJsb2NrLnRpbWVzdGFtcDsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.5.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span>b<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">42</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">block.timestamp</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p><code class="docutils literal notranslate"><span class="pre">constant</span></code> on functions used to be an alias to <code class="docutils literal notranslate"><span class="pre">view</span></code>, but this was dropped in version 0.5.0.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Getter methods are automatically marked <code class="docutils literal notranslate"><span class="pre">view</span></code>.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Prior to version 0.5.0, the compiler did not use the <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> opcode for <code class="docutils literal notranslate"><span class="pre">view</span></code> functions. This enabled state modifications in <code class="docutils literal notranslate"><span class="pre">view</span></code> functions through the use of invalid explicit type conversions. By using <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> for <code class="docutils literal notranslate"><span class="pre">view</span></code> functions, modifications to the state are prevented on the level of the EVM.</p> </div> </section> <section id="pure-functions"> <span id="index-11"></span><span id="id8"></span><h4>Pure Functions<a class="headerlink" href="#pure-functions" title="Permalink to this heading"></a></h4> <p>Functions can be declared <code class="docutils literal notranslate"><span class="pre">pure</span></code> in which case they promise not to read from or modify the state. In particular, it should be possible to evaluate a <code class="docutils literal notranslate"><span class="pre">pure</span></code> function at compile-time given only its inputs and <code class="docutils literal notranslate"><span class="pre">msg.data</span></code>, but without any knowledge of the current blockchain state. This means that reading from <code class="docutils literal notranslate"><span class="pre">immutable</span></code> variables can be a non-pure operation.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>If the compiler’s EVM target is Byzantium or newer (default) the opcode <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> is used, which does not guarantee that the state is not read, but at least that it is not modified.</p> </div> <p>In addition to the list of state modifying statements explained above, the following are considered reading from the state:</p> <ol class="arabic simple"> <li><p>Reading from state variables (storage and transient storage).</p></li> <li><p>Accessing <code class="docutils literal notranslate"><span class="pre">address(this).balance</span></code> or <code class="docutils literal notranslate"><span class="pre">&lt;address&gt;.balance</span></code>.</p></li> <li><p>Accessing any of the members of <code class="docutils literal notranslate"><span class="pre">block</span></code>, <code class="docutils literal notranslate"><span class="pre">tx</span></code>, <code class="docutils literal notranslate"><span class="pre">msg</span></code> (with the exception of <code class="docutils literal notranslate"><span class="pre">msg.sig</span></code> and <code class="docutils literal notranslate"><span class="pre">msg.data</span></code>).</p></li> <li><p>Calling any function not marked <code class="docutils literal notranslate"><span class="pre">pure</span></code>.</p></li> <li><p>Using inline assembly that contains certain opcodes.</p></li> </ol> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC41LjAgPDAuOS4wOwoKY29udHJhY3QgQyB7CiAgICBmdW5jdGlvbiBmKHVpbnQgYSwgdWludCBiKSBwdWJsaWMgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIGEgKiAoYiArIDQyKTsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.5.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span>b<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">42</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Pure functions are able to use the <code class="docutils literal notranslate"><span class="pre">revert()</span></code> and <code class="docutils literal notranslate"><span class="pre">require()</span></code> functions to revert potential state changes when an <a class="reference internal" href="control-structures.html#assert-and-require"><span class="std std-ref">error occurs</span></a>.</p> <p>Reverting a state change is not considered a “state modification”, as only changes to the state made previously in code that did not have the <code class="docutils literal notranslate"><span class="pre">view</span></code> or <code class="docutils literal notranslate"><span class="pre">pure</span></code> restriction are reverted and that code has the option to catch the <code class="docutils literal notranslate"><span class="pre">revert</span></code> and not pass it on.</p> <p>This behavior is also in line with the <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> opcode.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>It is not possible to prevent functions from reading the state at the level of the EVM, it is only possible to prevent them from writing to the state (i.e. only <code class="docutils literal notranslate"><span class="pre">view</span></code> can be enforced at the EVM level, <code class="docutils literal notranslate"><span class="pre">pure</span></code> can not).</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Prior to version 0.5.0, the compiler did not use the <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> opcode for <code class="docutils literal notranslate"><span class="pre">pure</span></code> functions. This enabled state modifications in <code class="docutils literal notranslate"><span class="pre">pure</span></code> functions through the use of invalid explicit type conversions. By using <code class="docutils literal notranslate"><span class="pre">STATICCALL</span></code> for <code class="docutils literal notranslate"><span class="pre">pure</span></code> functions, modifications to the state are prevented on the level of the EVM.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Prior to version 0.4.17 the compiler did not enforce that <code class="docutils literal notranslate"><span class="pre">pure</span></code> is not reading the state. It is a compile-time type check, which can be circumvented by doing invalid explicit conversions between contract types, because the compiler can verify that the type of the contract does not do state-changing operations, but it cannot check that the contract that will be called at runtime is actually of that type.</p> </div> </section> </section> <section id="special-functions"> <span id="id9"></span><h3>Special Functions<a class="headerlink" href="#special-functions" title="Permalink to this heading"></a></h3> <section id="receive-ether-function"> <span id="index-12"></span><span id="id10"></span><h4>Receive Ether Function<a class="headerlink" href="#receive-ether-function" title="Permalink to this heading"></a></h4> <p>A contract can have at most one <code class="docutils literal notranslate"><span class="pre">receive</span></code> function, declared using <code class="docutils literal notranslate"><span class="pre">receive()</span> <span class="pre">external</span> <span class="pre">payable</span> <span class="pre">{</span> <span class="pre">...</span> <span class="pre">}</span></code> (without the <code class="docutils literal notranslate"><span class="pre">function</span></code> keyword). This function cannot have arguments, cannot return anything and must have <code class="docutils literal notranslate"><span class="pre">external</span></code> visibility and <code class="docutils literal notranslate"><span class="pre">payable</span></code> state mutability. It can be virtual, can override and can have modifiers.</p> <p>The receive function is executed on a call to the contract with empty calldata. This is the function that is executed on plain Ether transfers (e.g. via <code class="docutils literal notranslate"><span class="pre">.send()</span></code> or <code class="docutils literal notranslate"><span class="pre">.transfer()</span></code>). If no such function exists, but a payable <a class="reference internal" href="#fallback-function"><span class="std std-ref">fallback function</span></a> exists, the fallback function will be called on a plain Ether transfer. If neither a receive Ether nor a payable fallback function is present, the contract cannot receive Ether through a transaction that does not represent a payable function call and throws an exception.</p> <p>In the worst case, the <code class="docutils literal notranslate"><span class="pre">receive</span></code> function can only rely on 2300 gas being available (for example when <code class="docutils literal notranslate"><span class="pre">send</span></code> or <code class="docutils literal notranslate"><span class="pre">transfer</span></code> is used), leaving little room to perform other operations except basic logging. The following operations will consume more gas than the 2300 gas stipend:</p> <ul class="simple"> <li><p>Writing to storage</p></li> <li><p>Creating a contract</p></li> <li><p>Calling an external function which consumes a large amount of gas</p></li> <li><p>Sending Ether</p></li> </ul> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>When Ether is sent directly to a contract (without a function call, i.e. sender uses <code class="docutils literal notranslate"><span class="pre">send</span></code> or <code class="docutils literal notranslate"><span class="pre">transfer</span></code>) but the receiving contract does not define a receive Ether function or a payable fallback function, an exception will be thrown, sending back the Ether (this was different before Solidity v0.4.0). If you want your contract to receive Ether, you have to implement a receive Ether function (using payable fallback functions for receiving Ether is not recommended, since the fallback is invoked and would not fail for interface confusions on the part of the sender).</p> </div> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>A contract without a receive Ether function can receive Ether as a recipient of a <em>coinbase transaction</em> (aka <em>miner block reward</em>) or as a destination of a <code class="docutils literal notranslate"><span class="pre">selfdestruct</span></code>.</p> <p>A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it.</p> <p>It also means that <code class="docutils literal notranslate"><span class="pre">address(this).balance</span></code> can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the receive Ether function).</p> </div> <p>Below you can see an example of a Sink contract that uses function <code class="docutils literal notranslate"><span class="pre">receive</span></code>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKLy8gVGhpcyBjb250cmFjdCBrZWVwcyBhbGwgRXRoZXIgc2VudCB0byBpdCB3aXRoIG5vIHdheQovLyB0byBnZXQgaXQgYmFjay4KY29udHJhY3QgU2luayB7CiAgICBldmVudCBSZWNlaXZlZChhZGRyZXNzLCB1aW50KTsKICAgIHJlY2VpdmUoKSBleHRlcm5hbCBwYXlhYmxlIHsKICAgICAgICBlbWl0IFJlY2VpdmVkKG1zZy5zZW5kZXIsIG1zZy52YWx1ZSk7CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="c1">// This contract keeps all Ether sent to it with no way</span> <span class="c1">// to get it back.</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Sink</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Received</span><span class="p">(</span><span class="kt">address</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="p">);</span> <span class="w"> </span>receive<span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">payable</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>emit<span class="w"> </span>Received<span class="p">(</span><span class="k">msg.sender</span><span class="p">,</span><span class="w"> </span><span class="k">msg.value</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="fallback-function"> <span id="index-13"></span><span id="id11"></span><h4>Fallback Function<a class="headerlink" href="#fallback-function" title="Permalink to this heading"></a></h4> <p>A contract can have at most one <code class="docutils literal notranslate"><span class="pre">fallback</span></code> function, declared using either <code class="docutils literal notranslate"><span class="pre">fallback</span> <span class="pre">()</span> <span class="pre">external</span> <span class="pre">[payable]</span></code> or <code class="docutils literal notranslate"><span class="pre">fallback</span> <span class="pre">(bytes</span> <span class="pre">calldata</span> <span class="pre">input)</span> <span class="pre">external</span> <span class="pre">[payable]</span> <span class="pre">returns</span> <span class="pre">(bytes</span> <span class="pre">memory</span> <span class="pre">output)</span></code> (both without the <code class="docutils literal notranslate"><span class="pre">function</span></code> keyword). This function must have <code class="docutils literal notranslate"><span class="pre">external</span></code> visibility. A fallback function can be virtual, can override and can have modifiers.</p> <p>The fallback function is executed on a call to the contract if none of the other functions match the given function signature, or if no data was supplied at all and there is no <a class="reference internal" href="#receive-ether-function"><span class="std std-ref">receive Ether function</span></a>. The fallback function always receives data, but in order to also receive Ether it must be marked <code class="docutils literal notranslate"><span class="pre">payable</span></code>.</p> <p>If the version with parameters is used, <code class="docutils literal notranslate"><span class="pre">input</span></code> will contain the full data sent to the contract (equal to <code class="docutils literal notranslate"><span class="pre">msg.data</span></code>) and can return data in <code class="docutils literal notranslate"><span class="pre">output</span></code>. The returned data will not be ABI-encoded. Instead it will be returned without modifications (not even padding).</p> <p>In the worst case, if a payable fallback function is also used in place of a receive function, it can only rely on 2300 gas being available (see <a class="reference internal" href="#receive-ether-function"><span class="std std-ref">receive Ether function</span></a> for a brief description of the implications of this).</p> <p>Like any function, the fallback function can execute complex operations as long as there is enough gas passed on to it.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>A <code class="docutils literal notranslate"><span class="pre">payable</span></code> fallback function is also executed for plain Ether transfers, if no <a class="reference internal" href="#receive-ether-function"><span class="std std-ref">receive Ether function</span></a> is present. It is recommended to always define a receive Ether function as well, if you define a payable fallback function to distinguish Ether transfers from interface confusions.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>If you want to decode the input data, you can check the first four bytes for the function selector and then you can use <code class="docutils literal notranslate"><span class="pre">abi.decode</span></code> together with the array slice syntax to decode ABI-encoded data: <code class="docutils literal notranslate"><span class="pre">(c,</span> <span class="pre">d)</span> <span class="pre">=</span> <span class="pre">abi.decode(input[4:],</span> <span class="pre">(uint256,</span> <span class="pre">uint256));</span></code> Note that this should only be used as a last resort and proper functions should be used instead.</p> </div> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOS4wOwoKY29udHJhY3QgVGVzdCB7CiAgICB1aW50IHg7CiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgYWxsIG1lc3NhZ2VzIHNlbnQgdG8KICAgIC8vIHRoaXMgY29udHJhY3QgKHRoZXJlIGlzIG5vIG90aGVyIGZ1bmN0aW9uKS4KICAgIC8vIFNlbmRpbmcgRXRoZXIgdG8gdGhpcyBjb250cmFjdCB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiwKICAgIC8vIGJlY2F1c2UgdGhlIGZhbGxiYWNrIGZ1bmN0aW9uIGRvZXMgbm90IGhhdmUgdGhlIGBwYXlhYmxlYAogICAgLy8gbW9kaWZpZXIuCiAgICBmYWxsYmFjaygpIGV4dGVybmFsIHsgeCA9IDE7IH0KfQoKY29udHJhY3QgVGVzdFBheWFibGUgewogICAgdWludCB4OwogICAgdWludCB5OwogICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIGFsbCBtZXNzYWdlcyBzZW50IHRvCiAgICAvLyB0aGlzIGNvbnRyYWN0LCBleGNlcHQgcGxhaW4gRXRoZXIgdHJhbnNmZXJzCiAgICAvLyAodGhlcmUgaXMgbm8gb3RoZXIgZnVuY3Rpb24gZXhjZXB0IHRoZSByZWNlaXZlIGZ1bmN0aW9uKS4KICAgIC8vIEFueSBjYWxsIHdpdGggbm9uLWVtcHR5IGNhbGxkYXRhIHRvIHRoaXMgY29udHJhY3Qgd2lsbCBleGVjdXRlCiAgICAvLyB0aGUgZmFsbGJhY2sgZnVuY3Rpb24gKGV2ZW4gaWYgRXRoZXIgaXMgc2VudCBhbG9uZyB3aXRoIHRoZSBjYWxsKS4KICAgIGZhbGxiYWNrKCkgZXh0ZXJuYWwgcGF5YWJsZSB7IHggPSAxOyB5ID0gbXNnLnZhbHVlOyB9CgogICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIHBsYWluIEV0aGVyIHRyYW5zZmVycywgaS5lLgogICAgLy8gZm9yIGV2ZXJ5IGNhbGwgd2l0aCBlbXB0eSBjYWxsZGF0YS4KICAgIHJlY2VpdmUoKSBleHRlcm5hbCBwYXlhYmxlIHsgeCA9IDI7IHkgPSBtc2cudmFsdWU7IH0KfQoKY29udHJhY3QgQ2FsbGVyIHsKICAgIGZ1bmN0aW9uIGNhbGxUZXN0KFRlc3QgdGVzdCkgcHVibGljIHJldHVybnMgKGJvb2wpIHsKICAgICAgICAoYm9vbCBzdWNjZXNzLCkgPSBhZGRyZXNzKHRlc3QpLmNhbGwoYWJpLmVuY29kZVdpdGhTaWduYXR1cmUoIm5vbkV4aXN0aW5nRnVuY3Rpb24oKSIpKTsKICAgICAgICByZXF1aXJlKHN1Y2Nlc3MpOwogICAgICAgIC8vIHJlc3VsdHMgaW4gdGVzdC54IGJlY29taW5nID09IDEuCgogICAgICAgIC8vIGFkZHJlc3ModGVzdCkgd2lsbCBub3QgYWxsb3cgdG8gY2FsbCBgYHNlbmRgYCBkaXJlY3RseSwgc2luY2UgYGB0ZXN0YGAgaGFzIG5vIHBheWFibGUKICAgICAgICAvLyBmYWxsYmFjayBmdW5jdGlvbi4KICAgICAgICAvLyBJdCBoYXMgdG8gYmUgY29udmVydGVkIHRvIHRoZSBgYGFkZHJlc3MgcGF5YWJsZWBgIHR5cGUgdG8gZXZlbiBhbGxvdyBjYWxsaW5nIGBgc2VuZGBgIG9uIGl0LgogICAgICAgIGFkZHJlc3MgcGF5YWJsZSB0ZXN0UGF5YWJsZSA9IHBheWFibGUoYWRkcmVzcyh0ZXN0KSk7CgogICAgICAgIC8vIElmIHNvbWVvbmUgc2VuZHMgRXRoZXIgdG8gdGhhdCBjb250cmFjdCwKICAgICAgICAvLyB0aGUgdHJhbnNmZXIgd2lsbCBmYWlsLCBpLmUuIHRoaXMgcmV0dXJucyBmYWxzZSBoZXJlLgogICAgICAgIHJldHVybiB0ZXN0UGF5YWJsZS5zZW5kKDIgZXRoZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIGNhbGxUZXN0UGF5YWJsZShUZXN0UGF5YWJsZSB0ZXN0KSBwdWJsaWMgcmV0dXJucyAoYm9vbCkgewogICAgICAgIChib29sIHN1Y2Nlc3MsKSA9IGFkZHJlc3ModGVzdCkuY2FsbChhYmkuZW5jb2RlV2l0aFNpZ25hdHVyZSgibm9uRXhpc3RpbmdGdW5jdGlvbigpIikpOwogICAgICAgIHJlcXVpcmUoc3VjY2Vzcyk7CiAgICAgICAgLy8gcmVzdWx0cyBpbiB0ZXN0LnggYmVjb21pbmcgPT0gMSBhbmQgdGVzdC55IGJlY29taW5nIDAuCiAgICAgICAgKHN1Y2Nlc3MsKSA9IGFkZHJlc3ModGVzdCkuY2FsbHt2YWx1ZTogMX0oYWJpLmVuY29kZVdpdGhTaWduYXR1cmUoIm5vbkV4aXN0aW5nRnVuY3Rpb24oKSIpKTsKICAgICAgICByZXF1aXJlKHN1Y2Nlc3MpOwogICAgICAgIC8vIHJlc3VsdHMgaW4gdGVzdC54IGJlY29taW5nID09IDEgYW5kIHRlc3QueSBiZWNvbWluZyAxLgoKICAgICAgICAvLyBJZiBzb21lb25lIHNlbmRzIEV0aGVyIHRvIHRoYXQgY29udHJhY3QsIHRoZSByZWNlaXZlIGZ1bmN0aW9uIGluIFRlc3RQYXlhYmxlIHdpbGwgYmUgY2FsbGVkLgogICAgICAgIC8vIFNpbmNlIHRoYXQgZnVuY3Rpb24gd3JpdGVzIHRvIHN0b3JhZ2UsIGl0IHRha2VzIG1vcmUgZ2FzIHRoYW4gaXMgYXZhaWxhYmxlIHdpdGggYQogICAgICAgIC8vIHNpbXBsZSBgYHNlbmRgYCBvciBgYHRyYW5zZmVyYGAuIEJlY2F1c2Ugb2YgdGhhdCwgd2UgaGF2ZSB0byB1c2UgYSBsb3ctbGV2ZWwgY2FsbC4KICAgICAgICAoc3VjY2VzcywpID0gYWRkcmVzcyh0ZXN0KS5jYWxse3ZhbHVlOiAyIGV0aGVyfSgiIik7CiAgICAgICAgcmVxdWlyZShzdWNjZXNzKTsKICAgICAgICAvLyByZXN1bHRzIGluIHRlc3QueCBiZWNvbWluZyA9PSAyIGFuZCB0ZXN0LnkgYmVjb21pbmcgMiBldGhlci4KCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.2</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Test</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">x</span><span class="p">;</span> <span class="w"> </span><span class="c1">// This function is called for all messages sent to</span> <span class="w"> </span><span class="c1">// this contract (there is no other function).</span> <span class="w"> </span><span class="c1">// Sending Ether to this contract will cause an exception,</span> <span class="w"> </span><span class="c1">// because the fallback function does not have the `payable`</span> <span class="w"> </span><span class="c1">// modifier.</span> <span class="w"> </span>fallback<span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>x<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">TestPayable</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">x</span><span class="p">;</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">y</span><span class="p">;</span> <span class="w"> </span><span class="c1">// This function is called for all messages sent to</span> <span class="w"> </span><span class="c1">// this contract, except plain Ether transfers</span> <span class="w"> </span><span class="c1">// (there is no other function except the receive function).</span> <span class="w"> </span><span class="c1">// Any call with non-empty calldata to this contract will execute</span> <span class="w"> </span><span class="c1">// the fallback function (even if Ether is sent along with the call).</span> <span class="w"> </span>fallback<span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">payable</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>x<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">;</span><span class="w"> </span>y<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.value</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// This function is called for plain Ether transfers, i.e.</span> <span class="w"> </span><span class="c1">// for every call with empty calldata.</span> <span class="w"> </span>receive<span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">payable</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>x<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">2</span><span class="p">;</span><span class="w"> </span>y<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">msg.value</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Caller</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">callTest</span><span class="p">(</span>Test<span class="w"> </span>test<span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="nv">success</span><span class="p">,)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">address</span><span class="p">(</span>test<span class="p">).</span>call<span class="p">(</span>abi<span class="p">.</span>encodeWithSignature<span class="p">(</span><span class="s2">&quot;nonExistingFunction()&quot;</span><span class="p">));</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="c1">// results in test.x becoming == 1.</span> <span class="w"> </span><span class="c1">// address(test) will not allow to call ``send`` directly, since ``test`` has no payable</span> <span class="w"> </span><span class="c1">// fallback function.</span> <span class="w"> </span><span class="c1">// It has to be converted to the ``address payable`` type to even allow calling ``send`` on it.</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">payable</span><span class="w"> </span>testPayable<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">payable</span><span class="p">(</span><span class="kt">address</span><span class="p">(</span>test<span class="p">));</span> <span class="w"> </span><span class="c1">// If someone sends Ether to that contract,</span> <span class="w"> </span><span class="c1">// the transfer will fail, i.e. this returns false here.</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>testPayable<span class="p">.</span>send<span class="p">(</span><span class="m m-Decimal">2</span><span class="w"> </span>ether<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">callTestPayable</span><span class="p">(</span>TestPayable<span class="w"> </span>test<span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="w"> </span><span class="nv">success</span><span class="p">,)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">address</span><span class="p">(</span>test<span class="p">).</span>call<span class="p">(</span>abi<span class="p">.</span>encodeWithSignature<span class="p">(</span><span class="s2">&quot;nonExistingFunction()&quot;</span><span class="p">));</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="c1">// results in test.x becoming == 1 and test.y becoming 0.</span> <span class="w"> </span><span class="p">(</span>success<span class="p">,)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">address</span><span class="p">(</span>test<span class="p">).</span>call<span class="p">{</span>value<span class="o">:</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">}(</span>abi<span class="p">.</span>encodeWithSignature<span class="p">(</span><span class="s2">&quot;nonExistingFunction()&quot;</span><span class="p">));</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="c1">// results in test.x becoming == 1 and test.y becoming 1.</span> <span class="w"> </span><span class="c1">// If someone sends Ether to that contract, the receive function in TestPayable will be called.</span> <span class="w"> </span><span class="c1">// Since that function writes to storage, it takes more gas than is available with a</span> <span class="w"> </span><span class="c1">// simple ``send`` or ``transfer``. Because of that, we have to use a low-level call.</span> <span class="w"> </span><span class="p">(</span>success<span class="p">,)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">address</span><span class="p">(</span>test<span class="p">).</span>call<span class="p">{</span>value<span class="o">:</span><span class="w"> </span><span class="m m-Decimal">2</span><span class="w"> </span>ether<span class="p">}(</span><span class="s2">&quot;&quot;</span><span class="p">);</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>success<span class="p">);</span> <span class="w"> </span><span class="c1">// results in test.x becoming == 2 and test.y becoming 2 ether.</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> </section> <section id="function-overloading"> <span id="overload-function"></span><span id="index-14"></span><h3>Function Overloading<a class="headerlink" href="#function-overloading" title="Permalink to this heading"></a></h3> <p>A contract can have multiple functions of the same name but with different parameter types. This process is called “overloading” and also applies to inherited functions. The following example shows overloading of the function <code class="docutils literal notranslate"><span class="pre">f</span></code> in the scope of contract <code class="docutils literal notranslate"><span class="pre">A</span></code>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IEEgewogICAgZnVuY3Rpb24gZih1aW50IHZhbHVlKSBwdWJsaWMgcHVyZSByZXR1cm5zICh1aW50IG91dCkgewogICAgICAgIG91dCA9IHZhbHVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGYodWludCB2YWx1ZSwgYm9vbCByZWFsbHkpIHB1YmxpYyBwdXJlIHJldHVybnMgKHVpbnQgb3V0KSB7CiAgICAgICAgaWYgKHJlYWxseSkKICAgICAgICAgICAgb3V0ID0gdmFsdWU7CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">out</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>value<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">,</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="nv">really</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">out</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>really<span class="p">)</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>value<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Overloaded functions are also present in the external interface. It is an error if two externally visible functions differ by their Solidity types but not by their external types.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCi8vIFRoaXMgd2lsbCBub3QgY29tcGlsZQpjb250cmFjdCBBIHsKICAgIGZ1bmN0aW9uIGYoQiB2YWx1ZSkgcHVibGljIHB1cmUgcmV0dXJucyAoQiBvdXQpIHsKICAgICAgICBvdXQgPSB2YWx1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBmKGFkZHJlc3MgdmFsdWUpIHB1YmxpYyBwdXJlIHJldHVybnMgKGFkZHJlc3Mgb3V0KSB7CiAgICAgICAgb3V0ID0gdmFsdWU7CiAgICB9Cn0KCmNvbnRyYWN0IEIgewp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="c1">// This will not compile</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span>B<span class="w"> </span>value<span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>B<span class="w"> </span>out<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>value<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">out</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>value<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">B</span><span class="w"> </span><span class="p">{</span> <span class="p">}</span> </pre></div> </div> <p>Both <code class="docutils literal notranslate"><span class="pre">f</span></code> function overloads above end up accepting the address type for the ABI although they are considered different inside Solidity.</p> <section id="overload-resolution-and-argument-matching"> <h4>Overload resolution and Argument matching<a class="headerlink" href="#overload-resolution-and-argument-matching" title="Permalink to this heading"></a></h4> <p>Overloaded functions are selected by matching the function declarations in the current scope to the arguments supplied in the function call. Functions are selected as overload candidates if all arguments can be implicitly converted to the expected types. If there is not exactly one candidate, resolution fails.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Return parameters are not taken into account for overload resolution.</p> </div> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjE2IDwwLjkuMDsKCmNvbnRyYWN0IEEgewogICAgZnVuY3Rpb24gZih1aW50OCB2YWwpIHB1YmxpYyBwdXJlIHJldHVybnMgKHVpbnQ4IG91dCkgewogICAgICAgIG91dCA9IHZhbDsKICAgIH0KCiAgICBmdW5jdGlvbiBmKHVpbnQyNTYgdmFsKSBwdWJsaWMgcHVyZSByZXR1cm5zICh1aW50MjU2IG91dCkgewogICAgICAgIG91dCA9IHZhbDsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.16</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint8</span><span class="w"> </span><span class="nv">val</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8</span><span class="w"> </span><span class="nv">out</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>val<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint256</span><span class="w"> </span><span class="nv">val</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint256</span><span class="w"> </span><span class="nv">out</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>out<span class="w"> </span><span class="o">=</span><span class="w"> </span>val<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Calling <code class="docutils literal notranslate"><span class="pre">f(50)</span></code> would create a type error since <code class="docutils literal notranslate"><span class="pre">50</span></code> can be implicitly converted both to <code class="docutils literal notranslate"><span class="pre">uint8</span></code> and <code class="docutils literal notranslate"><span class="pre">uint256</span></code> types. On another hand <code class="docutils literal notranslate"><span class="pre">f(256)</span></code> would resolve to <code class="docutils literal notranslate"><span class="pre">f(uint256)</span></code> overload as <code class="docutils literal notranslate"><span class="pre">256</span></code> cannot be implicitly converted to <code class="docutils literal notranslate"><span class="pre">uint8</span></code>.</p> </section> </section> </section> <section id="events"> <span id="index-15"></span><span id="id12"></span><h2>Events<a class="headerlink" href="#events" title="Permalink to this heading"></a></h2> <p>Solidity events give an abstraction on top of the EVM’s logging functionality. Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.</p> <p>Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries). When you call them, they cause the arguments to be stored in the transaction’s log - a special data structure in the blockchain. These logs are associated with the address of the contract that emitted them, are incorporated into the blockchain, and stay there as long as a block is accessible (forever as of now, but this might change in the future). The Log and its event data is not accessible from within contracts (not even from the contract that created them).</p> <p>It is possible to request a Merkle proof for logs, so if an external entity supplies a contract with such a proof, it can check that the log actually exists inside the blockchain. You have to supply block headers because the contract can only see the last 256 block hashes.</p> <p>You can add the attribute <code class="docutils literal notranslate"><span class="pre">indexed</span></code> to up to three parameters which adds them to a special data structure known as <a class="reference internal" href="abi-spec.html#abi-events"><span class="std std-ref">“topics”</span></a> instead of the data part of the log. A topic can only hold a single word (32 bytes) so if you use a <a class="reference internal" href="types.html#reference-types"><span class="std std-ref">reference type</span></a> for an indexed argument, the Keccak-256 hash of the value is stored as a topic instead.</p> <p>All parameters without the <code class="docutils literal notranslate"><span class="pre">indexed</span></code> attribute are <a class="reference internal" href="abi-spec.html#abi"><span class="std std-ref">ABI-encoded</span></a> into the data part of the log.</p> <p>Topics allow you to search for events, for example when filtering a sequence of blocks for certain events. You can also filter events by the address of the contract that emitted the event.</p> <p>For example, the code below uses the web3.js <code class="docutils literal notranslate"><span class="pre">subscribe(&quot;logs&quot;)</span></code> <a class="reference external" href="https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html#subscribe-logs">method</a> to filter logs that match a topic with a certain address value:</p> <div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="kd">var</span><span class="w"> </span><span class="nx">options</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nx">fromBlock</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span> <span class="w"> </span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="nx">web3</span><span class="p">.</span><span class="nx">eth</span><span class="p">.</span><span class="nx">defaultAccount</span><span class="p">,</span> <span class="w"> </span><span class="nx">topics</span><span class="o">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;0x0000000000000000000000000000000000000000000000000000000000000000&quot;</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">]</span> <span class="p">};</span> <span class="nx">web3</span><span class="p">.</span><span class="nx">eth</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="s1">&#39;logs&#39;</span><span class="p">,</span><span class="w"> </span><span class="nx">options</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">,</span><span class="w"> </span><span class="nx">result</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">error</span><span class="p">)</span> <span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span> <span class="p">})</span> <span class="w"> </span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">&quot;data&quot;</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">log</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">log</span><span class="p">);</span> <span class="w"> </span><span class="p">})</span> <span class="w"> </span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s2">&quot;changed&quot;</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">log</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="p">});</span> </pre></div> </div> <p>The hash of the signature of the event is one of the topics, except if you declared the event with the <code class="docutils literal notranslate"><span class="pre">anonymous</span></code> specifier. This means that it is not possible to filter for specific anonymous events by name, you can only filter by the contract address. The advantage of anonymous events is that they are cheaper to deploy and call. It also allows you to declare four indexed arguments rather than three.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Since the transaction log only stores the event data and not the type, you have to know the type of the event, including which parameter is indexed and if the event is anonymous in order to correctly interpret the data. In particular, it is possible to “fake” the signature of another event using an anonymous event.</p> </div> <section id="members-of-events"> <span id="index-16"></span><h3>Members of Events<a class="headerlink" href="#members-of-events" title="Permalink to this heading"></a></h3> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">event.selector</span></code>: For non-anonymous events, this is a <code class="docutils literal notranslate"><span class="pre">bytes32</span></code> value containing the <code class="docutils literal notranslate"><span class="pre">keccak256</span></code> hash of the event signature, as used in the default topic.</p></li> </ul> </section> <section id="example"> <h3>Example<a class="headerlink" href="#example" title="Permalink to this heading"></a></h3> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjIxIDwwLjkuMDsKCmNvbnRyYWN0IENsaWVudFJlY2VpcHQgewogICAgZXZlbnQgRGVwb3NpdCgKICAgICAgICBhZGRyZXNzIGluZGV4ZWQgZnJvbSwKICAgICAgICBieXRlczMyIGluZGV4ZWQgaWQsCiAgICAgICAgdWludCB2YWx1ZQogICAgKTsKCiAgICBmdW5jdGlvbiBkZXBvc2l0KGJ5dGVzMzIgaWQpIHB1YmxpYyBwYXlhYmxlIHsKICAgICAgICAvLyBFdmVudHMgYXJlIGVtaXR0ZWQgdXNpbmcgYGVtaXRgLCBmb2xsb3dlZCBieQogICAgICAgIC8vIHRoZSBuYW1lIG9mIHRoZSBldmVudCBhbmQgdGhlIGFyZ3VtZW50cwogICAgICAgIC8vIChpZiBhbnkpIGluIHBhcmVudGhlc2VzLiBBbnkgc3VjaCBpbnZvY2F0aW9uCiAgICAgICAgLy8gKGV2ZW4gZGVlcGx5IG5lc3RlZCkgY2FuIGJlIGRldGVjdGVkIGZyb20KICAgICAgICAvLyB0aGUgSmF2YVNjcmlwdCBBUEkgYnkgZmlsdGVyaW5nIGZvciBgRGVwb3NpdGAuCiAgICAgICAgZW1pdCBEZXBvc2l0KG1zZy5zZW5kZXIsIGlkLCBtc2cudmFsdWUpOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.21</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">ClientReceipt</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Deposit</span><span class="p">(</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">indexed</span><span class="w"> </span>from<span class="p">,</span> <span class="w"> </span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">indexed</span><span class="w"> </span>id<span class="p">,</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span> <span class="w"> </span><span class="p">);</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">deposit</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">id</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="kt">payable</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Events are emitted using `emit`, followed by</span> <span class="w"> </span><span class="c1">// the name of the event and the arguments</span> <span class="w"> </span><span class="c1">// (if any) in parentheses. Any such invocation</span> <span class="w"> </span><span class="c1">// (even deeply nested) can be detected from</span> <span class="w"> </span><span class="c1">// the JavaScript API by filtering for `Deposit`.</span> <span class="w"> </span>emit<span class="w"> </span>Deposit<span class="p">(</span><span class="k">msg.sender</span><span class="p">,</span><span class="w"> </span>id<span class="p">,</span><span class="w"> </span><span class="k">msg.value</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>The use in the JavaScript API is as follows:</p> <div class="highlight-javascript notranslate"><div class="highlight"><pre><span></span><span class="kd">var</span><span class="w"> </span><span class="nx">abi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="cm">/* abi as generated by the compiler */</span><span class="p">;</span> <span class="kd">var</span><span class="w"> </span><span class="nx">ClientReceipt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">web3</span><span class="p">.</span><span class="nx">eth</span><span class="p">.</span><span class="nx">contract</span><span class="p">(</span><span class="nx">abi</span><span class="p">);</span> <span class="kd">var</span><span class="w"> </span><span class="nx">clientReceipt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ClientReceipt</span><span class="p">.</span><span class="nx">at</span><span class="p">(</span><span class="s2">&quot;0x1234...ab67&quot;</span><span class="w"> </span><span class="cm">/* address */</span><span class="p">);</span> <span class="kd">var</span><span class="w"> </span><span class="nx">depositEvent</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">clientReceipt</span><span class="p">.</span><span class="nx">Deposit</span><span class="p">();</span> <span class="c1">// watch for changes</span> <span class="nx">depositEvent</span><span class="p">.</span><span class="nx">watch</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span><span class="w"> </span><span class="nx">result</span><span class="p">){</span> <span class="w"> </span><span class="c1">// result contains non-indexed arguments and topics</span> <span class="w"> </span><span class="c1">// given to the `Deposit` call.</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">error</span><span class="p">)</span> <span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span> <span class="p">});</span> <span class="c1">// Or pass a callback to start watching immediately</span> <span class="kd">var</span><span class="w"> </span><span class="nx">depositEvent</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">clientReceipt</span><span class="p">.</span><span class="nx">Deposit</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">,</span><span class="w"> </span><span class="nx">result</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">error</span><span class="p">)</span> <span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span> <span class="p">});</span> </pre></div> </div> <p>The output of the above looks like the following (trimmed):</p> <div class="highlight-json notranslate"><div class="highlight"><pre><span></span><span class="p">{</span> <span class="w"> </span><span class="nt">&quot;returnValues&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nt">&quot;from&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0x1111…FFFFCCCC&quot;</span><span class="p">,</span> <span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0x50…sd5adb20&quot;</span><span class="p">,</span> <span class="w"> </span><span class="nt">&quot;value&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0x420042&quot;</span> <span class="w"> </span><span class="p">},</span> <span class="w"> </span><span class="nt">&quot;raw&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;0x7f…91385&quot;</span><span class="p">,</span> <span class="w"> </span><span class="nt">&quot;topics&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;0xfd4…b4ead7&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;0x7f…1a91385&quot;</span><span class="p">]</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="additional-resources-for-understanding-events"> <h3>Additional Resources for Understanding Events<a class="headerlink" href="#additional-resources-for-understanding-events" title="Permalink to this heading"></a></h3> <ul class="simple"> <li><p><a class="reference external" href="https://github.com/web3/web3.js/blob/1.x/docs/web3-eth-contract.rst#events">JavaScript documentation</a></p></li> <li><p><a class="reference external" href="https://github.com/ethchange/smart-exchange/blob/master/lib/contracts/SmartExchange.sol">Example usage of events</a></p></li> <li><p><a class="reference external" href="https://github.com/ethchange/smart-exchange/blob/master/lib/exchange_transactions.js">How to access them in js</a></p></li> </ul> </section> </section> <section id="custom-errors"> <span id="errors"></span><span id="index-17"></span><h2>Custom Errors<a class="headerlink" href="#custom-errors" title="Permalink to this heading"></a></h2> <p>Errors in Solidity provide a convenient and gas-efficient way to explain to the user why an operation failed. They can be defined inside and outside of contracts (including interfaces and libraries).</p> <p>They have to be used together with the <a class="reference internal" href="control-structures.html#revert-statement"><span class="std std-ref">revert statement</span></a> or the <a class="reference internal" href="control-structures.html#assert-and-require-statements"><span class="std std-ref">require function</span></a>. In the case of <code class="docutils literal notranslate"><span class="pre">revert</span></code> statements, or <code class="docutils literal notranslate"><span class="pre">require</span></code> calls where the condition is evaluated to be false, all changes in the current call are reverted, and the error data passed back to the caller.</p> <p>The example below shows custom error usage with the <code class="docutils literal notranslate"><span class="pre">revert</span></code> statement in function <code class="docutils literal notranslate"><span class="pre">transferWithRevertError</span></code>, as well as the newer approach with <code class="docutils literal notranslate"><span class="pre">require</span></code> in function <code class="docutils literal notranslate"><span class="pre">transferWithRequireError</span></code>.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMjc7CgovLy8gSW5zdWZmaWNpZW50IGJhbGFuY2UgZm9yIHRyYW5zZmVyLiBOZWVkZWQgYHJlcXVpcmVkYCBidXQgb25seQovLy8gYGF2YWlsYWJsZWAgYXZhaWxhYmxlLgovLy8gQHBhcmFtIGF2YWlsYWJsZSBiYWxhbmNlIGF2YWlsYWJsZS4KLy8vIEBwYXJhbSByZXF1aXJlZCByZXF1ZXN0ZWQgYW1vdW50IHRvIHRyYW5zZmVyLgplcnJvciBJbnN1ZmZpY2llbnRCYWxhbmNlKHVpbnQyNTYgYXZhaWxhYmxlLCB1aW50MjU2IHJlcXVpcmVkKTsKCmNvbnRyYWN0IFRlc3RUb2tlbiB7CiAgICBtYXBwaW5nKGFkZHJlc3MgPT4gdWludCkgYmFsYW5jZTsKICAgIGZ1bmN0aW9uIHRyYW5zZmVyV2l0aFJldmVydEVycm9yKGFkZHJlc3MgdG8sIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgewogICAgICAgIGlmIChhbW91bnQgPiBiYWxhbmNlW21zZy5zZW5kZXJdKQogICAgICAgICAgICByZXZlcnQgSW5zdWZmaWNpZW50QmFsYW5jZSh7CiAgICAgICAgICAgICAgICBhdmFpbGFibGU6IGJhbGFuY2VbbXNnLnNlbmRlcl0sCiAgICAgICAgICAgICAgICByZXF1aXJlZDogYW1vdW50CiAgICAgICAgICAgIH0pOwogICAgICAgIGJhbGFuY2VbbXNnLnNlbmRlcl0gLT0gYW1vdW50OwogICAgICAgIGJhbGFuY2VbdG9dICs9IGFtb3VudDsKICAgIH0KICAgIGZ1bmN0aW9uIHRyYW5zZmVyV2l0aFJlcXVpcmVFcnJvcihhZGRyZXNzIHRvLCB1aW50MjU2IGFtb3VudCkgcHVibGljIHsKICAgICAgICByZXF1aXJlKGFtb3VudCA8PSBiYWxhbmNlW21zZy5zZW5kZXJdLCBJbnN1ZmZpY2llbnRCYWxhbmNlKGJhbGFuY2VbbXNnLnNlbmRlcl0sIGFtb3VudCkpOwogICAgICAgIGJhbGFuY2VbbXNnLnNlbmRlcl0gLT0gYW1vdW50OwogICAgICAgIGJhbGFuY2VbdG9dICs9IGFtb3VudDsKICAgIH0KICAgIC8vIC4uLgp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.27</span><span class="p">;</span> <span class="c1">/// Insufficient balance for transfer. Needed `required` but only</span> <span class="c1">/// `available` available.</span> <span class="c1">/// @param available balance available.</span> <span class="c1">/// @param required requested amount to transfer.</span> error<span class="w"> </span>InsufficientBalance<span class="p">(</span><span class="kt">uint256</span><span class="w"> </span><span class="nv">available</span><span class="p">,</span><span class="w"> </span><span class="kt">uint256</span><span class="w"> </span><span class="nv">required</span><span class="p">);</span> <span class="k">contract</span><span class="w"> </span><span class="ni">TestToken</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span>balance<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">transferWithRevertError</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">to</span><span class="p">,</span><span class="w"> </span><span class="kt">uint256</span><span class="w"> </span><span class="nv">amount</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>amount<span class="w"> </span><span class="o">&gt;</span><span class="w"> </span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">])</span> <span class="w"> </span>revert<span class="w"> </span>InsufficientBalance<span class="p">({</span> <span class="w"> </span>available<span class="o">:</span><span class="w"> </span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">],</span> <span class="w"> </span>required<span class="o">:</span><span class="w"> </span>amount <span class="w"> </span><span class="p">});</span> <span class="w"> </span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">]</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span>amount<span class="p">;</span> <span class="w"> </span>balance<span class="p">[</span>to<span class="p">]</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span>amount<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">transferWithRequireError</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">to</span><span class="p">,</span><span class="w"> </span><span class="kt">uint256</span><span class="w"> </span><span class="nv">amount</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>amount<span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">],</span><span class="w"> </span>InsufficientBalance<span class="p">(</span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">],</span><span class="w"> </span>amount<span class="p">));</span> <span class="w"> </span>balance<span class="p">[</span><span class="k">msg.sender</span><span class="p">]</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span>amount<span class="p">;</span> <span class="w"> </span>balance<span class="p">[</span>to<span class="p">]</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span>amount<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// ...</span> <span class="p">}</span> </pre></div> </div> <p>Another important detail to mention when it comes to using <code class="docutils literal notranslate"><span class="pre">require</span></code> with custom errors, is that memory allocation for the error-based revert reason will only happen in the reverting case, which, along with optimization of constants and string literals makes this about as gas-efficient as the <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">(!condition)</span> <span class="pre">revert</span> <span class="pre">CustomError(args)</span></code> pattern.</p> <p>Errors cannot be overloaded or overridden but are inherited. The same error can be defined in multiple places as long as the scopes are distinct. Instances of errors can only be created using <code class="docutils literal notranslate"><span class="pre">revert</span></code> statements, or as the second argument to <code class="docutils literal notranslate"><span class="pre">require</span></code> functions.</p> <p>The error creates data that is then passed to the caller with the revert operation to either return to the off-chain component or catch it in a <a class="reference internal" href="control-structures.html#try-catch"><span class="std std-ref">try/catch statement</span></a>. Note that an error can only be caught when coming from an external call, reverts happening in internal calls or inside the same function cannot be caught.</p> <p>If you do not provide any parameters, the error only needs four bytes of data and you can use <a class="reference internal" href="natspec-format.html#natspec"><span class="std std-ref">NatSpec</span></a> as above to further explain the reasons behind the error, which is not stored on chain. This makes this a very cheap and convenient error-reporting feature at the same time.</p> <p>More specifically, an error instance is ABI-encoded in the same way as a function call to a function of the same name and types would be and then used as the return data in the <code class="docutils literal notranslate"><span class="pre">revert</span></code> opcode. This means that the data consists of a 4-byte selector followed by <a class="reference internal" href="abi-spec.html#abi"><span class="std std-ref">ABI-encoded</span></a> data. The selector consists of the first four bytes of the keccak256-hash of the signature of the error type.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>It is possible for a contract to revert with different errors of the same name or even with errors defined in different places that are indistinguishable by the caller. For the outside, i.e. the ABI, only the name of the error is relevant, not the contract or file where it is defined.</p> </div> <p>The statement <code class="docutils literal notranslate"><span class="pre">require(condition,</span> <span class="pre">&quot;description&quot;);</span></code> would be equivalent to <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">(!condition)</span> <span class="pre">revert</span> <span class="pre">Error(&quot;description&quot;)</span></code> if you could define <code class="docutils literal notranslate"><span class="pre">error</span> <span class="pre">Error(string)</span></code>. Note, however, that <code class="docutils literal notranslate"><span class="pre">Error</span></code> is a built-in type and cannot be defined in user-supplied code.</p> <p>Similarly, a failing <code class="docutils literal notranslate"><span class="pre">assert</span></code> or similar conditions will revert with an error of the built-in type <code class="docutils literal notranslate"><span class="pre">Panic(uint256)</span></code>.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Error data should only be used to give an indication of failure, but not as a means for control-flow. The reason is that the revert data of inner calls is propagated back through the chain of external calls by default. This means that an inner call can “forge” revert data that looks like it could have come from the contract that called it.</p> </div> <section id="members-of-errors"> <h3>Members of Errors<a class="headerlink" href="#members-of-errors" title="Permalink to this heading"></a></h3> <ul class="simple"> <li><p><code class="docutils literal notranslate"><span class="pre">error.selector</span></code>: A <code class="docutils literal notranslate"><span class="pre">bytes4</span></code> value containing the error selector.</p></li> </ul> </section> </section> <section id="inheritance"> <span id="index-18"></span><h2>Inheritance<a class="headerlink" href="#inheritance" title="Permalink to this heading"></a></h2> <p>Solidity supports multiple inheritance including polymorphism.</p> <p>Polymorphism means that a function call (internal and external) always executes the function of the same name (and parameter types) in the most derived contract in the inheritance hierarchy. This has to be explicitly enabled on each function in the hierarchy using the <code class="docutils literal notranslate"><span class="pre">virtual</span></code> and <code class="docutils literal notranslate"><span class="pre">override</span></code> keywords. See <a class="reference internal" href="#function-overriding"><span class="std std-ref">Function Overriding</span></a> for more details.</p> <p>It is possible to call functions further up in the inheritance hierarchy internally by explicitly specifying the contract using <code class="docutils literal notranslate"><span class="pre">ContractName.functionName()</span></code> or using <code class="docutils literal notranslate"><span class="pre">super.functionName()</span></code> if you want to call the function one level higher up in the flattened inheritance hierarchy (see below).</p> <p>When a contract inherits from other contracts, only a single contract is created on the blockchain, and the code from all the base contracts is compiled into the created contract. This means that all internal calls to functions of base contracts also just use internal function calls (<code class="docutils literal notranslate"><span class="pre">super.f(..)</span></code> will use JUMP and not a message call).</p> <p>State variable shadowing is considered as an error. A derived contract can only declare a state variable <code class="docutils literal notranslate"><span class="pre">x</span></code>, if there is no visible state variable with the same name in any of its bases.</p> <p>The general inheritance system is very similar to <a class="reference external" href="https://docs.python.org/3/tutorial/classes.html#inheritance">Python’s</a>, especially concerning multiple inheritance, but there are also some <a class="reference internal" href="#multi-inheritance"><span class="std std-ref">differences</span></a>.</p> <p>Details are given in the following example.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgT3duZWQgewogICAgYWRkcmVzcyBwYXlhYmxlIG93bmVyOwogICAgY29uc3RydWN0b3IoKSB7IG93bmVyID0gcGF5YWJsZShtc2cuc2VuZGVyKTsgfQp9CgovLyBVc2UgYGlzYCB0byBkZXJpdmUgZnJvbSBhbm90aGVyIGNvbnRyYWN0LiBEZXJpdmVkCi8vIGNvbnRyYWN0cyBjYW4gYWNjZXNzIGFsbCBub24tcHJpdmF0ZSBtZW1iZXJzIGluY2x1ZGluZwovLyBpbnRlcm5hbCBmdW5jdGlvbnMgYW5kIHN0YXRlIHZhcmlhYmxlcy4gVGhlc2UgY2Fubm90IGJlCi8vIGFjY2Vzc2VkIGV4dGVybmFsbHkgdmlhIGB0aGlzYCwgdGhvdWdoLgpjb250cmFjdCBFbWl0dGFibGUgaXMgT3duZWQgewogICAgZXZlbnQgRW1pdHRlZCgpOwoKICAgIC8vIFRoZSBrZXl3b3JkIGB2aXJ0dWFsYCBtZWFucyB0aGF0IHRoZSBmdW5jdGlvbiBjYW4gY2hhbmdlCiAgICAvLyBpdHMgYmVoYXZpb3IgaW4gZGVyaXZlZCBjbGFzc2VzICgib3ZlcnJpZGluZyIpLgogICAgZnVuY3Rpb24gZW1pdEV2ZW50KCkgdmlydHVhbCBwdWJsaWMgewogICAgICAgIGlmIChtc2cuc2VuZGVyID09IG93bmVyKQogICAgICAgICAgICBlbWl0IEVtaXR0ZWQoKTsKICAgIH0KfQoKLy8gVGhlc2UgYWJzdHJhY3QgY29udHJhY3RzIGFyZSBvbmx5IHByb3ZpZGVkIHRvIG1ha2UgdGhlCi8vIGludGVyZmFjZSBrbm93biB0byB0aGUgY29tcGlsZXIuIE5vdGUgdGhlIGZ1bmN0aW9uCi8vIHdpdGhvdXQgYm9keS4gSWYgYSBjb250cmFjdCBkb2VzIG5vdCBpbXBsZW1lbnQgYWxsCi8vIGZ1bmN0aW9ucyBpdCBjYW4gb25seSBiZSB1c2VkIGFzIGFuIGludGVyZmFjZS4KYWJzdHJhY3QgY29udHJhY3QgQ29uZmlnIHsKICAgIGZ1bmN0aW9uIGxvb2t1cCh1aW50IGlkKSBwdWJsaWMgdmlydHVhbCByZXR1cm5zIChhZGRyZXNzIGFkcik7Cn0KCmFic3RyYWN0IGNvbnRyYWN0IE5hbWVSZWcgewogICAgZnVuY3Rpb24gcmVnaXN0ZXIoYnl0ZXMzMiBuYW1lKSBwdWJsaWMgdmlydHVhbDsKICAgIGZ1bmN0aW9uIHVucmVnaXN0ZXIoKSBwdWJsaWMgdmlydHVhbDsKfQoKLy8gTXVsdGlwbGUgaW5oZXJpdGFuY2UgaXMgcG9zc2libGUuIE5vdGUgdGhhdCBgT3duZWRgIGlzCi8vIGFsc28gYSBiYXNlIGNsYXNzIG9mIGBFbWl0dGFibGVgLCB5ZXQgdGhlcmUgaXMgb25seSBhIHNpbmdsZQovLyBpbnN0YW5jZSBvZiBgT3duZWRgIChhcyBmb3IgdmlydHVhbCBpbmhlcml0YW5jZSBpbiBDKyspLgpjb250cmFjdCBOYW1lZCBpcyBPd25lZCwgRW1pdHRhYmxlIHsKICAgIGNvbnN0cnVjdG9yKGJ5dGVzMzIgbmFtZSkgewogICAgICAgIENvbmZpZyBjb25maWcgPSBDb25maWcoMHhENWY5RDhEOTQ4ODZFNzBiMDZFNDc0YzNmQjE0RmQ0M0UyZjIzOTcwKTsKICAgICAgICBOYW1lUmVnKGNvbmZpZy5sb29rdXAoMSkpLnJlZ2lzdGVyKG5hbWUpOwogICAgfQoKICAgIC8vIEZ1bmN0aW9ucyBjYW4gYmUgb3ZlcnJpZGRlbiBieSBhbm90aGVyIGZ1bmN0aW9uIHdpdGggdGhlIHNhbWUgbmFtZSBhbmQKICAgIC8vIHRoZSBzYW1lIG51bWJlci90eXBlcyBvZiBpbnB1dHMuIElmIHRoZSBvdmVycmlkaW5nIGZ1bmN0aW9uIGhhcyBkaWZmZXJlbnQKICAgIC8vIHR5cGVzIG9mIG91dHB1dCBwYXJhbWV0ZXJzLCB0aGF0IGNhdXNlcyBhbiBlcnJvci4KICAgIC8vIEJvdGggbG9jYWwgYW5kIG1lc3NhZ2UtYmFzZWQgZnVuY3Rpb24gY2FsbHMgdGFrZSB0aGVzZSBvdmVycmlkZXMKICAgIC8vIGludG8gYWNjb3VudC4KICAgIC8vIElmIHlvdSB3YW50IHRoZSBmdW5jdGlvbiB0byBvdmVycmlkZSwgeW91IG5lZWQgdG8gdXNlIHRoZQogICAgLy8gYG92ZXJyaWRlYCBrZXl3b3JkLiBZb3UgbmVlZCB0byBzcGVjaWZ5IHRoZSBgdmlydHVhbGAga2V5d29yZCBhZ2FpbgogICAgLy8gaWYgeW91IHdhbnQgdGhpcyBmdW5jdGlvbiB0byBiZSBvdmVycmlkZGVuIGFnYWluLgogICAgZnVuY3Rpb24gZW1pdEV2ZW50KCkgcHVibGljIHZpcnR1YWwgb3ZlcnJpZGUgewogICAgICAgIGlmIChtc2cuc2VuZGVyID09IG93bmVyKSB7CiAgICAgICAgICAgIENvbmZpZyBjb25maWcgPSBDb25maWcoMHhENWY5RDhEOTQ4ODZFNzBiMDZFNDc0YzNmQjE0RmQ0M0UyZjIzOTcwKTsKICAgICAgICAgICAgTmFtZVJlZyhjb25maWcubG9va3VwKDEpKS51bnJlZ2lzdGVyKCk7CiAgICAgICAgICAgIC8vIEl0IGlzIHN0aWxsIHBvc3NpYmxlIHRvIGNhbGwgYSBzcGVjaWZpYwogICAgICAgICAgICAvLyBvdmVycmlkZGVuIGZ1bmN0aW9uLgogICAgICAgICAgICBFbWl0dGFibGUuZW1pdEV2ZW50KCk7CiAgICAgICAgfQogICAgfQp9CgoKLy8gSWYgYSBjb25zdHJ1Y3RvciB0YWtlcyBhbiBhcmd1bWVudCwgaXQgbmVlZHMgdG8gYmUKLy8gcHJvdmlkZWQgaW4gdGhlIGhlYWRlciBvciBtb2RpZmllci1pbnZvY2F0aW9uLXN0eWxlIGF0Ci8vIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgZGVyaXZlZCBjb250cmFjdCAoc2VlIGJlbG93KS4KY29udHJhY3QgUHJpY2VGZWVkIGlzIE93bmVkLCBFbWl0dGFibGUsIE5hbWVkKCJHb2xkRmVlZCIpIHsKICAgIHVpbnQgaW5mbzsKCiAgICBmdW5jdGlvbiB1cGRhdGVJbmZvKHVpbnQgbmV3SW5mbykgcHVibGljIHsKICAgICAgICBpZiAobXNnLnNlbmRlciA9PSBvd25lcikgaW5mbyA9IG5ld0luZm87CiAgICB9CgogICAgLy8gSGVyZSwgd2Ugb25seSBzcGVjaWZ5IGBvdmVycmlkZWAgYW5kIG5vdCBgdmlydHVhbGAuCiAgICAvLyBUaGlzIG1lYW5zIHRoYXQgY29udHJhY3RzIGRlcml2aW5nIGZyb20gYFByaWNlRmVlZGAKICAgIC8vIGNhbm5vdCBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGBlbWl0RXZlbnRgIGFueW1vcmUuCiAgICBmdW5jdGlvbiBlbWl0RXZlbnQoKSBwdWJsaWMgb3ZlcnJpZGUoRW1pdHRhYmxlLCBOYW1lZCkgeyBOYW1lZC5lbWl0RXZlbnQoKTsgfQogICAgZnVuY3Rpb24gZ2V0KCkgcHVibGljIHZpZXcgcmV0dXJucyh1aW50IHIpIHsgcmV0dXJuIGluZm87IH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Owned</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">payable</span><span class="w"> </span>owner<span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">payable</span><span class="p">(</span><span class="k">msg.sender</span><span class="p">);</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="c1">// Use `is` to derive from another contract. Derived</span> <span class="c1">// contracts can access all non-private members including</span> <span class="c1">// internal functions and state variables. These cannot be</span> <span class="c1">// accessed externally via `this`, though.</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Emittable</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Owned<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Emitted</span><span class="p">();</span> <span class="w"> </span><span class="c1">// The keyword `virtual` means that the function can change</span> <span class="w"> </span><span class="c1">// its behavior in derived classes (&quot;overriding&quot;).</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">)</span> <span class="w"> </span>emit<span class="w"> </span>Emitted<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="c1">// These abstract contracts are only provided to make the</span> <span class="c1">// interface known to the compiler. Note the function</span> <span class="c1">// without body. If a contract does not implement all</span> <span class="c1">// functions it can only be used as an interface.</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">Config</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">lookup</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">id</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">adr</span><span class="p">);</span> <span class="p">}</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">NameReg</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">register</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">unregister</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="p">;</span> <span class="p">}</span> <span class="c1">// Multiple inheritance is possible. Note that `Owned` is</span> <span class="c1">// also a base class of `Emittable`, yet there is only a single</span> <span class="c1">// instance of `Owned` (as for virtual inheritance in C++).</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Named</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Owned<span class="p">,</span><span class="w"> </span>Emittable<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">bytes32</span><span class="w"> </span><span class="nv">name</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>Config<span class="w"> </span>config<span class="w"> </span><span class="o">=</span><span class="w"> </span>Config<span class="p">(</span><span class="mh">0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970</span><span class="p">);</span> <span class="w"> </span>NameReg<span class="p">(</span>config<span class="p">.</span>lookup<span class="p">(</span><span class="m m-Decimal">1</span><span class="p">)).</span>register<span class="p">(</span>name<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// Functions can be overridden by another function with the same name and</span> <span class="w"> </span><span class="c1">// the same number/types of inputs. If the overriding function has different</span> <span class="w"> </span><span class="c1">// types of output parameters, that causes an error.</span> <span class="w"> </span><span class="c1">// Both local and message-based function calls take these overrides</span> <span class="w"> </span><span class="c1">// into account.</span> <span class="w"> </span><span class="c1">// If you want the function to override, you need to use the</span> <span class="w"> </span><span class="c1">// `override` keyword. You need to specify the `virtual` keyword again</span> <span class="w"> </span><span class="c1">// if you want this function to be overridden again.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span>override<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>Config<span class="w"> </span>config<span class="w"> </span><span class="o">=</span><span class="w"> </span>Config<span class="p">(</span><span class="mh">0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970</span><span class="p">);</span> <span class="w"> </span>NameReg<span class="p">(</span>config<span class="p">.</span>lookup<span class="p">(</span><span class="m m-Decimal">1</span><span class="p">)).</span>unregister<span class="p">();</span> <span class="w"> </span><span class="c1">// It is still possible to call a specific</span> <span class="w"> </span><span class="c1">// overridden function.</span> <span class="w"> </span>Emittable<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="c1">// If a constructor takes an argument, it needs to be</span> <span class="c1">// provided in the header or modifier-invocation-style at</span> <span class="c1">// the constructor of the derived contract (see below).</span> <span class="k">contract</span><span class="w"> </span><span class="ni">PriceFeed</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Owned<span class="p">,</span><span class="w"> </span>Emittable<span class="p">,</span><span class="w"> </span>Named<span class="p">(</span><span class="s2">&quot;GoldFeed&quot;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">info</span><span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">updateInfo</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">newInfo</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">)</span><span class="w"> </span>info<span class="w"> </span><span class="o">=</span><span class="w"> </span>newInfo<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// Here, we only specify `override` and not `virtual`.</span> <span class="w"> </span><span class="c1">// This means that contracts deriving from `PriceFeed`</span> <span class="w"> </span><span class="c1">// cannot change the behavior of `emitEvent` anymore.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>override<span class="p">(</span>Emittable<span class="p">,</span><span class="w"> </span>Named<span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>Named<span class="p">.</span>emitEvent<span class="p">();</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">get</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>view<span class="w"> </span><span class="kt">returns</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">r</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>info<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Note that above, we call <code class="docutils literal notranslate"><span class="pre">Emittable.emitEvent()</span></code> to “forward” the emit event request. The way this is done is problematic, as seen in the following example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgT3duZWQgewogICAgYWRkcmVzcyBwYXlhYmxlIG93bmVyOwogICAgY29uc3RydWN0b3IoKSB7IG93bmVyID0gcGF5YWJsZShtc2cuc2VuZGVyKTsgfQp9Cgpjb250cmFjdCBFbWl0dGFibGUgaXMgT3duZWQgewogICAgZXZlbnQgRW1pdHRlZCgpOwoKICAgIGZ1bmN0aW9uIGVtaXRFdmVudCgpIHZpcnR1YWwgcHVibGljIHsKICAgICAgICBpZiAobXNnLnNlbmRlciA9PSBvd25lcikgewogICAgICAgICAgICBlbWl0IEVtaXR0ZWQoKTsKICAgICAgICB9CiAgICB9Cn0KCmNvbnRyYWN0IEJhc2UxIGlzIEVtaXR0YWJsZSB7CiAgICBldmVudCBCYXNlMUVtaXR0ZWQoKTsKICAgIGZ1bmN0aW9uIGVtaXRFdmVudCgpIHB1YmxpYyB2aXJ0dWFsIG92ZXJyaWRlIHsKICAgICAgICAvKiBIZXJlLCB3ZSBlbWl0IGFuIGV2ZW50IHRvIHNpbXVsYXRlIHNvbWUgQmFzZTEgbG9naWMgKi8KICAgICAgICBlbWl0IEJhc2UxRW1pdHRlZCgpOwogICAgICAgIEVtaXR0YWJsZS5lbWl0RXZlbnQoKTsKICAgIH0KfQoKY29udHJhY3QgQmFzZTIgaXMgRW1pdHRhYmxlIHsKICAgIGV2ZW50IEJhc2UyRW1pdHRlZCgpOwogICAgZnVuY3Rpb24gZW1pdEV2ZW50KCkgcHVibGljIHZpcnR1YWwgb3ZlcnJpZGUgewogICAgICAgIC8qIEhlcmUsIHdlIGVtaXQgYW4gZXZlbnQgdG8gc2ltdWxhdGUgc29tZSBCYXNlMiBsb2dpYyAqLwogICAgICAgIGVtaXQgQmFzZTJFbWl0dGVkKCk7CiAgICAgICAgRW1pdHRhYmxlLmVtaXRFdmVudCgpOwogICAgfQp9Cgpjb250cmFjdCBGaW5hbCBpcyBCYXNlMSwgQmFzZTIgewogICAgZXZlbnQgRmluYWxFbWl0dGVkKCk7CiAgICBmdW5jdGlvbiBlbWl0RXZlbnQoKSBwdWJsaWMgb3ZlcnJpZGUoQmFzZTEsIEJhc2UyKSB7CiAgICAgICAgLyogSGVyZSwgd2UgZW1pdCBhbiBldmVudCB0byBzaW11bGF0ZSBzb21lIEZpbmFsIGxvZ2ljICovCiAgICAgICAgZW1pdCBGaW5hbEVtaXR0ZWQoKTsKICAgICAgICBCYXNlMi5lbWl0RXZlbnQoKTsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Owned</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">payable</span><span class="w"> </span>owner<span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">payable</span><span class="p">(</span><span class="k">msg.sender</span><span class="p">);</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Emittable</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Owned<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>emit<span class="w"> </span>Emitted<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base1</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Emittable<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Base1Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span>override<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Base1 logic */</span> <span class="w"> </span>emit<span class="w"> </span>Base1Emitted<span class="p">();</span> <span class="w"> </span>Emittable<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base2</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Emittable<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Base2Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span>override<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Base2 logic */</span> <span class="w"> </span>emit<span class="w"> </span>Base2Emitted<span class="p">();</span> <span class="w"> </span>Emittable<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Final</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">FinalEmitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>override<span class="p">(</span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Final logic */</span> <span class="w"> </span>emit<span class="w"> </span>FinalEmitted<span class="p">();</span> <span class="w"> </span>Base2<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>A call to <code class="docutils literal notranslate"><span class="pre">Final.emitEvent()</span></code> will call <code class="docutils literal notranslate"><span class="pre">Base2.emitEvent</span></code> because we specify it explicitly in the final override, but this function will bypass <code class="docutils literal notranslate"><span class="pre">Base1.emitEvent</span></code>, resulting in the following sequence of events: <code class="docutils literal notranslate"><span class="pre">FinalEmitted</span> <span class="pre">-&gt;</span> <span class="pre">Base2Emitted</span> <span class="pre">-&gt;</span> <span class="pre">Emitted</span></code>, instead of the expected sequence: <code class="docutils literal notranslate"><span class="pre">FinalEmitted</span> <span class="pre">-&gt;</span> <span class="pre">Base2Emitted</span> <span class="pre">-&gt;</span> <span class="pre">Base1Emitted</span> <span class="pre">-&gt;</span> <span class="pre">Emitted</span></code>. The way around this is to use <code class="docutils literal notranslate"><span class="pre">super</span></code>:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgT3duZWQgewogICAgYWRkcmVzcyBwYXlhYmxlIG93bmVyOwogICAgY29uc3RydWN0b3IoKSB7IG93bmVyID0gcGF5YWJsZShtc2cuc2VuZGVyKTsgfQp9Cgpjb250cmFjdCBFbWl0dGFibGUgaXMgT3duZWQgewogICAgZXZlbnQgRW1pdHRlZCgpOwoKICAgIGZ1bmN0aW9uIGVtaXRFdmVudCgpIHZpcnR1YWwgcHVibGljIHsKICAgICAgICBpZiAobXNnLnNlbmRlciA9PSBvd25lcikgewogICAgICAgICAgICBlbWl0IEVtaXR0ZWQoKTsKICAgICAgICB9CiAgICB9Cn0KCmNvbnRyYWN0IEJhc2UxIGlzIEVtaXR0YWJsZSB7CiAgICBldmVudCBCYXNlMUVtaXR0ZWQoKTsKICAgIGZ1bmN0aW9uIGVtaXRFdmVudCgpIHB1YmxpYyB2aXJ0dWFsIG92ZXJyaWRlIHsKICAgICAgICAvKiBIZXJlLCB3ZSBlbWl0IGFuIGV2ZW50IHRvIHNpbXVsYXRlIHNvbWUgQmFzZTEgbG9naWMgKi8KICAgICAgICBlbWl0IEJhc2UxRW1pdHRlZCgpOwogICAgICAgIHN1cGVyLmVtaXRFdmVudCgpOwogICAgfQp9CgoKY29udHJhY3QgQmFzZTIgaXMgRW1pdHRhYmxlIHsKICAgIGV2ZW50IEJhc2UyRW1pdHRlZCgpOwogICAgZnVuY3Rpb24gZW1pdEV2ZW50KCkgcHVibGljIHZpcnR1YWwgb3ZlcnJpZGUgewogICAgICAgIC8qIEhlcmUsIHdlIGVtaXQgYW4gZXZlbnQgdG8gc2ltdWxhdGUgc29tZSBCYXNlMiBsb2dpYyAqLwogICAgICAgIGVtaXQgQmFzZTJFbWl0dGVkKCk7CiAgICAgICAgc3VwZXIuZW1pdEV2ZW50KCk7CiAgICB9Cn0KCmNvbnRyYWN0IEZpbmFsIGlzIEJhc2UxLCBCYXNlMiB7CiAgICBldmVudCBGaW5hbEVtaXR0ZWQoKTsKICAgIGZ1bmN0aW9uIGVtaXRFdmVudCgpIHB1YmxpYyBvdmVycmlkZShCYXNlMSwgQmFzZTIpIHsKICAgICAgICAvKiBIZXJlLCB3ZSBlbWl0IGFuIGV2ZW50IHRvIHNpbXVsYXRlIHNvbWUgRmluYWwgbG9naWMgKi8KICAgICAgICBlbWl0IEZpbmFsRW1pdHRlZCgpOwogICAgICAgIHN1cGVyLmVtaXRFdmVudCgpOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Owned</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">address</span><span class="w"> </span><span class="nv">payable</span><span class="w"> </span>owner<span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>owner<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">payable</span><span class="p">(</span><span class="k">msg.sender</span><span class="p">);</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Emittable</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Owned<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="k">msg.sender</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>owner<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>emit<span class="w"> </span>Emitted<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base1</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Emittable<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Base1Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span>override<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Base1 logic */</span> <span class="w"> </span>emit<span class="w"> </span>Base1Emitted<span class="p">();</span> <span class="w"> </span>super<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base2</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Emittable<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">Base2Emitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span>override<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Base2 logic */</span> <span class="w"> </span>emit<span class="w"> </span>Base2Emitted<span class="p">();</span> <span class="w"> </span>super<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Final</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">event</span><span class="w"> </span><span class="nv">FinalEmitted</span><span class="p">();</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">emitEvent</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>override<span class="p">(</span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="cm">/* Here, we emit an event to simulate some Final logic */</span> <span class="w"> </span>emit<span class="w"> </span>FinalEmitted<span class="p">();</span> <span class="w"> </span>super<span class="p">.</span>emitEvent<span class="p">();</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>If <code class="docutils literal notranslate"><span class="pre">Final</span></code> calls a function of <code class="docutils literal notranslate"><span class="pre">super</span></code>, it does not simply call this function on one of its base contracts. Rather, it calls this function on the next base contract in the final inheritance graph, so it will call <code class="docutils literal notranslate"><span class="pre">Base1.emitEvent()</span></code> (note that the final inheritance sequence is – starting with the most derived contract: Final, Base2, Base1, Emittable, Owned). The actual function that is called when using super is not known in the context of the class where it is used, although its type is known. This is similar for ordinary virtual method lookup.</p> <section id="function-overriding"> <span id="index-19"></span><span id="id13"></span><h3>Function Overriding<a class="headerlink" href="#function-overriding" title="Permalink to this heading"></a></h3> <p>Base functions can be overridden by inheriting contracts to change their behavior if they are marked as <code class="docutils literal notranslate"><span class="pre">virtual</span></code>. The overriding function must then use the <code class="docutils literal notranslate"><span class="pre">override</span></code> keyword in the function header. The overriding function may only change the visibility of the overridden function from <code class="docutils literal notranslate"><span class="pre">external</span></code> to <code class="docutils literal notranslate"><span class="pre">public</span></code>. The mutability may be changed to a more strict one following the order: <code class="docutils literal notranslate"><span class="pre">nonpayable</span></code> can be overridden by <code class="docutils literal notranslate"><span class="pre">view</span></code> and <code class="docutils literal notranslate"><span class="pre">pure</span></code>. <code class="docutils literal notranslate"><span class="pre">view</span></code> can be overridden by <code class="docutils literal notranslate"><span class="pre">pure</span></code>. <code class="docutils literal notranslate"><span class="pre">payable</span></code> is an exception and cannot be changed to any other mutability.</p> <p>The following example demonstrates changing mutability and visibility:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZQp7CiAgICBmdW5jdGlvbiBmb28oKSB2aXJ0dWFsIGV4dGVybmFsIHZpZXcge30KfQoKY29udHJhY3QgTWlkZGxlIGlzIEJhc2Uge30KCmNvbnRyYWN0IEluaGVyaXRlZCBpcyBNaWRkbGUKewogICAgZnVuY3Rpb24gZm9vKCkgb3ZlcnJpZGUgcHVibGljIHB1cmUge30KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base</span> <span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">external</span><span class="w"> </span>view<span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Middle</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base<span class="w"> </span><span class="p">{}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Inherited</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Middle <span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">()</span><span class="w"> </span>override<span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="p">{}</span> <span class="p">}</span> </pre></div> </div> <p>For multiple inheritance, the most derived base contracts that define the same function must be specified explicitly after the <code class="docutils literal notranslate"><span class="pre">override</span></code> keyword. In other words, you have to specify all base contracts that define the same function and have not yet been overridden by another base contract (on some path through the inheritance graph). Additionally, if a contract inherits the same function from multiple (unrelated) bases, it has to explicitly override it:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZTEKewogICAgZnVuY3Rpb24gZm9vKCkgdmlydHVhbCBwdWJsaWMge30KfQoKY29udHJhY3QgQmFzZTIKewogICAgZnVuY3Rpb24gZm9vKCkgdmlydHVhbCBwdWJsaWMge30KfQoKY29udHJhY3QgSW5oZXJpdGVkIGlzIEJhc2UxLCBCYXNlMgp7CiAgICAvLyBEZXJpdmVzIGZyb20gbXVsdGlwbGUgYmFzZXMgZGVmaW5pbmcgZm9vKCksIHNvIHdlIG11c3QgZXhwbGljaXRseQogICAgLy8gb3ZlcnJpZGUgaXQKICAgIGZ1bmN0aW9uIGZvbygpIHB1YmxpYyBvdmVycmlkZShCYXNlMSwgQmFzZTIpIHt9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base1</span> <span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base2</span> <span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Inherited</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base1<span class="p">,</span><span class="w"> </span>Base2 <span class="p">{</span> <span class="w"> </span><span class="c1">// Derives from multiple bases defining foo(), so we must explicitly</span> <span class="w"> </span><span class="c1">// override it</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>override<span class="p">(</span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="p">)</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> </pre></div> </div> <p>An explicit override specifier is not required if the function is defined in a common base contract or if there is a unique function in a common base contract that already overrides all other functions.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKY29udHJhY3QgQSB7IGZ1bmN0aW9uIGYoKSBwdWJsaWMgcHVyZXt9IH0KY29udHJhY3QgQiBpcyBBIHt9CmNvbnRyYWN0IEMgaXMgQSB7fQovLyBObyBleHBsaWNpdCBvdmVycmlkZSByZXF1aXJlZApjb250cmFjdCBEIGlzIEIsIEMge30=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="p">{}</span><span class="w"> </span><span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">B</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>A<span class="w"> </span><span class="p">{}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>A<span class="w"> </span><span class="p">{}</span> <span class="c1">// No explicit override required</span> <span class="k">contract</span><span class="w"> </span><span class="ni">D</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>B<span class="p">,</span><span class="w"> </span>C<span class="w"> </span><span class="p">{}</span> </pre></div> </div> <p>More formally, it is not required to override a function (directly or indirectly) inherited from multiple bases if there is a base contract that is part of all override paths for the signature, and (1) that base implements the function and no paths from the current contract to the base mentions a function with that signature or (2) that base does not implement the function and there is at most one mention of the function in all paths from the current contract to that base.</p> <p>In this sense, an override path for a signature is a path through the inheritance graph that starts at the contract under consideration and ends at a contract mentioning a function with that signature that does not override.</p> <p>If you do not mark a function that overrides as <code class="docutils literal notranslate"><span class="pre">virtual</span></code>, derived contracts can no longer change the behavior of that function.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Functions with the <code class="docutils literal notranslate"><span class="pre">private</span></code> visibility cannot be <code class="docutils literal notranslate"><span class="pre">virtual</span></code>.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Functions without implementation have to be marked <code class="docutils literal notranslate"><span class="pre">virtual</span></code> outside of interfaces. In interfaces, all functions are automatically considered <code class="docutils literal notranslate"><span class="pre">virtual</span></code>.</p> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Starting from Solidity 0.8.8, the <code class="docutils literal notranslate"><span class="pre">override</span></code> keyword is not required when overriding an interface function, except for the case where the function is defined in multiple bases.</p> </div> <p>Public state variables can override external functions if the parameter and return types of the function matches the getter function of the variable:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKY29udHJhY3QgQQp7CiAgICBmdW5jdGlvbiBmKCkgZXh0ZXJuYWwgdmlldyB2aXJ0dWFsIHJldHVybnModWludCkgeyByZXR1cm4gNTsgfQp9Cgpjb250cmFjdCBCIGlzIEEKewogICAgdWludCBwdWJsaWMgb3ZlcnJpZGUgZjsKfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span> <span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span>view<span class="w"> </span>virtual<span class="w"> </span><span class="kt">returns</span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="m m-Decimal">5</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">B</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>A <span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">public </span><span class="nv">override</span><span class="w"> </span>f<span class="p">;</span> <span class="p">}</span> </pre></div> </div> <div class="admonition note"> <p class="admonition-title">Note</p> <p>While public state variables can override external functions, they themselves cannot be overridden.</p> </div> </section> <section id="modifier-overriding"> <span id="index-20"></span><span id="id14"></span><h3>Modifier Overriding<a class="headerlink" href="#modifier-overriding" title="Permalink to this heading"></a></h3> <p>Function modifiers can override each other. This works in the same way as <a class="reference internal" href="#function-overriding"><span class="std std-ref">function overriding</span></a> (except that there is no overloading for modifiers). The <code class="docutils literal notranslate"><span class="pre">virtual</span></code> keyword must be used on the overridden modifier and the <code class="docutils literal notranslate"><span class="pre">override</span></code> keyword must be used in the overriding modifier:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZQp7CiAgICBtb2RpZmllciBmb28oKSB2aXJ0dWFsIHtfO30KfQoKY29udHJhY3QgSW5oZXJpdGVkIGlzIEJhc2UKewogICAgbW9kaWZpZXIgZm9vKCkgb3ZlcnJpZGUge187fQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base</span> <span class="p">{</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>foo<span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="p">{</span>_<span class="p">;}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Inherited</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base <span class="p">{</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>foo<span class="p">()</span><span class="w"> </span>override<span class="w"> </span><span class="p">{</span>_<span class="p">;}</span> <span class="p">}</span> </pre></div> </div> <p>In case of multiple inheritance, all direct base contracts must be specified explicitly:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZTEKewogICAgbW9kaWZpZXIgZm9vKCkgdmlydHVhbCB7Xzt9Cn0KCmNvbnRyYWN0IEJhc2UyCnsKICAgIG1vZGlmaWVyIGZvbygpIHZpcnR1YWwge187fQp9Cgpjb250cmFjdCBJbmhlcml0ZWQgaXMgQmFzZTEsIEJhc2UyCnsKICAgIG1vZGlmaWVyIGZvbygpIG92ZXJyaWRlKEJhc2UxLCBCYXNlMikge187fQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base1</span> <span class="p">{</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>foo<span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="p">{</span>_<span class="p">;}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base2</span> <span class="p">{</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>foo<span class="p">()</span><span class="w"> </span>virtual<span class="w"> </span><span class="p">{</span>_<span class="p">;}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Inherited</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base1<span class="p">,</span><span class="w"> </span>Base2 <span class="p">{</span> <span class="w"> </span><span class="kt">modifier</span><span class="w"> </span>foo<span class="p">()</span><span class="w"> </span>override<span class="p">(</span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="p">)</span><span class="w"> </span><span class="p">{</span>_<span class="p">;}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="constructors"> <span id="constructor"></span><span id="index-21"></span><h3>Constructors<a class="headerlink" href="#constructors" title="Permalink to this heading"></a></h3> <p>A constructor is an optional function declared with the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> keyword which is executed upon contract creation, and where you can run contract initialization code.</p> <p>Before the constructor code is executed, state variables are initialised to their specified value if you initialise them inline, or their <a class="reference internal" href="control-structures.html#default-value"><span class="std std-ref">default value</span></a> if you do not.</p> <p>After the constructor has run, the final code of the contract is deployed to the blockchain. The deployment of the code costs additional gas linear to the length of the code. This code includes all functions that are part of the public interface and all functions that are reachable from there through function calls. It does not include the constructor code or internal functions that are only called from the constructor.</p> <p>If there is no constructor, the contract will assume the default constructor, which is equivalent to <code class="docutils literal notranslate"><span class="pre">constructor()</span> <span class="pre">{}</span></code>. For example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKYWJzdHJhY3QgY29udHJhY3QgQSB7CiAgICB1aW50IHB1YmxpYyBhOwoKICAgIGNvbnN0cnVjdG9yKHVpbnQgYV8pIHsKICAgICAgICBhID0gYV87CiAgICB9Cn0KCmNvbnRyYWN0IEIgaXMgQSgxKSB7CiAgICBjb25zdHJ1Y3RvcigpIHt9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="k">public </span><span class="nv">a</span><span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a_</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>a<span class="w"> </span><span class="o">=</span><span class="w"> </span>a_<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">B</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>A<span class="p">(</span><span class="m m-Decimal">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> </pre></div> </div> <p>You can use internal parameters in a constructor (for example storage pointers). In this case, the contract has to be marked <a class="reference internal" href="#abstract-contract"><span class="std std-ref">abstract</span></a>, because these parameters cannot be assigned valid values from outside but only through the constructors of derived contracts.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. This syntax was deprecated and is not allowed anymore in version 0.5.0.</p> </div> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>Prior to version 0.7.0, you had to specify the visibility of constructors as either <code class="docutils literal notranslate"><span class="pre">internal</span></code> or <code class="docutils literal notranslate"><span class="pre">public</span></code>.</p> </div> </section> <section id="arguments-for-base-constructors"> <span id="index-22"></span><h3>Arguments for Base Constructors<a class="headerlink" href="#arguments-for-base-constructors" title="Permalink to this heading"></a></h3> <p>The constructors of all the base contracts will be called following the linearization rules explained below. If the base constructors have arguments, derived contracts need to specify all of them. This can be done in two ways:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZSB7CiAgICB1aW50IHg7CiAgICBjb25zdHJ1Y3Rvcih1aW50IHhfKSB7IHggPSB4XzsgfQp9CgovLyBFaXRoZXIgZGlyZWN0bHkgc3BlY2lmeSBpbiB0aGUgaW5oZXJpdGFuY2UgbGlzdC4uLgpjb250cmFjdCBEZXJpdmVkMSBpcyBCYXNlKDcpIHsKICAgIGNvbnN0cnVjdG9yKCkge30KfQoKLy8gb3IgdGhyb3VnaCBhICJtb2RpZmllciIgb2YgdGhlIGRlcml2ZWQgY29uc3RydWN0b3IuLi4KY29udHJhY3QgRGVyaXZlZDIgaXMgQmFzZSB7CiAgICBjb25zdHJ1Y3Rvcih1aW50IHkpIEJhc2UoeSAqIHkpIHt9Cn0KCi8vIG9yIGRlY2xhcmUgYWJzdHJhY3QuLi4KYWJzdHJhY3QgY29udHJhY3QgRGVyaXZlZDMgaXMgQmFzZSB7Cn0KCi8vIGFuZCBoYXZlIHRoZSBuZXh0IGNvbmNyZXRlIGRlcml2ZWQgY29udHJhY3QgaW5pdGlhbGl6ZSBpdC4KY29udHJhY3QgRGVyaXZlZEZyb21EZXJpdmVkIGlzIERlcml2ZWQzIHsKICAgIGNvbnN0cnVjdG9yKCkgQmFzZSgxMCArIDEwKSB7fQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">x</span><span class="p">;</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">x_</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>x<span class="w"> </span><span class="o">=</span><span class="w"> </span>x_<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="c1">// Either directly specify in the inheritance list...</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Derived1</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base<span class="p">(</span><span class="m m-Decimal">7</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="c1">// or through a &quot;modifier&quot; of the derived constructor...</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Derived2</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">y</span><span class="p">)</span><span class="w"> </span>Base<span class="p">(</span>y<span class="w"> </span><span class="o">*</span><span class="w"> </span>y<span class="p">)</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="c1">// or declare abstract...</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">Derived3</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base<span class="w"> </span><span class="p">{</span> <span class="p">}</span> <span class="c1">// and have the next concrete derived contract initialize it.</span> <span class="k">contract</span><span class="w"> </span><span class="ni">DerivedFromDerived</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Derived3<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span>Base<span class="p">(</span><span class="m m-Decimal">10</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">10</span><span class="p">)</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> </pre></div> </div> <p>One way is directly in the inheritance list (<code class="docutils literal notranslate"><span class="pre">is</span> <span class="pre">Base(7)</span></code>). The other is in the way a modifier is invoked as part of the derived constructor (<code class="docutils literal notranslate"><span class="pre">Base(y</span> <span class="pre">*</span> <span class="pre">y)</span></code>). The first way to do it is more convenient if the constructor argument is a constant and defines the behavior of the contract or describes it. The second way has to be used if the constructor arguments of the base depend on those of the derived contract. Arguments have to be given either in the inheritance list or in modifier-style in the derived constructor. Specifying arguments in both places is an error.</p> <p>If a derived contract does not specify the arguments to all of its base contracts’ constructors, it must be declared abstract. In that case, when another contract derives from it, that other contract’s inheritance list or constructor must provide the necessary parameters for all base classes that haven’t had their parameters specified (otherwise, that other contract must be declared abstract as well). For example, in the above code snippet, see <code class="docutils literal notranslate"><span class="pre">Derived3</span></code> and <code class="docutils literal notranslate"><span class="pre">DerivedFromDerived</span></code>.</p> </section> <section id="multiple-inheritance-and-linearization"> <span id="multi-inheritance"></span><span id="index-23"></span><h3>Multiple Inheritance and Linearization<a class="headerlink" href="#multiple-inheritance-and-linearization" title="Permalink to this heading"></a></h3> <p>Languages that allow multiple inheritance have to deal with several problems. One is the <a class="reference external" href="https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem">Diamond Problem</a>. Solidity is similar to Python in that it uses “<a class="reference external" href="https://en.wikipedia.org/wiki/C3_linearization">C3 Linearization</a>” to force a specific order in the directed acyclic graph (DAG) of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the <code class="docutils literal notranslate"><span class="pre">is</span></code> directive is important: You have to list the direct base contracts in the order from “most base-like” to “most derived”. Note that this order is the reverse of the one used in Python.</p> <p>Another simplifying way to explain this is that when a function is called that is defined multiple times in different contracts, the given bases are searched from right to left (left to right in Python) in a depth-first manner, stopping at the first match. If a base contract has already been searched, it is skipped.</p> <p>In the following code, Solidity will give the error “Linearization of inheritance graph impossible”.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC40LjAgPDAuOS4wOwoKY29udHJhY3QgWCB7fQpjb250cmFjdCBBIGlzIFgge30KLy8gVGhpcyB3aWxsIG5vdCBjb21waWxlCmNvbnRyYWN0IEMgaXMgQSwgWCB7fQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.4.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">X</span><span class="w"> </span><span class="p">{}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">A</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>X<span class="w"> </span><span class="p">{}</span> <span class="c1">// This will not compile</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>A<span class="p">,</span><span class="w"> </span>X<span class="w"> </span><span class="p">{}</span> </pre></div> </div> <p>The reason for this is that <code class="docutils literal notranslate"><span class="pre">C</span></code> requests <code class="docutils literal notranslate"><span class="pre">X</span></code> to override <code class="docutils literal notranslate"><span class="pre">A</span></code> (by specifying <code class="docutils literal notranslate"><span class="pre">A,</span> <span class="pre">X</span></code> in this order), but <code class="docutils literal notranslate"><span class="pre">A</span></code> itself requests to override <code class="docutils literal notranslate"><span class="pre">X</span></code>, which is a contradiction that cannot be resolved.</p> <p>Due to the fact that you have to explicitly override a function that is inherited from multiple bases without a unique override, C3 linearization is not too important in practice.</p> <p>One area where inheritance linearization is especially important and perhaps not as clear is when there are multiple constructors in the inheritance hierarchy. The constructors will always be executed in the linearized order, regardless of the order in which their arguments are provided in the inheriting contract’s constructor. For example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC43LjAgPDAuOS4wOwoKY29udHJhY3QgQmFzZTEgewogICAgY29uc3RydWN0b3IoKSB7fQp9Cgpjb250cmFjdCBCYXNlMiB7CiAgICBjb25zdHJ1Y3RvcigpIHt9Cn0KCi8vIENvbnN0cnVjdG9ycyBhcmUgZXhlY3V0ZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjoKLy8gIDEgLSBCYXNlMQovLyAgMiAtIEJhc2UyCi8vICAzIC0gRGVyaXZlZDEKY29udHJhY3QgRGVyaXZlZDEgaXMgQmFzZTEsIEJhc2UyIHsKICAgIGNvbnN0cnVjdG9yKCkgQmFzZTEoKSBCYXNlMigpIHt9Cn0KCi8vIENvbnN0cnVjdG9ycyBhcmUgZXhlY3V0ZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjoKLy8gIDEgLSBCYXNlMgovLyAgMiAtIEJhc2UxCi8vICAzIC0gRGVyaXZlZDIKY29udHJhY3QgRGVyaXZlZDIgaXMgQmFzZTIsIEJhc2UxIHsKICAgIGNvbnN0cnVjdG9yKCkgQmFzZTIoKSBCYXNlMSgpIHt9Cn0KCi8vIENvbnN0cnVjdG9ycyBhcmUgc3RpbGwgZXhlY3V0ZWQgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjoKLy8gIDEgLSBCYXNlMgovLyAgMiAtIEJhc2UxCi8vICAzIC0gRGVyaXZlZDMKY29udHJhY3QgRGVyaXZlZDMgaXMgQmFzZTIsIEJhc2UxIHsKICAgIGNvbnN0cnVjdG9yKCkgQmFzZTEoKSBCYXNlMigpIHt9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.7.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base1</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Base2</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="c1">// Constructors are executed in the following order:</span> <span class="c1">// 1 - Base1</span> <span class="c1">// 2 - Base2</span> <span class="c1">// 3 - Derived1</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Derived1</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base1<span class="p">,</span><span class="w"> </span>Base2<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span>Base1<span class="p">()</span><span class="w"> </span>Base2<span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="c1">// Constructors are executed in the following order:</span> <span class="c1">// 1 - Base2</span> <span class="c1">// 2 - Base1</span> <span class="c1">// 3 - Derived2</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Derived2</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base2<span class="p">,</span><span class="w"> </span>Base1<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span>Base2<span class="p">()</span><span class="w"> </span>Base1<span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="c1">// Constructors are still executed in the following order:</span> <span class="c1">// 1 - Base2</span> <span class="c1">// 2 - Base1</span> <span class="c1">// 3 - Derived3</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Derived3</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Base2<span class="p">,</span><span class="w"> </span>Base1<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">constructor</span><span class="p">()</span><span class="w"> </span>Base1<span class="p">()</span><span class="w"> </span>Base2<span class="p">()</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="inheriting-different-kinds-of-members-of-the-same-name"> <h3>Inheriting Different Kinds of Members of the Same Name<a class="headerlink" href="#inheriting-different-kinds-of-members-of-the-same-name" title="Permalink to this heading"></a></h3> <p>The only situations where, due to inheritance, a contract may contain multiple definitions sharing the same name are:</p> <ul class="simple"> <li><p>Overloading of functions.</p></li> <li><p>Overriding of virtual functions.</p></li> <li><p>Overriding of external virtual functions by state variable getters.</p></li> <li><p>Overriding of virtual modifiers.</p></li> <li><p>Overloading of events.</p></li> </ul> </section> </section> <section id="abstract-contracts"> <span id="abstract-contract"></span><span id="index-24"></span><h2>Abstract Contracts<a class="headerlink" href="#abstract-contracts" title="Permalink to this heading"></a></h2> <p>Contracts must be marked as abstract when at least one of their functions is not implemented or when they do not provide arguments for all of their base contract constructors. Even if this is not the case, a contract may still be marked abstract, such as when you do not intend for the contract to be created directly. Abstract contracts are similar to <a class="reference internal" href="#interfaces"><span class="std std-ref">Interfaces</span></a> but an interface is more limited in what it can declare.</p> <p>An abstract contract is declared using the <code class="docutils literal notranslate"><span class="pre">abstract</span></code> keyword as shown in the following example. Note that this contract needs to be defined as abstract, because the function <code class="docutils literal notranslate"><span class="pre">utterance()</span></code> is declared, but no implementation was provided (no implementation body <code class="docutils literal notranslate"><span class="pre">{</span> <span class="pre">}</span></code> was given).</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKYWJzdHJhY3QgY29udHJhY3QgRmVsaW5lIHsKICAgIGZ1bmN0aW9uIHV0dGVyYW5jZSgpIHB1YmxpYyB2aXJ0dWFsIHJldHVybnMgKGJ5dGVzMzIpOwp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">Feline</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">utterance</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>virtual<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bytes32</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> <p>Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement all defined functions. The usage of an abstract contract as a base class is shown in the following example:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKYWJzdHJhY3QgY29udHJhY3QgRmVsaW5lIHsKICAgIGZ1bmN0aW9uIHV0dGVyYW5jZSgpIHB1YmxpYyBwdXJlIHZpcnR1YWwgcmV0dXJucyAoYnl0ZXMzMik7Cn0KCmNvbnRyYWN0IENhdCBpcyBGZWxpbmUgewogICAgZnVuY3Rpb24gdXR0ZXJhbmNlKCkgcHVibGljIHB1cmUgb3ZlcnJpZGUgcmV0dXJucyAoYnl0ZXMzMikgeyByZXR1cm4gIm1pYW93IjsgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> abstract<span class="w"> </span><span class="k">contract</span><span class="w"> </span><span class="ni">Feline</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">utterance</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span>virtual<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bytes32</span><span class="p">);</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Cat</span><span class="w"> </span><span class="kt">is</span><span class="w"> </span>Feline<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">utterance</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span>override<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bytes32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="s2">&quot;miaow&quot;</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>If a contract inherits from an abstract contract and does not implement all non-implemented functions by overriding, it needs to be marked as abstract as well.</p> <p>Note that a function without implementation is different from a <a class="reference internal" href="types.html#function-types"><span class="std std-ref">Function Type</span></a> even though their syntax looks very similar.</p> <p>Example of function without implementation (a function declaration):</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=ZnVuY3Rpb24gZm9vKGFkZHJlc3MpIGV4dGVybmFsIHJldHVybnMgKGFkZHJlc3MpOw==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="kt">function</span><span class="w"> </span><span class="nv">foo</span><span class="p">(</span><span class="kt">address</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">address</span><span class="p">);</span> </pre></div> </div> <p>Example of a declaration of a variable whose type is a function type:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=ZnVuY3Rpb24oYWRkcmVzcykgZXh0ZXJuYWwgcmV0dXJucyAoYWRkcmVzcykgZm9vOw==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="kt">function</span><span class="p">(</span><span class="kt">address</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">address</span><span class="p">)</span><span class="w"> </span>foo<span class="p">;</span> </pre></div> </div> <p>Abstract contracts decouple the definition of a contract from its implementation providing better extensibility and self-documentation and facilitating patterns like the <a class="reference external" href="https://en.wikipedia.org/wiki/Template_method_pattern">Template method</a> and removing code duplication. Abstract contracts are useful in the same way that defining methods in an interface is useful. It is a way for the designer of the abstract contract to say “any child of mine must implement this method”.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Abstract contracts cannot override an implemented virtual function with an unimplemented one.</p> </div> </section> <section id="interfaces"> <span id="index-25"></span><span id="id15"></span><h2>Interfaces<a class="headerlink" href="#interfaces" title="Permalink to this heading"></a></h2> <p>Interfaces are similar to abstract contracts, but they cannot have any functions implemented. There are further restrictions:</p> <ul class="simple"> <li><p>They cannot inherit from other contracts, but they can inherit from other interfaces.</p></li> <li><p>All declared functions must be external in the interface, even if they are public in the contract.</p></li> <li><p>They cannot declare a constructor.</p></li> <li><p>They cannot declare state variables.</p></li> <li><p>They cannot declare modifiers.</p></li> </ul> <p>Some of these restrictions might be lifted in the future.</p> <p>Interfaces are basically limited to what the Contract ABI can represent, and the conversion between the ABI and an interface should be possible without any information loss.</p> <p>Interfaces are denoted by their own keyword:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOS4wOwoKaW50ZXJmYWNlIFRva2VuIHsKICAgIGVudW0gVG9rZW5UeXBlIHsgRnVuZ2libGUsIE5vbkZ1bmdpYmxlIH0KICAgIHN0cnVjdCBDb2luIHsgc3RyaW5nIG9idmVyc2U7IHN0cmluZyByZXZlcnNlOyB9CiAgICBmdW5jdGlvbiB0cmFuc2ZlcihhZGRyZXNzIHJlY2lwaWVudCwgdWludCBhbW91bnQpIGV4dGVybmFsOwp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.2</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> interface<span class="w"> </span>Token<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">enum</span><span class="w"> </span><span class="nv">TokenType</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>Fungible<span class="p">,</span><span class="w"> </span>NonFungible<span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">struct</span><span class="w"> </span><span class="nv">Coin</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="nv">obverse</span><span class="p">;</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="nv">reverse</span><span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">transfer</span><span class="p">(</span><span class="kt">address</span><span class="w"> </span><span class="nv">recipient</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">amount</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="p">;</span> <span class="p">}</span> </pre></div> </div> <p>Contracts can inherit interfaces as they would inherit other contracts.</p> <p>All functions declared in interfaces are implicitly <code class="docutils literal notranslate"><span class="pre">virtual</span></code> and any functions that override them do not need the <code class="docutils literal notranslate"><span class="pre">override</span></code> keyword. This does not automatically mean that an overriding function can be overridden again - this is only possible if the overriding function is marked <code class="docutils literal notranslate"><span class="pre">virtual</span></code>.</p> <p>Interfaces can inherit from other interfaces. This has the same rules as normal inheritance.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjIgPDAuOS4wOwoKaW50ZXJmYWNlIFBhcmVudEEgewogICAgZnVuY3Rpb24gdGVzdCgpIGV4dGVybmFsIHJldHVybnMgKHVpbnQyNTYpOwp9CgppbnRlcmZhY2UgUGFyZW50QiB7CiAgICBmdW5jdGlvbiB0ZXN0KCkgZXh0ZXJuYWwgcmV0dXJucyAodWludDI1Nik7Cn0KCmludGVyZmFjZSBTdWJJbnRlcmZhY2UgaXMgUGFyZW50QSwgUGFyZW50QiB7CiAgICAvLyBNdXN0IHJlZGVmaW5lIHRlc3QgaW4gb3JkZXIgdG8gYXNzZXJ0IHRoYXQgdGhlIHBhcmVudAogICAgLy8gbWVhbmluZ3MgYXJlIGNvbXBhdGlibGUuCiAgICBmdW5jdGlvbiB0ZXN0KCkgZXh0ZXJuYWwgb3ZlcnJpZGUoUGFyZW50QSwgUGFyZW50QikgcmV0dXJucyAodWludDI1Nik7Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.2</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> interface<span class="w"> </span>ParentA<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">test</span><span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint256</span><span class="p">);</span> <span class="p">}</span> interface<span class="w"> </span>ParentB<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">test</span><span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint256</span><span class="p">);</span> <span class="p">}</span> interface<span class="w"> </span>SubInterface<span class="w"> </span><span class="kt">is</span><span class="w"> </span>ParentA<span class="p">,</span><span class="w"> </span>ParentB<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Must redefine test in order to assert that the parent</span> <span class="w"> </span><span class="c1">// meanings are compatible.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">test</span><span class="p">()</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span>override<span class="p">(</span>ParentA<span class="p">,</span><span class="w"> </span>ParentB<span class="p">)</span><span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint256</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> <p>Types defined inside interfaces and other contract-like structures can be accessed from other contracts: <code class="docutils literal notranslate"><span class="pre">Token.TokenType</span></code> or <code class="docutils literal notranslate"><span class="pre">Token.Coin</span></code>.</p> <div class="admonition warning"> <p class="admonition-title">Warning</p> <p>Interfaces have supported <code class="docutils literal notranslate"><span class="pre">enum</span></code> types since <a class="reference internal" href="050-breaking-changes.html"><span class="doc">Solidity version 0.5.0</span></a>, make sure the pragma version specifies this version as a minimum.</p> </div> </section> <section id="libraries"> <span id="index-26"></span><span id="id16"></span><h2>Libraries<a class="headerlink" href="#libraries" title="Permalink to this heading"></a></h2> <p>Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> (<code class="docutils literal notranslate"><span class="pre">CALLCODE</span></code> until Homestead) feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e. <code class="docutils literal notranslate"><span class="pre">this</span></code> points to the calling contract, and especially the storage from the calling contract can be accessed. As a library is an isolated piece of source code, it can only access state variables of the calling contract if they are explicitly supplied (it would have no way to name them, otherwise). Library functions can only be called directly (i.e. without the use of <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code>) if they do not modify the state (i.e. if they are <code class="docutils literal notranslate"><span class="pre">view</span></code> or <code class="docutils literal notranslate"><span class="pre">pure</span></code> functions), because libraries are assumed to be stateless. In particular, it is not possible to destroy a library.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>Until version 0.4.20, it was possible to destroy libraries by circumventing Solidity’s type system. Starting from that version, libraries contain a <a class="reference internal" href="#call-protection"><span class="std std-ref">mechanism</span></a> that disallows state-modifying functions to be called directly (i.e. without <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code>).</p> </div> <p>Libraries can be seen as implicit base contracts of the contracts that use them. They will not be explicitly visible in the inheritance hierarchy, but calls to library functions look just like calls to functions of explicit base contracts (using qualified access like <code class="docutils literal notranslate"><span class="pre">L.f()</span></code>). Of course, calls to internal functions use the internal calling convention, which means that all internal types can be passed and types <a class="reference internal" href="types.html#data-location"><span class="std std-ref">stored in memory</span></a> will be passed by reference and not copied. To realize this in the EVM, the code of internal library functions that are called from a contract and all functions called from therein will at compile time be included in the calling contract, and a regular <code class="docutils literal notranslate"><span class="pre">JUMP</span></code> call will be used instead of a <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code>.</p> <div class="admonition note"> <p class="admonition-title">Note</p> <p>The inheritance analogy breaks down when it comes to public functions. Calling a public library function with <code class="docutils literal notranslate"><span class="pre">L.f()</span></code> results in an external call (<code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> to be precise). In contrast, <code class="docutils literal notranslate"><span class="pre">A.f()</span></code> is an internal call when <code class="docutils literal notranslate"><span class="pre">A</span></code> is a base contract of the current contract.</p> </div> <p id="index-27">The following example illustrates how to use libraries (but using a manual method, be sure to check out <a class="reference internal" href="#using-for"><span class="std std-ref">using for</span></a> for a more advanced example to implement a set).</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC42LjAgPDAuOS4wOwoKCi8vIFdlIGRlZmluZSBhIG5ldyBzdHJ1Y3QgZGF0YXR5cGUgdGhhdCB3aWxsIGJlIHVzZWQgdG8KLy8gaG9sZCBpdHMgZGF0YSBpbiB0aGUgY2FsbGluZyBjb250cmFjdC4Kc3RydWN0IERhdGEgewogICAgbWFwcGluZyh1aW50ID0+IGJvb2wpIGZsYWdzOwp9CgpsaWJyYXJ5IFNldCB7CiAgICAvLyBOb3RlIHRoYXQgdGhlIGZpcnN0IHBhcmFtZXRlciBpcyBvZiB0eXBlICJzdG9yYWdlCiAgICAvLyByZWZlcmVuY2UiIGFuZCB0aHVzIG9ubHkgaXRzIHN0b3JhZ2UgYWRkcmVzcyBhbmQgbm90CiAgICAvLyBpdHMgY29udGVudHMgaXMgcGFzc2VkIGFzIHBhcnQgb2YgdGhlIGNhbGwuICBUaGlzIGlzIGEKICAgIC8vIHNwZWNpYWwgZmVhdHVyZSBvZiBsaWJyYXJ5IGZ1bmN0aW9ucy4gIEl0IGlzIGlkaW9tYXRpYwogICAgLy8gdG8gY2FsbCB0aGUgZmlyc3QgcGFyYW1ldGVyIGBzZWxmYCwgaWYgdGhlIGZ1bmN0aW9uIGNhbgogICAgLy8gYmUgc2VlbiBhcyBhIG1ldGhvZCBvZiB0aGF0IG9iamVjdC4KICAgIGZ1bmN0aW9uIGluc2VydChEYXRhIHN0b3JhZ2Ugc2VsZiwgdWludCB2YWx1ZSkKICAgICAgICBwdWJsaWMKICAgICAgICByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmIChzZWxmLmZsYWdzW3ZhbHVlXSkKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBhbHJlYWR5IHRoZXJlCiAgICAgICAgc2VsZi5mbGFnc1t2YWx1ZV0gPSB0cnVlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbW92ZShEYXRhIHN0b3JhZ2Ugc2VsZiwgdWludCB2YWx1ZSkKICAgICAgICBwdWJsaWMKICAgICAgICByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghc2VsZi5mbGFnc1t2YWx1ZV0pCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gbm90IHRoZXJlCiAgICAgICAgc2VsZi5mbGFnc1t2YWx1ZV0gPSBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb250YWlucyhEYXRhIHN0b3JhZ2Ugc2VsZiwgdWludCB2YWx1ZSkKICAgICAgICBwdWJsaWMKICAgICAgICB2aWV3CiAgICAgICAgcmV0dXJucyAoYm9vbCkKICAgIHsKICAgICAgICByZXR1cm4gc2VsZi5mbGFnc1t2YWx1ZV07CiAgICB9Cn0KCgpjb250cmFjdCBDIHsKICAgIERhdGEga25vd25WYWx1ZXM7CgogICAgZnVuY3Rpb24gcmVnaXN0ZXIodWludCB2YWx1ZSkgcHVibGljIHsKICAgICAgICAvLyBUaGUgbGlicmFyeSBmdW5jdGlvbnMgY2FuIGJlIGNhbGxlZCB3aXRob3V0IGEKICAgICAgICAvLyBzcGVjaWZpYyBpbnN0YW5jZSBvZiB0aGUgbGlicmFyeSwgc2luY2UgdGhlCiAgICAgICAgLy8gImluc3RhbmNlIiB3aWxsIGJlIHRoZSBjdXJyZW50IGNvbnRyYWN0LgogICAgICAgIHJlcXVpcmUoU2V0Lmluc2VydChrbm93blZhbHVlcywgdmFsdWUpKTsKICAgIH0KICAgIC8vIEluIHRoaXMgY29udHJhY3QsIHdlIGNhbiBhbHNvIGRpcmVjdGx5IGFjY2VzcyBrbm93blZhbHVlcy5mbGFncywgaWYgd2Ugd2FudC4KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.6.0</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="c1">// We define a new struct datatype that will be used to</span> <span class="c1">// hold its data in the calling contract.</span> <span class="kt">struct</span><span class="w"> </span><span class="nv">Data</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span>flags<span class="p">;</span> <span class="p">}</span> <span class="kt">library</span><span class="w"> </span>Set<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Note that the first parameter is of type &quot;storage</span> <span class="w"> </span><span class="c1">// reference&quot; and thus only its storage address and not</span> <span class="w"> </span><span class="c1">// its contents is passed as part of the call. This is a</span> <span class="w"> </span><span class="c1">// special feature of library functions. It is idiomatic</span> <span class="w"> </span><span class="c1">// to call the first parameter `self`, if the function can</span> <span class="w"> </span><span class="c1">// be seen as a method of that object.</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">insert</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">])</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// already there</span> <span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">remove</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">])</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// not there</span> <span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">contains</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span>view <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">];</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>Data<span class="w"> </span>knownValues<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">register</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// The library functions can be called without a</span> <span class="w"> </span><span class="c1">// specific instance of the library, since the</span> <span class="w"> </span><span class="c1">// &quot;instance&quot; will be the current contract.</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>Set<span class="p">.</span>insert<span class="p">(</span>knownValues<span class="p">,</span><span class="w"> </span>value<span class="p">));</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="c1">// In this contract, we can also directly access knownValues.flags, if we want.</span> <span class="p">}</span> </pre></div> </div> <p>Of course, you do not have to follow this way to use libraries: they can also be used without defining struct data types. Functions also work without any storage reference parameters, and they can have multiple storage reference parameters and in any position.</p> <p>The calls to <code class="docutils literal notranslate"><span class="pre">Set.contains</span></code>, <code class="docutils literal notranslate"><span class="pre">Set.insert</span></code> and <code class="docutils literal notranslate"><span class="pre">Set.remove</span></code> are all compiled as calls (<code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code>) to an external contract/library. If you use libraries, be aware that an actual external function call is performed. <code class="docutils literal notranslate"><span class="pre">msg.sender</span></code>, <code class="docutils literal notranslate"><span class="pre">msg.value</span></code> and <code class="docutils literal notranslate"><span class="pre">this</span></code> will retain their values in this call, though (prior to Homestead, because of the use of <code class="docutils literal notranslate"><span class="pre">CALLCODE</span></code>, <code class="docutils literal notranslate"><span class="pre">msg.sender</span></code> and <code class="docutils literal notranslate"><span class="pre">msg.value</span></code> changed, though).</p> <p>The following example shows how to use <a class="reference internal" href="types.html#data-location"><span class="std std-ref">types stored in memory</span></a> and internal functions in libraries in order to implement custom types without the overhead of external function calls:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMDsKCnN0cnVjdCBiaWdpbnQgewogICAgdWludFtdIGxpbWJzOwp9CgpsaWJyYXJ5IEJpZ0ludCB7CiAgICBmdW5jdGlvbiBmcm9tVWludCh1aW50IHgpIGludGVybmFsIHB1cmUgcmV0dXJucyAoYmlnaW50IG1lbW9yeSByKSB7CiAgICAgICAgci5saW1icyA9IG5ldyB1aW50W10oMSk7CiAgICAgICAgci5saW1ic1swXSA9IHg7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkKGJpZ2ludCBtZW1vcnkgYSwgYmlnaW50IG1lbW9yeSBiKSBpbnRlcm5hbCBwdXJlIHJldHVybnMgKGJpZ2ludCBtZW1vcnkgcikgewogICAgICAgIHIubGltYnMgPSBuZXcgdWludFtdKG1heChhLmxpbWJzLmxlbmd0aCwgYi5saW1icy5sZW5ndGgpKTsKICAgICAgICB1aW50IGNhcnJ5ID0gMDsKICAgICAgICBmb3IgKHVpbnQgaSA9IDA7IGkgPCByLmxpbWJzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIHVpbnQgbGltYkEgPSBsaW1iKGEsIGkpOwogICAgICAgICAgICB1aW50IGxpbWJCID0gbGltYihiLCBpKTsKICAgICAgICAgICAgdW5jaGVja2VkIHsKICAgICAgICAgICAgICAgIHIubGltYnNbaV0gPSBsaW1iQSArIGxpbWJCICsgY2Fycnk7CgogICAgICAgICAgICAgICAgaWYgKGxpbWJBICsgbGltYkIgPCBsaW1iQSB8fCAobGltYkEgKyBsaW1iQiA9PSB0eXBlKHVpbnQpLm1heCAmJiBjYXJyeSA+IDApKQogICAgICAgICAgICAgICAgICAgIGNhcnJ5ID0gMTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBjYXJyeSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGNhcnJ5ID4gMCkgewogICAgICAgICAgICAvLyB0b28gYmFkLCB3ZSBoYXZlIHRvIGFkZCBhIGxpbWIKICAgICAgICAgICAgdWludFtdIG1lbW9yeSBuZXdMaW1icyA9IG5ldyB1aW50W10oci5saW1icy5sZW5ndGggKyAxKTsKICAgICAgICAgICAgdWludCBpOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgci5saW1icy5sZW5ndGg7ICsraSkKICAgICAgICAgICAgICAgIG5ld0xpbWJzW2ldID0gci5saW1ic1tpXTsKICAgICAgICAgICAgbmV3TGltYnNbaV0gPSBjYXJyeTsKICAgICAgICAgICAgci5saW1icyA9IG5ld0xpbWJzOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBsaW1iKGJpZ2ludCBtZW1vcnkgYSwgdWludCBpbmRleCkgaW50ZXJuYWwgcHVyZSByZXR1cm5zICh1aW50KSB7CiAgICAgICAgcmV0dXJuIGluZGV4IDwgYS5saW1icy5sZW5ndGggPyBhLmxpbWJzW2luZGV4XSA6IDA7CiAgICB9CgogICAgZnVuY3Rpb24gbWF4KHVpbnQgYSwgdWludCBiKSBwcml2YXRlIHB1cmUgcmV0dXJucyAodWludCkgewogICAgICAgIHJldHVybiBhID4gYiA/IGEgOiBiOwogICAgfQp9Cgpjb250cmFjdCBDIHsKICAgIHVzaW5nIEJpZ0ludCBmb3IgYmlnaW50OwoKICAgIGZ1bmN0aW9uIGYoKSBwdWJsaWMgcHVyZSB7CiAgICAgICAgYmlnaW50IG1lbW9yeSB4ID0gQmlnSW50LmZyb21VaW50KDcpOwogICAgICAgIGJpZ2ludCBtZW1vcnkgeSA9IEJpZ0ludC5mcm9tVWludCh0eXBlKHVpbnQpLm1heCk7CiAgICAgICAgYmlnaW50IG1lbW9yeSB6ID0geC5hZGQoeSk7CiAgICAgICAgYXNzZXJ0KHoubGltYigxKSA+IDApOwogICAgfQp9" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.0</span><span class="p">;</span> <span class="kt">struct</span><span class="w"> </span><span class="nv">bigint</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span>limbs<span class="p">;</span> <span class="p">}</span> <span class="kt">library</span><span class="w"> </span>BigInt<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">fromUint</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">x</span><span class="p">)</span><span class="w"> </span><span class="kt">internal</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>r<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>r<span class="p">.</span>limbs<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span><span class="kt">uint</span><span class="p">[](</span><span class="m m-Decimal">1</span><span class="p">);</span> <span class="w"> </span>r<span class="p">.</span>limbs<span class="p">[</span><span class="m m-Decimal">0</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>x<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">add</span><span class="p">(</span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>a<span class="p">,</span><span class="w"> </span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>b<span class="p">)</span><span class="w"> </span><span class="kt">internal</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>r<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>r<span class="p">.</span>limbs<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span><span class="kt">uint</span><span class="p">[](</span>max<span class="p">(</span>a<span class="p">.</span>limbs<span class="p">.</span>length<span class="p">,</span><span class="w"> </span>b<span class="p">.</span>limbs<span class="p">.</span>length<span class="p">));</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">carry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span> <span class="w"> </span><span class="kt">for</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span><span class="w"> </span>i<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>r<span class="p">.</span>limbs<span class="p">.</span>length<span class="p">;</span><span class="w"> </span><span class="o">++</span>i<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">limbA</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>limb<span class="p">(</span>a<span class="p">,</span><span class="w"> </span>i<span class="p">);</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">limbB</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>limb<span class="p">(</span>b<span class="p">,</span><span class="w"> </span>i<span class="p">);</span> <span class="w"> </span>unchecked<span class="w"> </span><span class="p">{</span> <span class="w"> </span>r<span class="p">.</span>limbs<span class="p">[</span>i<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>limbA<span class="w"> </span><span class="o">+</span><span class="w"> </span>limbB<span class="w"> </span><span class="o">+</span><span class="w"> </span>carry<span class="p">;</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>limbA<span class="w"> </span><span class="o">+</span><span class="w"> </span>limbB<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>limbA<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">(</span>limbA<span class="w"> </span><span class="o">+</span><span class="w"> </span>limbB<span class="w"> </span><span class="o">==</span><span class="w"> </span>type<span class="p">(</span><span class="kt">uint</span><span class="p">).</span>max<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>carry<span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">))</span> <span class="w"> </span>carry<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">;</span> <span class="w"> </span><span class="kt">else</span> <span class="w"> </span>carry<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>carry<span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// too bad, we have to add a limb</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span><span class="kt">memory</span><span class="w"> </span>newLimbs<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span><span class="kt">uint</span><span class="p">[](</span>r<span class="p">.</span>limbs<span class="p">.</span>length<span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m m-Decimal">1</span><span class="p">);</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">i</span><span class="p">;</span> <span class="w"> </span><span class="kt">for</span><span class="w"> </span><span class="p">(</span>i<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span><span class="w"> </span>i<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>r<span class="p">.</span>limbs<span class="p">.</span>length<span class="p">;</span><span class="w"> </span><span class="o">++</span>i<span class="p">)</span> <span class="w"> </span>newLimbs<span class="p">[</span>i<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>r<span class="p">.</span>limbs<span class="p">[</span>i<span class="p">];</span> <span class="w"> </span>newLimbs<span class="p">[</span>i<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>carry<span class="p">;</span> <span class="w"> </span>r<span class="p">.</span>limbs<span class="w"> </span><span class="o">=</span><span class="w"> </span>newLimbs<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">limb</span><span class="p">(</span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>a<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">index</span><span class="p">)</span><span class="w"> </span><span class="kt">internal</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>index<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>a<span class="p">.</span>limbs<span class="p">.</span>length<span class="w"> </span><span class="o">?</span><span class="w"> </span>a<span class="p">.</span>limbs<span class="p">[</span>index<span class="p">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">max</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">a</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">b</span><span class="p">)</span><span class="w"> </span><span class="kt">private</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>a<span class="w"> </span><span class="o">&gt;</span><span class="w"> </span>b<span class="w"> </span><span class="o">?</span><span class="w"> </span>a<span class="w"> </span><span class="o">:</span><span class="w"> </span>b<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>using<span class="w"> </span>BigInt<span class="w"> </span><span class="kt">for</span><span class="w"> </span>bigint<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="p">{</span> <span class="w"> </span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>x<span class="w"> </span><span class="o">=</span><span class="w"> </span>BigInt<span class="p">.</span>fromUint<span class="p">(</span><span class="m m-Decimal">7</span><span class="p">);</span> <span class="w"> </span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>y<span class="w"> </span><span class="o">=</span><span class="w"> </span>BigInt<span class="p">.</span>fromUint<span class="p">(</span>type<span class="p">(</span><span class="kt">uint</span><span class="p">).</span>max<span class="p">);</span> <span class="w"> </span>bigint<span class="w"> </span><span class="kt">memory</span><span class="w"> </span>z<span class="w"> </span><span class="o">=</span><span class="w"> </span>x<span class="p">.</span>add<span class="p">(</span>y<span class="p">);</span> <span class="w"> </span>assert<span class="p">(</span>z<span class="p">.</span>limb<span class="p">(</span><span class="m m-Decimal">1</span><span class="p">)</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>It is possible to obtain the address of a library by converting the library type to the <code class="docutils literal notranslate"><span class="pre">address</span></code> type, i.e. using <code class="docutils literal notranslate"><span class="pre">address(LibraryName)</span></code>.</p> <p>As the compiler does not know the address where the library will be deployed, the compiled hex code will contain placeholders of the form <code class="docutils literal notranslate"><span class="pre">__$30bbc0abd4d6364515865950d3e0d10953$__</span></code> <a class="reference external" href="https://docs.soliditylang.org/en/v0.4.26/contracts.html#libraries">(format was different &lt;v0.5.0)</a>. The placeholder is a 34 character prefix of the hex encoding of the keccak256 hash of the fully qualified library name, which would be for example <code class="docutils literal notranslate"><span class="pre">libraries/bigint.sol:BigInt</span></code> if the library was stored in a file called <code class="docutils literal notranslate"><span class="pre">bigint.sol</span></code> in a <code class="docutils literal notranslate"><span class="pre">libraries/</span></code> directory. Such bytecode is incomplete and should not be deployed. Placeholders need to be replaced with actual addresses. You can do that by either passing them to the compiler when the library is being compiled or by using the linker to update an already compiled binary. See <a class="reference internal" href="using-the-compiler.html#library-linking"><span class="std std-ref">Library Linking</span></a> for information on how to use the commandline compiler for linking.</p> <p>In comparison to contracts, libraries are restricted in the following ways:</p> <ul class="simple"> <li><p>they cannot have state variables</p></li> <li><p>they cannot inherit nor be inherited</p></li> <li><p>they cannot receive Ether</p></li> <li><p>they cannot be destroyed</p></li> </ul> <p>(These might be lifted at a later point.)</p> <span class="target" id="library-selectors"></span><section id="function-signatures-and-selectors-in-libraries"> <span id="index-28"></span><h3>Function Signatures and Selectors in Libraries<a class="headerlink" href="#function-signatures-and-selectors-in-libraries" title="Permalink to this heading"></a></h3> <p>While external calls to public or external library functions are possible, the calling convention for such calls is considered to be internal to Solidity and not the same as specified for the regular <a class="reference internal" href="abi-spec.html#abi"><span class="std std-ref">contract ABI</span></a>. External library functions support more argument types than external contract functions, for example recursive structs and storage pointers. For that reason, the function signatures used to compute the 4-byte selector are computed following an internal naming schema and arguments of types not supported in the contract ABI use an internal encoding.</p> <p>The following identifiers are used for the types in the signatures:</p> <ul class="simple"> <li><p>Value types, non-storage <code class="docutils literal notranslate"><span class="pre">string</span></code> and non-storage <code class="docutils literal notranslate"><span class="pre">bytes</span></code> use the same identifiers as in the contract ABI.</p></li> <li><p>Non-storage array types follow the same convention as in the contract ABI, i.e. <code class="docutils literal notranslate"><span class="pre">&lt;type&gt;[]</span></code> for dynamic arrays and <code class="docutils literal notranslate"><span class="pre">&lt;type&gt;[M]</span></code> for fixed-size arrays of <code class="docutils literal notranslate"><span class="pre">M</span></code> elements.</p></li> <li><p>Non-storage structs are referred to by their fully qualified name, i.e. <code class="docutils literal notranslate"><span class="pre">C.S</span></code> for <code class="docutils literal notranslate"><span class="pre">contract</span> <span class="pre">C</span> <span class="pre">{</span> <span class="pre">struct</span> <span class="pre">S</span> <span class="pre">{</span> <span class="pre">...</span> <span class="pre">}</span> <span class="pre">}</span></code>.</p></li> <li><p>Storage pointer mappings use <code class="docutils literal notranslate"><span class="pre">mapping(&lt;keyType&gt;</span> <span class="pre">=&gt;</span> <span class="pre">&lt;valueType&gt;)</span> <span class="pre">storage</span></code> where <code class="docutils literal notranslate"><span class="pre">&lt;keyType&gt;</span></code> and <code class="docutils literal notranslate"><span class="pre">&lt;valueType&gt;</span></code> are the identifiers for the key and value types of the mapping, respectively.</p></li> <li><p>Other storage pointer types use the type identifier of their corresponding non-storage type, but append a single space followed by <code class="docutils literal notranslate"><span class="pre">storage</span></code> to it.</p></li> </ul> <p>The argument encoding is the same as for the regular contract ABI, except for storage pointers, which are encoded as a <code class="docutils literal notranslate"><span class="pre">uint256</span></code> value referring to the storage slot to which they point.</p> <p>Similarly to the contract ABI, the selector consists of the first four bytes of the Keccak256-hash of the signature. Its value can be obtained from Solidity using the <code class="docutils literal notranslate"><span class="pre">.selector</span></code> member as follows:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5ID49MC41LjE0IDwwLjkuMDsKCmxpYnJhcnkgTCB7CiAgICBmdW5jdGlvbiBmKHVpbnQyNTYpIGV4dGVybmFsIHt9Cn0KCmNvbnRyYWN0IEMgewogICAgZnVuY3Rpb24gZygpIHB1YmxpYyBwdXJlIHJldHVybnMgKGJ5dGVzNCkgewogICAgICAgIHJldHVybiBMLmYuc2VsZWN0b3I7CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">&gt;=</span><span class="k">0.5.14</span><span class="w"> </span><span class="o">&lt;</span><span class="k">0.9.0</span><span class="p">;</span> <span class="kt">library</span><span class="w"> </span>L<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">f</span><span class="p">(</span><span class="kt">uint256</span><span class="p">)</span><span class="w"> </span><span class="kt">external</span><span class="w"> </span><span class="p">{}</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">g</span><span class="p">()</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>bytes4<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>L<span class="p">.</span>f<span class="p">.</span>selector<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> <section id="call-protection-for-libraries"> <span id="call-protection"></span><h3>Call Protection For Libraries<a class="headerlink" href="#call-protection-for-libraries" title="Permalink to this heading"></a></h3> <p>As mentioned in the introduction, if a library’s code is executed using a <code class="docutils literal notranslate"><span class="pre">CALL</span></code> instead of a <code class="docutils literal notranslate"><span class="pre">DELEGATECALL</span></code> or <code class="docutils literal notranslate"><span class="pre">CALLCODE</span></code>, it will revert unless a <code class="docutils literal notranslate"><span class="pre">view</span></code> or <code class="docutils literal notranslate"><span class="pre">pure</span></code> function is called.</p> <p>The EVM does not provide a direct way for a contract to detect whether it was called using <code class="docutils literal notranslate"><span class="pre">CALL</span></code> or not, but a contract can use the <code class="docutils literal notranslate"><span class="pre">ADDRESS</span></code> opcode to find out “where” it is currently running. The generated code compares this address to the address used at construction time to determine the mode of calling.</p> <p>More specifically, the runtime code of a library always starts with a push instruction, which is a zero of 20 bytes at compilation time. When the deploy code runs, this constant is replaced in memory by the current address and this modified code is stored in the contract. At runtime, this causes the deploy time address to be the first constant to be pushed onto the stack and the dispatcher code compares the current address against this constant for any non-view and non-pure function.</p> <p>This means that the actual code stored on chain for a library is different from the code reported by the compiler as <code class="docutils literal notranslate"><span class="pre">deployedBytecode</span></code>.</p> </section> </section> <section id="using-for"> <span id="index-29"></span><span id="id17"></span><h2>Using For<a class="headerlink" href="#using-for" title="Permalink to this heading"></a></h2> <p>The directive <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">A</span> <span class="pre">for</span> <span class="pre">B</span></code> can be used to attach functions (<code class="docutils literal notranslate"><span class="pre">A</span></code>) as operators to user-defined value types or as member functions to any type (<code class="docutils literal notranslate"><span class="pre">B</span></code>). The member functions receive the object they are called on as their first parameter (like the <code class="docutils literal notranslate"><span class="pre">self</span></code> variable in Python). The operator functions receive operands as parameters.</p> <p>It is valid either at file level or inside a contract, at contract level.</p> <p>The first part, <code class="docutils literal notranslate"><span class="pre">A</span></code>, can be one of:</p> <ul class="simple"> <li><p>A list of functions, optionally with an operator name assigned (e.g. <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">{f,</span> <span class="pre">g</span> <span class="pre">as</span> <span class="pre">+,</span> <span class="pre">h,</span> <span class="pre">L.t}</span> <span class="pre">for</span> <span class="pre">uint</span></code>). If no operator is specified, the function can be either a library function or a free function and is attached to the type as a member function. Otherwise it must be a free function and it becomes the definition of that operator on the type.</p></li> <li><p>The name of a library (e.g. <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">L</span> <span class="pre">for</span> <span class="pre">uint</span></code>) - all non-private functions of the library are attached to the type as member functions</p></li> </ul> <p>At file level, the second part, <code class="docutils literal notranslate"><span class="pre">B</span></code>, has to be an explicit type (without data location specifier). Inside contracts, you can also use <code class="docutils literal notranslate"><span class="pre">*</span></code> in place of the type (e.g. <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">L</span> <span class="pre">for</span> <span class="pre">*;</span></code>), which has the effect that all functions of the library <code class="docutils literal notranslate"><span class="pre">L</span></code> are attached to <em>all</em> types.</p> <p>If you specify a library, <em>all</em> non-private functions in the library get attached, even those where the type of the first parameter does not match the type of the object. The type is checked at the point the function is called and function overload resolution is performed.</p> <p>If you use a list of functions (e.g. <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">{f,</span> <span class="pre">g,</span> <span class="pre">h,</span> <span class="pre">L.t}</span> <span class="pre">for</span> <span class="pre">uint</span></code>), then the type (<code class="docutils literal notranslate"><span class="pre">uint</span></code>) has to be implicitly convertible to the first parameter of each of these functions. This check is performed even if none of these functions are called. Note that private library functions can only be specified when <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">for</span></code> is inside a library.</p> <p>If you define an operator (e.g. <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">{f</span> <span class="pre">as</span> <span class="pre">+}</span> <span class="pre">for</span> <span class="pre">T</span></code>), then the type (<code class="docutils literal notranslate"><span class="pre">T</span></code>) must be a <a class="reference internal" href="types.html#user-defined-value-types"><span class="std std-ref">user-defined value type</span></a> and the definition must be a <code class="docutils literal notranslate"><span class="pre">pure</span></code> function. Operator definitions must be global. The following operators can be defined this way:</p> <table class="docutils align-default"> <thead> <tr class="row-odd"><th class="head"><p>Category</p></th> <th class="head"><p>Operator</p></th> <th class="head"><p>Possible signatures</p></th> </tr> </thead> <tbody> <tr class="row-even"><td rowspan="4"><p>Bitwise</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">&amp;</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">|</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">^</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">~</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-even"><td rowspan="6"><p>Arithmetic</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">+</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-odd"><td rowspan="2"><p><code class="docutils literal notranslate"><span class="pre">-</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">*</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">/</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">%</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(T)</span></code></p></td> </tr> <tr class="row-even"><td rowspan="6"><p>Comparison</p></td> <td><p><code class="docutils literal notranslate"><span class="pre">==</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">!=</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">&lt;</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">&lt;=</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> <tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">&gt;</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> <tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">&gt;=</span></code></p></td> <td><p><code class="docutils literal notranslate"><span class="pre">function</span> <span class="pre">(T,</span> <span class="pre">T)</span> <span class="pre">pure</span> <span class="pre">returns</span> <span class="pre">(bool)</span></code></p></td> </tr> </tbody> </table> <p>Note that unary and binary <code class="docutils literal notranslate"><span class="pre">-</span></code> need separate definitions. The compiler will choose the right definition based on how the operator is invoked.</p> <p>The <code class="docutils literal notranslate"><span class="pre">using</span> <span class="pre">A</span> <span class="pre">for</span> <span class="pre">B;</span></code> directive is active only within the current scope (either the contract or the current module/source unit), including within all of its functions, and has no effect outside of the contract or module in which it is used.</p> <p>When the directive is used at file level and applied to a user-defined type which was defined at file level in the same file, the word <code class="docutils literal notranslate"><span class="pre">global</span></code> can be added at the end. This will have the effect that the functions and operators are attached to the type everywhere the type is available (including other files), not only in the scope of the using statement.</p> <p>Let us rewrite the set example from the <a class="reference internal" href="#libraries"><span class="std std-ref">Libraries</span></a> section in this way, using file-level functions instead of library functions.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMTM7CgpzdHJ1Y3QgRGF0YSB7IG1hcHBpbmcodWludCA9PiBib29sKSBmbGFnczsgfQovLyBOb3cgd2UgYXR0YWNoIGZ1bmN0aW9ucyB0byB0aGUgdHlwZS4KLy8gVGhlIGF0dGFjaGVkIGZ1bmN0aW9ucyBjYW4gYmUgdXNlZCB0aHJvdWdob3V0IHRoZSByZXN0IG9mIHRoZSBtb2R1bGUuCi8vIElmIHlvdSBpbXBvcnQgdGhlIG1vZHVsZSwgeW91IGhhdmUgdG8KLy8gcmVwZWF0IHRoZSB1c2luZyBkaXJlY3RpdmUgdGhlcmUsIGZvciBleGFtcGxlIGFzCi8vICAgaW1wb3J0ICJmbGFncy5zb2wiIGFzIEZsYWdzOwovLyAgIHVzaW5nIHtGbGFncy5pbnNlcnQsIEZsYWdzLnJlbW92ZSwgRmxhZ3MuY29udGFpbnN9Ci8vICAgICBmb3IgRmxhZ3MuRGF0YTsKdXNpbmcge2luc2VydCwgcmVtb3ZlLCBjb250YWluc30gZm9yIERhdGE7CgpmdW5jdGlvbiBpbnNlcnQoRGF0YSBzdG9yYWdlIHNlbGYsIHVpbnQgdmFsdWUpCiAgICByZXR1cm5zIChib29sKQp7CiAgICBpZiAoc2VsZi5mbGFnc1t2YWx1ZV0pCiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBhbHJlYWR5IHRoZXJlCiAgICBzZWxmLmZsYWdzW3ZhbHVlXSA9IHRydWU7CiAgICByZXR1cm4gdHJ1ZTsKfQoKZnVuY3Rpb24gcmVtb3ZlKERhdGEgc3RvcmFnZSBzZWxmLCB1aW50IHZhbHVlKQogICAgcmV0dXJucyAoYm9vbCkKewogICAgaWYgKCFzZWxmLmZsYWdzW3ZhbHVlXSkKICAgICAgICByZXR1cm4gZmFsc2U7IC8vIG5vdCB0aGVyZQogICAgc2VsZi5mbGFnc1t2YWx1ZV0gPSBmYWxzZTsKICAgIHJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiBjb250YWlucyhEYXRhIHN0b3JhZ2Ugc2VsZiwgdWludCB2YWx1ZSkKICAgIHZpZXcKICAgIHJldHVybnMgKGJvb2wpCnsKICAgIHJldHVybiBzZWxmLmZsYWdzW3ZhbHVlXTsKfQoKCmNvbnRyYWN0IEMgewogICAgRGF0YSBrbm93blZhbHVlczsKCiAgICBmdW5jdGlvbiByZWdpc3Rlcih1aW50IHZhbHVlKSBwdWJsaWMgewogICAgICAgIC8vIEhlcmUsIGFsbCB2YXJpYWJsZXMgb2YgdHlwZSBEYXRhIGhhdmUKICAgICAgICAvLyBjb3JyZXNwb25kaW5nIG1lbWJlciBmdW5jdGlvbnMuCiAgICAgICAgLy8gVGhlIGZvbGxvd2luZyBmdW5jdGlvbiBjYWxsIGlzIGlkZW50aWNhbCB0bwogICAgICAgIC8vIGBTZXQuaW5zZXJ0KGtub3duVmFsdWVzLCB2YWx1ZSlgCiAgICAgICAgcmVxdWlyZShrbm93blZhbHVlcy5pbnNlcnQodmFsdWUpKTsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.13</span><span class="p">;</span> <span class="kt">struct</span><span class="w"> </span><span class="nv">Data</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">mapping</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span>flags<span class="p">;</span><span class="w"> </span><span class="p">}</span> <span class="c1">// Now we attach functions to the type.</span> <span class="c1">// The attached functions can be used throughout the rest of the module.</span> <span class="c1">// If you import the module, you have to</span> <span class="c1">// repeat the using directive there, for example as</span> <span class="c1">// import &quot;flags.sol&quot; as Flags;</span> <span class="c1">// using {Flags.insert, Flags.remove, Flags.contains}</span> <span class="c1">// for Flags.Data;</span> using<span class="w"> </span><span class="p">{</span>insert<span class="p">,</span><span class="w"> </span>remove<span class="p">,</span><span class="w"> </span>contains<span class="p">}</span><span class="w"> </span><span class="kt">for</span><span class="w"> </span>Data<span class="p">;</span> <span class="kt">function</span><span class="w"> </span><span class="nv">insert</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">])</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// already there</span> <span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">function</span><span class="w"> </span><span class="nv">remove</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="p">{</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">])</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// not there</span> <span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">false</span><span class="p">;</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="kt">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">function</span><span class="w"> </span><span class="nv">contains</span><span class="p">(</span>Data<span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span>view <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>self<span class="p">.</span>flags<span class="p">[</span>value<span class="p">];</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>Data<span class="w"> </span>knownValues<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">register</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// Here, all variables of type Data have</span> <span class="w"> </span><span class="c1">// corresponding member functions.</span> <span class="w"> </span><span class="c1">// The following function call is identical to</span> <span class="w"> </span><span class="c1">// `Set.insert(knownValues, value)`</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>knownValues<span class="p">.</span>insert<span class="p">(</span>value<span class="p">));</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>It is also possible to extend built-in types in that way. In this example, we will use a library.</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMTM7CgpsaWJyYXJ5IFNlYXJjaCB7CiAgICBmdW5jdGlvbiBpbmRleE9mKHVpbnRbXSBzdG9yYWdlIHNlbGYsIHVpbnQgdmFsdWUpCiAgICAgICAgcHVibGljCiAgICAgICAgdmlldwogICAgICAgIHJldHVybnMgKHVpbnQpCiAgICB7CiAgICAgICAgZm9yICh1aW50IGkgPSAwOyBpIDwgc2VsZi5sZW5ndGg7IGkrKykKICAgICAgICAgICAgaWYgKHNlbGZbaV0gPT0gdmFsdWUpIHJldHVybiBpOwogICAgICAgIHJldHVybiB0eXBlKHVpbnQpLm1heDsKICAgIH0KfQp1c2luZyBTZWFyY2ggZm9yIHVpbnRbXTsKCmNvbnRyYWN0IEMgewogICAgdWludFtdIGRhdGE7CgogICAgZnVuY3Rpb24gYXBwZW5kKHVpbnQgdmFsdWUpIHB1YmxpYyB7CiAgICAgICAgZGF0YS5wdXNoKHZhbHVlKTsKICAgIH0KCiAgICBmdW5jdGlvbiByZXBsYWNlKHVpbnQgZnJvbSwgdWludCB0bykgcHVibGljIHsKICAgICAgICAvLyBUaGlzIHBlcmZvcm1zIHRoZSBsaWJyYXJ5IGZ1bmN0aW9uIGNhbGwKICAgICAgICB1aW50IGluZGV4ID0gZGF0YS5pbmRleE9mKGZyb20pOwogICAgICAgIGlmIChpbmRleCA9PSB0eXBlKHVpbnQpLm1heCkKICAgICAgICAgICAgZGF0YS5wdXNoKHRvKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGRhdGFbaW5kZXhdID0gdG87CiAgICB9Cn0=" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.13</span><span class="p">;</span> <span class="kt">library</span><span class="w"> </span>Search<span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">indexOf</span><span class="p">(</span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span>storage<span class="w"> </span>self<span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span> <span class="w"> </span><span class="kt">public</span> <span class="w"> </span>view <span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="p">)</span> <span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">for</span><span class="w"> </span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">0</span><span class="p">;</span><span class="w"> </span>i<span class="w"> </span><span class="o">&lt;</span><span class="w"> </span>self<span class="p">.</span>length<span class="p">;</span><span class="w"> </span>i<span class="o">++</span><span class="p">)</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>self<span class="p">[</span>i<span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span>value<span class="p">)</span><span class="w"> </span><span class="kt">return</span><span class="w"> </span>i<span class="p">;</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>type<span class="p">(</span><span class="kt">uint</span><span class="p">).</span>max<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> using<span class="w"> </span>Search<span class="w"> </span><span class="kt">for</span><span class="w"> </span><span class="kt">uint</span><span class="p">[];</span> <span class="k">contract</span><span class="w"> </span><span class="ni">C</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint</span><span class="p">[]</span><span class="w"> </span>data<span class="p">;</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">append</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">value</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span>data<span class="p">.</span>push<span class="p">(</span>value<span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">replace</span><span class="p">(</span><span class="kt">uint</span><span class="w"> </span><span class="nv">from</span><span class="p">,</span><span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">to</span><span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="c1">// This performs the library function call</span> <span class="w"> </span><span class="kt">uint</span><span class="w"> </span><span class="nv">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>data<span class="p">.</span>indexOf<span class="p">(</span>from<span class="p">);</span> <span class="w"> </span><span class="kt">if</span><span class="w"> </span><span class="p">(</span>index<span class="w"> </span><span class="o">==</span><span class="w"> </span>type<span class="p">(</span><span class="kt">uint</span><span class="p">).</span>max<span class="p">)</span> <span class="w"> </span>data<span class="p">.</span>push<span class="p">(</span>to<span class="p">);</span> <span class="w"> </span><span class="kt">else</span> <span class="w"> </span>data<span class="p">[</span>index<span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>to<span class="p">;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> <p>Note that all external library calls are actual EVM function calls. This means that if you pass memory or value types, a copy will be performed, even in case of the <code class="docutils literal notranslate"><span class="pre">self</span></code> variable. The only situation where no copy will be performed is when storage reference variables are used or when internal library functions are called.</p> <p>Another example shows how to define a custom operator for a user-defined type:</p> <p class="remix-link-container"><a class="remix-link reference external" href="https://remix.ethereum.org/?#language=solidity&amp;version=0.8.29&amp;code=Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0zLjAKcHJhZ21hIHNvbGlkaXR5IF4wLjguMTk7Cgp0eXBlIFVGaXhlZDE2eDIgaXMgdWludDE2OwoKdXNpbmcgewogICAgYWRkIGFzICssCiAgICBkaXYgYXMgLwp9IGZvciBVRml4ZWQxNngyIGdsb2JhbDsKCnVpbnQzMiBjb25zdGFudCBTQ0FMRSA9IDEwMDsKCmZ1bmN0aW9uIGFkZChVRml4ZWQxNngyIGEsIFVGaXhlZDE2eDIgYikgcHVyZSByZXR1cm5zIChVRml4ZWQxNngyKSB7CiAgICByZXR1cm4gVUZpeGVkMTZ4Mi53cmFwKFVGaXhlZDE2eDIudW53cmFwKGEpICsgVUZpeGVkMTZ4Mi51bndyYXAoYikpOwp9CgpmdW5jdGlvbiBkaXYoVUZpeGVkMTZ4MiBhLCBVRml4ZWQxNngyIGIpIHB1cmUgcmV0dXJucyAoVUZpeGVkMTZ4MikgewogICAgdWludDMyIGEzMiA9IFVGaXhlZDE2eDIudW53cmFwKGEpOwogICAgdWludDMyIGIzMiA9IFVGaXhlZDE2eDIudW53cmFwKGIpOwogICAgdWludDMyIHJlc3VsdDMyID0gYTMyICogU0NBTEUgLyBiMzI7CiAgICByZXF1aXJlKHJlc3VsdDMyIDw9IHR5cGUodWludDE2KS5tYXgsICJEaXZpZGUgb3ZlcmZsb3ciKTsKICAgIHJldHVybiBVRml4ZWQxNngyLndyYXAodWludDE2KGEzMiAqIFNDQUxFIC8gYjMyKSk7Cn0KCmNvbnRyYWN0IE1hdGggewogICAgZnVuY3Rpb24gYXZnKFVGaXhlZDE2eDIgYSwgVUZpeGVkMTZ4MiBiKSBwdWJsaWMgcHVyZSByZXR1cm5zIChVRml4ZWQxNngyKSB7CiAgICAgICAgcmV0dXJuIChhICsgYikgLyBVRml4ZWQxNngyLndyYXAoMjAwKTsKICAgIH0KfQ==" target="_blank">open in Remix</a></p> <div class="highlight-solidity notranslate"><div class="highlight"><pre><span></span><span class="c1">// SPDX-License-Identifier: GPL-3.0</span> <span class="k">pragma solidity</span><span class="w"> </span><span class="o">^</span><span class="k">0.8.19</span><span class="p">;</span> type<span class="w"> </span>UFixed16x2<span class="w"> </span><span class="kt">is</span><span class="w"> </span><span class="kt">uint16</span><span class="p">;</span> using<span class="w"> </span><span class="p">{</span> <span class="w"> </span>add<span class="w"> </span>as<span class="w"> </span><span class="o">+</span><span class="p">,</span> <span class="w"> </span>div<span class="w"> </span>as<span class="w"> </span><span class="o">/</span> <span class="p">}</span><span class="w"> </span><span class="kt">for</span><span class="w"> </span>UFixed16x2<span class="w"> </span>global<span class="p">;</span> <span class="kt">uint32</span><span class="w"> </span><span class="nv">constant</span><span class="w"> </span>SCALE<span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m m-Decimal">100</span><span class="p">;</span> <span class="kt">function</span><span class="w"> </span><span class="nv">add</span><span class="p">(</span>UFixed16x2<span class="w"> </span>a<span class="p">,</span><span class="w"> </span>UFixed16x2<span class="w"> </span>b<span class="p">)</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>UFixed16x2<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>UFixed16x2<span class="p">.</span>wrap<span class="p">(</span>UFixed16x2<span class="p">.</span>unwrap<span class="p">(</span>a<span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span>UFixed16x2<span class="p">.</span>unwrap<span class="p">(</span>b<span class="p">));</span> <span class="p">}</span> <span class="kt">function</span><span class="w"> </span><span class="nv">div</span><span class="p">(</span>UFixed16x2<span class="w"> </span>a<span class="p">,</span><span class="w"> </span>UFixed16x2<span class="w"> </span>b<span class="p">)</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>UFixed16x2<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">uint32</span><span class="w"> </span><span class="nv">a32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>UFixed16x2<span class="p">.</span>unwrap<span class="p">(</span>a<span class="p">);</span> <span class="w"> </span><span class="kt">uint32</span><span class="w"> </span><span class="nv">b32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>UFixed16x2<span class="p">.</span>unwrap<span class="p">(</span>b<span class="p">);</span> <span class="w"> </span><span class="kt">uint32</span><span class="w"> </span><span class="nv">result32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>a32<span class="w"> </span><span class="o">*</span><span class="w"> </span>SCALE<span class="w"> </span><span class="o">/</span><span class="w"> </span>b32<span class="p">;</span> <span class="w"> </span><span class="kt">require</span><span class="p">(</span>result32<span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span>type<span class="p">(</span><span class="kt">uint16</span><span class="p">).</span>max<span class="p">,</span><span class="w"> </span><span class="s2">&quot;Divide overflow&quot;</span><span class="p">);</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span>UFixed16x2<span class="p">.</span>wrap<span class="p">(</span><span class="kt">uint16</span><span class="p">(</span>a32<span class="w"> </span><span class="o">*</span><span class="w"> </span>SCALE<span class="w"> </span><span class="o">/</span><span class="w"> </span>b32<span class="p">));</span> <span class="p">}</span> <span class="k">contract</span><span class="w"> </span><span class="ni">Math</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">function</span><span class="w"> </span><span class="nv">avg</span><span class="p">(</span>UFixed16x2<span class="w"> </span>a<span class="p">,</span><span class="w"> </span>UFixed16x2<span class="w"> </span>b<span class="p">)</span><span class="w"> </span><span class="kt">public</span><span class="w"> </span>pure<span class="w"> </span><span class="kt">returns</span><span class="w"> </span><span class="p">(</span>UFixed16x2<span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="kt">return</span><span class="w"> </span><span class="p">(</span>a<span class="w"> </span><span class="o">+</span><span class="w"> </span>b<span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span>UFixed16x2<span class="p">.</span>wrap<span class="p">(</span><span class="m m-Decimal">200</span><span class="p">);</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </pre></div> </div> </section> </section> </div> </div> <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> <a href="control-structures.html" class="btn btn-neutral float-left" title="Expressions and Control Structures" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> <a href="assembly.html" class="btn btn-neutral float-right" title="Inline Assembly" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> </div> <hr/> <div role="contentinfo"> <p>&#169; Copyright 2016-2024, The Solidity Authors.</p> </div> <p> <a href="credits-and-attribution.html">Credits and attribution</a>. </p> </footer> </div> </div> </section> </div> <script> jQuery(function () { SphinxRtdTheme.Navigation.enable(true); }); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10