Solidity

Оглавление

Part 6: A Complete Solidity Smart Contract

Now let’s create a complete smart contract that will demonstrate several new concepts. This will be different from previous lessons where we focused on individual topics.

We’ll create a Hotel Room contract that lets users book rooms and pay for them with cryptocurrency. We’ll start of by creating the contract like this:

Let’s keep track of the owner of the Hotel Room. This is the person that will get paid whenever the room is booked:

We’ll assign the ownership to the account that deploys the smart contract inside the function like this:

Next, we’ll create a function that will book the hotel room. This function will handle several responsibilities, but at first we’ll make pay the hotel owner whenever the room is booked.

Note, that we send ether to the owner with the function. Here refers to the amount of Ether sent in when the function is called. Also, this function has been declared in order to receive Ether with the transaction.

Next, let’s keep track of the hotel room’s occupancy status. For example, we’ll determine whether the hotel room is «vacant» or «occupied». We can do that with an like this:

Here we have created an called with the options or .

Then, we create a state variable called that tracks an instance of the enum, and its current value. For example, if the current status is , then the variable will reflect that.

Now let’s set the default status inside the constructor function like this:

Now let’s change the status of the hotel room once it’s booked:

Now let’s require that the hotel room is actually vacant when it’s booked:

This uses Solidity’s built in function to check the current status. Here’s how it works: if the value passed into the function is true, then the function will resume execution. If it’s false, then it will halt execution and throw an error. In this case, if the current status is «Vacant», then the function will continue. If not, it will throw the error .

Next, we can refactor this with a modifier. This is a special piece of reusable code that we can add to our function:

Now we can remove that line from our function and add the modifier like this:

Next, we can add a price to the hotel room. We’ll specify that it costs 2 Ether. We’ll do that with a new modifier like this:

We can add that to our function like this:

Next, let’s create a notification that the hotel room was booked. Anyone will be able to subscribe to this notification to find out as soon as it has been booked. We can accomplish this with an like this:

Then, we can emit the event inside the function like this:

Finally, we want to rename this function to simplify the behavior of our smart contract. We’ll use the special function like this:

This will allow the smart contract to receive Ethereum payments. Whenever this happens, it will run the code inside the function and book the hotel room. This greatly simplifies the smart contract interface. Instead of having to call the function by a specific name, and pass in arguments, you simply pay the smart contract from your wallet, and it books the hotel room for you!

FAQs

Happy with this tutorial? Then you NEED to join my free training here where I’ll show you how to build a real world blockchain app so that you can become a highly paid blockchain developer!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Memory types

​ Перед тем, как начать погружаться в тонкости работы EVM, следует понять один из самых выжных моментов — где и как хранятся все данные

Это очень важно, т.к области памяти в EVM сильно отличаются своим устройством, и, как следствие, разнится не только стоимость чтения/записи данных, но и механизмы работы с ними

Storage

​ Первый и самый дорогой тип памяти — это Storage. Каждый контракт обладает своей собственной storage памятью, где хранятся все глобальные переменные (state variables), состояние которых постоянно между вызовами функций. Её можно сравнить с жестким диском — после завершения выполнения текущего кода все запишется в блокчейн, и при следующем вызове контракта у нас будет доступ ко всем полученным ранее данным.

Структурно storage представляет из себя хранилище типа ключ-значение, где все ячейки имеют размер в 32 байта, что сильно напоминает хэш-таблицы, поэтому эта память сильно разрежена и мы не получим никакого преимущества от сохранения данных в двух соседних ячейках: хранение одной переменной в 1ой чейке и другой в 1000ой ячейке будет стоить столько же газа, как если бы мы хранили их в ячейках 1 и 2.

Как я уже говорил, этот тип памяти является самым дорогим — занять новую ячейку в storage стоит 20000 газа, изменить занятую — 5000 и прочесть — 200. Почему это так дорого? Причина проста — данные, сохранненные в storage контракта, будут записаны в блокчейн и останутся там навсегда.

Также, совсем несложно подсчитать максимальный объем информации, который можно сохранить в контракте: количество ячеек — 2^256, размер каждой — 32 байта, таким образом имеем 2^261 байт! По сути имеем некую машину Тьюринга — возможность рекурсивного вызова/прыжков и практически бесконечная память. Более чем достаточно, чтобы симулировать внутри еще один Ethereum, который будет симулировать Ethereum 🙂

Memory

​ Вторым типом памяти является Memory. Она намного дешевле чем storage, очищается между внешними (о типах функций можете прочитать в следующих главах) вызовами функций и используется для хранения временных данных: например аргументов, передаваемых в функции, локальных перемеменных и хранения значений return. Её можно сравнить с RAM — когда компьютер (в нашем случае EVM) выключается, ее содержимое стирается.

По внутреннему устройству memory представляет из себя байт-массив. Сначала она имеет нулевой размер, но может быть расширена 32-байтовыми порциями. В отличие от storage, memory непрерывна и поэтому хорошо упакована — намного дешевле хранить массив длины 2, хранящий 2 переменные, чем массив длины 1000, хранящий те же 2 переменные на концах и нули в середине.

Чтение и запись одного машинного слова (напомню, в EVM — это 256 бит) стоит всего 3 газа, а вот расширение памяти увеличивает свою стоимость в зависимости от текущего размера. Хранение некольких KB будет стоить недорого, однако уже 1 MB обойдется в миллионы газа, т.к цена растет квадратично.

Stack

​ Так как EVM имеет стэковую организацию, неудивительно, что последней областью памяти является stack — он используется для проведения всех вычислений EVM, а цена его использования аналогична memory. Он имеет максимальный размер в 1024 элемента по 256 бит, однако только верхние 16 элементов доступны для использования. Конечно, можно перемемещать элементы стэка в memory или storage, однако произвольный доступ невозможен без предварительного удаления верхушки стэка. Если стэк переполнить — выполнение контракта прервется, так что я советую оставить всю работу с ним компилятору 😉

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.

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 использует гибридную модель для функционирования блокчейна, что позволяет валидаторам и стандартным узлам легко и быстро переключаться между алгоритмами консенсуса для наиболее эффективного взаимодействия.

`msg` global variables explained

The global variables in particular are special global variables that contain properties which allow access to the blockchain. For instance, is always the address where the current (external) function call came from. Let’s take a look at an example from the blockchain-based puzzle game we built.

In our game there are six levels, each with their own puzzle to solve. The first user to correctly solve all of the puzzles in order is awarded a sum of ETH.

Now let’s take a look at our function. This function is called when a user correctly solves a puzzle and is used to move them on to the next level in the game:

// @dev A mapping of user addresses and their associated levelsmapping(address => uint) public userLevel;// @dev This function will advance a user to the next levelfunction incrementLevel() internal {        userLevel++;}

You’ll notice we’re using the special global variable to obtain the current user’s address (e.g., 0x44d33a….) from where the function call came from. We’re then advancing them to the next level in the game by incrementing their level (of type ) in the mapping.

Along with there are other special global variables that are useful:

  • — The complete which is a non-modifiable, non-persistent area where function arguments are stored and behave mostly like
  • — Returns the available gas remaining for a current transaction (you can learn more about gas in Ethereum here)
  • — The first four bytes of the calldata for a function that specifies the function to be called (i.e., it’s function identifier)
  • — The amount of wei sent with a message to a contract (wei is a denomination of ETH)

Part 5: Solidity Conditionals & Loops

Now let’s talk about conditionals in Solidity. These allow you to execute code based upon a set of pre-defined criteria.

For example, we can write code that looks somewhat like this:

Let’s see how this works inside of solidity. Let’s create a function that checks whether a number is Even or not:

Inside this function, we use a / statement that checks whether a number is even or not. If it’s even, then it returns . If not, then it returns .

Here we use the modulo operator (

So that’s the basic idea behind conditionals. Pretty simple, right?

Let’s see conditionals in action AND explore another new concept inside Solidiy: Loops. To illustrate this, let’s create a function that counts a set of even numbers:

Let me explain what this function does.

First, we store a list of numbers 1-10 in an array called at the top of the contract.

Next, inside the function we use a loop to iterate over each item in the array. For each number, it checks if the number is even with our previously-created function inside the statement.

If the number is even, then we increment the variable value by 1 (that’s what the operator does). If not, then we do nothing and skip this number.

Finally, once this loop has checked every number in the array, it will return the value of the variable, which will be total number of even numbers in the array.

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 – уменьшаться, соответственно.

How to Comment on Solidity

In Solidity, you can leave simple and NatSpec comments. There is one major difference between them. Solidity compilers understand NatSpec formatting, making these comments machine-readable. We recommend using NatSpec for all notes in public interfaces.

Writing simple comments in Solidity is easy. The syntax depends on the length of your comment:

  • Start the line with to include a single-line comment.
  • Start with and end with to include a multi-line comment.

Example Copy

NatSpec

You can also write your Solidity comments in the Ethereum Natural Language Specification Format (NatSpec). It defines a special form of comments in Solidity contracts. Developers use it for documenting return variables, functions, and so on.

You should insert all documentation before , , and keywords. You can write single or multi-line comments in Solidity, and use two types of syntax:

  • Start the line with to include a single-line comment.
  • Start with and end with to include a multi-line comment.

Example Copy

Solidity comments written in NatSpec can be of two types:

  • Developer-focused
  • End-user-facing

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

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.

Use Structs as ValueTypes in mappings.

The declaration below is a mapping that reference each Instructor by their ethereum address.

mapping(address => Instructor) instructors;

You can use this mapping to lookup a specific instructor with their ethereum address and retrieve their informations. The function below implements this functionality by returning a tuple that contains the instructor’s age, first name and last name.

pragma solidity ^0.5.0;contract Course {    struct Instructor {        uint age;        string first_name;        string last_name;    }    mapping(address => Instructor) instructors;    function getInstructorInfos(address _instructor_address) public view returns (uint, string memory, string memory) {        uint _age = instructors.age;        string memory _first_name = instructors.first_name;        string memory _last_name = instructors.last_name;        return (_age, _first_name, _last_name);    }}

You could also write the the , and directly in the statement for brevity, as shown below.

function getInstructorInfos(address _instructor_address) public view returns (uint, string memory, string memory) {    return (        instructors.age,        instructors.first_name,        instructors.last_name    );}

Going back to our previous example, you can’t return the mapping and iterate through all the instructors (because a mapping contains all the possible values by default).

Instead, you would need the following protocol:

  1. save all the ‘s addresses who registered in your contract in an array.
address[] public instructorAccounts;

2. Iterate through all the addresses stored he array

for (uint i = 0; i <= instructorAccounts.length; i++) {    // logic goes here}

How Externally Owned Account’s addresses are created?

Source: Ethereum Yellow Paper (Byzantium Version, 2019–06–13, p24, point 284)

Let’s apply the yellow paper specification, and build an ethereum address from scratch. We will use this article from Vincent Kobel as a step-by-step guide on how to create an Ethereum address.

  1. Start with the public key (128 characters / 64 bytes)
pubKey = 6e145ccef1033dea239875dd00dfb4fee6e3348b84985c92f103444683bae07b83b5c38e5e...

2. Apply the Keccak-256 hash to the public key. You should obtain a string that is 64 characters / 32 bytes long.

Keccak256(pubKey) = 2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9

3. Take the last 40 characters / 20 bytes (least significant bytes) of the resulting hash. (Or, in other words, drop the first 24 characters / 12 bytes).

These 40 characters / 20 bytes are the address (they are in bold below).

2a5bc342ed616b5ba5732269001d3f1ef827552ae1114027bd3ecf1f086ba0f9Address = 0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9

When prefixed with 0x, the address actually becomes 42 characters long. . Moreover it is important to note that they are case-insensitive. All wallets are supposed to accept Ethereum addresses expressed in capital or lowercase characters, without any difference in interpretation. (Since EIP-55, UpperCase addresses are used to validate a checksum)

0x001d3f1ef827552ae1114027bd3ecf1f086ba0f9 or0X001D3F1EF827552AE1114027BD3ECF1F086BA0F9

Linting

There are two linters included with the extension, solhint and solium / ethlint. You can chose your preferred linter using this setting, or disable it by typing »

Solhint

To lint Solidity code you can use the Solhint linter https://github.com/protofire/solhint, the linter can be configured it using the following user settings:

"solidity.linter": "solhint",
"solidity.solhintRules": {
  "avoid-sha3": "warn"
}

This extension supports configuration file. It must be placed to project root
directory. After any changes in it will be synchronized with current IDE
configuration.

This is the default linter now.

NOTE: Solhint plugins are not supported yet.

Solium / Ethlint

Solium is also supported by the extension https://github.com/duaraghav8/Solium, you can configure it using the following user settings:

"solidity.linter": "solium",
"solidity.soliumRules": {
    "quotes": ,
    "indentation": 
},

Formatting using Prettier and the Prettier Solidity Plugin

Formatting uses the default formatting settings provided by prettier, if you want to provide your custom settings create a .prettierrc file as follows

{
  "overrides": 
}

If you would like to format on save, add this entry to your user / workspace settings:

Code generation Nethereum

The extension integrates with the Nethereum code generator to create Contract integration definitions. You can either generate the api for a single contract, all compiled contracts, or automatically every time you compile a smart contract solidity file.

The simplest way to code generate a the contract definition for a smart contract is to right click and select the project / language you require:

3.5 Отменённая транзакция

Откат транзакции

Контракт транзакции можно откатить, например, потому что GAS превышает лимит, программа выдает оператор throw или исключение низкого уровня

В этом сценарии очень важно идентифицировать аномальный код и определить местонахождение аномального кода. Когда выполнение выдает исключение, Remix выдаст предупреждение

Кнопка предупреждения перейдет к последнему примитиву выполнения до возникновения исключения. Следует отметить, что выполнение транзакций интеллектуального контракта осуществляется на уровне событий, то есть значение переменной не может быть изменено во время работы, подобной C ++, и может быть выполнено только один раз. Отладчик записывает примитивы выполнения, поэтому вы можете двигаться вперед и откатываться назад. Для отката, как и для отката фильма, это очень круто.

Function Types

Solidity function types represent types of functions. Function type variables can be assigned from functions. To designate functions to and return functions from function calls, use function parameters.

The usage of function members is illustrated in this code example:

Example Copy

Members that the public and external functions can have:

  • : retrieves the ABI function selector.
  • : retrieves a callable function object. After that function is called, it sends the indicated amount of gas to the target function.
  • : retrieves a callable function object. After that function is called, it sends the specified amount of wei to the target function.

The following example shows the usage of internal function. It can be applied to internal library functions because they will belong to the same code context:

Example Copy

This example shows the usage of external functions:

Example Copy

Call internal functions only on the current contract since they cannot be completed outside the context of the current contract.

External functions contain signatures of functions and addresses: such functions can be passed and returned from external function calls.

Notation of function types:

Example Copy

Function types are internal by default. Therefore, it is possible to remove the internal keyword. Remember that this is only applicable for function types.

Слушать события

Из-за приведенного выше введения вы можете все еще не понимать роль инцидента.Web3 и умный контракт интерактивного бояВ этой статье вы узнаете, что после нажатия кнопки «Информация об обновлении», хотя смарт-контракт успешно вызван, текущий интерфейс не был обновлен. Использование мониторинга событий может хорошо решить эту проблему, давайте посмотрим, как ее реализовать.

Изменить договор, определить события и вызвать события

Сначала просмотрите код контракта:

Во-первых, вам нужно определить событие:

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

Затем вам нужно вызвать событие Instructor в функции setInfo, например:

вWeb3 и умный контракт интерактивного боя, После нажатия кнопки «Информация об обновлении» будет вызвана функция setInfo, и во время этой функции будет вызвано событие «Инструктор».

Используйте Web3 для мониторинга событий и обновления пользовательского интерфейса

Теперь вам нужно использовать Web3 для мониторинга событий и обновления пользовательского интерфейса. Сначала просмотрите предыдущий код, который использовал Web3 для взаимодействия со смарт-контрактами:

Теперь вам не нужна info.getInfo () для получения информации, а вместо этого используйте события прослушивания для получения информации. Сначала определите переменное ссылочное событие:

Тогда используйте.watch()Метод добавления функции обратного вызова:

После обновления кода вы можете просмотреть эффект в браузере. После нажатия кнопки «Информация об обновлении» интерфейс будет обновлен во времени, как показано на рисунке:

Пожалуйста, подпишитесь на небольшую колонку для полного кодаБлокчейн технологияПосмотреть.

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!

3.6 Точки останова и одношаговая отладка

5,7 кнопок на панели навигации используются для прокрутки назад к предыдущей точке останова и выполнения до следующей точки останова. Нажмите на номер строки в поле редактирования слева, чтобы добавить и удалить точки останова. Например, дважды щелкните по строкам 18 и 20, установите 2 точки останова, введите параметры в поле ввода moveFund на панели «Выполнить» и перенесите 0,0005 ETH на второй счет. Нажмите «MoveFund», чтобы выполнить торговую функцию.

После успешного выполнения транзакции по контракту нажмите кнопку «Отладка» на устройстве вывода терминала и нажмите программу «Перейти к следующей точке останова» на панели отладки, чтобы перейти к первой точке останова.

Перейти к первой точке останова

Снова нажмите кнопку «Перейти к следующей точке останова» и перейдите непосредственно ко второй точке останова в строке 20. Нажмите на функцию «Выскочить», чтобы выйти из функции.После завершения операции вы увидите, что баланс второго счета изменился, добавив 0,0005 ETH. Нажмите, чтобы развернуть Подробности, вы можете увидеть информацию о параметрах записи события СОБЫТИЕ.

Результаты

Recursive Structs

A Struct is said recursive when it contains within its definition a member variable in its own type.

We naturally understand why this is not possible: a struct can’t contain a member of its own type because the size of the struct has to be finite.

The Remix compiler would throw an ErrorType as displayed below.

Let’s use the example above to better understand the problem.

Imagine we want to create a new player: Christiano Ronaldo ! We would then create a new variable _Christiano_Ronaldo and assign to him some values.

Each FootballPlayer (the struct), has a name (a string), an age (an uint) and a mentor (another FootballPlayer, so the struct itself).

The problem here is that since every football player has a mentor being a football player itself, the definition of the variable would never end.

For a bit of fun, the in-depth look at our variable _Christiano_Ronaldo would look something like this: