Случайная активация бага в Ethereum-кошельке Parity заблокировала $280 000 000

Рост популярности криптовалют и возникновение множества токенов с развитием индустрии ICO обусловили появление сотен специализированных криптовалютных кошельков. Однако далеко не все они являются удобными в использовании. Некоторые криптокошельки работают с ограниченным количеством монет, другие — не поддерживают токены стандарта ERC-20, третьи же просто ненадежны.

Представляем подборку криптовалютных кошельков для Ethereum (ETH) и токенов стандарта ERC-20, на которые стоит обратить внимание владельцам цифровых активов.

MyEtherWallet

Один из самых популярных Ethereum-сервисов. Здесь можно хранить не только ETH, но и токены стандарта ERC-20. Стоит также отметить, что кошелек является браузерным, а это означает, что пользователям не нужно скачивать специальное ПО на свой компьютер — достаточно просто открыть сайт сервиса, создать свой кошелек и произвести транзакцию.

Взлом DNS серверов MyEtherWallet

Преимущества: Одной из особенностей MyEtherWallet является то, что он не является онлайн-кошельком в классическом понимании. По сути, сервис не хранит монеты пользователей — MyEtherWallet просто помогает взаимодействовать с блокчейном и распоряжаться цифровыми активами. Еще одно преимущество кошелька — пользователи могут размещать собственное ICO на платформе Ethereum непосредственно через сервис.

Недостатки: Вероятно, из-за высокой популярности сервиса он часто становится объектом манипуляций со стороны мошенников. Так, в прошлом году злоумышленники создали поддельную копию официального сайта MyEtherWallet и за два часа похитили более $15 тысяч в эквиваленте Ethereum у доверчивых пользователей, а в апреле текущего года ряд DNS-серверов MyEtherWallet был заменен неизвестными для переадресации пользователей на фишинговый сайт.

Ethereum-клиент Parity официально начинает тестирование кода Constantinople

По сообщению ETHNews, в Ethereum-клиент Parity интегрировали код Constantinople и в ближайшее время начнут тестирование. Разработчик Parity Technologies Афри Шоэдон разместил ссылку на запрос на включение кода, опубликованный на GitHub, в своём Twitter и встретил преимущественно положительный отклик сообществ Reddit и Twitter.

Однако некоторые по-прежнему остаются не удовлетворены внедрением предложения по улучшению Ethereum EIP 1234, согласно которому эмиссия криптовалюты будет снижена с 3 ETH до 2 ETH на блок. Прочие критикуют разработчиков за отказ немедленно внедрить механизм консенсуса ProgPOW, который позволит защитить сеть от майнинга на специализированных высокопроизводительных устройствах и повысить уровень конкуренции среди обычных майнеров. На фоне продолжающей своё снижение цены Ethereum часть сообщества называет этот аспект особенно важным, однако разработчики, по всей видимости, на этот счёт имеют своё мнение.

Имплементация означает, что EIP-ы (1234, 145, 1014, 1052, 1283) были внедрены в код Parity, однако содержат ли они какие-то баги, установить удастся только после дальнейшего тестирования.

EIP 145, предложенный разработчиками Алексом Берегшаси и Павлом Былицей, определяет инструкции для виртуальной машины Ethereum (EVM)

EIP 1014, также известный как Skinny CREATE2 и предложенный Виталиком Бутериным, добавляет новый оп-код, который позволит повысить производительность state-каналов.

EIP 1052, предложенный Ником Джонсоном и Былицей, также определяет новый оп-код, EXTCODEHASH, который предназначен для снижения расходования газа и повышения эффективности кода в определённых сценариях, в частности когда один контракт осуществляет проверку байт-кода другого контракта.

EIP 1283 за авторством Вея Танга заменяет более ранний EIP 1087 и определяет методы расчёта расходования газа, позволяя снизить операционные издержки сети.

Ожидается, что в ближайшее время другие клиенты Ethereum, в том числе Geth, Trinity, cpp-ethereum, EthereumJ/Harmony и Aleth/Cpp-Ethereum, также внедрят необходимые изменения в свой код. За прогрессом каждого из них можно следить на соответствующей странице на GitHub.

Вероятно, проделанная Parity работа станет предметом обсуждения разработчиков на встрече, которая должна состояться в пятницу, 14 сентября. Помимо этого, разработчики намерены обсудить тестирование, обновления прочих клиентов, продвижение исследований и Constantinople.

The following two tabs change content below.

  • Автор публикации
  • Последние новости криптовалюты

Bitcoin-Novosti.ru

Редакция сайта Bitcoin-Novosti.ru: главный редактор — Сергей Дорошев, автор — Дмитрий Ребров, автор — Андрей Бородин

Последние публикации Bitcoin-Novosti.ru (see all)

  • Exxon Mobil получила самый большой убыток в современной истории — 02.08.2020
  • В Иране электростанциям разрешили майнить биткоин — 02.08.2020
  • Тренд на долгосрочное хранение биткоинов продолжает усиливаться — 02.08.2020
  • Биткоин обвалился на 12% после достижения годовых максимумов выше $12 000 — 02.08.2020
  • Омкар Годбоул: Июль вероятно станет лучшим годом для биткоина за 8 лет — 02.08.2020

Coinomi

Мультивалютный кошелек Coinomi, поддерживающий более чем 150 различных токенов, — не самый распространенный, но достаточно функциональный сервис. Команда разработчиков из Греции запустила приложение Coinomi для Android в 2020 году, а в начале текущего года представила версию для iOS.

Преимущества: Первым и, пожалуй, главным достоинством кошелька является поддержка широкого спектра цифровых активов. Coinomi работает с достаточно большим количеством монет, среди которых не только популярные криптовалюты, вроде биткоина и Ethereum, но и малоизвестные цифровые активы, не поддерживаемые большинством кошельков — к примеру, POA, Insanecoin или Cannacoin. Кроме того, в кошельке есть встроенная возможность для обмена криптовалют.

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

Недостатки: Существенным минусом кошелька является отсутствие десктопной и веб-версии — Coinomi представлен только в виде приложений для мобильных устройств.

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

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

На сегодняшний день рынок представлен такими устройствами как Ledger Nano S, Trezor и KeepKey. Это аппаратные кошельки, которые имеют высокий уровень защиты, но как уже было сказано, их возможности ограничены, стоимость высокая, а во время подключения могут случаться задержки.

Аппаратный кошелек — это устройство, в котором средства находятся под контролем в любой момент времени.

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

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

Одним из таких решений стало Parity Signer V2.0, в котором команда разработчиков реализовало функциональность, так необходимую продвинутым пользователям криптовалют. Причем, согласно заявлениям авторов проекта, для этой цели подойдет любой телефон на iOS или Android. Поэтому если у вас завалялся какой-то старенький смартфон, которым вы уже не пользуетесь, то вы вполне можете превратить его в аппаратный кошелек. Делается это с помощью программного обеспечения, которое делает настройку очень удобной.

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

На данный момент приложение уже поддерживает разные валюты и их соответствующие тестовые сети, например, Ethereum, Ethereum Classic, The Ropsten Testnet и т.д. Особенно стоит выделить функцию уведомления о безопасности, которая предупреждает пользователя о безопасном или небезопасном использовании устройства. Кроме того, есть возможность выполнить синхронизацию Parity с кошельком MyCrypto, а также с Ethereum Alarm Clock, что позволяет планировать отправку транзакций

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

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

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

Parity

Десктопный кошелек, принцип работы которого во многом схож с вышеописанным MyEtherWallet. Он также работает непосредственно с сетью Ethereum и поддерживает токены стандарта ERC-20.

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

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

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

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

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

В чем проблема кошельков Parity?

Первая негативная история с кошельками этого типа произошла еще летом прошлого года. 19 июля неизвестные злоумышленники воспользовались багом в кошельках с мультиподписями и украли 153 000 ETH (почти 30 миллионов долларов) с 596 кошельков. Тогда благодаря оперативным действиям группы The White Hat Group эти деньги были быстро возвращены владельцам, а разработчики кошелька заверили всех, что подобное больше не повториться и ими были приняты все необходимые для этого меры.

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

В ноябре 2020 на кошельки Parity обрушилась еще большая проблема. 6 числа этого месяца некто «devops199» написал в github Parity: «Я случайно его убил» (I accidentally killed it).

devops199 написал в github Parity запись

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

То есть все кошельки оказались без электронного договора скрепляющего их и описывающего правила доступа к средствам на них и условия их перемещения. Как говорят специалисты, Parity просто «забыли» определить владельца новой версии смарт-контракта в результате чего наш «экспериментатор» присвоил себе эти права, а потом приказал ему самоуничтожится. В результате все деньги, что поступили на кошельки Parity с 20 июня 2020 года были просто заморожены из-за потери доступа к ним. А это было 513 000 ETH или более 150 миллионов долларов (по курсу того времени).

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

Создаем контракт-визитку

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

  • Имя, почта, контакты и так далее
  • Список проектов
  • Образование: вузы, курсы и тд
  • Навыки
  • Публикации

Первый шаг

Первым делом создадим шаблон контракта и функцию-конструктор. Она должна называться также как и сам контракт и вызывается лишь однажды — при загрузке контракта в блокчейн. Мы будем использовать ее для инициализации одной единственной переменной — address owner. Как вы уже наверное догадались, в нее будет записан адрес того, кто залил контракт в сеть. А использоваться она будет для реализации функций администратора контракта, но об этом позже.

pragma solidity ^0.4.0, contract EthereumCV is Structures { address owner, // ===================== // ==== CONSTRUCTOR ==== // ===================== function EthereumCV() { owner = msg.sender, } }

Базовая информация

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

address owner, mapping (string =&gt, string) basic_data,

Для того, чтобы иметь возможность «получать» от контракта эти данные, создадим следующую функцию:

function getBasicData (string arg) constant returns (string) { return basic_data[arg], }

Здесь все просто, стоит только отметить модификатор constant — его можно (и нужно) использовать для тех функций, которые не изменяют state приложения. Главный плюс таких функций (sic!), в том что их можно использовать как обычные функции.

Администрирование

Теперь стоит задуматься о наполнении своего резюме контентом. В самом простом случае мы могли бы обойтись функцией вроде

function setBasicData (string key, string value) { basic_data[key] = value, }

Но в этом случае любой при желании смог бы изменить, например, наше имя, вызвав setBasicData(«name», «New Name»). К счастью, есть способ всего в одну строку пресечь любые такие попытки:

function setBasicData (string key, string value) { if (msg.sender != owner) { throw, } basic_data[key] = value, }

Так как нам еще не раз придется использовать подобную конструкцию (при добавлении нового проекта, например), то стоит создать специальный модификатор:

modifier onlyOwner() { if (msg.sender != owner) { throw, } _, // Will be replaced with function body } // Now you can use it with any function function setBasicData (string key, string value) onlyOwner() { basic_data[key] = value, }

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

Модульность

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

Для этого в той же директории создадим новый файл structures.sol и библиотеку Structures. А уже внутри нее опишем каждую из структур:

pragma solidity ^0.4.0, library Structures { struct Project { string name, string link, string description, } struct Education { string name, string speciality, int32 year_start, int32 year_finish, } struct Publication { string name, string link, string language, } struct Skill { string name, int32 level, } }

Теперь осталось только импортировать полученный файл

pragma solidity ^0.4.0, import «./structures.sol», contract EthereumCV { mapping (string =&gt, string) basic_data, address owner, Structures.Project[] public projects, Structures.Education[] public educations, Structures.Skill[] public skills, Structures.Publication[] public publications, // … }

Самые сообразительные уже догадались, что нотация Structures.Project[] projects означает создание динамического массива с элеметнами типа Project. А вот с модификатором public уже сложнее. По сути, он заменяет нам написание функции вроде get_project(int position) { return projects[position], } — компилятор сам создаст такую функцию. Называться она будет так же как и переменная, в нашем случае — projects.

Вы можете спросить — почему мы в самом начале не написали mapping (string =&gt, string) public basic_data, а вместо этого сами создавали такую функцию? Причина банальна — public пока что не умеет работать c переменными, для которых ключом является динамический тип данных (string именно такой тип).

Unimplemented feature (/src/libsolidity/codegen/ExpressionCompiler.cpp:105): Accessors for mapping with dynamically-sized keys not yet implemented.

Для этого нужно объявлять basic_data как например mapping (bytes32 =&gt, string).

BTW На всякий случай отмечу, что кроме локального файла, Remix умеет импортировать .sol файлы по ссылке на Github и даже с помощью протокола Swarm (это что-то вроде распределенного хранилища для Ethereum, подробнее здесь)

Загружаем и удаляем данные

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

function editPublication (bool operation, string name, string link, string language) onlyOwner() { if (operation) { publications.push(Structures.Publication(name, link, language)), } else { delete publications[publications.length — 1], } }

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

Отдаем данные

Как я уже сказал, модификатор public в строке Project[] public projects обеспечил нас функцией которая по индексу i вернет проект projects. Но мы не знаем, сколько у нас всего проектов, и здесь есть два пути. Первый — итерироваться по i до того момента, пока мы не получим ошибку о несуществующем элементе. Второй — написать отдельную функцию, которая вернет нам размер projects. Я пойду вторым путем, чуть позже скажу почему:

function getSize(string arg) constant returns (uint) { if (sha3(arg) == sha3(«projects»)) { return projects.length, } if (sha3(arg) == sha3(«educations»)) { return educations.length, } if (sha3(arg) == sha3(«publications»)) { return quotes.length, } if (sha3(arg) == sha3(«skills»)) { return skills.length, } throw, }

Заметьте, что мы не можем сравнить две строки привычным способом ‘aaa’ == ‘bbb’. Причина все та же, string — это динамический тип данных, работа с ними довольно болезненна. Так что остается либо сравнивать хэши, либо использовать функцию для посимвольного сравнения. В этом случае можете использовать популярную библиотеку stringUtils.sol, в ней есть такая функция.

Деплой

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

Сначала, само собой, заливаем весь код (финальную версию можете найти в репозитории проекта). Далее в выпадающем списке Select execution environment выберите Javascript VM — пока что протестируем контракт на JS эмуляторе блокчейна, чуть позже научимся работать и с настоящим. Если с контрактом все в порядке, то вам будет доступна кнопка Create — нажимаем и видим:



Теперь, когда контракт залит в блокчейн (его эмуляцию, но не суть), можем попробовать вызвать какую-нибудь функцию и посмотреть, что из этого выйдет. Например можно сохранить в контракте email — для этого найдите функцию setBasicData, заполните поле и нажмите кнопку с именем функции:



Функция ничего не возвращает, поэтому result: 0x. Теперь можно запросить у контракта email: ищем функцию getBasicData и пробуем:



С остальными функциями предлагаю вам поэксперементировать самим.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий