## File: README.md [](https://github.com/vyperlang/vyper/actions/workflows/test.yml) [](http://docs.vyperlang.org/en/latest/?badge=latest "ReadTheDocs") [](https://discord.gg/6tw7PTM7C2) [](https://t.me/vyperlang) [](https://x.com/vyperlang) [](https://pypi.org/project/vyper "PyPI") [](https://hub.docker.com/r/vyperlang/vyper "DockerHub") [](https://codecov.io/gh/vyperlang/vyper "Codecov") [](https://github.com/vyperlang/vyper/actions/workflows/codeql.yml) # Getting Started See [Installing Vyper](http://docs.vyperlang.org/en/latest/installing-vyper.html) to install vyper. See [Tools and Resources](https://docs.vyperlang.org/en/latest/resources.html) for an additional list of framework and tools with vyper support. See [Documentation](http://docs.vyperlang.org/en/latest/index.html) for the documentation and overall design goals of the Vyper language. See [learn.vyperlang.org](https://learn.vyperlang.org/) for **learning Vyper by building a Pokémon game**. See [try.vyperlang.org](https://try.vyperlang.org/) to use Vyper in a hosted jupyter environment! **Note: Vyper is constantly evolving, use with care and understand the risks associated with smart contract development.** # Installation See the [Vyper documentation](https://docs.vyperlang.org/en/latest/installing-vyper.html) for build instructions. # Compiling a contract To compile a contract, use: ```bash vyper your_file_name.vy ``` ***generate bytecode*** vyper -f bytecode file-name.vy > file-name.bin ***generate abi*** vyper -f abi file-name.vy > file-name.abi There is also an [online compiler](https://vyper.online/) available you can use to experiment with the language and compile to ``bytecode`` and/or ``IR``. **Note: While the vyper version of the online compiler is updated on a regular basis it might be a bit behind the latest version found in the master branch of this repository.** # Contributing * See Issues tab, and feel free to submit your own issues * Add PRs if you discover a solution to an existing issue * For further discussions and questions, post in [Discussions](https://github.com/vyperlang/vyper/discussions) or talk to us on [Discord](https://discord.gg/6tw7PTM7C2) * For more information, see [Contributing](http://docs.vyperlang.org/en/latest/contributing.html) ## Contributing Code ### Setup #### uv (recommended) Make sure you have `uv` installed 1. Clone this repo and `cd` into it 2. Run `git fetch --tags git@github.com:vyperlang/vyper.git` to get the tags necessary for version inference 3. Run `uv sync` 4. Run `source .venv/bin/activate` to activate the virtual environment 5. Run `vyper --version` to verify the setup 6. (optional) Run `git config blame.ignoreRevsFile .git-blame-ignore-revs` to improve `git blame` #### pip Make sure you have `pip` (version 25.1 or above), `setuptools`, and `pytest` installed 1. Clone this repo and `cd` into it 2. Run `git fetch --tags git@github.com:vyperlang/vyper.git` to get the tags necessary for version inference 3. Run `python -m venv .venv` to create a virtual environment 4. Run `source .venv/bin/activate` to activate it 5. Run `make init` to install the main dependencies 6. Run `make dev-init` to install the dev dependencies 7. Run `vyper --version` to verify the setup 6. (optional) Run `git config blame.ignoreRevsFile .git-blame-ignore-revs` to improve `git blame` ### Commands * `vyper path/to/file.vy` to run your local copy of the compiler * `pytest` to test your changes Useful pytest flags: * `-x`: Fail test run on first test failure * `--instafail`: Show reason for test failure directly, instead of at the end of a test run * `--disable-warnings`: Hide warnings which occurred during tests * `make mypy` to type check your changes * `make lint` to check your files are correctly formatted (also runs mypy) ### Docker Setup Note: This is only useful for contributors, if you just want to use vyper, look [here](https://docs.vyperlang.org/en/latest/installing-vyper.html#docker). #### Build the image: `docker build . -t vyper -f Dockerfile` #### Check it runs: `docker run -v $(pwd):/code vyper --help` #### Run vyper: It works like `vyper` locally, with the difference that you should add `/code/` before the local path: `docker run -v $(pwd):/code vyper /code/` Example: * `vyper -f abi_python examples/name_registry/name_registry.vy` becomes * `docker run -v $(pwd):/code vyper -f abi_python /code/examples/name_registry/name_registry.vy` ### Other Tips #### Checking performance To run a python performance profile (to find compiler perf hotspots): ```bash PYTHONPATH=. python -m cProfile -s tottime vyper/cli/vyper_compile.py "$@" ``` The utility timer functions `timeit`, `profileit` and `cumtimeit` are available in `vyper/utils.py`. #### Getting call graph To get a call graph from a python profile, install `gprof2dot` and `xdot`, and run it like `gprof2dot -f pstats stats | xdot -`. (See https://stackoverflow.com/a/23164271/). #### Testing with hevm Install hevm by downloading it from the releases page (https://github.com/ethereum/hevm/releases/latest) and making sure it is in your PATH. hevm tests can be enabled with `--hevm` flag, and hevm tests can be selected with the `-m hevm` marker. For instance, `pytest -m "hevm" --hevm`. #### Fuzzing tests Fuzzing test are very slow, so they are not run by default. To run them, use `pytest -m "fuzzing"`. --- ## File: docs/built-in-functions.rst .. index:: function, built-in; .. _built_in_functions: Built-in Functions ################## Vyper provides a collection of built-in functions available in the global namespace of all contracts. Bitwise Operations ================== .. py:function:: shift(x: int256 | uint256, _shift: integer) -> uint256 Return ``x`` with the bits shifted ``_shift`` places. A positive ``_shift`` value equals a left shift, a negative value is a right shift. .. code-block:: vyper @external @view def foo(x: uint256, y: int128) -> uint256: return shift(x, y) .. code-block:: vyper >>> ExampleContract.foo(2, 8) 512 .. note:: This function has been deprecated from version 0.3.8 onwards. Please use the ``<<`` and ``>>`` operators instead. .. note:: The functions ``bitwise_and``, ``bitwise_or``, ``bitwise_xor`` and ``bitwise_not`` have been deprecated from version 0.3.4., and removed in version 0.4.2. Please use their operator versions instead: ``&``, ``|``, ``^``, ``~``. Chain Interaction ================= Vyper has four built-ins for contract creation; the first three contract creation built-ins rely on the code to deploy already being stored on-chain, but differ in call vs deploy overhead, and whether or not they invoke the constructor of the contract to be deployed. The following list provides a short summary of the differences between them. * ``create_minimal_proxy_to(target: address, ...)`` * Creates an immutable proxy to ``target`` * Expensive to call (incurs a single ``DELEGATECALL`` overhead on every invocation), cheap to create (since it only deploys ``EIP-1167`` forwarder bytecode) * Does not have the ability to call a constructor * Does **not** check that there is code at ``target`` (allows one to deploy proxies counterfactually) * ``create_copy_of(target: address, ...)`` * Creates a byte-for-byte copy of runtime code stored at ``target`` * Cheap to call (no ``DELEGATECALL`` overhead), expensive to create (200 gas per deployed byte) * Does not have the ability to call a constructor * Performs an ``EXTCODESIZE`` check to check there is code at ``target`` * ``create_from_blueprint(target: address, ...)`` * Deploys a contract using the initcode stored at ``target`` * Cheap to call (no ``DELEGATECALL`` overhead), expensive to create (200 gas per deployed byte) * Invokes constructor, requires a special "blueprint" contract to be deployed * Performs an ``EXTCODESIZE`` check to check there is code at ``target`` * ``raw_create(initcode: Bytes[...], ...)`` * Low-level create. Takes the given initcode, along with the arguments to be abi-encoded, and deploys the initcode after concatenating the abi-encoded arguments. .. py:function:: create_minimal_proxy_to(target: address, value: uint256 = 0, revert_on_failure: bool = True[, salt: bytes32]) -> address Deploys a small, EIP1167-compliant "minimal proxy contract" that duplicates the logic of the contract at ``target``, but has its own state since every call to ``target`` is made using ``DELEGATECALL`` to ``target``. To the end user, this should be indistinguishable from an independently deployed contract with the same code as ``target``. * ``target``: Address of the contract to proxy to * ``value``: The wei value to send to the new contract address (Optional, default 0) * ``revert_on_failure``: If ``False``, instead of reverting when the create operation fails, return the zero address (Optional, default ``True``) * ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used) Returns the address of the newly created proxy contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. .. code-block:: vyper @external def foo(target: address) -> address: return create_minimal_proxy_to(target) .. note:: It is very important that the deployed contract at ``target`` is code you know and trust, and does not implement the ``selfdestruct`` opcode or have upgradeable code as this will affect the operation of the proxy contract. .. note:: There is no runtime check that there is code already deployed at ``target`` (since a proxy may be deployed counterfactually). Most applications may want to insert this check. .. note:: Before version 0.3.4, this function was named ``create_forwarder_to``. .. py:function:: create_copy_of(target: address, value: uint256 = 0, revert_on_failure: bool = True[, salt: bytes32]) -> address Create a physical copy of the runtime code at ``target``. The code at ``target`` is byte-for-byte copied into a newly deployed contract. * ``target``: Address of the contract to copy * ``value``: The wei value to send to the new contract address (Optional, default 0) * ``revert_on_failure``: If ``False``, instead of reverting when the create operation fails, return the zero address (Optional, default ``True``) * ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used) Returns the address of the created contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. If there is no code at ``target``, execution will revert. .. code-block:: vyper @external def foo(target: address) -> address: return create_copy_of(target) .. note:: The implementation of ``create_copy_of`` assumes that the code at ``target`` is smaller than 16MB. While this is much larger than the EIP-170 constraint of 24KB, it is a conservative size limit intended to future-proof deployer contracts in case the EIP-170 constraint is lifted. If the code at ``target`` is larger than 16MB, the behavior of ``create_copy_of`` is undefined. .. py:function:: create_from_blueprint(target: address, *args, value: uint256 = 0, raw_args: bool = False, code_offset: int = 3, revert_on_failure: bool = True[, salt: bytes32]) -> address Copy the code of ``target`` into memory and execute it as initcode. In other words, this operation interprets the code at ``target`` not as regular runtime code, but directly as initcode. The ``*args`` are interpreted as constructor arguments, and are ABI-encoded and included when executing the initcode. * ``target``: Address of the blueprint to invoke * ``*args``: Constructor arguments to forward to the initcode. * ``value``: The wei value to send to the new contract address (Optional, default 0) * ``raw_args``: If ``True``, ``*args`` must be a single ``Bytes[...]`` argument, which will be interpreted as a raw bytes buffer to forward to the create operation (which is useful for instance, if pre- ABI-encoded data is passed in from elsewhere). (Optional, default ``False``) * ``code_offset``: The offset to start the ``EXTCODECOPY`` from (Optional, default 3) * ``revert_on_failure``: If ``False``, instead of reverting when the create operation fails, return the zero address (Optional, default ``True``) * ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used) Returns the address of the created contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. If ``code_offset >= target.codesize`` (ex. if there is no code at ``target``), execution will revert. .. code-block:: vyper @external def foo(blueprint: address) -> address: arg1: uint256 = 18 arg2: String[32] = "some string" return create_from_blueprint(blueprint, arg1, arg2, code_offset=1) .. note:: To properly deploy a blueprint contract, special deploy bytecode must be used. The output of ``vyper -f blueprint_bytecode`` will produce bytecode which deploys an ERC-5202 compatible blueprint. .. note:: Prior to Vyper version ``0.4.0``, the ``code_offset`` parameter defaulted to ``0``. .. warning:: It is recommended to deploy blueprints with an `ERC-5202 `_ preamble like ``0xFE7100`` to guard them from being called as regular contracts. This is particularly important for factories where the constructor has side effects (including ``SELFDESTRUCT``!), as those could get executed by *anybody* calling the blueprint contract directly. The ``code_offset=`` kwarg is provided (and defaults to the ERC-5202 default of 3) to enable this pattern: .. code-block:: vyper @external def foo(blueprint: address) -> address: # `blueprint` is a blueprint contract with some known preamble b"abcd..." return create_from_blueprint(blueprint, code_offset=) .. py:function:: raw_create(initcode: Bytes[...], *args, value: uint256 = 0, revert_on_failure: bool = True[, salt: bytes32]) -> address Create a contract using the given ``initcode``. Provides low-level access to the ``CREATE`` and ``CREATE2`` opcodes. * ``initcode``: Initcode bytes * ``value``: The wei value to send to the new contract address (Optional, default 0) * ``*args``: Constructor arguments to forward to the initcode. * ``revert_on_failure``: If ``False``, instead of reverting when the create operation fails, return the zero address (Optional, default ``True``) * ``salt``: A ``bytes32`` value utilized by the deterministic ``CREATE2`` opcode (Optional, if not supplied, ``CREATE`` is used) Returns the address of the created contract. If the create operation fails (for instance, in the case of a ``CREATE2`` collision), execution will revert. .. code-block:: vyper @external def foo() -> address: # create the bytes of an empty vyper contract return raw_create(x"0x61000361000f6000396100036000f35f5ffd855820cd372fb85148700fa88095e3492d3f9f5beb43e555e5ff26d95f5a6adc36f8e6038000a1657679706572830004020033") .. py:function:: raw_call(to: address, data: Bytes, max_outsize: uint256 = 0, gas: uint256 = gasLeft, value: uint256 = 0, is_delegate_call: bool = False, is_static_call: bool = False, revert_on_failure: bool = True) -> Bytes[max_outsize] Call to the specified Ethereum address. * ``to``: Destination address to call to * ``data``: Data to send to the destination address * ``max_outsize``: Maximum length of the bytes array returned from the call. If the returned call data exceeds this length, only this number of bytes is returned. (Optional, default ``0``) * ``gas``: The amount of gas to attach to the call. (Optional, defaults to ``msg.gas``). * ``value``: The wei value to send to the address (Optional, default ``0``) * ``is_delegate_call``: If ``True``, the call will be sent as ``DELEGATECALL`` (Optional, default ``False``) * ``is_static_call``: If ``True``, the call will be sent as ``STATICCALL`` (Optional, default ``False``) * ``revert_on_failure``: If ``True``, the call will revert on a failure, otherwise ``success`` will be returned (Optional, default ``True``) .. note:: Returns the data returned by the call as a ``Bytes`` list, with ``max_outsize`` as the max length. The actual size of the returned data may be less than ``max_outsize``. You can use ``len`` to obtain the actual size. Returns nothing if ``max_outsize`` is omitted or set to ``0``. Returns ``success`` in a tuple with return value if ``revert_on_failure`` is set to ``False``. .. code-block:: vyper @external @payable def foo(_target: address) -> Bytes[32]: response: Bytes[32] = raw_call(_target, method_id("someMethodName()"), max_outsize=32, value=msg.value) return response @external @payable def bar(_target: address) -> Bytes[32]: success: bool = False response: Bytes[32] = b"" x: uint256 = 123 success, response = raw_call( _target, abi_encode(x, method_id=method_id("someMethodName(uint256)")), max_outsize=32, value=msg.value, revert_on_failure=False ) assert success return response .. note:: Regarding "forwarding all gas", note that, while Vyper will provide ``msg.gas`` to the call, in practice, there are some subtleties around forwarding all remaining gas on the EVM which are out of scope of this documentation and could be subject to change. For instance, see the language in EIP-150 around "all but one 64th". .. py:function:: raw_log(topics: bytes32[4], data: Union[Bytes, bytes32]) -> None Provides low level access to the ``LOG`` opcodes, emitting a log without having to specify an ABI type. * ``topics``: List of ``bytes32`` log topics. The length of this array determines which opcode is used. * ``data``: Unindexed event data to include in the log. May be given as ``Bytes`` or ``bytes32``. .. code-block:: vyper @external def foo(_topic: bytes32, _data: Bytes[100]): raw_log([_topic], _data) .. py:function:: raw_revert(data: Bytes) -> None Provides low level access to the ``REVERT`` opcode, reverting execution with the specified data returned. * ``data``: Data representing the error message causing the revert. .. code-block:: vyper @external def foo(_data: Bytes[100]): raw_revert(_data) .. py:function:: selfdestruct(to: address) -> None Trigger the ``SELFDESTRUCT`` opcode (``0xFF``), causing the contract to be destroyed. * ``to``: Address to forward the contract's ether balance to .. warning:: As of the Cancun hardfork (EIP-6780), this opcode no longer deletes contract code unless called in the same transaction as contract creation. It only transfers the contract's ETH balance to the specified address. .. note:: This function has been deprecated from version 0.3.8 onwards. The underlying opcode will eventually undergo breaking changes, and its use is not recommended. .. code-block:: vyper @external def do_the_needful(): selfdestruct(msg.sender) .. py:function:: send(to: address, value: uint256, gas: uint256 = 0) -> None Send ether from the contract to the specified Ethereum address. * ``to``: The destination address to send ether to * ``value``: The wei value to send to the address * ``gas``: The amount of gas (the "stipend") to attach to the call. If not set, the stipend defaults to 0. .. note:: The amount to send is always specified in ``wei``. .. warning:: The ``gas`` parameter defaults to ``0``. When transferring a **non-zero amount of ETH**, the EVM `automatically `_ grants the callee a 2300-gas stipend (``GAS_STIPEND``). However, no stipend is added when ``value == 0``. As a result, ``send(to, 0)`` forwards no gas and will only succeed if the recipient requires no execution gas (for example, an account with no code). .. code-block:: vyper @external def foo(_receiver: address, _amount: uint256, gas: uint256): send(_receiver, _amount, gas=gas) Cryptography ============ .. py:function:: ecadd(a: uint256[2], b: uint256[2]) -> uint256[2] Take two points on the Alt-BN128 curve and add them together. .. code-block:: vyper @external @view def foo(x: uint256[2], y: uint256[2]) -> uint256[2]: return ecadd(x, y) .. code-block:: vyper >>> ExampleContract.foo([1, 2], [1, 2]) [ 1368015179489954701390400359078579693043519447331113978918064868415326638035, 9918110051302171585080402603319702774565515993150576347155970296011118125764, ] .. py:function:: ecmul(point: uint256[2], scalar: uint256) -> uint256[2] Take a point on the Alt-BN128 curve (``p``) and a scalar value (``s``), and return the result of adding the point to itself ``s`` times, i.e. ``p * s``. * ``point``: Point to be multiplied * ``scalar``: Scalar value .. code-block:: vyper @external @view def foo(point: uint256[2], scalar: uint256) -> uint256[2]: return ecmul(point, scalar) .. code-block:: vyper >>> ExampleContract.foo([1, 2], 3) [ 3353031288059533942658390886683067124040920775575537747144343083137631628272, 19321533766552368860946552437480515441416830039777911637913418824951667761761, ] .. py:function:: ecrecover(hash: bytes32, v: uint256 | uint8, r: uint256 | bytes32, s: uint256 | bytes32) -> address Recover the address associated with the public key from the given elliptic curve signature. * ``r``: first 32 bytes of signature * ``s``: second 32 bytes of signature * ``v``: final 1 byte of signature Returns the associated address, or ``empty(address)`` on error. .. note:: Prior to Vyper ``0.3.10``, the ``ecrecover`` function could return an undefined (possibly nonzero) value for invalid inputs to ``ecrecover``. For more information, please see `GHSA-f5x6-7qgp-jhf3 `_. .. code-block:: vyper @external @view def foo(hash: bytes32, v: uint8, r: bytes32, s: bytes32) -> address: return ecrecover(hash, v, r, s) Alternatively, ``v``, ``r``, and ``s`` can be passed as ``uint256``: .. code-block:: vyper @external @view def bar(hash: bytes32, v: uint256, r: uint256, s: uint256) -> address: return ecrecover(hash, v, r, s) .. code-block:: vyper >>> ExampleContract.bar('0x6c9c5e133b8aafb2ea74f524a5263495e7ae5701c7248805f7b511d973dc7055', 28, 78616903610408968922803823221221116251138855211764625814919875002740131251724, 37668412420813231458864536126575229553064045345107737433087067088194345044408 ) '0x9eE53ad38Bb67d745223a4257D7d48cE973FeB7A' .. py:function:: keccak256(_value) -> bytes32 Return a ``keccak256`` hash of the given value. * ``_value``: Value to hash. Can be a ``String``, ``Bytes``, or ``bytes32``. .. code-block:: vyper @external @view def foo(_value: Bytes[100]) -> bytes32: return keccak256(_value) .. code-block:: vyper >>> ExampleContract.foo(b"potato") 0x9e159dfcfe557cc1ca6c716e87af98fdcb94cd8c832386d0429b2b7bec02754f .. py:function:: sha256(_value) -> bytes32 Return a ``sha256`` (SHA2 256-bit output) hash of the given value. * ``_value``: Value to hash. Can be a ``String``, ``Bytes``, or ``bytes32``. .. code-block:: vyper @external @view def foo(_value: Bytes[100]) -> bytes32: return sha256(_value) .. code-block:: vyper >>> ExampleContract.foo(b"potato") 0xe91c254ad58860a02c788dfb5c1a65d6a8846ab1dc649631c7db16fef4af2dec Data Manipulation ================= .. py:function:: concat(a, b, *args) -> Union[Bytes, String] Take 2 or more bytes arrays of type ``bytesM``, ``Bytes`` or ``String`` and combine them into a single value. If the input arguments are ``String`` the return type is ``String``. Otherwise the return type is ``Bytes``. .. code-block:: vyper @external @view def foo(a: String[5], b: String[5], c: String[5]) -> String[100]: return concat(a, " ", b, " ", c, "!") .. code-block:: vyper >>> ExampleContract.foo("why","hello","there") "why hello there!" .. py:function:: convert(value, type_) -> Any Converts a variable or literal from one type to another. * ``value``: Value to convert * ``type_``: The destination type to convert to (e.g., ``bool``, ``decimal``, ``int128``, ``uint256`` or ``bytes32``) Returns a value of the type specified by ``type_``. For more details on available type conversions, see :ref:`type_conversions`. .. py:function:: uint2str(value: unsigned integer) -> String Returns an unsigned integer's string representation. * ``value``: Unsigned integer to convert. Returns the string representation of ``value``. .. code-block:: vyper @external @view def foo(b: uint256) -> String[78]: return uint2str(b) .. code-block:: vyper >>> ExampleContract.foo(420) "420" .. py:function:: extract32(b: Bytes, start: uint256, output_type=bytes32) -> Any Extract a value from a ``Bytes`` list. * ``b``: ``Bytes`` list to extract from * ``start``: Start point to extract from * ``output_type``: Type of output (``bytesM``, ``integer``, or ``address``). Defaults to ``bytes32``. Returns a value of the type specified by ``output_type``. .. code-block:: vyper @external @view def foo(b: Bytes[32]) -> address: return extract32(b, 0, output_type=address) .. code-block:: vyper >>> ExampleContract.foo("0x0000000000000000000000009f8F72aA9304c8B593d555F12eF6589cC3A579A2") "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2" .. py:function:: slice(b: Union[Bytes, bytes32, String], start: uint256, length: uint256) -> Union[Bytes, String] Copy a list of bytes and return a specified slice. * ``b``: value being sliced * ``start``: start position of the slice * ``length``: length of the slice If the value being sliced is a ``Bytes`` or ``bytes32``, the return type is ``Bytes``. If it is a ``String``, the return type is ``String``. .. code-block:: vyper @external @view def foo(s: String[32]) -> String[5]: return slice(s, 4, 5) .. code-block:: vyper >>> ExampleContract.foo("why hello! how are you?") "hello" Math ==== .. py:function:: abs(value: int256) -> int256 Return the absolute value of a signed integer. * ``value``: Integer to return the absolute value of .. code-block:: vyper @external @view def foo(value: int256) -> int256: return abs(value) .. code-block:: vyper >>> ExampleContract.foo(-31337) 31337 .. py:function:: ceil(value: decimal) -> int256 Round a decimal up to the nearest integer. * ``value``: Decimal value to round up .. code-block:: vyper @external @view def foo(x: decimal) -> int256: return ceil(x) .. code-block:: vyper >>> ExampleContract.foo(3.1337) 4 .. py:function:: epsilon(typename) -> Any Returns the smallest non-zero value for a decimal type. * ``typename``: Name of the decimal type (currently only ``decimal``) .. code-block:: vyper @external @view def foo() -> decimal: return epsilon(decimal) .. code-block:: vyper >>> ExampleContract.foo() Decimal('1E-10') .. py:function:: floor(value: decimal) -> int256 Round a decimal down to the nearest integer. * ``value``: Decimal value to round down .. code-block:: vyper @external @view def foo(x: decimal) -> int256: return floor(x) .. code-block:: vyper >>> ExampleContract.foo(3.1337) 3 .. py:function:: max(a: numeric, b: numeric) -> numeric Return the greater value of ``a`` and ``b``. The input values may be any numeric type as long as they are both of the same type. The output value is of the same type as the input values. .. code-block:: vyper @external @view def foo(a: uint256, b: uint256) -> uint256: return max(a, b) .. code-block:: vyper >>> ExampleContract.foo(23, 42) 42 .. py:function:: max_value(type_) -> numeric Returns the maximum value of the numeric type specified by ``type_`` (e.g., ``int128``, ``uint256``, ``decimal``). .. code-block:: vyper @external @view def foo() -> int256: return max_value(int256) .. code-block:: vyper >>> ExampleContract.foo() 57896044618658097711785492504343953926634992332820282019728792003956564819967 .. py:function:: min(a: numeric, b: numeric) -> numeric Returns the lesser value of ``a`` and ``b``. The input values may be any numeric type as long as they are both of the same type. The output value is of the same type as the input values. .. code-block:: vyper @external @view def foo(a: uint256, b: uint256) -> uint256: return min(a, b) .. code-block:: vyper >>> ExampleContract.foo(23, 42) 23 .. py:function:: min_value(type_) -> numeric Returns the minimum value of the numeric type specified by ``type_`` (e.g., ``int128``, ``uint256``, ``decimal``). .. code-block:: vyper @external @view def foo() -> int256: return min_value(int256) .. code-block:: vyper >>> ExampleContract.foo() -57896044618658097711785492504343953926634992332820282019728792003956564819968 .. py:function:: pow_mod256(a: uint256, b: uint256) -> uint256 Return the result of ``a ** b % (2 ** 256)``. This method is used to perform exponentiation without overflow checks. .. code-block:: vyper @external @view def foo(a: uint256, b: uint256) -> uint256: return pow_mod256(a, b) .. code-block:: vyper >>> ExampleContract.foo(2, 3) 8 >>> ExampleContract.foo(100, 100) 59041770658110225754900818312084884949620587934026984283048776718299468660736 .. py:function:: sqrt(d: decimal) -> decimal Return the square root of the provided decimal number, using the Babylonian square root algorithm. The rounding mode is to round down to the nearest epsilon. For instance, ``sqrt(0.9999999998) == 0.9999999998``. .. note:: ``sqrt`` has been moved to the ``math`` stdlib module as part of the ``0.4.2`` release (see `PR #4520 `_). See :ref:`stdlib-math`. Import it with ``import math`` and call ``math.sqrt(d)``. .. code-block:: vyper import math @external @view def foo(d: decimal) -> decimal: return math.sqrt(d) .. code-block:: vyper >>> ExampleContract.foo(9.0) 3.0 .. py:function:: isqrt(x: uint256) -> uint256 Return the (integer) square root of the provided integer number, using the Babylonian square root algorithm. The rounding mode is to round down to the nearest integer. For instance, ``isqrt(101) == 10``. .. note:: ``isqrt`` has been moved to the ``math`` stdlib module as part of the ``0.5.0`` release (see `PR #4923 `_). See :ref:`stdlib-math`. Import it with ``import math`` and call ``math.isqrt(x)``. .. code-block:: vyper import math @external @view def foo(x: uint256) -> uint256: return math.isqrt(x) .. code-block:: vyper >>> ExampleContract.foo(101) 10 .. py:function:: uint256_addmod(a: uint256, b: uint256, c: uint256) -> uint256 Return the modulo of ``(a + b) % c``. Reverts if ``c == 0``. As this built-in function is intended to provides access to the underlying ``ADDMOD`` opcode, all intermediate calculations of this operation are not subject to the ``2 ** 256`` modulo according to the EVM specifications. .. code-block:: vyper @external @view def foo(a: uint256, b: uint256, c: uint256) -> uint256: return uint256_addmod(a, b, c) .. code-block:: vyper >>> (6 + 13) % 8 3 >>> ExampleContract.foo(6, 13, 8) 3 .. py:function:: uint256_mulmod(a: uint256, b: uint256, c: uint256) -> uint256 Return the modulo from ``(a * b) % c``. Reverts if ``c == 0``. As this built-in function is intended to provides access to the underlying ``MULMOD`` opcode, all intermediate calculations of this operation are not subject to the ``2 ** 256`` modulo according to the EVM specifications. .. code-block:: vyper @external @view def foo(a: uint256, b: uint256, c: uint256) -> uint256: return uint256_mulmod(a, b, c) .. code-block:: vyper >>> (11 * 2) % 5 2 >>> ExampleContract.foo(11, 2, 5) 2 .. py:function:: unsafe_add(x: integer, y: integer) -> integer Add ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result exceeds the bounds of the input type, it will be wrapped. .. code-block:: vyper @external @view def foo(x: uint8, y: uint8) -> uint8: return unsafe_add(x, y) @external @view def bar(x: int8, y: int8) -> int8: return unsafe_add(x, y) .. code-block:: vyper >>> ExampleContract.foo(1, 1) 2 >>> ExampleContract.foo(255, 255) 254 >>> ExampleContract.bar(127, 127) -2 .. note:: Performance note: for the native word types of the EVM ``uint256`` and ``int256``, this will compile to a single ``ADD`` instruction, since the EVM natively wraps addition on 256-bit words. .. py:function:: unsafe_sub(x: integer, y: integer) -> integer Subtract ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result underflows the bounds of the input type, it will be wrapped. .. code-block:: vyper @external @view def foo(x: uint8, y: uint8) -> uint8: return unsafe_sub(x, y) @external @view def bar(x: int8, y: int8) -> int8: return unsafe_sub(x, y) .. code-block:: vyper >>> ExampleContract.foo(4, 3) 1 >>> ExampleContract.foo(0, 1) 255 >>> ExampleContract.bar(-128, 1) 127 .. note:: Performance note: for the native word types of the EVM ``uint256`` and ``int256``, this will compile to a single ``SUB`` instruction, since the EVM natively wraps subtraction on 256-bit words. .. py:function:: unsafe_mul(x: integer, y: integer) -> integer Multiply ``x`` and ``y``, without checking for overflow. ``x`` and ``y`` must both be integers of the same type. If the result exceeds the bounds of the input type, it will be wrapped. .. code-block:: vyper @external @view def foo(x: uint8, y: uint8) -> uint8: return unsafe_mul(x, y) @external @view def bar(x: int8, y: int8) -> int8: return unsafe_mul(x, y) .. code-block:: vyper >>> ExampleContract.foo(1, 1) 1 >>> ExampleContract.foo(255, 255) 1 >>> ExampleContract.bar(-128, -128) 0 >>> ExampleContract.bar(127, -128) -128 .. note:: Performance note: for the native word types of the EVM ``uint256`` and ``int256``, this will compile to a single ``MUL`` instruction, since the EVM natively wraps multiplication on 256-bit words. .. py:function:: unsafe_div(x: integer, y: integer) -> integer Divide ``x`` and ``y``, without checking for division-by-zero. ``x`` and ``y`` must both be integers of the same type. If the denominator is zero, the result will (following EVM semantics) be zero. .. code-block:: vyper @external @view def foo(x: uint8, y: uint8) -> uint8: return unsafe_div(x, y) @external @view def bar(x: int8, y: int8) -> int8: return unsafe_div(x, y) .. code-block:: vyper >>> ExampleContract.foo(1, 1) 1 >>> ExampleContract.foo(1, 0) 0 >>> ExampleContract.bar(-128, -1) -128 .. note:: Performance note: this will compile to a single ``SDIV`` or ``DIV`` instruction, depending on if the inputs are signed or unsigned (respectively). Utilities ========= .. py:function:: as_wei_value(_value, unit: str) -> uint256 Take an amount of ether currency specified by a number and a unit and return the integer quantity of wei equivalent to that amount. * ``_value``: Value for the ether unit. Any numeric type may be used, however, the value cannot be negative. * ``unit``: Ether unit name (e.g. ``"wei"``, ``"ether"``, ``"gwei"``, etc.) indicating the denomination of ``_value``. Must be given as a literal string. .. code-block:: vyper @external @view def foo(s: String[32]) -> uint256: return as_wei_value(1.337, "ether") .. code-block:: vyper >>> ExampleContract.foo(1) 1337000000000000000 .. note:: When ``as_wei_value`` is given some ``decimal``, the result might be rounded down to the nearest integer, for example, the following is true: ``as_wei_value(12.2, "wei") == 12``. .. py:function:: blockhash(block_num: uint256) -> bytes32 Return the hash of the block at the specified height. .. note:: The EVM only provides access to the most recent 256 blocks. This function reverts if the block number is greater than or equal to the current block number or more than 256 blocks behind the current block. .. code-block:: vyper @external @view def foo() -> bytes32: return blockhash(block.number - 16) .. code-block:: vyper >>> ExampleContract.foo() 0xf3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 .. py:function:: blobhash(index: uint256) -> bytes32 Return the versioned hash of the ``index``-th BLOB associated with the current transaction. .. note:: A versioned hash consists of a single byte representing the version (currently ``0x01``), followed by the last 31 bytes of the ``SHA256`` hash of the KZG commitment (`EIP-4844 `_). For the case ``index >= len(tx.blob_versioned_hashes)``, ``blobhash(index: uint256)`` returns ``empty(bytes32)``. .. code-block:: vyper @external @view def foo(index: uint256) -> bytes32: return blobhash(index) .. code-block:: vyper >>> ExampleContract.foo(0) 0xfd28610fb309939bfec12b6db7c4525446f596a5a5a66b8e2cb510b45b2bbeb5 >>> ExampleContract.foo(6) 0x0000000000000000000000000000000000000000000000000000000000000000 .. py:function:: empty(typename) -> Any Return a value which is the default (zero-ed) value of its type. Useful for initializing new memory variables. * ``typename``: Name of the type, except ``HashMap[_KeyType, _ValueType]`` .. code-block:: vyper @external @view def foo(): x: uint256[2][5] = empty(uint256[2][5]) .. py:function:: len(b: Union[Bytes, String, DynArray[_Type, _Integer]]) -> uint256 Return the length of a given ``Bytes``, ``String`` or ``DynArray[_Type, _Integer]``. .. code-block:: vyper @external @view def foo(s: String[32]) -> uint256: return len(s) .. code-block:: vyper >>> ExampleContract.foo("hello") 5 .. py:function:: method_id(method, output_type: type = Bytes[4]) -> Union[Bytes[4], bytes4] Takes a function declaration and returns its method_id (used in data field to call it). * ``method``: Method declaration as given as a literal string * ``output_type``: The type of output (``Bytes[4]`` or ``bytes4``). Defaults to ``Bytes[4]``. Returns a value of the type specified by ``output_type``. .. code-block:: vyper @external @view def foo() -> Bytes[4]: return method_id('transfer(address,uint256)', output_type=Bytes[4]) .. code-block:: vyper >>> ExampleContract.foo() 0xa9059cbb .. py:function:: abi_encode(*args, ensure_tuple: bool = True, method_id: Bytes[4] = None) -> Bytes[] Takes a variable number of args as input, and returns the ABIv2-encoded bytestring. Used for packing arguments to raw_call, EIP712 and other cases where a consistent and efficient serialization method is needed. Once this function has seen more use we provisionally plan to put it into the ``ethereum.abi`` namespace. * ``*args``: Arbitrary arguments * ``ensure_tuple``: If set to True, ensures that even a single argument is encoded as a tuple. In other words, ``bytes`` gets encoded as ``(bytes,)``, and ``(bytes,)`` gets encoded as ``((bytes,),)`` This is the calling convention for Vyper and Solidity functions. Except for very specific use cases, this should be set to True. Must be a literal. * ``method_id``: A literal hex or Bytes[4] value to append to the beginning of the abi-encoded bytestring. Returns a bytestring whose max length is determined by the arguments. For example, encoding a ``Bytes[32]`` results in a ``Bytes[64]`` (first word is the length of the bytestring variable). .. code-block:: vyper @external @view def foo() -> Bytes[132]: x: uint256 = 1 y: Bytes[32] = b"234" return abi_encode(x, y, method_id=method_id("foo()")) .. code-block:: vyper >>> ExampleContract.foo().hex() "c2985578" "0000000000000000000000000000000000000000000000000000000000000001" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000003" "3233340000000000000000000000000000000000000000000000000000000000" .. note:: Prior to v0.4.0, this function was named ``_abi_encode``. .. py:function:: abi_decode(b: Bytes, output_type: type_, unwrap_tuple: bool = True) -> Any Takes a byte array as input, and returns the decoded values according to the specified output types. Used for unpacking ABIv2-encoded values. Once this function has seen more use we provisionally plan to put it into the ``ethereum.abi`` namespace. * ``b``: A byte array of a length that is between the minimum and maximum ABIv2 size bounds of the ``output type``. * ``output_type``: Name of the output type, or tuple of output types, to be decoded. * ``unwrap_tuple``: If set to True, the input is decoded as a tuple even if only one output type is specified. In other words, ``abi_decode(b, Bytes[32])`` gets decoded as ``(Bytes[32],)``. This is the convention for ABIv2-encoded values generated by Vyper and Solidity functions. Except for very specific use cases, this should be set to True. Must be a literal. Returns the decoded value(s), with type as specified by `output_type`. .. code-block:: vyper @external @view def foo(someInput: Bytes[128]) -> (uint256, Bytes[32]): x: uint256 = empty(uint256) y: Bytes[32] = empty(Bytes[32]) x, y = abi_decode(someInput, (uint256, Bytes[32])) return x, y .. note:: Prior to v0.4.0, this function was named ``_abi_decode``. .. py:function:: print(*args, hardhat_compat=False) -> None "prints" the arguments by issuing a static call to the "console" address, ``0x000000000000000000636F6E736F6C652E6C6F67``. This is supported by some smart contract development frameworks. The default mode works natively with titanoboa. For hardhat-style frameworks, use ``hardhat_compat=True)``. .. note:: Issuing of the static call is *NOT* mode-dependent (that is, it is not removed from production code), although the compiler will issue a warning whenever ``print`` is used. .. warning:: In Vyper, as of v0.4.0, the order of argument evaluation of builtins is not defined. That means that the compiler may choose to reorder evaluation of arguments. For example, ``extract32(x(), y())`` may yield unexpected results if ``x()`` and ``y()`` both touch the same data. For this reason, it is best to avoid calling functions with side-effects inside of builtins. For more information, see `GHSA-g2xh-c426-v8mf `_ and `issue #4019 `_. --- ## File: docs/compiler-exceptions.rst .. _compiler-exceptions: Compiler Exceptions ################### .. _exceptions-common: Vyper raises one or more of the following exceptions when an issue is encountered while compiling a contract. Whenever possible, exceptions include a source highlight displaying the location of the error within the code: .. code-block:: python vyper.exceptions.VariableDeclarationException: line 79:17 Persistent variable undeclared: highstBid 78 # If bid is less than highest bid, bid fails ---> 79 if (value <= self.highstBid): -------------------------^ 80 return False .. py:exception:: ArgumentException Raises when calling a function with invalid arguments, for example an incorrect number of positional arguments or an invalid keyword argument. .. py:exception:: CallViolation Raises on an illegal function call, such as attempting to call between two external functions. .. py:exception:: ArrayIndexException Raises when an array index is out of bounds. .. py:exception:: EventDeclarationException Raises when an event declaration is invalid. .. py:exception:: EvmVersionException Raises when a contract contains an action that cannot be performed with the active EVM ruleset. .. py:exception:: FunctionDeclarationException Raises when a function declaration is invalid, for example because of incorrect or mismatched return values. .. py:exception:: ImmutableViolation Raises when attempting to perform a change a variable, constant or definition that cannot be changed. For example, trying to update a constant, or trying to assign to a function definition. .. py:exception:: InterfaceViolation Raises when an interface is not fully implemented. .. py:exception:: InvalidAttribute Raises on a reference to an attribute that does not exist. .. py:exception:: InvalidLiteral Raises when no valid type can be found for a literal value. .. code-block:: vyper #pragma enable-decimals @external def foo(): bar: decimal = 3.123456789123456789 This example raises ``InvalidLiteral`` because the given literal value has too many decimal places and so cannot be assigned any valid Vyper type. .. py:exception:: InvalidOperation Raises when using an invalid operator for a given type. .. code-block:: vyper @external def foo(): a: String[10] = "hello" * 2 This example raises ``InvalidOperation`` because multiplication is not possible on string types. .. py:exception:: InvalidReference Raises on an invalid reference to an existing definition. .. code-block:: vyper baz: int128 @external def foo(): bar: int128 = baz This example raises ``InvalidReference`` because ``baz`` is a storage variable. The reference to it should be written as ``self.baz``. .. py:exception:: InvalidType Raises when using an invalid literal value for the given type. .. code-block:: vyper @external def foo(): bar: int128 = 3.5 This example raises ``InvalidType`` because ``3.5`` is a valid literal value, but cannot be cast as ``int128``. .. py:exception:: IteratorException Raises when an iterator is constructed or used incorrectly. .. py:exception:: JSONError Raises when the compiler JSON input is malformed. .. py:exception:: NamespaceCollision Raises when attempting to assign a variable to a name that is already in use. .. py:exception:: NatSpecSyntaxException Raises when a contract contains an invalid :ref:`NatSpec` docstring. .. code-block:: python vyper.exceptions.SyntaxException: line 14:5 No description given for tag '@param' 13 @dev the feet are sticky like rice ---> 14 @param -------------^ 15 @return always True .. py:exception:: NonPayableViolation Raises when attempting to access ``msg.value`` from within a function that has not been marked as ``@payable``. .. code-block:: vyper @external def _foo(): bar: uint256 = msg.value .. py:exception:: OverflowException Raises when a numeric value is out of bounds for the given type. .. py:exception:: StateAccessViolation Raises when attempting to perform a modifying action within view-only or stateless context. For example, writing to storage in a ``@view`` function, reading from storage in a ``@pure`` function. .. py:exception:: StructureException Raises on syntax that is parsable, but invalid in some way. .. code-block:: python vyper.exceptions.StructureException: line 181:0 Invalid top-level statement 180 ---> 181 ''' ---------^ 182 .. py:exception:: SyntaxException Raises on invalid syntax that cannot be parsed. .. code-block:: python vyper.exceptions.SyntaxException: line 4:20 invalid syntax 3 struct Bid: ---> 4 blindedBid bytes32 ---------------------------^ 5 deposit: uint256 .. py:exception:: TypeMismatch Raises when attempting to perform an action between two or more objects with incompatible types. .. code-block:: vyper #pragma enable-decimals @external def foo(): bar: int128 = 3 baz: decimal = 4.2 if baz + bar > 4: pass ``bar`` has a type of ``int128`` and ``baz`` has a type of ``decimal``, so attempting to add them together raises a ``TypeMismatch``. .. py:exception:: UndeclaredDefinition Raises when attempting to access an object that has not been declared. .. py:exception:: VariableDeclarationException Raises on an invalid variable declaration. .. code-block:: bash vyper.exceptions.VariableDeclarationException: line 79:17 Persistent variable undeclared: highstBid 78 # If bid is less than highest bid, bid fails ---> 79 if (value <= self.highstBid): -------------------------^ 80 return False .. py:exception:: VersionException Raises when a contract version string is malformed or incompatible with the current compiler version. .. py:exception:: ZeroDivisionException Raises when a divide by zero or modulo zero situation arises. CompilerPanic ============= .. py:exception:: CompilerPanic .. code:: shell $ vyper v.vy Error compiling: v.vy vyper.exceptions.CompilerPanic: Number of times repeated must be a constant nonzero positive integer: 0 Please create an issue. A compiler panic error indicates that there is a problem internally to the compiler and an issue should be reported right away on the Vyper Github page. Open an issue if you are experiencing this error. Please `Open an Issue `_ --- ## File: docs/compiling-a-contract.rst Compiling a Contract ******************** Command-Line Compiler Tools =========================== Vyper includes the following command-line scripts for compiling contracts: * ``vyper``: Compiles vyper contract or archive files * ``vyper-json``: Provides a JSON interface to the compiler .. note:: The ``--help`` flag gives verbose explanations of how to use each of these scripts. .. _vyper-cli-command: vyper ----- ``vyper`` provides CLI access to the compiler. It can generate various outputs including simple binaries, ASTs, interfaces and source mappings. To compile a contract: .. code:: shell $ vyper yourFileName.vy Include the ``-f`` flag to specify which output formats to return. Use ``vyper --help`` for a full list of output options. .. code:: shell $ vyper -f abi,abi_python,bytecode,bytecode_runtime,blueprint_bytecode,cfg,cfg_runtime,interface,external_interface,ast,annotated_ast,integrity,ir,ir_json,ir_runtime,asm,opcodes,opcodes_runtime,source_map,source_map_runtime,archive,solc_json,method_identifiers,userdoc,devdoc,metadata,combined_json,layout yourFileName.vy .. note:: The ``opcodes`` and ``opcodes_runtime`` output of the compiler has been returning incorrect opcodes since ``0.2.0`` due to a lack of 0 padding (patched via `PR 3735 `_). If you rely on these functions for debugging, please use the latest patched versions. The ``-p`` flag allows you to set a root path that is used when searching for interface files to import. If none is given, it will default to the current working directory. See :ref:`searching_for_imports` for more information. .. code:: shell $ vyper -p yourProject yourProject/yourFileName.vy .. _compiler-storage-layout: Storage Layout ~~~~~~~~~~~~~~ To display the default storage layout for a contract: .. code:: shell $ vyper -f layout yourFileName.vy This outputs a JSON object detailing the locations for all state variables as determined by the compiler. To override the default storage layout for a contract: .. code:: shell $ vyper --storage-layout-file storageLayout.json yourFileName.vy The input to the ``--storage-layout-file`` flag must match the format of the ``.storage_layout`` field from the ``vyper -f layout`` command. .. _vyper-json: vyper-json ---------- ``vyper-json`` provides a JSON interface for the compiler. It expects a :ref:`JSON formatted input` and returns the compilation result in a :ref:`JSON formatted output`. To compile from JSON supplied via ``stdin``: .. code:: shell $ vyper-json To compile from a JSON file: .. code:: shell $ vyper-json yourProject.json By default, the output is sent to ``stdout``. To redirect to a file, use the ``-o`` flag: .. code:: shell $ vyper-json -o compiled.json Importing Interfaces ~~~~~~~~~~~~~~~~~~~~ ``vyper-json`` searches for imported interfaces in the following sequence: 1. Interfaces defined in the ``interfaces`` field of the input JSON. 2. Derived interfaces generated from contracts in the ``sources`` field of the input JSON. See :ref:`searching_for_imports` for more information on Vyper's import system. Online Compilers ================ Try VyperLang! ----------------- `Try VyperLang! `_ is a JupyterHub instance hosted by the Vyper team as a sandbox for developing and testing contracts in Vyper. It requires github for login, and supports deployment via the browser. Remix IDE --------- `Remix IDE `_ is a compiler and JavaScript VM for developing and testing contracts in Vyper, as well as Solidity. .. note:: While the Vyper version of the Remix IDE compiler is updated on a regular basis, it might be a bit behind the latest version found in the master branch of the repository. Make sure the byte code matches the output from your local compiler. .. _optimization-mode: Compiler Optimization Modes =========================== The Vyper CLI tool accepts an optimization mode ``"none"``, ``"codesize"``, or ``"gas"`` (default). It can be set using the ``--optimize`` flag. For example, invoking ``vyper --optimize codesize MyContract.vy`` will compile the contract, optimizing for code size. As a rough summary of the differences between gas and codesize mode, in gas optimized mode, the compiler will try to generate bytecode which minimizes gas (up to a point), including: * using a sparse selector table which optimizes for gas over codesize * inlining some constants, and * trying to unroll some loops, especially for data copies. In codesize optimized mode, the compiler will try hard to minimize codesize by * using a dense selector table * out-lining code, and * using more loops for data copies. Enabling Experimental Code Generation ===================================== When compiling, you can use the CLI flag ``--experimental-codegen`` (or its alias ``--venom-experimental``) to activate the new `Venom IR `_. Venom IR is inspired by LLVM IR and enables new advanced analysis and optimizations. .. _evm-version: Setting the Target EVM Version ============================== When you compile your contract code, you can specify the target Ethereum Virtual Machine version to compile for, to access or avoid particular features. You can specify the version either with a source code pragma or as a compiler option. It is recommended to use the compiler option when you want flexibility (for instance, ease of deploying across different chains), and the source code pragma when you want bytecode reproducibility (for instance, when verifying code on a block explorer). .. note:: If the evm version specified by the compiler options conflicts with the source code pragma, an exception will be raised and compilation will not continue. For instance, the adding the following pragma to a contract indicates that it should be compiled for the "prague" fork of the EVM. .. code-block:: vyper #pragma evm-version prague .. warning:: Compiling for the wrong EVM version can result in wrong, strange, or failing behavior. Please ensure, especially if running a private chain, that you use matching EVM versions. When compiling via the ``vyper`` CLI, you can specify the EVM version option using the ``--evm-version`` flag: .. code:: shell $ vyper --evm-version [VERSION] When using the JSON interface, you can include the ``"evmVersion"`` key within the ``"settings"`` field: .. code-block:: json { "settings": { "evmVersion": "[VERSION]" } } Target Options -------------- The following is a list of supported EVM versions, and changes in the compiler introduced with each version. Backward compatibility is not guaranteed between each version. In general, the compiler team maintains an informal policy that the compiler will support 3 years of hard fork rulesets, but this policy may be revisited as appropriate. .. py:attribute:: london .. py:attribute:: paris - ``block.difficulty`` is deprecated in favor of its new alias, ``block.prevrandao``. .. py:attribute:: shanghai - The ``PUSH0`` opcode is automatically generated by the compiler instead of ``PUSH1 0`` .. py:attribute:: cancun - The ``transient`` keyword allows declaration of variables which live in transient storage - Functions marked with ``@nonreentrant`` are protected with TLOAD/TSTORE instead of SLOAD/SSTORE - The ``MCOPY`` opcode will be generated automatically by the compiler for most memory operations. .. py:attribute:: prague (default) .. _warnings: Controlling Warnings ==================== Vyper allows suppression of warnings via the CLI flag ``-Wnone``, or promotion of (all) warnings to errors via the ``-Werror`` flag. .. code:: shell $ vyper -Wnone foo.vy # suppress warnings .. code:: shell $ vyper -Werror foo.vy # promote warnings to errors .. _integrity-hash: Integrity Hash ============== To help tooling detect whether two builds are the same, Vyper provides the ``-f integrity`` output, which outputs the integrity hash of a contract. The integrity hash is recursively defined as the sha256 of the source code with the integrity hashes of its dependencies (imports) and storage layout overrides (if provided). .. _vyper-archives: Vyper Archives ============== A Vyper archive is a compileable bundle of input sources and settings. Technically, it is a `ZIP file `_, with a special structure to make it useable as input to the compiler. It can use any suffix, but the convention is to use a ``.zip`` suffix or ``.vyz`` suffix. It must contain a ``MANIFEST/`` folder, with the following directory structure. :: MANIFEST ├── cli_settings.txt ├── compilation_targets ├── compiler_version ├── integrity ├── settings.json ├── searchpaths └── storage_layout.json [OPTIONAL] * ``cli_settings.txt`` is a text representation of the settings that were used on the compilation run that generated this archive. * ``compilation_targets`` is a newline separated list of compilation targets. Currently only one compilation is supported * ``compiler_version`` is a text representation of the compiler version used to generate this archive * ``integrity`` is the :ref:`integrity hash ` of the input contract * ``searchpaths`` is a newline-separated list of the search paths used on this compilation run * ``settings.json`` is a json representation of the settings used on this compilation run. It is 1:1 with ``cli_settings.txt``, but both are provided as they are convenient for different workflows (typically, manually vs automated). * ``storage_layout.json`` is a json representation of the storage layout overrides to be used on this compilation run. It is optional. A Vyper archive file can be produced by requesting the ``-f archive`` output format. The compiler can also produce the archive in base64 encoded form using the ``--base64`` flag. The Vyper compiler can accept both ``.vyz`` and base64-encoded Vyper archives directly as input. .. code-block:: bash $ vyper -f archive my_contract.vy -o my_contract.vyz # write the archive to my_contract.vyz $ vyper -f archive my_contract.vy --base64 > my_contract.vyz.b64 # write the archive, as base64-encoded text $ vyper my_contract.vyz # compile my_contract.vyz $ vyper my_contract.vyz.b64 # compile my_contract.vyz.b64 Compiler Input and Output JSON Description ========================================== JSON input/output is provided for compatibility with solidity, however, the recommended way is to use the aforementioned :ref:`Vyper archives `. So-called "standard json" input can be generated from a contract using the ``vyper -f solc_json`` output format. Where possible, the Vyper JSON compiler formats follow those of `Solidity `_. .. _vyper-json-input: Input JSON Description ---------------------- The following example describes the expected input format of ``vyper-json``. (Comments are not normally permitted in JSON and are used here for explanatory purposes). .. code-block:: json { // Required: Source code language. Must be set to "Vyper". "language": "Vyper", // Required // Source codes given here will be compiled. "sources": { "contracts/foo.vy": { // Optional: keccak256 hash of the source file "keccak256": "0x234...", // Required: literal contents of the source file "content": "@external\ndef foo() -> bool:\n return True" } }, // Optional // Sources given here are made available for import by the contracts // that are compiled. If the suffix is ".vy", the compiler will expect // Vyper syntax. If the suffix is "abi" the compiler will expect an // ABI object. "interfaces": { "contracts/bar.vy": { "content": "" }, "contracts/baz.json": { "abi": [] } }, // Optional // Storage layout overrides for the contracts that are compiled "storage_layout_overrides": { "contracts/foo.vy": { "a": {"type": "uint256", "slot": 1, "n_slots": 1}, "b": {"type": "uint256", "slot": 0, "n_slots": 1}, } }, // Required "settings": { "evmVersion": "prague", // EVM version to compile for. Can be london, paris, shanghai, cancun or prague (default). // optional, optimization mode // defaults to "gas". can be one of "gas", "codesize", "none", // false and true (the last two are for backwards compatibility). "optimize": "gas", // optional, whether or not the bytecode should include Vyper's signature // defaults to true "bytecodeMetadata": true, // optional, whether to use the experimental venom pipeline // defaults to false "experimentalCodegen": false, // the search paths to use for resolving imports "search_paths": [], // The following is used to select desired outputs based on file names. // File names are given as keys, a star as a file name matches all files. // Outputs can also follow the Solidity format where second level keys // denoting contract names - all 2nd level outputs are applied to the file. // // To select all possible compiler outputs: "outputSelection: { '*': ["*"] }" // Note that this might slow down the compilation process needlessly. // // The available output types are as follows: // // abi - The contract ABI // ast - Abstract syntax tree // interface - Derived interface of the contract, in proper Vyper syntax // ir - intermediate representation of the code // userdoc - Natspec user documentation // devdoc - Natspec developer documentation // evm.bytecode.object - Bytecode object // evm.bytecode.opcodes - Opcodes list // evm.bytecode.sourceMap - Source mapping (useful for debugging) // evm.deployedBytecode.object - Deployed bytecode object // evm.deployedBytecode.opcodes - Deployed opcodes list // evm.deployedBytecode.sourceMap - Deployed source mapping (useful for debugging) // evm.methodIdentifiers - The list of function hashes // layout - Storage layout of the contract // // Using `evm`, `evm.bytecode`, etc. will select every target part of that output. // Additionally, `*` can be used as a wildcard to request everything. // Note that the sourceMapFull.pc_ast_map is the recommended source map to use; // the other types are included for legacy and compatibility reasons. // "outputSelection": { "*": ["evm.bytecode", "abi"], // Enable the abi and bytecode outputs for every single contract "contracts/foo.vy": ["ast"] // Enable the ast output for contracts/foo.vy } } } .. _vyper-json-output: Output JSON Description ----------------------- The following example describes the output format of ``vyper-json``. Comments are of course not permitted and used here *only for explanatory purposes*. .. code-block:: json { // The compiler version used to generate the JSON "compiler": "vyper-0.4.0", // Optional: not present if no errors/warnings were encountered "errors": [ { // Optional: Location within the source file. "sourceLocation": { "file": "source_file.vy", "lineno": 5, "col_offset": 11 }, // Mandatory: Exception type, such as "JSONError", "StructureException", etc. "type": "TypeMismatch", // Mandatory: Component where the error originated, such as "json", "compiler", "vyper", etc. "component": "compiler", // Mandatory ("error" or "warning") "severity": "error", // Mandatory "message": "Unsupported type conversion: int128 to bool" // Optional: the message formatted with source location "formattedMessage": "line 5:11 Unsupported type conversion: int128 to bool" } ], // Optional: not present if there are no storage layout overrides "storage_layout_overrides": { "contracts/foo.vy": { "a": {"type": "uint256", "slot": 1, "n_slots": 1}, "b": {"type": "uint256", "slot": 0, "n_slots": 1}, } }, // This contains the file-level outputs. Can be limited/filtered by the outputSelection settings. "sources": { "source_file.vy": { // Identifier of the source (used in source maps) "id": 0, // The AST object "ast": {}, } }, // This contains the contract-level outputs. Can be limited/filtered by the outputSelection settings. "contracts": { "source_file.vy": { // The contract name will always be the file name without a suffix "source_file": { // The Ethereum Contract ABI. // See https://docs.soliditylang.org/en/latest/abi-spec.html "abi": [], // Natspec developer documentation "devdoc": {}, // Intermediate representation (the IR node tree as a JSON object) "ir": {}, // Natspec user documentation "userdoc": {}, // Storage layout of the contract "layout": { "storage_layout": { "variableName": { "type": "uint256", "slot": 0, "n_slots": 1 } } }, // EVM-related outputs "evm": { "bytecode": { // The bytecode as a hex string. "object": "00fe", // Opcodes list (string) "opcodes": "", // The creation source mapping. "sourceMap": { "breakpoints": [], "error_map": {}, "pc_ast_map": {}, "pc_ast_map_item_keys": [], "pc_breakpoints": [], "pc_jump_map": {}, "pc_pos_map": {}, // The creation source mapping as a string. "pc_pos_map_compressed": "" } }, "deployedBytecode": { // The deployed bytecode as a hex string. "object": "00fe", // Deployed opcodes list (string) "opcodes": "", // The deployed source mapping. "sourceMap": { "breakpoints": [], "error_map": {}, "pc_ast_map": {}, "pc_ast_map_item_keys": [], "pc_breakpoints": [], "pc_jump_map": {}, "pc_pos_map": {}, // The deployed source mapping as a string. "pc_pos_map_compressed": "" } }, // The list of function hashes "methodIdentifiers": { "delegate(address)": "5c19a95c" } } } } } } Errors ~~~~~~ Each error includes a ``component`` field, indicating the stage at which it occurred: * ``json``: Errors that occur while parsing the input JSON. Usually, a result of invalid JSON or a required value that is missing. * ``parser``: Errors that occur while parsing the contracts. Usually, a result of invalid Vyper syntax. * ``compiler``: Errors that occur while compiling the contracts. * ``vyper``: Unexpected errors that occur within Vyper. If you receive an error of this type, please open an issue. You can also use the ``--traceback`` flag to receive a standard Python traceback when an error is encountered. --- ## File: docs/constants-and-vars.rst Environment Variables and Constants ################################### .. _types-env-vars: Environment Variables ===================== Environment variables always exist in the namespace and are primarily used to provide information about the blockchain or current transaction. Block and Transaction Properties -------------------------------- ===================== ================ ========================================================= Name Type Value ===================== ================ ========================================================= ``block.coinbase`` ``address`` Current block miner's address ``block.difficulty`` ``uint256`` Current block difficulty ``block.prevrandao`` ``bytes32`` Current randomness beacon provided by the beacon chain ``block.number`` ``uint256`` Current block number ``block.gaslimit`` ``uint256`` Current block's gas limit ``block.basefee`` ``uint256`` Current block's base fee ``block.blobbasefee`` ``uint256`` Current block's blob gas base fee ``block.prevhash`` ``bytes32`` Equivalent to ``blockhash(block.number - 1)`` ``block.timestamp`` ``uint256`` Current block epoch timestamp ``chain.id`` ``uint256`` Chain ID ``msg.data`` ``Bytes`` Message data ``msg.gas`` ``uint256`` Remaining gas ``msg.mana`` ``uint256`` Remaining gas (alias for ``msg.gas``) ``msg.sender`` ``address`` Sender of the message (current call) ``msg.value`` ``uint256`` Number of wei sent with the message ``tx.origin`` ``address`` Sender of the transaction (full call chain) ``tx.gasprice`` ``uint256`` Gas price of current transaction in wei ===================== ================ ========================================================= .. note:: ``block.prevrandao`` is an alias for the ``block.difficulty`` opcode. Since ``block.difficulty`` is considered deprecated according to `EIP-4399 `_ after "The Merge" (Paris hard fork), we recommend using ``block.prevrandao``. .. note:: ``msg.data`` requires the usage of :func:`slice ` to explicitly extract a section of calldata. If the extracted section exceeds the bounds of calldata, this will throw. You can check the size of ``msg.data`` using :func:`len `. .. _constants-self: The self Variable ----------------- ``self`` is an environment variable used to reference a contract from within itself. Along with the normal :ref:`address
` members, ``self`` allows you to read and write to state variables and to call internal functions within the contract. ==================== ================ ========================== Name Type Value ==================== ================ ========================== ``self`` ``address`` Current contract's address ``self.balance`` ``uint256`` Current contract's balance ==================== ================ ========================== Accessing State Variables ~~~~~~~~~~~~~~~~~~~~~~~~~ ``self`` is used to access a contract's :ref:`state variables`, as shown in the following example: .. code-block:: vyper state_var: uint256 @external def set_var(value: uint256) -> bool: self.state_var = value return True @external @view def get_var() -> uint256: return self.state_var Calling Internal Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ ``self`` is also used to call :ref:`internal functions` within a contract: .. code-block:: vyper @internal def _times_two(amount: uint256) -> uint256: return amount * 2 @external def calculate(amount: uint256) -> uint256: return self._times_two(amount) .. _types-constants: Custom Constants ================ Custom constants can be defined at a global level in Vyper. To define a constant, make use of the ``constant`` keyword. .. code-block:: vyper TOTAL_SUPPLY: constant(uint256) = 10000000 total_supply: public(uint256) @deploy def __init__(): self.total_supply = TOTAL_SUPPLY --- ## File: docs/contributing.rst .. _contributing: Contributing ############ Help is always appreciated! To get started, you can try `installing Vyper `_ in order to familiarize yourself with the components of Vyper and the build process. Also, it may be useful to become well-versed at writing smart-contracts in Vyper. Types of Contributions ====================== In particular, we need help in the following areas: * Improving the documentation * Responding to questions from other users on `StackExchange `_ and `Discussions `_ * Add to the discussions on the `Vyper (Smart Contract Programming Language) Discord `_ * Suggesting Improvements * Fixing and responding to `Vyper's GitHub issues `_ How to Suggest Improvements =========================== To suggest an improvement, please create a Vyper Improvement Proposal (VIP for short) using the `VIP Template `_. How to Report Issues ==================== To report an issue, please use the `GitHub issues tracker `_. When reporting issues, please mention the following details: * Which version of Vyper you are using * What was the source code (if applicable) * Which platform are you running on * Your operating system name and version * Detailed steps to reproduce the issue * What was the result of the issue * What the expected behaviour is Reducing the source code that caused the issue to a bare minimum is always very helpful and sometimes even clarifies a misunderstanding. Fix Bugs ======== Find or report bugs at our `issues page `_. Anything tagged with "bug" is open to whoever wants to implement it. Style Guide =========== Our :ref:`style guide` outlines best practices for the Vyper repository. Please ask us on the `Vyper (Smart Contract Programming Language) Discord `_ ``#compiler-dev`` channel if you have questions about anything that is not outlined in the style guide. Workflow for Pull Requests ========================== In order to contribute, please fork off of the ``master`` branch and make your changes there. Your commit messages should detail *why* you made your change in addition to *what* you did (unless it is a tiny change). If you need to pull in any changes from ``master`` after making your fork (for example, to resolve potential merge conflicts), please avoid using ``git merge`` and instead, ``git rebase`` your branch. Commit Messages --------------- For guidance on writing good commit messages, see `How to Write a Git Commit Message `_. To ensure your commit message is properly formatted (wrapped at 72 characters), use the included formatter: 1. Write your commit message in a text file 2. Run ``python fmt_commit_msg.py commitmsg.txt`` (this formats the file in-place) 3. Paste the formatted message in your PR description, wrapped in triple backticks The maintainer will use this message when squash-merging your PR. Implementing New Features ------------------------- If you are writing a new feature, please ensure you write appropriate Pytest test cases and place them under ``tests/``. If you are making a larger change, please consult first with the `Vyper (Smart Contract Programming Language) Discord `_ ``#compiler-dev`` channel. Although we do CI testing, please make sure that the tests pass for supported Python version and ensure that it builds locally before submitting a pull request. Thank you for your help! --- ## File: docs/control-structures.rst .. _control-structures: Control Structures ################## .. _control-structures-functions: Functions ========= Functions are executable units of code within a contract. Functions may only be declared within a contract's :ref:`module scope `. .. code-block:: vyper @external def bid(): ... Functions may be called internally or externally depending on their :ref:`visibility `. Functions may accept input arguments and return variables in order to pass values between them. Visibility ---------- .. _function-visibility: You can optionally declare a function's visibility by using a :ref:`decorator `. There are three visibility levels in Vyper: * ``@external``: exposed in the selector table, can be called by an external call into this contract * ``@internal`` (default): can be invoked only from within this contract. Not available to external callers * ``@deploy``: constructor code. This is code which is invoked once in the lifetime of a contract, upon its deploy. It is not available at runtime to either external callers or internal call invocations. At this time, only the :ref:`__init__() function ` may be marked as ``@deploy``. .. _structure-functions-external: External Functions ****************** External functions (marked with the ``@external`` decorator) are a part of the contract interface and may only be called via transactions or from other contracts. .. code-block:: vyper @external def add_seven(a: int128) -> int128: return a + 7 @external def add_seven_with_overloading(a: uint256, b: uint256 = 3) -> uint256: return a + b A Vyper contract cannot call directly between two external functions. If you must do this, you can use an :ref:`interface `. External functions can use the ``@raw_return`` decorator to return raw bytes without ABI-encoding: .. code-block:: vyper @external @payable @raw_return def proxy_call(target: address) -> Bytes[128]: # Forward a call and return the raw response without ABI-encoding return raw_call( target, msg.data, is_delegate_call=True, max_outsize=128, value=msg.value ) .. note:: For external functions with default arguments like ``def my_function(x: uint256, b: uint256 = 1)`` the Vyper compiler will generate ``N+1`` overloaded function selectors based on ``N`` default arguments. Consequently, the ABI signature for a function (this includes interface functions) excludes optional arguments when their default values are used in the function call. .. code-block:: vyper from ethereum.ercs import IERC4626 @external def foo(x: IERC4626): extcall x.withdraw(0, self, self) # keccak256("withdraw(uint256,address,address)")[:4] = 0xb460af94 extcall x.withdraw(0) # keccak256("withdraw(uint256)")[:4] = 0x2e1a7d4d .. _structure-functions-internal: Internal Functions ****************** Internal functions (optionally marked with the ``@internal`` decorator) are only accessible from other functions within the same contract. They are invoked via the :ref:`self` object: .. code-block:: vyper def _times_two(amount: uint256) -> uint256: return amount * 2 @external def calculate(amount: uint256) -> uint256: return self._times_two(amount) Or for internal functions which are defined in :ref:`imported modules `, they are invoked by prefixing the name of the module to the function name: .. code-block:: vyper import calculator_library @external def calculate(amount: uint256) -> uint256: return calculator_library._times_two(amount) Marking an internal function as ``payable`` specifies that the function can interact with ``msg.value``. A ``nonpayable`` internal function can be called from an external ``payable`` function, but it cannot access ``msg.value``. .. code-block:: vyper @payable def _foo() -> uint256: return msg.value % 2 .. note:: As of v0.4.0, the ``@internal`` decorator is optional. That is, functions with no visibility decorator default to being ``internal``. .. note:: Please note that for ``internal`` functions which use more than one default parameter, Vyper versions ``>=0.3.8`` are recommended due to the security advisory `GHSA-ph9x-4vc9-m39g `_. The ``__init__`` Function ------------------------- .. _init-function: The ``__init__()`` function, also known as the constructor, is a special initialization function that is only called at the time of deploying a contract. It can be used to set initial values for storage or immutable variables. It must be declared with the ``@deploy`` decorator. A common use case is to set an ``owner`` variable with the creator of the contract: .. code-block:: vyper owner: address @deploy def __init__(): self.owner = msg.sender Additionally, :ref:`immutable variables ` may only be set within the constructor. Mutability ---------- .. _function-mutability: You can optionally declare a function's mutability by using a :ref:`decorator `. There are four mutability levels: * ``@pure``: does not read from the contract state or any environment variables. * ``@view``: may read from the contract state, but does not alter it. * ``@nonpayable`` (default): may read from and write to the contract state, but cannot receive Ether. * ``@payable``: may read from and write to the contract state, and can receive and access Ether via ``msg.value``. .. code-block:: vyper @view @external def readonly(): # this function cannot write to state ... @payable @external def send_me_money(): # this function can receive ether ... Functions default to ``nonpayable`` when no mutability decorator is used. Functions marked with ``@view`` cannot call mutable (``payable`` or ``nonpayable``) functions. Any external calls are made using the special ``STATICCALL`` opcode, which prevents state changes at the EVM level. Functions marked with ``@pure`` cannot call non-``pure`` functions. .. note:: The ``@nonpayable`` decorator is not strictly enforced on ``internal`` functions when they are invoked through an ``external`` ``payable`` function. As a result, an ``external`` ``payable`` function can invoke an ``internal`` ``nonpayable`` function. However, the ``nonpayable`` ``internal`` function cannot have access to ``msg.value``. Nonreentrancy Locks ------------------- .. _reentrancy: The ``@nonreentrant`` decorator places a global nonreentrancy lock on a function. An attempt by an external contract to call back into any other ``@nonreentrant`` function causes the transaction to revert. .. code-block:: vyper @external @nonreentrant def make_a_call(_addr: address): # this function is protected from re-entrancy ... Nonreentrancy locks work by setting a specially allocated storage slot to a ```` value on function entrance, and setting it to an ```` value on function exit. On function entrance, if the storage slot is detected to be the ```` value, execution reverts. You cannot put the ``@nonreentrant`` decorator on a ``pure`` function. You can put it on a ``view`` function, but it only checks that the function is not in a callback (the storage slot is not in the ```` state), as ``view`` functions can only read the state, not change it. You can put the ``@nonreentrant`` decorator on a ``__default__`` function, but keep in mind that this will result in the contract rejecting ETH payments from callbacks. You can view where the nonreentrant key is physically laid out in storage by using ``vyper`` with the ``-f layout`` option (e.g., ``vyper -f layout foo.vy``). Unless it is overridden, the compiler will allocate it at slot ``0``. .. note:: A mutable function can protect a ``view`` function from being called back into (which is useful for instance, if a ``view`` function would return inconsistent state during a mutable function), but a ``view`` function cannot protect itself from being called back into. Note that mutable functions can never be called from a ``view`` function because all external calls out from a ``view`` function are protected by the use of the ``STATICCALL`` opcode. .. note:: A nonreentrant lock has an ```` value of 3, and a ```` value of 2. Nonzero values are used to take advantage of net gas metering - as of the Berlin hard fork, the net cost for utilizing a nonreentrant lock is 2300 gas. Prior to v0.3.4, the ```` and ```` values were 0 and 1, respectively. .. note:: Prior to 0.4.0, nonreentrancy keys took a "key" argument for fine-grained nonreentrancy control. As of 0.4.0, only a global nonreentrancy lock is available. The nonreentrant pragma ----------------------- Beginning in 0.4.2, the ``#pragma nonreentrancy on`` pragma is available, and it enables nonreentrancy on all external functions and public getters (except for ``constants`` and ``immutables``) in the file. This is to prepare for a future release, probably in the 0.5.x series, where nonreentrant locks will be enabled by default language-wide. When the pragma is on, to re-enable reentrancy for a specific function, add the ``@reentrant`` decorator. For getters, add the ``reentrant()`` modifier. Here is an example: .. code-block:: vyper # pragma nonreentrancy on x: public(uint256) # this is protected from view-only reentrancy y: public(reentrant(uint256)) # this is not protected from view-only reentrancy @external def make_a_call(addr: address): # this function is protected from re-entrancy ... @external @reentrant def callback(addr: address): # this function is allowed to be reentered into ... @external def __default__(): # this function is nonreentrant! ... The default is ``#pragma nonreentrancy off``, which can be used to signal specifically that nonreentrancy protection is off in this file. Note that the same caveats about nonreentrancy on ``__default__()`` as mentioned in the previous section apply here, since the ``__default__()`` function will be nonreentrant by default with the pragma on. With the pragma on, internal functions remain unlocked by default but can still use the ``@nonreentrant`` decorator. External ``view`` functions are protected by default (as before, checking the lock upon entry but only reading its state). External ``pure`` functions do not interact with the lock. Internal functions, ``__init__`` function and getters for ``constants`` and ``immutables`` can be marked ``reentrant``. Reentrant behavior is the default for these structures anyway, and this feature can be used to explicitly highlight the fact. .. note:: All the protected functions share the same, global lock. .. note:: Vyper disallows calling a ``nonreentrant`` function from another ``nonreentrant`` function, since the compiler implements nonreentrancy as a global lock which is acquired at function entry. .. note:: The ``nonreentrancy on/off`` pragma is scoped to the current file. If you import a file without the ``nonreentrancy on`` pragma, the functions in that file will behave as the author intended, that is, they will be reentrant unless marked otherwise. .. note:: The ``constant`` and ``immutable`` state variable getters don't check the lock because the value of the variables can't change. The ``__default__`` Function ---------------------------- A contract can also have a default function, which is executed on a call to the contract if no other functions match the given function identifier (or if none was supplied at all, such as through someone sending it Eth). It is the same construct as fallback functions `in Solidity `_. This function is always named ``__default__``. It must be annotated with ``@external``. It cannot expect any input arguments. If the function is annotated as ``@payable``, this function is executed whenever the contract is sent Ether (without data). This is why the default function cannot accept arguments - it is a design decision of Ethereum to make no differentiation between sending ether to a contract or a user address. .. code-block:: vyper event Payment: amount: uint256 sender: indexed(address) @external @payable def __default__(): log Payment(msg.value, msg.sender) Considerations ************** Just as in Solidity, Vyper generates a default function if one isn't found, in the form of a ``REVERT`` call. Note that this rolls back state changes, and thus will not succeed in receiving funds. Ethereum specifies that the operations will be rolled back if the contract runs out of gas in execution. ``send`` calls to the contract come with a free stipend of 2300 gas, which does not leave much room to perform other operations except basic logging. **However**, if the sender includes a higher gas amount through a ``call`` instead of ``send``, then more complex functionality can be run. It is considered a best practice to ensure your payable default function is compatible with this stipend. The following operations will consume more than 2300 gas: * Writing to storage * Creating a contract * Calling an external function which consumes a large amount of gas * Sending Ether Lastly, although the default function receives no arguments, it can still access the ``msg`` object, including: * the address of who is interacting with the contract (``msg.sender``) * the amount of ETH sent (``msg.value``) * the gas provided (``msg.gas``). .. _function-decorators: Decorators Reference -------------------- =============================== =========================================================== Decorator Description =============================== =========================================================== ``@external`` Function can only be called externally, it is part of the runtime selector table ``@internal`` Function can only be called within current contract ``@deploy`` Function is called only at deploy time ``@pure`` Function does not read contract state or environment variables ``@view`` Function does not alter contract state ``@payable`` Function is able to receive Ether ``@nonreentrant`` Function cannot be called back into during an external call ``@raw_return`` Function returns raw bytes without ABI-encoding (``@external`` functions only) ``@abstract`` Function body must be ``...``; an ``@override`` must provide the implementation (see :ref:`abstract-modules`) ``@override(module)`` Function provides the implementation for an ``@abstract`` function in ``module`` (see :ref:`abstract-modules`) =============================== =========================================================== Raw Return ---------- The ``@raw_return`` decorator allows a function to return raw bytes without ABI-encoding. This is particularly useful for proxy contracts and other helper contracts where you want to forward the exact output bytes from another contract call without adding an additional layer of ABI-encoding. .. code-block:: vyper @external @payable @raw_return def forward_call(target: address) -> Bytes[1024]: # Returns the raw bytes from the external call without ABI-encoding return raw_call(target, msg.data, max_outsize=1024, value=msg.value, is_delegate_call=True) The ``@raw_return`` decorator has the following restrictions: * It can only be used on ``@external`` functions * The function must have a ``Bytes[N]`` return type * It cannot be used on ``@deploy`` (constructor) functions (you can however use it in the ``__default__()`` function) * It cannot be used on ``@internal`` functions When a function is marked with ``@raw_return``, the compiler directly returns the bytes value using the EVM ``RETURN`` opcode, bypassing the normal ABI-encoding that would wrap the bytes in a ``(bytes)`` tuple. .. note:: The ``@raw_return`` decorator cannot be used in interface definitions (``.vyi`` files). Note that to call a ``@raw_return`` function from another contract, you should use ``raw_call`` instead of an interface call, since the return data may not be ABI-encoded. .. warning:: When using ``@raw_return``, ensure all return paths in your function use raw bytes. Having multiple return statements where some use ABI-encoded data and others don't can lead to decoding errors. ``if`` statements ================= The ``if`` statement is a control flow construct used for conditional execution: .. code-block:: vyper if CONDITION: ... ``CONDITION`` is a boolean or boolean operation. The boolean is evaluated left-to-right, one expression at a time, until the condition is found to be true or false. If true, the logic in the body of the ``if`` statement is executed. Note that unlike Python, Vyper does not allow implicit conversion from non-boolean types within the condition of an ``if`` statement. ``if 1: pass`` will fail to compile with a type mismatch. You can also include ``elif`` and ``else`` statements, to add more conditional statements and a body that executes when the conditionals are false: .. code-block:: vyper if CONDITION: ... elif OTHER_CONDITION: ... else: ... ``for`` loops ============= The ``for`` statement is a control flow construct used to iterate over a value: .. code-block:: vyper for i: in : ... The iterated value can be a static array, a dynamic array, or generated from the built-in ``range`` function. Array Iteration --------------- You can use ``for`` to iterate through the values of any array variable: .. code-block:: vyper foo: int128[3] = [4, 23, 42] for i: int128 in foo: ... In the above, example, the loop executes three times with ``i`` assigned the values of ``4``, ``23``, and then ``42``. You can also iterate over a literal array, as long as the annotated type is valid for each item in the array: .. code-block:: vyper for i: int128 in [4, 23, 42]: ... Some restrictions: * You cannot iterate over a multi-dimensional array. ``i`` must always be a base type. * You cannot modify a value in an array while it is being iterated, or call to a function that might modify the array being iterated. Range Iteration --------------- Ranges are created using the ``range`` function. The following examples are valid uses of ``range``: .. code-block:: vyper for i: uint256 in range(STOP): ... ``STOP`` is a literal integer greater than zero. ``i`` begins as zero and increments by one until it is equal to ``STOP``. ``i`` must be of the same type as ``STOP``. .. code-block:: vyper for i: uint256 in range(stop, bound=N): ... Here, ``stop`` can be a variable with integer type, greater than zero. ``N`` must be a compile-time constant. ``i`` begins as zero and increments by one until it is equal to ``stop``. If ``stop`` is larger than ``N``, execution will revert at runtime. In certain cases, you may not have a guarantee that ``stop`` is less than ``N``, but still want to avoid the possibility of runtime reversion. To accomplish this, use the ``bound=`` keyword in combination with ``min(stop, N)`` as the argument to ``range``, like ``range(min(stop, N), bound=N)``. This is helpful for use cases like chunking up operations on larger arrays across multiple transactions. ``i``, ``stop`` and ``N`` must be of the same type. Another use of range can be with ``START`` and ``STOP`` bounds. .. code-block:: vyper for i: uint256 in range(START, STOP): ... Here, ``START`` and ``STOP`` are literal integers, with ``STOP`` being a greater value than ``START``. ``i`` begins as ``START`` and increments by one until it is equal to ``STOP``. ``i``, ``START`` and ``STOP`` must be of the same type. Finally, it is possible to use ``range`` with runtime `start` and `stop` values as long as a constant `bound` value is provided. In this case, Vyper checks at runtime that `end - start <= bound`. ``N`` must be a compile-time constant. ``i``, ``stop`` and ``N`` must be of the same type. .. code-block:: vyper for i: uint256 in range(start, end, bound=N): ... --- ## File: docs/deploying-contracts.rst .. index:: deploying;deploying; .. _deploying: Deploying a Contract ******************** Once you are ready to deploy your contract to a public test net or the main net, you have several options: * Take the bytecode generated by the vyper compiler and deploy it through geth or another Ethereum client: .. code-block:: bash vyper yourFileName.vy # returns bytecode * Take the byte code and ABI and deploy it with your current browser on `myetherwallet's `_ contract menu: .. code-block:: bash vyper -f abi yourFileName.vy # returns ABI * Use `Titanoboa `_: .. code-block:: python import boa boa.set_network_env() from eth_account import Account # in a real codebase, always load private keys safely from an encrypted store! boa.env.add_account(Account()) deployer = boa.load_partial("yourFileName.vy") deployer.deploy() * Use the development environment provided at https://try.vyperlang.org to compile and deploy your contract on your net of choice. try.vyperlang.org comes "batteries-included", with Titanoboa pre-installed, and browser signer integration as well. --- ## File: docs/event-logging.rst .. _event-logging: Event Logging ############# Vyper can log events to be caught and displayed by user interfaces. Example of Logging ================== This example is taken from the `sample ERC20 contract `_ and shows the basic flow of event logging: .. code-block:: vyper # Events of the token. event Transfer: sender: indexed(address) receiver: indexed(address) value: uint256 event Approval: owner: indexed(address) spender: indexed(address) value: uint256 # Transfer some tokens from message sender to another address @external def transfer(_to : address, _value : uint256) -> bool: ... Logic here to do the real work ... # All done, log the event for listeners log Transfer(sender=msg.sender, receiver=_to, value=_value) Let's look at what this is doing. 1. We declare two event types to log. The two events are similar in that they contain two indexed address fields. Indexed fields do not make up part of the event data itself, but can be searched by clients that want to catch the event. Also, each event contains one single data field, in each case called ``value``. Events can contain several arguments with any names desired. 2. In the ``transfer`` function, after we do whatever work is necessary, we log the event. We pass three arguments, corresponding with the three arguments of the Transfer event declaration. Clients listening to the events will declare and handle the events they are interested in using a `library such as web3.js `_: .. code-block:: javascript var abi = /* abi as generated by the compiler */; var MyToken = web3.eth.contract(abi); var myToken = MyToken.at("0x1234...ab67" /* address */); // watch for changes in the callback var event = myToken.Transfer(function(error, result) { if (!error) { var args = result.returnValues; console.log('value transferred = ', args._amount); } }); In this example, the listening client declares the event to listen for. Any time the contract sends this log event, the callback will be invoked. Declaring Events ================ Let's look at an event declaration in more detail. .. code-block:: vyper event Transfer: sender: indexed(address) receiver: indexed(address) value: uint256 The EVM currently has five opcodes for emitting event logs: ``LOG0``, ``LOG1``, ``LOG2``, ``LOG3``, and ``LOG4``. These opcodes can be used to create log records, where each log record consists of both **topics** and **data**. Topics are 32-byte ''words'' that are used to describe what is happening in an event. While topics are searchable, data is not. Event data is however not limited, which means that you can include large or complicated data like arrays or strings. Different opcodes (``LOG0`` through ``LOG4``) allow for different numbers of topics. For instance, ``LOG1`` includes one topic, ``LOG2`` includes two topics, and so on. Event declarations look similar to struct declarations, containing one or more arguments that are passed to the event. Typical events will contain two kinds of arguments: * **Indexed** arguments (topics), which can be searched for by listeners. Each indexed argument is identified by the ``indexed`` keyword. Here, each indexed argument is an address. You can have up to four indexed arguments (``LOG4``), but indexed arguments are not passed directly to listeners, although some of this information (such as the sender) may be available in the listener's `results` object. * **Value** arguments (data), which are passed through to listeners. You can have any number of value arguments and they can have arbitrary names. Note that the first topic of a log record consists of the signature of the name of the event that occurred, including the types of its parameters. It is also possible to create an event with no arguments. In this case, use the ``pass`` statement: .. code-block:: vyper event Foo: pass Logging Events ============== Once an event is declared, you can log (send) events. You can send events as many times as you want to. Please note that events are stored in transaction logs rather than contract state storage, making them significantly cheaper than storage operations. However, the drawback is that events are not available to contracts, only to clients. Logging events is done using the ``log`` statement: .. code-block:: vyper log Transfer(sender=msg.sender, receiver=_to, value=_value) The types of arguments given must match those used when declaring the event. When using keyword arguments (as shown above), the order does not matter. Listening for Events ==================== In the example listener above, the ``result`` arg actually passes a `large amount of information `_. Here we're most interested in ``result.returnValues``. This is an object with properties that match the properties declared in the event. Note that this object does not contain the indexed properties, which can only be searched in the original ``myToken.Transfer`` that created the callback. --- ## File: docs/index.rst .. image:: _static/logo-dark.svg :class: dark-only :alt: Vyper logo :align: center .. image:: _static/logo-light.svg :class: light-only :alt: Vyper logo :align: center Overview ######## Vyper is a Pythonic smart contract language that compiles to `Ethereum Virtual Machine (EVM) `_ bytecode. It prioritises **security**, **auditability**, and **simplicity**. .. _design-principles: Principles ========== * **Security**: Building secure smart contracts should be natural, not an uphill battle. * **Simplicity**: Both the language and compiler should be easy to understand. * **Auditability**: Code should be maximally human-readable. Simplicity for the reader matters more than convenience for the writer. Key Features ============ **Safety by default** * Bounds and overflow checking on array accesses and arithmetic * Reentrancy protection via the ``@nonreentrant`` decorator (see :ref:`control-structures`) * Strong typing with explicit :ref:`type conversions ` **Predictable execution** * Decidable gas consumption: every function call has a calculable upper bound * Bounded loops only (compile-time maximum iterations) * No recursion: execution flow is structurally decreasing **Clean code reuse** * :ref:`Module imports ` instead of class inheritance * Explicit ``extcall`` and ``staticcall`` keywords for external contract interactions * Support for :ref:`pure functions ` that cannot modify state Compiler-Enforced Security ========================== Vyper eliminates entire vulnerability classes by excluding features that enable dangerous patterns: .. list-table:: :header-rows: 1 :widths: 25 75 * - Excluded Feature - Why It Matters * - Inline assembly - Preserves type safety, overflow protection, and searchability of variable usage * - Class inheritance - Removes ambiguity about which code executes and simplifies auditing * - Modifiers - All checks are inline and visible, no hidden pre/post conditions * - Function overloading - Function calls are unambiguous; ``foo(x)`` always means the same thing * - Operator overloading - Arithmetic operators do exactly what they appear to do * - Infinite loops - Gas costs are always bounded and predictable * - Recursive calls - Call graphs are simple and gas limits are enforceable These constraints mean developers cannot accidentally introduce dangerous patterns, even under time pressure or with limited blockchain experience. Deep Verification ================= Vyper’s design makes **deep verification** practical on a production smart-contract language. See :doc:`deep-verification` for the full discussion of verification depth, verification gap, and the current state of Vyper’s formal semantics and compiler verification work. Decimal Fixed Point =================== Vyper uses decimal (not binary) fixed point numbers. This ensures that literals like ``0.1`` have exact representations, avoiding the subtle precision errors common in binary floating-point arithmetic.