Написание более дешевых контрактов в Solidity
В блокчейне Ethereum газ - это плата за выполнение, используемая для компенсации майнерам вычислительных ресурсов, необходимых для работы смарт-контрактов. Использование сети постоянно увеличивается, при этом текущие затраты на газ составляют миллионы долларов в день. По мере того, как экосистема продолжает расти, будет расти и ценность оптимизации газа. В следующих разделах будут рассмотрены некоторые общие шаблоны оптимизации газа.
Схемы газосбережения
Ниже приведены шаблоны, которые вы можете использовать в своем коде для снижения потребления газа.
Короткое замыкание
Короткое замыкание - это стратегия, которую мы можем использовать, когда операция использует либо ||
, либо &&
. Этот шаблон работает, упорядочивая сначала более дешевую операцию, чтобы более дорогостоящая операция могла быть пропущена (замкнута накоротко), если первая операция оценивается как true
.
Ненужные библиотеки
Библиотеки часто импортируются только для небольшого числа использований, что означает, что они могут содержать значительный объем кода, избыточного для вашего контракта. Если вы можете безопасно и эффективно реализовать функциональность, импортированную из библиотеки в рамках вашего контракта, это будет оптимальным решением.
Явная видимость функции
Явная видимость функций часто может обеспечить преимущества с точки зрения безопасности смарт-контрактов, а также оптимизации газа. Например, явная маркировка внешних функций заставляет установить место хранения параметра функции как calldata
, что экономит газ при каждом выполнении функции.
Правильные типы данных
В Solidity одни типы данных дороже других. Важно знать, какой из наиболее эффективных типов можно использовать. Вот несколько правил о типах данных.
- По возможности, тип
uint
следует использовать вместо типаstring
. - Тип
uint256
требует меньше газа для хранения, чемuint8
(смотри почему). - Тип
bytes
следует использовать поверхbyte[]
. - Если длину
bytes
можно ограничить, используйте минимально возможное количество отbytes1
доbytes32
. - Тип
bytes32
дешевле в использовании, чем типstring
.
Дорогостоящие газовые модели
Следующие шаблоны были взяты из статьи Неоптимизированные смарт-контракты пожирают ваши деньги. Эти схемы увеличивают затраты на газ, и их следует избегать.
Мертвый код
Мертвый код - это код, который никогда не запустится, потому что его оценка основана на условии, которое всегда будет возвращать false
.
Непрозрачный предикат
Результат некоторых условий может быть известен без выполнения и, следовательно, не нуждается в оценке.
Дорогие операции в шлейфе
Из-за дорогостоящих кодов операций SLOAD и SSTORE управление переменной в хранилище намного дороже, чем управление переменными в памяти. По этой причине переменные хранилища не должны использоваться в циклах.
Исправление для этого шаблона - создать временную переменную для представления глобальной переменной, и после завершения цикла переназначить значение временной переменной глобальной переменной.
Постоянный исход цикла
Если результатом цикла является константа, которая может быть определена во время компиляции, ее не следует использовать.
Петля слияния
Иногда в смарт-контрактах вы можете обнаружить, что есть два цикла с одинаковыми параметрами. В случае, если параметры цикла совпадают, нет причин для создания отдельных циклов.
Повторные вычисления в цикле
Если выражение в цикле дает одинаковый результат на каждой итерации, его можно вывести из цикла. Это особенно важно, когда переменные, используемые в выражении, хранятся в хранилище.
Сравнение с односторонним исходом в петле
Если сравнение выполняется на каждой итерации цикла, но результат каждый раз один и тот же, его следует удалить из цикла.
использованная литература
- Https://medium.com/coinmonks/optimizing-your-solidity-contracts-gas-usage-9d65334db6c7
- Https://ethereum.stackexchange.com/questions/28813/how-to-write-an-optimized-gas-cost-smart-contract
- Https://arxiv.org/pdf/1703.03994.pdf
- Https://ethereum.stackexchange.com/questions/3067/why-does-uint8-cost-more-gas-than-uint256
- Https://www.youtube.com/watch?v=qwBkeJ84d2g&feature=youtu.be&t=68
- Https://ethereum.stackexchange.com/questions/11556/use-string-type-or-bytes32