Учитывая исходный код (Solidity) смарт-контракта, есть ли способ детерминистически скомпилировать код и сравнить его с кодом в блокчейне? Я хочу убедиться, что контракт делает то, что заявлено в исходном коде, и что автор не вмешался в него.
Насколько мне известно, лучший способ сделать это на данный момент — снова скомпилировать исходный код с той же версией компилятора, которую использовал автор (так что это необходимо раскрыть) и сравнить байт-код.
Таким образом, вы должны проверить совпадение скомпилированного байт-кода с данными создания контракта tx .
Чтобы добавить к ответу @thomas-bertani, сегодня etherchain.org выпустил инструмент проверки контрактов Ethereum .
Вот текст со страницы:
Проверка исходного кода обеспечивает прозрачность для пользователей, взаимодействующих со смарт-контрактами. Загрузив исходный код, Etherscan сопоставит скомпилированный код с кодом в блокчейне. Как и контракты, «умный контракт» должен предоставлять конечным пользователям больше информации о том, для чего они «цифровой подписью», и давать пользователям возможность проверять код, чтобы независимо убедиться, что он действительно делает то, что должен делать.
В настоящее время рабочий процесс довольно раздражает. Вам нужно скомпилировать контракт с той же версией компилятора и теми же настройками (обратите внимание на флаг «optimization=true» ).
Теперь обратите внимание, что полученный байт-код НЕ совпадает с байт-кодом, хранящимся в адресе. Причина этого в том, что скомпилированный контракт содержит часть инициализации, которая запускается только один раз, когда контракт отправляется в цепочку. Таким образом, байт-код, хранящийся в блокчейне, представляет собой код без части инициализации.
Для проверки кода у вас есть два варианта:
Etherchain помогает сделать этот процесс.
В принципе, для идентификации контакта могут применяться методы сопоставления с образцом, даже если используется не совсем тот же компилятор. Проект, который делает это и в целом связывает контракт высокого уровня (Serpent/Solidity) с адресами Ethereum: Etherscrape .
https://etherscan.io/verifyContract — инструмент проверки. Предоставляя исходный код Solidity, он проверяет, совпадает ли сгенерированный байт-код с байт-кодом контракта (по заданному адресу). пользователь должен выбрать тот же компилятор и включить или отключить оптимизацию.
Другой подход — декомпилировать байт-код и сравнить его с исходным кодом.
Существует инструмент под названием Porosity , который делает именно это.
Рекомендовать использовать инструмент командной строки с открытым исходным кодом ConsenSys, только что выпущенный, bytecode-verifier , соответствующий пакет npm
Bytecode Verifier — это удобный инструмент командной строки для проверки локально скомпилированного байт-кода целевого контракта Solidity по сравнению с его фактическим байт-кодом, хранящимся в блокчейне Etheruem, с указанием адреса контракта.
целостность / правильность байт-кода : то, что на самом деле хранится в цепочке, правильно скомпилировано из конкретного контракта, что может быть полезно в случае нетривиального развертывания контракта потенциального держателя с высокой стоимостью (например, MultiSig Wallet), особенно контракт развертывается через третье партийная платформа.
Минимум усилий, простота в использовании : компилятор Solidity требует сверхурочной работы с небольшими и некоторыми крупными изменениями, что усложняет проверку байт-кода. (поскольку на Ethereum Stack Exchange задают повторяющиеся вопросы «байт-код не соответствует»). Bytecode Verifier был протестирован на соответствие последней версии вплоть до некоторых из самых старых развернутых контрактов.
- Удобен для тестовой сети : большинство проектов запускаются в тестовой сети перед развертыванием контрактной системы в основной сети. Этот инструмент поддерживает Rinkeby, Kovan и Ropsten Testnet, которые представляют собой три активных, хорошо поддерживаемых тестовых сети, которые использует большинство разработчиков Ethereum.
Надеюсь, поможет!
Вот как я это делаю в сценарии web3.
Сначала скомпилируйте код.
const solc = require('solc');
//contract sources
const contractPath = "../contracts/";
const input = {
"ContractName.sol" : fs.readFileSync(contractPath + 'contractName.sol', 'utf8'),
}
let solcOutput = await solc.compile({ sources: input }, 1);
теперь сравните байт-код
let blockCode = await web3.eth.getCode(contractAddress);
let solcCode = '0x' + (solcOutput.contracts["contractName.sol:contracName"].runtimeBytecode);}
Охотник на оленей