Блокчейн разработка: как тестировать смарт контракты

smart contract audit Блокчейн разработка: как тестировать смарт контракты
3.2/5 - (73 голоса)

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

Например, кошелек Parity Ethereum потерял 30 млн. долларов из-за уязвимостей в смарт контрактах. По этой же причине, фонд Satoshi Pie потерял 32,4% своих акций. В 2016 злоумышленник взломал DAO и украл 50 миллионов долларов.

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

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

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

 

Подготовка к аудиту смарт контрактов

 

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

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

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

При подготовке спецификации опишите ожидаемое “поведение” смарт контракта: как должна работать каждая фича, как должна функционировать вся система, как каждая функция не должна работать.

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

2. Документируйте процесс развертывания смарт контрактов
 
Хотя код вашего смарт контракта может быть просто просто прекрасным, есть несколько важных действий, которые следует предпринять перед его развертыванием. Чтобы избежать сбоев, “посчитать” усилия команды, следует вести документацию процесса развертывания.

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

3. Чистите репозиторий проекта
 
Качественный “чистый” код смарт контракта значительно упрощает и автоматизирует работу аудиторов.

При подготовке проекта к процессу тестирования удалите неиспользуемые и ненужные файлы, фрагменты кода или даже какие-то контракты.

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

 

Процесс аудита смарт контрактов

 

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

  • Разработка тестов
  • Тестирование изменений состояния смарт контрактов
  • Тестирование событий
  • Тестирование ошибок
  • Проверка отправки сообщений

 
Для аудита проекта удобно использовать практики Behavior Driven Development (BDD), которые при использовании вместе с тестами позволяют создавать документацию и варианты применения смарт контрактов.

На сегодняшний день существует много фреймворков, библиотек и других инструментов для тестирования контрактов на платформе Ethereum.

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

 

Аудит смарт контрактов с Truffle

 

На данный момент Truffle является самым популярным фреймворком для Ethereum. Truffle представляет собой Node.js фреймворк, который применяется для компиляции, соединения и развертывания смарт контрактов. Плюс инструмента в том, что он позволяет блокчейн разработчикам выбирать нужные им функции.

В то время как в Truffle v.2 тесты написаны на JavaScript, в Truffle v.3 его создатели добавили возможность писать тесты на Solidity, чей синтаксис схож с синтаксисом JavaScript.

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

Принимая во внимание тот факт, что системы на блокчейне работают не так быстро, как хотелось бы, аудиторы используют тестовые клиенты блокчейн, например TestRPC, которые почти полностью имитируют работу API JSON RPC API для Ethereum клиентов.

Помимо стандартных методов, TestRPC также реализует большое число дополнительных, таких как evm_increaseTime и evm_mine. Хорошей альтернативой использованию TestRPC будет применение стандартных клиентов, к примеру, Parity, который работает в режиме dev и в котором транзакции мгновенно подтверждаются.
 
Для начала работы с Truffle установите фреймворк через npm:
 
npm install -g truffle
 
Затем выполните команду truffle init command. Это нужно для создания структуры проекта. Также, учитывайте, что контракты должны быть помещены в категории contracts/, а тесты — в test/.
 
$ mkdir solidity-test-example

$ cd solidity-test-example/

$ truffle init
 
При компиляции смарт контрактов Truffle ожидает, что каждый из них будет помещен в отдельный файл, при этом имя контракта будет эквивалентно названию его файла.

 

Разработка тестов с Truffle

 

Тесты используют объекты JavaScript, которые по сути являются абстракциями для работы со смарт контрактами, отвечающими за маппинг между операциями над объектами и вызовами методов JSON RPC. Когда вы компилируете исходный код контракта для *.sol файлов, вы автоматически получаете объекты JavaScript.

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

Кроме того, для упрощения работы лучше не смешивать миграции и процесс создания тестовых экземпляров. Вместо этого создайте их в тесте, используя при этом код, создающий новый экземпляр смарт контракта перед вызовом каждой тестовой функции. Для этого вы можете использовать функцию beforeEach async.
 
const congressInitialParams = {

  minimumQuorumForProposals: 3,

  minutesForDebate: 5,

  marginOfVotesForMajority: 1,

  congressLeader: accounts[0]

};

let congress;

beforeEach(async function() {

  congress = await Congress.new(…Object.values(congressInitialParams));

});

 

Тестирование событий в смарт контрактах

 

События в Ethereum могут быть использованы в следующих целях:
 

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

 
Рассмотрим следующий пример. Вам нужно проверить, что при вызове метода newProposal, добавляя предложение к контракту, создается запись о событии Proposal Added (Предложение добавлено).

Для этого вам сначала следует создать члена DAO в тесте и создать предложение от его имени. Затем создайте подписчика для события ProposalAdded и убедитесь, что после вызова метода newProposal событие произошло и его атрибуты полностью соответствуют переданным данным. Новый код newProposalfunction:
 
/* Function to create a new proposal */
 
function newProposal(

     address beneficiary,

     uint etherAmount,

     string JobDescription,

     bytes transactionBytecode

)

     onlyMembers

     returns (uint proposalID)

 

Тестирование изменений состояния смарт контрактов

 

Метод addMember отвечает за изменение состояния смарт контрактов. Чтобы протестировать метод, проверьте, записывает ли он информацию об участнике DAO в массив структур элементов.
 
/*make member*/

function addMember(address targetMember, string memberName) onlyOwner {

   uint id;

   if (memberId[targetMember] == 0) {

      memberId[targetMember] = members.length;

      id = members.length++;

      members[id] = Member({member: targetMember, memberSince: now, name: memberName});

   } else {

        id = memberId[targetMember];

        Member m = members[id];

  }

 MembershipChanged(targetMember, true);

}

function removeMember(address targetMember) onlyOwner {

   if (memberId[targetMember] == 0) throw;

  for (uint i = memberId[targetMember]; i<members.length-1; i++){

        members[i] = members[i+1];

  }

 delete members[members.length-1];

 Members.length–;

}
 
Используя массив с тестовыми учетными записями, добавьте участников в контракт в тесте. Затем проверьте, что функция members возвращает входные данные.

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

 

Тестирование ошибок и проверка отправителя сообщений

 

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

Для ее выполнения реализуется модификатор, который проверяет адрес учетной записи, вызывающий метод: если он не соответствует всем условиям, создается исключение.

 

Полезные рекомендации по аудиту смарт контрактов

 

1. Используйте покрытие тестами
 
Для аудита смарт контрактов используйте покрытие Solidity. Это поможет вам измерить покрытие тестами и определить фрагменты кода, которые еще не были протестированы или нуждаются в большем внимании.

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

 
2. Используйте линтеры
 
Линтеры позволяют блокчейн разработчикам улучшать качество кода, делая его более удобным для чтения и оценки. Есть много линтеров, которые вы можете использовать. Например, Solcheck — это JavaScript линтер для кода Solidity.

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

 
3. Проводите статический анализ
 
При тестировании контрактов статический анализ позволяет выявить уязвимости кода. Чтобы провести его аудит, вы можете использовать такие инструменты, как Oyente, который анализирует код и обнаруживает распространенные уязвимости, или Manticore, применяемый для динамического бинарного анализа с поддержкой EVM, или Solgraph, дающий возможность визуализировать поток управления функций смарт контрактов и определить потенциальные уязвимости.

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

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

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

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

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

Сейчас мы расширяем нашу команду и в случае, если вы только начинаете свой путь в этом направлении, мы вас обязательно всему обучим!

3.2/5 - (73 голоса)
×