Уроки The DAO: Насколько идеален код Эфириума? Часть 1

Тема в разделе "Общий раздел", создана пользователем Romero, 6 авг 2016.

  1. Romero

    Romero Новичок Проверенный

    Одной из наших целей в RSK было — сфокусироваться на применении технологии смарт-контрактов в реальном мире. Несмотря на то, что мы рады наблюдать новые подходы к решению старых проблем доверия, такие, как ДАО, мы думаем, что Биткойн, блокчейн, смарт-кошельки и крипто-активы имеют достаточный революционный потенциал, чтобы только при помощи этих инноваций мы могли достичь действительной финансовой общедоступности.
    [​IMG]

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

    В последние месяцы мы были свидетелями сотворения The DAO во время краудфандинговой кампании, которой удалось собрать более 200 миллионов долларов. Однако, я сомневаюсь, что создатели проекта были готовы защитить столь огромные средства, так как The DAO был и остается не прошедшим тестирование экспериментом. В этой статье я покажу вам, почему эксперимент с The DAO провалился и какие причины этому способствовали. Затем, мы проанализируем дизайн RSK и проследим, какие пути мы использовали для минимизации риск факторов. Нашей главной задачей в RSK было создание и предоставление многоуровневой безопасности, где сбой в работе одного уровня не виляет на работу остальных. Эфириум выживет во время падения The DAO, он даже станет еще сильнее. Однако, он все же пострадал. Я надеюсь, что из этого будут вынесены правильные уроки.

    Аналогия с летящим самолетом
    Когда большинство из нас стали использовать Биткойн (либо из-за нужды в покупке, либо из-за получения гонораров биткойнами), криптовалюта была работающим экспериментом: весь его функционал был уже «в полёте». Несколько раз Биткойн сравнивали с самолетом, который надо ремонтировать прямо в воздухе. Однако Биткойн — это самолет, который летал на протяжении более сем лет и ни разу не приземлялся, это многое говорит про его надежность.

    В ситуации, когда множество людей инвестировали в The DAO, все было наоборот – код никогда не выполнялся. Вы доверите свою жизнь программе автопилоту, которую никогда не тестировали на реальных самолетах? К сожалению, именно так поступили инвесторы в The DAO. Они позволили хайп-системе одурачить себя и забыли о предварительном анализе фактов. Кто-то может заметить, что большинство инвесторов в The DAO «поделились» с проектом небольшим количеством денег, поэтому их инвестицию можно рассматривать как ставку (Я знаю лично высококвалифицированных людей, которые инвестировали слепо). Но были и некоторые киты, инвестировавшие в The DAO миллионы. Так что давайте возложим часть вины за этот инцидент в том числе на инвесторов.

    Дизайн VM Эфириума
    Среди целей дизайна Виртуальной Машины Эфириума (Eth VM) было упрощение спецификации уровня консенсуса. Это благородная цель, поскольку она способствует ре-внедрению платформы в разные программные языки и требования. Однако, даже если минимальное количество инструкций, необходимых для включения Тьюринг-полных смарт-контрактов менее 10, Эфириум не стал ограничивать себя таким минимумом по нескольким причинам:

    а) Это заметно снижает производительность

    б) Это делает скомпилированный код сложным для аудита

    Так что, у Эфириума есть около 100 разных операционных кодов. Так или иначе, мне кажется что ради минимизации CALL opcode был перегружен двумя функциями: вызвать метод из другого контракта и отправить эфир. Но семантика этих двух функций и контекст, где каждая из них используется, очень разные. Нехватка образования была одним из факторов, которые способствовали атаке на The DAO. Интересно заметить, что косвенно виртуальная машина уже предоставляет средства для отправки эфира без вызова какой-либо функции, создавая временный контракт и используя операционный код самоубийства, на что придется затратить куда больше топлива.

    Эта возможность ведет нас к простому заключению, что VM должна предлагать операционный код SEND, который не вызывает никакого дополнительного кода, упрощая тем самым сложность высших уровней. Кто-то может поспорить, что, ограничивая количество топлива, предложенного для вызова, до 2300, имеет побочный эффект — никто не сможет добавить дополнительный операционный код CALL, а значит, это безопасно. Этот аргумент ложный, если учитывать, что в будущем система попадет под влияние хард-форков, которые: могут уменьшить стоимость операции CALL, или позволить контрактам платить за её топливо. Так что, в общем это решение — недальновидное, скрывает реальную проблему от пользователя и блокирует будущие улучшения. В RSK мы создали простой SEND операционный код, который не вызывает никакого дополнительного кода в конечном контракте.

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

    Solidity
    Языки программирования с динамическим контролем типов хорошо известны тем, что их сложнее правильно интерпретировать чем статически вводимые языки. Также, необходимо тратить ресурсы на память и вычисления смарт-контрактов Эфириума, это делает объекты динамически-вводимого кода куда более дорогостоящими чем объекты статического кода.

    Solidity — это статически типизированный язык, основанный на JavaScript. Выбор статической типизации на первый взгляд кажется правильным. Однако, он поднимает вопрос о целесообразности создания нового программного языка с нуля. Это язык, который не влияет на проблемные области кода и не предоставляет никаких специальных фич касательно смарт-контрактов. Разве существующие языки недостаточно хороши?

    Некоторые из предыдущих дизайнов смарт-контрактов, такие как QixCoin, были основаны на эмуляции процессорного ядра RISC. Некоторые дизайны поновее эмулируют другие процессоры: Codius исполняет x86 код в песочнице, а Bloq Ora исполняет Moxie. Эмуляция существующего ядра позволяет программисту использовать стандартные распространенные языки программирования и протестированные компиляторы. Solidity слишком молод. Например, у меня есть контракт, который заставляет Solidity аварийно завершить работу, и причина не известна. Я также нашел случаи, где этот язык генерирует плохой код.

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

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

    a) if (_recipient.call.value(_amount)()) {

    b) if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false)

    В первой строке, нетипизированный контакт _получатель отправил _количество эфира. Не указан никакой метод. Во второй строке, определенный метод, называемый (createTokenProxy) отправляет эфир с помощью fundsToBeMoved. Документация к Solidity 0.2.0 предупреждает, что добавление .value(x) или .gas(y) только (локально) устанавливает цену и количество топлива, отправляемого вместе с вызовом функции, и только круглые скобки в конце действительно выполняют вызов. Если постфикс .gas() отсутствует, все количество неиспользованного топлива предлагается внешнему вызову, так что рекурсия контракта возможна (однако, этот факт не указан в документации). Я верю, что описание вызова неполноценно, так как он слишком необычен. Очень немногие языки программирования позволяют изменять ссылку на вызов такими модификаторами (один из них — Питон), и такая конструкция используется не часто. Становится непонятным, какой именно метод вызывается. Похоже, что метод называется »value()» а не »createTokenProxy».

    Было проделано множество исследований для того, чтобы разработать практичные языки программирования, которые также помогают программисту в понимании кода, golang, c# и Java — хорошие примеры правильного баланса между человеческим пониманием, языковым самовыражением и компактной документацией. Solidity — точно не один из них. Однако, я не могу рекомендовать использование Serpent, потому как о нем доступно еще меньше информации, а также присутствует недостаток примеров, связанных с ним.

    Помощь с выполнением кода
    Кажется, что безопасность выполнения умных контрактов была возложена целиком на код самих контрактов. Виртуальная машина Эфириума не дает никаких конкретных способов ограничить рекурсию, точно также как и среда исполнения Solidity. Баг с рекурсией средств, использованный в атаке на The DAO, был известен еще с 2014 года, так что у разработчиков было предостаточно времени на подготовку. Однако уже понятно, что данные инструменты — сырые, и понадобятся годы интенсивной разработки высококачественных инструментов. Децентрализованная разработка Эфириума возможно и имела множество выгод, но также она повлекла за собой плохие последствия: у нее нет четко определенных директив, а обновления безопасности стали откладываться на неопределенный срок.

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


    RSK Blog
     
  2. FanatMonet

    FanatMonet Новичок

    Виталиг опять пиар начал! Интересно, найдутся ли ещё влошенцы, после всего что с ним было
     
  3. Romero

    Romero Новичок Проверенный

    Надо же как то доверие вернуть, или хотя бы подтянуть новый инвесторов, и плевать на доверие))))
     
  4. FanatMonet

    FanatMonet Новичок

    доверие к эфиру после ДАО и хардфорка? Не,не слышал:D