Обзор методологий разработки триггеров событий смарт-контрактов

В этой статье обсуждаются плюсы и минусы использования встроенных переменных смарт-контракта, таких как временная метка или высота блока, по сравнению с такими службами Oracle, как Ethereum Alarm Clock, при создании триггеров или событий в коде блокчейна. Кратко обсуждается полезность службы имен Ethereum (ENS).

Пример использования: триггер доказуемо справедливого запуска

Недавно я начал работу над экспериментальным токеном ERC20 с некоторыми уникальными свойствами, основанным на более старом эксперименте, который измеряет стоимость энергии для генерации различных криптовалют.

Общая идея состоит в том, чтобы создать токен, который бесплатно распределяется «партиями» по n единиц (помимо газа, затрачиваемого на каждую транзакцию распределения). В нем не будет какого-либо распределения для разработчиков (без предварительного майнинга и т. Д.). Вкратце: токен, не имеющий ценности, превышающей ту, которую люди хотят ему дать, и избегающий общих схем личного обогащения, которые вы видите сегодня в Первоначальных предложениях монет (ICO).

Однако был сделан вывод: при таком распределении вы все равно можете получить несправедливое преимущество, если опубликуете контракт в блокчейне до того, как сообщите об этом массам.

Как предотвратить преимущество на старте и сделать его запуск доказуемо честным?

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

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

Как мы можем добиться этого на таком языке, как Solidity?

Отметка времени и высота блока

Ethereum изначально поддерживает коды операций TIMESTAMP (0x42) и NUMBER (0x43). Один дает метку времени текущего блока в формате POSIX / Epoch, другой возвращает высоту текущего блока. Оба они представлены на языке Solidity как block.timestamp и block.number соответственно.

Временная метка. На первый взгляд, выбор TIMESTAMP кажется наиболее подходящим, поскольку мы можем выделить точную дату и время для условного триггера, хотя и с пониманием того, что контракт будет разрешать распространение только в первом блок, равный или позже самой отметки времени. Учитывая, что среднее время создания блока составляет пятнадцать секунд на момент написания, погрешность при определении времени запуска ICO минимальна.

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

Создание метки времени. Предостережение относительно точности метки времени заключается в том, что отдельные майнеры могут изменять свои метки времени на срок до 900 секунд, прежде чем блок будет автоматически отклонен сетевым консенсусом. В среде ICO это вполне может иметь катастрофические последствия, поскольку сговорившийся пул майнинга может победить толпу, добывая собственные блоки, отдавая приоритет своим запросам на распространение почти на 15 минут раньше других.

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

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

Оценка будущей высоты блока

Основная формула расчета будущей высоты блока:

Где:

  • H = высота целевого блока
  • h = текущая высота блока
  • t0 = текущая отметка времени (в секундах)
  • t1 = целевая отметка времени (в секундах)
  • a = среднее время для решения блока (в секундах)

Текущая цель решения блока Ethereum - 15 секунд по данным Homestead Release (2016–03–14) и EIP-2/4.

В следующих примерах будет использоваться оценка в 14 дней (2 недели) для изучения возможных сценариев, основанных на изменении значения для «a», среднего времени для решения данного блока Ethereum.

Постоянные тестовые значения будут:

  • h = 6 249 399 (https://etherscan.io/block/6249399)
  • t0 = 1 535 760 013 (1 сентября 2018 г. 12:00:13 + всемирное координированное время)
  • t1 = 1 536 969 613 (15 сентября - 12:00:13 + всемирное координированное время, 15 сентября 2018 г.)

Пример 1. Использование цели для решения блоков Ethereum

Цель решения блока Ethereum - 15 секунд (конкретно: от 10 до 20 секунд).

Таким образом, в нашем первом примере с разницей во времени 1 209 600 мы ожидаем 1 209 600/15 или приблизительно 80 640 блоков, пока не пройдут две недели.

Исторически, используя блок 6,249,399 в качестве основы, мы можем видеть, что метка времени для блока 6,330,039 - 14 сентября - 12:00:25 PM + UTC, что примерно на 12 часов раньше, чем хотелось бы.

Среднее время решения блоков в мире и среднее время на местном уровне

Алгоритмы сложности Ethereum и связанное с ними целевое время решения блоков менялись в прошлом. Кроме того, поскольку хешрейт сети увеличился, среднее время решения блока было быстрее, чем целевые 15 секунд, но все еще в пределах окна 10–20 секунд.

Используя исторические данные Etherscan, мы видим, что в конце 2017 года произошли большие всплески (https://etherscan.io/chart/blocktime) до 30 секунд между блокировками. Хешрейт Ethereum примерно 15,69 секунды.

Однако за последние три месяца среднее время решения блока составляет 14,2 секунды, а только за последний месяц - 13,97 секунды.

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

Пример 2. Использование среднего времени решения за последний месяц

За последний период в один месяц среднее время решения составляло 13,96 секунды.

В нашем примере нам теперь потребуется 86 648 блоков, чтобы достичь целевого времени. Это будет блок 6 336 047 с отметкой времени 11:52:08 по Гринвичу 15 сентября 2018 г. + всемирное координированное время.

Это почти на 12 часов позже, чем ожидалось.

Пример 3. Среднее значение первых двух методов

В этом конкретном случае возможно сглаживание окна (-12 часов или +12 часов) путем усреднения высот блоков, полученных из метода 1 и метода 2.

(80640 + 86648) / 2 = 83,644

Это будет Блок № 6 333 043 (https://etherscan.io/block/6333043), который находится всего в 2 минутах от цели.

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

Оракулы: подход вне сети

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

Другие смарт-контракты, которые хотят реагировать на события и триггеры, могут не иметь такого ограничения. Пример: промышленный индекс DOW Jones упал на 1%, и смарт-контракт должен активировать событие, выполняющее сделку на торговой площадке Ethereum, косвенно связанной с ней (сообщение «продайте мои монеты, рынки падают!»).

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

Тем не менее, подобные сервисы, называемые оракулами, жизненно важны для выполнения действий, которые Ethereum не может выполнять самостоятельно. В этих случаях репутация и доверие к конкретному смарт-контракту Oracle становятся критическими и подтверждают необходимость таких проектов, как Ethereum Name Service (ENS), так что простые для понимания теги и псевдонимы могут быть присвоены смарт-контрактам Oracle.

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

Резюме

Обсуждались три различных метода синхронизации событий в Ethereum: временные метки, высота блоков и службы оракула.

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

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

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