10 фактов, которые мне хотелось бы знать перед созданием первого Dapp на Эфириуме

BVГород-призрак Буссана-Веккья в Италии

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

Я предполагаю, что вы используете Solidity и фреймворк Embark, потому что именно их я использовал для создания Etherpot.

1. Используйте браузерный компилятор Solidity в реальном времени

Realtime Solidity Browser Compiler предоставляет много отладочной информации, которую вы не получаете, если работаете локально. Если бы я просто использовал RSBC, а не пытался искать баги методом проб и ошибок, у меня сейчас было бы немного больше волос.

Следует оговориться, однако, что RSBC, по-видимому, не точно соответствует локальному компилятору (SOLC), так что не сходите с ума, если в браузере все работает, а на локальном компьютере — нет.

2. «Объектов» нет, есть только ассоциативные массивы

Объекты и ассоциативные массивы (mappings) различаются:

  1. В ассоциативных массивах ключами могут быть целые числа, строки и адреса.
  2. Все ключи должны иметь один тип. Если первый ключ — целое число, все ключи должны быть целыми числами.
  3. Каждый ключ в ассоциативном массиве разрешается в один и тот же тип. Если первый ключ в ассоциативном массиве разрешается в целое число, то и любой другой ключ в нем разрешается в целое число, включая ключи, которые не были заданы.
  4. Перебирать ассоциативные массивы невозможно (mappings can’t be iterated over). Допустим, у вас есть отображение адресов на целые числа, в котором адреса представляют покупателей лотерейных билетов, а целые числа — количество купленных билетов. Как получить список всех покупателей? Вы не можете! При создании ассоциативного массива вам, вероятно, также захочется создать массив ключей (в нашем примере это массив покупателей).

3. Функции, возвращающие константы

Функции, возвращающие константы (определенные с модификатором constant), выполняются локально и возвращают значение. Остальные функции (без модификатора constant) выполняются в блокчейне и возвращают шестнадцатеричный идентификатор транзакции (transaction hex).

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

Вот пример функции, возвращающей константу

4. Смешанных массивов не существует

Все массивы должны содержать значения одного типа. Если первый элемент массива — целое число, то и все остальные элементы массива должны быть целыми числами.

5. Динамические массивы в памяти невозможны (они возможны только в хранилище)

Если вы объявляете массив в функции контракта, скорее всего, это ошибка, потому что, в отличие от массивов в хранилище, вы не можете изменить размер массива в цикле.

6. Размерами массивов необходимо управлять вручную

В Solidity нет функции array.push, поэтому для добавления значения в массив нужно:

  1. Увеличить длину массива: arr.length++
  2. Добавить элемент: arr[arr.length-1] = element

Вероятно, значительную долю ваших контрактов будет составлять код управления массивами вручную.

7. Особенности операции ++

Вот блок кода. Скажите мне, каким после его выполнения будет значение b.

var a = 4;
var b = a++;

Вероятно, вы ответили 5, но на самом деле b по-прежнему равно 4. Вообще говоря, в Javascript это тоже так. Однако, поскольку в Javascript нет причин управлять размерами массивов вручную, я за 3 года так и не узнал об этой особенности. Теперь вы просветлены!

Поправка: пользователь /u/secretlymallard указал, что a++ и ++a имеют разный смысл. a++ означает «возвратить a, а затем увеличить его значение», в то время как ++a означает «увеличить a, и только потом возвратить его значение». (Похоже, автор на C не программировал, лол!).

8. Объединяйте RPC-запросы в пакеты (особенно если вы на сервере)

Каждый раз, когда вы вызываете свой контракт или проверяете состояние блокчейна, вы совершаете отдельный RPC-запрос. Когда я выпустил бета-версию своего приложения, в нем была одна функция, выполняющая 10 RPC-запросов, и мой сервер был тотально ошеломлен. Не будьте таким же дураком, как я!

9. Оценки газа пока ненадежны

Когда я создавал первый вариант EtherPot, объем необходимого газа в моем контракте коррелировал с количеством покупаемых билетов. Это было ОК для небольшого количества билетов, но когда я попробовал купить больше билетов, я заметил, что запросы не синхронизируются. Я попытался использовать функцию (?) estimateGas для увеличения объема газа, но ничего не вышло.

В итоге я переделал контракт так, чтобы для покупки и 10, и 100 билетов требовался одинаковый объем газа, и с тех пор у меня не было этой проблемы. Размышляя о газе для своего контракта, стремитесь унифицировать требования, чтобы потом не удивляться, что некоторые запросы не синхронизируются.

10. Если что-то не работает, проверьте результаты вызовов embark blockchain и embark run

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

Источник: aakilfernandes.github.io

Аакил Фернандес (Aakil Fernandes)

Русскоязычный чат об Эфириуме: https://join.skype.com/m0AURDS

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: