Solidity tutorial: all about functions

Алан-э-Дейл       14.02.2023 г.

Оглавление

Ethereum

Язык Solidity разработала команда Ethereum, которая на нем же и создала блокчейн-платформу. Сейчас сеть Ethereum является ведущей в мире среди проектов, работающих на смарт-контрактах. Ethereum создан в 2014, а его создателем стал Виталик Бутерин – одна из самых влиятельных персон в криптоиндустрии.

Ethereum предоставляет экосистему для разработки автономных децентрализованных приложений (DApps) и на ее основе были созданы крупнейшие DeFi-протоколы, такие как Uniswap, MakerDAO, Compound, Aave и многие другие. На самом деле, для Ethereum это не является преимуществом, поскольку чем больше приложений использует Ethereum, тем сильнее будет загружена сеть.

Стремительный рост популярности DeFi наглядно это продемонстрировал: из-за высокой пользовательской активности стоимость транзакций достигла небывалых высот, а иногда комиссии превышали $100 за транзакцию.

Платформу поддерживает огромное комьюнити, которое сформировалось за 7 лет существования Ethereum. Несмотря на такую популярность, сеть Эфира обладает проблемами с масштабируемостью, что приводит к медленным и дорогостоящим транзакциям.

Пока разработчики пытаются решить проблему, работая над обновлением Ethereum 2.0. Обновленная платформа будет полностью функционировать на алгоритме консенсуса Proof-of-Stake (PoS), а в основе протокола будет заложен дефляционный механизм, появившийся в сети после хардфорка London. Это значит, что часть монет, оплаченных за Gas, будут безвозвратно сжигаться, а эмиссия ETH – уменьшаться, соответственно.

Avalanche

Avalanche – открытая децентрализованная платформа для создания блокчейн-сетей и приложений на основе Ethereum, созданная компанией Ava Labs. Платформа Avalanche ставит своей целью сместить Ethereum как основную сеть для запуска децентрализованных приложений.

Разработчики Avalanche создали собственную экосистему DeFi

Это привлекло внимание криптоэнтузиастов, в результате чего AVAX стал одним из самых быстрорастущих токенов в 2020 году. Известные криптопроекты, такие как bZx, Reef, SushiSwap и TrueUSD, интегрировали свои решения с платформой Avalanche

Ядром архитектуры Avalanche выступает подсеть (subnetwork), называемой также Primary Network, которая представляет собой группу валидаторов, обеспечивающих безопасность всей сети, подтверждающих транзакции и добавляющие блоки.

Primary Network состоит из трех блокчейнов:

  • X-Chain – платформа для выпуска и торговли криптоактивами (токенами).
  • P-Chain – блокчейн, который координирует работу валидаторов, позволяет создавать новые подсети и пользовательские блокчейны.
  • C-Chain – блокчейн, упрощающий создание смарт-контрактов.

Разработчики представили собственную виртуальную машину Avalanche Virtual Machine (AVM) и алгоритм консенсуса Proof-of-Stake под названием Snowball. Основное отличие от классического PoS в том, что Snowball полностью отменяет награды, если валидаторы ведут себя злонамеренно, вместо того, чтобы урезать их. Хотя концепция кажется интересной, блокчейн-эксперты не уверены в том, что Avalanche представляет серьезную угрозу для Ethereum.

Contributing / Issues / Requests

Credits

Many thanks to:

Christian Reitwiessner and the Ethereum team for Solidity https://github.com/ethereum/solidity

Raghav Dua and everyone that contributed to Solium, the solidity linter, and the solidity parser.

Ilya Drabenia for creating the Solhint linter and the integration into the extension.

Nexus team for the original creation of the dappfile to structure contracts in projects https://github.com/nexusdev/dapple.

Beau Gunderson for contributing the initial integration of solium https://github.com/juanfranblanco/vscode-solidity/issues/24, the initial server and error mappings.

Mattia Richetto, Klaus Hott Vidal and Franco Victorio for creating the Prettier Solidity plugin and of course all the developers of Prettier. Please go to https://github.com/prettier-solidity/prettier-plugin-solidity for help and collaboration.

