Найти тему
Nervos Network

Обновление sUDT и контракта anyone-can-pay

Теперь у нас есть новая версия нашего контракта о блокировке sUDT и any-can-pay (acp) в основной сети Nervos CKB. Контракты были проверены Trail of Bits, полный отчет об аудите можно найти здесь.

Некоторые, возможно, уже видели уведомление о запросе обновлений для смарт-контракта acp в Neuron (версия 0.33.2 или новее), либо в кошельке Bitpie (версия 5.0.009 или новее). Активы в предыдущей версии контракта ACP-блокировки безопасны, пользователи могут перенести свои активы в новый контракт ACP-блокировки в своих кошельках.

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

Trail of Bits Audit Collaboration

С октября 2020 года мы провели несколько раундов аудитов безопасности для контракта sUDT, а также anyone-can-pay контракта на блокировку. Эксперты по безопасности в Trail of Bits проделали потрясающую работу по аудиту смарт-контрактов и помогли нам выявить несколько проблем.

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

Процесс формирования контракта на основе Docker зависит от деталей в PATH

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

В контрактах используется устаревшая зависимость ckb-c-stdlib

Для нас это скорее выбор дизайна, сделанный при разработке смарт-контрактов CKB. На данный момент все смарт-контракты статически связаны, это означает, что смарт-контракт должен включать все зависимые библиотеки в свой собственный двоичный файл. После того, как смарт-контракт будет реализован в основной сети, все его зависимые библиотеки будут исправлены, и мы не сможем изменить эти библиотеки без создания нового двоичного файла.

Благодаря такому дизайну каждый развернутый смарт-контракт будет привязан к определенной версии библиотеки ckb-c-stdlib. Даже когда мы добавляем новые функции в будущем, мы не сможем легко перейти на новую версию ckb-c-stdlib. Бинарная стабильность, а также воспроизводимая конструкция - очень важная основа для CKB.

Наша стратегия здесь заключается в том, что мы будем рассматривать конкретную версию библиотеки ckb-c-stdlib, как часть смарт-контракта. Когда в библиотеке обнаруживается некоторая уязвимость, мыусиливаем безопасность, а также обновляем двоичный файл. Даже при использовании устаревших библиотек, их будет достаточно для использования в цепочке.

Еще одно возможное решение этой проблемы - это методы динамического связывания на CKB, которые разрабатываются Nervos Foundation. Как только динамическое связывание будет усовершенствовано, мы сможем динамически связывать зависимые библиотеки в CKB-VM. Таким образом, при обнаружении уязвимости в библиотеке можно обновить только конкретную библиотеку - бинарные файлы в цепочке могут оставаться неизменными.

GCC с 9.2 по 10.2 неправильно компилируют некоторые варианты использования memcmp

Недавно мы узнали об ошибке GCC, которая может повлиять на библиотеку secp256k1, используемую во многих смарт-контрактах CKB. Итак, мы проконсультировались по этому поводу со специалистами по безопасности в Trail of Bits. Оказывается, версия GCC, используемая в CKB, не подвержена этой проблеме. Тогда с нашей стороны не потребуется никаких дальнейших действий.

Реализация sbrk не устанавливает errno при сбое

Эта проблема присутсвует в нашем коде, поскольку мы не устанавливали errno в качестве стандартных вызовов sbrk. Однако это не повлияет на наши смарт-контракты, поскольку ни один из смарт-контрактов, используемых в CKB, пока не использует mallocs: следовательно, вызовы sbrk производиться не будут. Тем не менее, мы планируем исправить эту проблему в ближайшее время и выпустить новую версию инструментальной цепочки CKB RISC-V, которая не содержит этой ошибки.

Считываются неинициализированные переменные

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

Неопределенное поведение для ячеек, содержащих только CKB.

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

Дублированная логика в контракте Anyone Can Pay

Вариант исправление этой ошибки можно найти здесь.

Библиотека mbedtls построена в непроизводственном режиме

У нас есть связанный с RSA код в репозитории, содержащий два вышеупомянутых смарт-контракта, но, как указывается в отчете аудита, контракты RSA в то время все еще разрабатывались и не были готовы к производству. Мы полностью признательны Trail of Bits за то, что указали на это, и мы решили эту проблему в нашем коде. Мы хотим отметить, что смарт-контракт RSA будет иметь свой собственный раунд аудитов безопасности, только после этого мы сможем порекомендовать производственное использование смарт-контракта RSA.

nervosnetwork / riscv-newlib на 700 коммитов устарели

Это также связано с дизайном смарт-контрактов CKB, который аналогичен примечанию к библиотеке ckb-c-stdlib выше. Из-за воспроизводимых проблем сборки, мы не можем просто обновить зависимости, используемые в смарт-контракте, после того, как смарт-контракт был выпущен. Итак, в Nervos мы применяем другую практику: мы будем обновлять набор инструментов RISC-V гораздо медленнее. Предоставленный нами набор инструментов RISC-V был тщательно протестирован, поэтому мы можем быть уверены, что в них мало шансов на наличие ошибок или уязвимостей. Мы планируем обновить набор инструментов до более новой версии GCC, а также до библиотеки newlib. Но мы хотим отметить, что это требует времени и тщательного тестирования с нашей стороны. Кроме того, при обнаружении уязвимости в более старой версии цепочки инструментов мы обязательно внесем в цепочку инструментов исправления, и обновим затронутые смарт-контракты до более новой версии.

Обновление смарт-контракта в будущем

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

Учитывая это, мы планируем ввести "возможность обновления для смарт-контрактов", развернутую основной командой CKB (емкость ячеек предоставляется фондом Nervos). Возможность обновления смарт-контрактов работает следующим образом:

* Когда смарт-контракт впервые развертывается на ckb, будет предоставлен специальный механизм с именем Type ID, чтобы каждый смарт-контракт мог получить уникальное имя. Блокировка с несколькими подписями используется для ячейки, содержащей смарт-контракт, а блокировка с несколькими подписями поддерживается комитетом по обновлению системных контрактов, сформированным членами основной команды CKB и фонда Nervos. Мультиподпись установлена ​​3 из 5, это означает, что, пока 3 из этих 5 предоставляют подписи, смарт-контракт может быть обновлен.

* При использовании смарт-контракта не следует использовать хэш данных напрямую, а следует использовать методы Type ID.

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

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

* Более того, если пользователь не хочет, чтобы блокировка обновлялась автоматически комитетом или руководством, он все равно может использовать блокировку sUDT и ACP с хешем кода, вместо типа хеша. Никакое обновление не повлияет на него, и никто не может изменить контракт пользователя, который будет продолжать использовать код, указанный при создании ячейки, а не новый код после обновления.

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