Bram Hoven for starting the multiple package dependency support for different environments (node_modules, lib)

Piotr Szlachciak for refactoring the syntaxes

James Lefrere for further refactoring the syntaxes.

Forest Fang for providing the implementation of the «Go to definition», allowing you to navigate to structs, contracts, functions calls, etc

Bernardo Vieira for adding the capability to read the solium settings from a file in the workspace root directory.

Mirko Garozzo and Rocky Bernstein for the work on creating and integrating the Mythx api to analyse smart contracts (OBSOLETE NOW)

Nick Addison, Elazar Gershuni, Joe Whittles, Iñigo Villalba, Thien Toan, Jonathan Carter, Stefan Lew, Nikita Savchenko, Josh Stevens, Paul Berg for their contributions.

Sebastian Bürgel for keeping reminding me of the offline installation suppport

David Krmpotic and Ralph Pichler for the original Sublime extension
https://github.com/davidhq/SublimeEthereum

Everyone for their support and feedback!

Окончательный запрет устаревших конструкций

В Solidity накопилось довольно много устаревших конструкций, которые хотелось бы удалить из языка, но все никак не удается из-за обратной совместимости. В эту категорию изменений попадают:

  • Отказ от в пользу //. Механизм откатывания транзакции отличается от механизма исключений, и хочется подчеркнуть эту разницу на уровне языка.
  • Отказ от , который с учетом правил вывода типов легко приводит к ошибкам, например:
    Дополнительно обсуждают, на что заменить конструкции вроде
    и как поэлегантнее пропускать ненужные значения.
  • Запретили использовать для функций — всюду должно быть view или pure.
  • Встроенная вместо . Так понятнее, что это не какая-то константа, а оставшееся количество газа. Да, можно переопределить.
  • Перенесли в . Логично, ведь текущего блока недоступен ().
  • Запретили смешивать шестнадцатеричные константы и множители времени/эфира. В самом деле, не совсем понятно, что такое .
  • Отказались от / в inline assembly.
  • Отказ от унарного плюса, потому что он не имеет какой-то специальной роли и может участвовать в глупых ошибках (вроде вместо ).
  • Планируется отказ от множителя , потому что сейчас он определен как , и это не слишком точно соотносится с привычным календарем. Мне это представляется спорным решением — казалось бы, пока можно ограничиться предупреждением.

Более строгий синтаксис

В Solidity очень разные по смыслу конструкции имеют схожий синтаксис. Это мешает читать код, но еще больше это портит жизнь разработчикам инструментов для работы с исходниками (это касается компилятора в том числе). Приятно видеть, что работы ведутся и в этом направлении тоже.

  • Обязательное ключевое слово при генерации событий.
    Создание эвента синтаксически не отличалось от вызова функции (и создания структуры). Особенно ярко эта проблема проявлялась в стандарте ERC20, в котором есть функция и эвент с одинаковой “сигнатурой”.
  • Новый синтаксис для конструкторов:.
    С выходом 0.5.0 это будет единственный вариант — функции, чьи имена совпадают с контрактом, запрещены.
    Это изменение решает проблему переименования файлов, когда конструктор внезапно превращается в обычную функцию и его можно вызывать повторно или не вызывать вовсе.
    Более обоснованным это решение выглядит, если вспомнить, что констрктор может быть только или , не может быть или , не может иметь возвращаемых значений, т.е. является особой сущностью.
    Любопытно, что при этом было открыто issue с предложением разрешить одноименные контракту функции в 0.6.0.
  • Изменение правил видимости локальных переменных — с принятых в Javascript на C99/C++.
    Мое любимое. Ничего не могу с собой сделать, каждый раз радуюсь, когда показываю, как компилируется код
  • Принудительное включение строгого режима для ассемблера. Он и сейчас доступен с опцией компилятора . В нем ограничены манипуляции со стеком и недоступны метки и переходы — вместо них предлагается использовать более привычные управляющие конструкции вроде или .
  • Запретили использовать адреса без чек-суммы или неправильной длины (отличной от 20 байт). Неплохая идея, хотя с непривычки и вызовет трудности — придется срочно учиться писать адреса с чек-суммой, а вместо привычного использовать .
  • Запретили объявлять пустые структуры (). Не очень-то и хотелось, но раньше грамматика такое позволяла.

Strings

Please be aware that some of these functions can be quite gas heavy so use appropriately!

The functionality of this library is based loosely around the Java implementation:

concat(string) : string

Concatenate two strings together.

    function concat() {
        string memory myVal = "firstname";
        myVal = myVal.concat(" ").concat("lastname");
    }

indexOf(string) : int

Find the position of a character.

    function indexOf() {
        string memory myVal = "haystack";
        uint positionOfFirstA = myVal.indexOf("a");
        uint positionOfSecondA = myVal._indexOf("a", positionOfFirstA+1);
    }

length() : uint

Get the length of a string.

    function length() {
        string memory myVal = "length";
        if (myVal.length() == 6) {
          // Length is 6!
        }
    }

substring(uint) : string

Get a partial section of the string.

    function substring() {
        string memory myVal = "sub string example";
        string memory firstWord = myVal.substring(3);
        string memory secondWord = myVal._substring(6,4);
    }

split(string) : string[]

Splits a string into an array of smaller strings based off a delimiter.

    function split() {
        string memory myVal = "my example split";
        string storage split = myVal.split(" ");
        if (3 == split.length) {
          if(split1.compareTo("example")) {
            // Valid split length and second word
          }
        }
    }

compareTo(string) : bool

Compare two strings.

    function compareTo() {
        string memory myVal = "my example split";
        if(myVal.compareTo("my example split")) {
          // They match!
        }
    }

compareToIgnoreCase(string) : bool

Compare two strings discarding alphabetic case.

    function compareToIgnoreCase() {
        string memory myVal = "my example split";
        if(myVal.compareTo("mY Example Split")) {
          // They match regardless of case!
        }
    }

upper(string) : string

Converts a string to use upper alphabetic case.

    function upper() {
        string memory myVal = "lower";
        if(myVal.upper().compareTo("LOWER")) {
          // It's now upper!
        }
    }

lower(string) : string

Converts a string to use lower alphabetic case.

    function lower() {
        string memory myVal = "UPPER";
        if (myVal.lower().compareTo("upper")) {
          // It's now lower!
        }
    }

Feel free to contribute!

Contract interactions methods

Solidity offers the convenience of high-level syntax for calling functions in other contracts (for instance: ). However, this high-level syntax is only available when the target contract’s interface is known at compile time.

The EVM provides 4 special opcodes to interact with other smart contracts, among which 3 are available as methods of the type: , and .

All the low-level functions define below accept one argument: the raw message ( ).

In this section, we will describe describe these low-level message passing methods. To better understand, we need to divide the context in three parts:

  • We consider a scenario where a contract A interacts with a contract B
  • Who is the caller ? Which contract’s storage is updated ?
  • Technical details (returned values, gas transferred, etc…)

— — — — — — — — — — — — — — — — — — — — — — — — — —

Specifications

  • Creates an arbitrary message call (low-level , see ) given the (data payload) passed as an argument.
  • Forward all available gas, adjustable.
  • Returns a tuple with :
  1. a boolean for the call result (true on success, false on failure or error).
  2. The data in format.

— — — — — — — — — — — — — — — — — — — — — — — — — —

Specifications

  • Low-level CALLCODE function, like address(this).call(…) but with this contract’s code replaced with that of address.
  • Returns false on error.

— — — — — — — — — — — — — — — — — — — — — — — — — —

In this case, contract A is essentially delegating the function call to B. The difference with the former method is that using not only enable to overwrite contract A storage.

If contract B call another contract C, contract C will see that is contract A.

Specifications

  • Low-level , see ) (with the full msg context seen by the current contract) given the (data payload) passed as an argument.
  • Forward all available gas, adjustable
  • Returns a tuple with :
  1. a boolean for the delegatecall result (true on success, false on failure or error).
  2. The data in format.

— — — — — — — — — — — — — — — — — — — — — — — — — —

Specification

  • Low-level , see ) (with the full msg context seen by the current contract) given the (data payload) passed as an argument.
  • Returns a tuple with :
  1. a boolean for the staticcall result (true on success, false on failure or error).
  2. The data in format.

Forward all available gas, adjustable

Pragma Explained

We should start by explaining the pragma. Solidity source files always have it placed in the very beginning. It defines the versions of the compiler that particular code is compatible with.

Example Copy

A file that starts with the line we see in the example above would not work on compiler version 0.4.6 or earlier. Using also specifies it will not compile with 0.5.0 or a newer version. Thus, the code will compile successfully in all versions from 0.4.7 to 0.4.25.

These limitations are crucial because versions that have a name of x.0.0 or 0.x.0 introduce major changes to the program.

It’s important to understand that when you include version pragma, Solidity compiler does not change versions, enable or disable any features. It is only used for checking whether the compiler you’re using is compatible with the code.

Special Functions and Variables

Variables and methods that remain permanently in the global namespace are special. They give details about the blockchain or the overall use of utility functions.

Block and Transaction Properties

Property Description
blockhash(uint blockNumber) returns (bytes32) Hash of the provided block. It functions for 256 most recent blocks (not including the current ones).
block.coinbase (address payable) Address of the current block miner.
block.difficulty (uint) Difficulty of the current block.
block.gaslimit (uint) Gas limit of the current block.
block.number (uint) Number of the current block.
block.timestamp (uint) Timestamp of the current block (in seconds since Unix epoch).
gasleft() returns (uint256) Remaining gas.
msg.data (bytes calldata) Full calldata.
msg.sender (address payable) Sender of the message.
msg.sig (bytes4) First four bytes of the calldata.
msg.value (uint) Number of wei transferred with the message.
now (uint) Timestamp of the current block.
tx.gasprice (uint) Gas price of the transaction.
tx.origin (address payable) Sender of the transaction.

External function calls can change the values of members (also and ).

Solidity ABI Encoding and Decoding Functions

Function Description
abi.decode(bytes memory encodedData, (…)) returns (…) ABI-decodes the provided data. The second argument indicates the types.
abi.encode(…) returns (bytes memory) ABI-encodes the provided arguments.
abi.encodePacked(…) returns (bytes memory) Starts packed encoding for the provided arguments.
abi.encodeWithSelector(bytes4 selector, …) returns (bytes memory) ABI-encodes the provided arguments (starting from the second) and adds the indicated four-byte selector.
abi.encodeWithSignature(string memory signature, …) returns (bytes memory) Same as abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), …)`

Functions for Error Handling

Function Description
assert(bool condition) If the condition is not met, it will cause an invalid opcode and thus state change reversion (for internal errors).
require(bool condition) If the condition is not met, it will revert (for errors in inputs or external components).
require(bool condition, string memory message) If the condition is not met, it will revert (for errors in inputs or external components). Shows an error message as well.
revert() Cancels execution and reverts state changes.
revert(string memory reason) Cancels execution and reverts state changes. Gives an explanatory string.

A Simple Analogy

This postcard story might sound like an oversimplified example. Everyone knows how to send a letter, or open his letterbox to look up the courier they have received.

However, Ethereum address share similar characteristics to postal addresses. Thanks to the use of public key cryptography. (Note that this apply to any Blockchain platform).

Unique

Even if there are several John Doe in the world, there is only one John Doe living at “13 example street, London, E11 2E3, United Kingdom” at the present time.

The postal address is like the label on the letterbox, which correspond to name of the person and where the letterbox is located.

An Ethereum address is the last 20 bytes of the Hash of a given public key. The hashing algorithm used is Keccak-256.

Because Hashing functions are , they are unique to their input. So for a unique private key => unique hash

Private and Secret

Not only the key of your letter box is unique, it is also private and secret. We have already seen unique before, so let’s now look at “private” and “secret”.

Private = only you own the key to open your letterbox. You keep the key private, by attaching it to a key ring, along with all your other set of keys.

Secret = You and only you know what this physical key can be used for. If I give you my set of keys, you will not know which specific key can be used to open my letterbox.

Similarly in Ethereum, your private key is stored in your wallet. Only you should know it, and never share it !

Controlled by a secret key

Your letter box has a built-in lock, tied to a unique key to open it. You can

In the cryptography world, “private” and “secret” keys are interchangeable terms. The public key is derived from the private key, so they are linked together.

Private keys in Ethereum enables you to send Ether by signing transactions. The only exception is smart contracts, as we will see later.

external

Вызов, реализованный как вызов внешнего сообщения контракта. Итак, когда контракт инициализируется,Метод для вызова собственной функции, потому что контракт еще не инициализирован. Давайте посмотрим наПример вызова метода:

Хотя текущий контрактс участиемКоды объединены, но после развертывания в сети они представляют собой два полностью независимых контракта, и вызовы методов между ними осуществляются посредством вызовов сообщений. В приведенном выше коде в контрактесреднийЧтобыНазовите договориз。

При вызове он фактически отправляет сообщение call в целевой контракт. Часть сообщения, определяющая функцию, представляет собой тело сообщения размером 24 байта, 20 байтов для адреса и 4 байта для сигнатуры функции.。

Мы можем добавить перед вызывающей функцией контрактаЗаставитьСпособ звонка. То, что требует внимания, находится здесьИспользование несовместимо с большинством языков.

Описание метода вызова

Упомянутое вышес участиемОтносится к методу вызова функции, пожалуйста, не объявляйте с видимостью следующей функции,,,Сбивать с толку. Объявление просто означает, что эту функцию нужно вызвать с помощью соответствующего вызывающего метода. Будет использоваться в последующих инструкциях, Чтобы подчеркнуть, это разработка вызывающего метода различения.

Bitwise Operators

Solidity supports the following bitwise operators −

Assume variable A holds 2 and variable B holds 3, then −

Sr.No. Operator & Description
1

& (Bitwise AND)

It performs a Boolean AND operation on each bit of its integer arguments.

Ex: (A & B) is 2.

2

| (BitWise OR)

It performs a Boolean OR operation on each bit of its integer arguments.

Ex: (A | B) is 3.

3

^ (Bitwise XOR)

It performs a Boolean exclusive OR operation on each bit of its integer arguments. Exclusive OR means that either operand one is true or operand two is true, but not both.

Ex: (A ^ B) is 1.

4

~ (Bitwise Not)

It is a unary operator and operates by reversing all the bits in the operand.

Ex: (~B) is -4.

5

<< (Left Shift)

It moves all the bits in its first operand to the left by the number of places specified in the second operand. New bits are filled with zeros. Shifting a value left by one position is equivalent to multiplying it by 2, shifting two positions is equivalent to multiplying by 4, and so on.

Ex: (A << 1) is 4.

6

>> (Right Shift)

Binary Right Shift Operator. The left operand’s value is moved right by the number of bits specified by the right operand.

Ex: (A >> 1) is 1.

7

>>> (Right shift with Zero)

This operator is just like the >> operator, except that the bits shifted in on the left are always zero.

Ex: (A >>> 1) is 1.

Hedera Hashgraph

Особенность Hedera Hashgraph в том, что сеть построена полностью с нуля и не использует технологии существующих блокчейн сетей, входящих в глобальную экосистему DeFi. Примечательно, что разработчики используют язык Solidity: это говорит о широком функционале этого языка программирования для разработки продвинутых блокчейн-сетей.

Вместо сложного и трудоемкого майнинга платформа Hedera Hashgraph предлагает иной алгоритм – ориентированный ациклический граф (Directed Acyclic Graph или DAG). Hedera Hashgraph – не блокчейн в привычном смысле этого слова. Сеть Hedera Hashgraph скорее можно представить в виде дерева графов.

Такая структура примечательна тем, что скорость транзакций увеличивается по мере добавления новых транзакций в сеть. Другими словами, транзакции в сети Hedera Hashgraph обрабатываются и подтверждаются параллельно, а не последовательно, как в сетях Bitcoin или Ethereum. Разработчики стремятся достичь пропускной способности, превышающей 100 000 транзакций в секунду, с минимальными затратами на вычисления.

Команда Hedera Hashgraph используют тот же язык, что и создатели Ethereum, для разработки смарт-контракта. Умные контракты в сети Hedera Hashgraph нужны, чтобы пользователи могли создавать собственные DApp-приложения поверх сети, используемые для разных целей: игры, DeFi-платформы, цифровая идентификация и многое другое.

Но у Hedera Hashgraph есть один существенный недостаток: в отличие от большинства проектов, платформа содержит закрытый исходный код, что осложняет аудит и не позволяет раскрыть замысел основателей. Кроме того, создатели Hedera Hashgraph запатентовали технологию, благодаря чему независимые разработчики не смогут создавать форки для улучшения работы протокола.

Заключение

Существует немного платформ, использующих язык Solidity для создания архитектуры и смарт-контрактов. Однако за время своего существования этот язык программирования стал стандартом для блокчейн-индустрии. Ведь многие ведущие платформы, такие как Ethereum, Binance Smart Chain, Polkadot и другие, созданы именно на Solidity. Однако, большинство разработчиков этих платформ не стремятся идти своим путем, а пытаются сместить Ethereum, заняв его почетное место в экосистеме DeFi.

Вместо того, чтобы просто конкурировать с Ethereum, разработчики Zhcash создали уникальную концепцию, использующую самые эффективные свойства блокчейнов. Zhcash использует гибридную модель для функционирования блокчейна, что позволяет валидаторам и стандартным узлам легко и быстро переключаться между алгоритмами консенсуса для наиболее эффективного взаимодействия.

ZHCASH, ETH, BTC и др. криптовалюты вы сможете купить здесь.

Zhcash

Платформа Zhcash основана на гибридном подходе, обеспечивая гибкость смарт-контрактов, созданных на основе Ethereum. Zhcash объединяет блокчейны и виртуальные машины Ethereum (EVM) для создания гибких и производительных блокчейн-приложений.

Команда Zcash представила инструменты для быстрой разработки собственных смарт-контрактов, DApps и выпуска токенов на основе Ethereum. Это позволяет быстро запускать эффективные приложения с минимальными навыками программирования на языке Solidity.

Zchash – это форк Bitcoin с виртуальной машиной Ethereum. Другими словами, разработчики извлекли лучшие свойства обоих протоколов для создания инновационной блокчейн-сети.

Децентрализованная платформа использует комбинацию сразу трех алгоритмов консенсуса:

  • PoS V3 – это новая концепция Proof-of-Stake. Благодаря ей каждый кошелек в сети Zcash становится полноценным узлом, который может участвовать в стейкинге на уровне с валидаторами.
  • IPoS – уникальный механизм, разработанный командой Zhcash. Владельцы токенов могут делегировать монеты супернодам.
  • DPoS – алгоритм, разделяющий сеть на валидаторов и делегаторов. На основе этого консенсусного механизма построено большинство современных блокчейнов, таких как Solana, Cosmos, Tezos и многих других.

Особенность Zhcash в том, что сеть не использует блокчейн Ethereum, а является отдельным полноценным блокчейном. Обладая суверенитетом, платформа Zhcash не зависит от ограничений Bitcoin или Ethereum, что позволяет ему добавлять новый, улучшенный функционал.

Assignment Operators

Solidity supports the following assignment operators −

Sr.No. Operator & Description
1

= (Simple Assignment )

Assigns values from the right side operand to the left side operand

Ex: C = A + B will assign the value of A + B into C

2

+= (Add and Assignment)

It adds the right operand to the left operand and assigns the result to the left operand.

Ex: C += A is equivalent to C = C + A

3

−= (Subtract and Assignment)

It subtracts the right operand from the left operand and assigns the result to the left operand.

Ex: C -= A is equivalent to C = C — A

4

*= (Multiply and Assignment)

It multiplies the right operand with the left operand and assigns the result to the left operand.

Ex: C *= A is equivalent to C = C * A

5

/= (Divide and Assignment)

It divides the left operand with the right operand and assigns the result to the left operand.

Ex: C /= A is equivalent to C = C / A

6

%= (Modules and Assignment)

It takes modulus using two operands and assigns the result to the left operand.

Ex: C %= A is equivalent to C = C % A

Note − Same logic applies to Bitwise operators so they will become like <<=, >>=, >>=, &=, |= and ^=.

Arithmetic Operators

Solidity supports the following arithmetic operators −

Assume variable A holds 10 and variable B holds 20, then −

Sr.No. Operator & Description
1

+ (Addition)

Adds two operands

Ex: A + B will give 30

2

— (Subtraction)

Subtracts the second operand from the first

Ex: A — B will give -10

3

* (Multiplication)

Multiply both operands

Ex: A * B will give 200

4

/ (Division)

Divide the numerator by the denominator

Ex: B / A will give 2

5

% (Modulus)

Outputs the remainder of an integer division

Ex: B % A will give 0

6

++ (Increment)

Increases an integer value by one

Ex: A++ will give 11

7

— (Decrement)

Decreases an integer value by one

Ex: A— will give 9

Модификаторы на практике

Только владелец или определенные пользователи

Можно использовать модификатор для проверки того, что функция может быть вызвана и выполнена только по определенному адресу.

Поддержка нескольких администраторов

Или вместо того чтобы ограничивать вызов функции только одним определенным пользователем, мы можем дать это право запуска функции нескольким заранее определенным пользователям.

Проверка данных

Еще один отличный вариант использования модификаторов — проверка вводимых данных.

Ниже приведены некоторые примеры, основанные на различных типах данных.

Возврат случайно отправленного eth

Мир блокчейна не допускает ошибок. Если eth или другие ценности были случайно отправлены не по адресу, то тут нет кого-то, к которому можно обратиться с претензиями, поскольку нет банка или центрального органа, контролирующего транзакции.

Однако вы можете подготовить свой смарт-контракт к непредвиденным ситуациям, сказав ему, что делать, когда пользователи ведут себя странно и шлют в ваши функции eth.

Взимать сборы

Ваш смарт-контракт может взимать сборы с пользователей, которые хотят вызвать определенную функцию вашего смарт-контакта.

Вернуть сдачу

Мы уже видели, как модификатор может быть использован для возврата eth, отправленных случайно на смарт-контракт. Но как насчет случая, когда пользователь отправляет больше eth, чем следовало бы?

Пример реализации выглядит следующим образом.

Переключение между состояниями

Модификатор может быть использован для сложных образцов проектирования. К ним относится образец проектирования — Машина состояний.

Запретить смарт-контрактам взаимодействовать со смарт-контрактами

SUSHISWAP приводит отличный пример модификатора, который позволяет только внешним учетным записям (т.е. пользователям) требовать вознаграждения по своему смарт-контракту.

В результате это не позволяет другим смарт-контрактам вызывать функцию, к которой прикреплен модификатор.

Проверка типа account’а

Этот модификатор дополняет предыдущий, который проверял, принадлежит ли address человеку или является смарт-контрактом. А этот модификатор проверяет есть ли по адресу код кода, используя опкод extcodesize(…) через assembly. Если есть, то это смарт-контракт.

Conversions Between Elementary Types

Implicit Conversions

When you use operators on different Solidity types, the compiler aims to implicitly convert one of the operands to the type of the other.

Therefore, the operations execute in the type of one of the operands. The implicit conversion takes place without any issues if it is semantically logic, and data is not lost.

For instance, you can convert to and to . However, cannot be converted to (it can’t hold values like -1).

Explicit Conversions

When you are confident that a conversion will take place correctly, attempt to perform the explicit type conversion.

The example below depicts the conversion of a negative to a :

Example Copy

At the end of this conversion, the will have the value of (64 hex characters). It is -3 in the two’s complement representation of 256 bits.

In cases when integers are converted into a smaller type, higher-order bits are removed. After the second line is compiled, will be :

Example Copy

The next example shows the opposite situation when an integer is converted to larger Solidity types. It will be padded at the higher order end. After the second line, will be . Comparison between equal and the original integer is the result:

Example Copy

The fixed-size bytes Solidity types act differently during conversions. After the second line, will be . If you try to convert them to smaller type, the sequence will be disturbed:

Example Copy

In cases when fixed-size bytes type is converted to a larger type, it is padded on the right. After the second line, will be :

Example Copy

During truncating or padding, integers and fixed-size byte types act differently. Therefore, explicit conversions between them are not permitted (unless their sizes are identical). To convert them from different sizes, intermediate conversions make the truncation and padding rules explicit:

Example Copy

Ethereum Classic

Немногим известно, но именно Ethereum Classic – это оригинальный блокчейн Ethereum, который «откололся» после хардфорка, возникшего в результате взлома печально известного проекта The DAO, а монеты ETC стали токенами ERC-20. Это необходимо было сделать, чтобы восстановить утерянные средства, а основной блокчейн при этом продолжил функционировать в виде форка.

Ethereum Classic работает на алгоритме Proof-of-Work, как и Ethereum в настоящее время. Сторонники оригинального блокчейна стремятся сохранить протокол в исходном виде и не собираются его менять, что является основным недостатком платформы. Дело в том, что оригинальный блокчейн ограничивает эмиссию криптовалюты до 210 млн ETC в то время, как эмиссия ETH со временем будет только падать.

Несмотря на недостатки, токен Ethereum Classic занимает 19 место в рейтинге Coinmarketcap по капитализации, что указывает на сильную поддержку сообщества. Но устаревшая механика PoW и отсутствие масштабируемости в перспективе не даст преимуществ платформе.

Basic example

Let’s take a look at what the hash looks like. with a simple example. We will use the function from the Open Zeppelin ERC20 token contract.

/**      * @dev See {IERC20-balanceOf}.      */    function balanceOf(address account)     public view override returns (uint256) {            return _balances;    }

As we said, the name of the parameters are not taken into account. So the is applied to what is in bold (don’t forget the closing parentheses!). The formula will be:

keccak256(balanceOf(address))

Here is the hash obtained below, with the function selector in bold.

70a08231b98ef4ca268c9cc3f6b4590e4bfec28280db06bb5d45e689f2a360be

Comparison Operators

Solidity supports the following comparison operators −

Assume variable A holds 10 and variable B holds 20, then −

Sr.No. Operator & Description
1

= = (Equal)

Checks if the value of two operands are equal or not, if yes, then the condition becomes true.

Ex: (A == B) is not true.

2

!= (Not Equal)

Checks if the value of two operands are equal or not, if the values are not equal, then the condition becomes true.

Ex: (A != B) is true.

3

> (Greater than)

Checks if the value of the left operand is greater than the value of the right operand, if yes, then the condition becomes true.

Ex: (A > B) is not true.

4

< (Less than)

Checks if the value of the left operand is less than the value of the right operand, if yes, then the condition becomes true.

Ex: (A < B) is true.

5

>= (Greater than or Equal to)

Checks if the value of the left operand is greater than or equal to the value of the right operand, if yes, then the condition becomes true.

Ex: (A >= B) is not true.

6

<= (Less than or Equal to)

Checks if the value of the left operand is less than or equal to the value of the right operand, if yes, then the condition becomes true.

Ex: (A <= B) is true.

Как работают модификаторы?

Давайте начнем с базовых примеров, приведенных ниже.

Символ _;

Символ _; называется подстановочным знаком. Он объединяет код функции с кодом модификатора.

Другими словами, тело функции (к которой присоединен модификатор) будет вставлено туда, где в определении модификатора появляется специальный символ _;.

Используя термины документации Solidity, этот символ «возвращает поток выполнения к исходному коду функции».

Модификатор должен содержать символ _; в своем теле. Это обязательно.

Куда поместить _; ?

Вместо _; будет подставлена функция, поэтому выполнение функции зависит от того места, где вы укажите этот символ: до, посредине или после основного кода модификатора.

Как показано в примере выше, вы можете поместить символ _; в начало, середину или конец тела модификатора.

На практике наиболее безопасной схемой использования является размещение _; в конце. В этом сценарии модификатор служит для последовательной проверки условий, то есть для того, чтобы сначала проверить условие, а затем продолжить выполнение функции. Приведенный ниже код демонстрирует это на примере:

Гость форума
От: admin

Эта тема закрыта для публикации ответов.