При написании этой статьи я использовал Parity 1.7.8-stable (Parity/v1.7.8-stable-d5fcf3b-20171025/x86_64-macos/rustc1.21.0) в качестве клиента Ethereum. Вы можете найти руководство по установке на этом сайте: Parity — быстрый, легкий и надежный клиент Ethereum или, если вы используете macOSX, следуйте инструкциям, описанным в следующем абзаце.

На следующем сайте вы можете найти пакеты Parity: https://d1h4xl4cr1h0mo.cloudfront.net/. Пожалуйста, имейте в виду, что если выходит новая версия четности, то обычно старые пакеты удаляются.

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

Установка четности на macOSX

Если у вас еще не установлен менеджер пакетов homebrew, выполните:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

а теперь установка паритета:

brew tap paritytech/paritytech
brew install parity --stable

Начальный паритет

Для целей этой статьи мы начнем паритет с:

  • определение частной цепочки разработки --chain=dev
  • JSON RPC API: --jsonrpc-apis web3,rpc,personal,parity_accounts,eth,net,parity,parity_set,signer
  • цена газа установлена ​​на 0 --gasprice 0
  • IP-адрес интерфейса --ui-interface 0.0.0.0
  • отключена проверка имени хоста --ui-no-validation
  • разрешить всем хостам (значения заголовка хоста) использовать JSON RPC API --jsonrpc-hosts all
  • IP-адрес интерфейса — все интерфейсы --jsonrpc-interface all
parity --chain=dev --jsonrpc-apis web3,rpc,personal,parity_accounts,eth,net,parity,parity_set,signer --gasprice 0 --ui-interface 0.0.0.0 --ui-no-validation --jsonrpc-hosts all --jsonrpc-interface all

Теперь нам нужна учетная запись с некоторым количеством эфира, чтобы иметь возможность выполнять транзакции. Цепочка разработки Parity позволяет вам создать учетную запись с практически неограниченным количеством эфира, но только в цепочке разработки. Вы не найдете создание такой учетной записи как обычную опцию пользовательского интерфейса, она доступна как хак. Пожалуйста, сначала откройте ссылку на паритетный пользовательский интерфейс (http://0.0.0.0:8180/) и откройте АККАУНТЫ, а затем ВОССТАНОВИТЕ, вы должны увидеть:

Хитрость заключается в том, чтобы восстановить учетную запись с пустой фразой восстановления. Пожалуйста, заполните имя учетной записи, подсказку для пароля, пароли и нажмите ИМПОРТ в правом нижнем углу:

После создания учетной записи вы должны увидеть:

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

  • адрес для разблокировки --unlock 0x00a329c0648769A73afAc7F9381E08FB43dBEA72
  • пароль пользователя для указанной учетной записи для разблокировки --password ./password, где ./password — путь к файлу, содержащему пароль пользователя
parity --chain=dev --jsonrpc-apis web3,rpc,personal,parity_accounts,eth,net,parity,parity_set,signer --gasprice 0 --ui-interface 0.0.0.0 --ui-no-validation --jsonrpc-hosts all --jsonrpc-interface all --unlock 0x00a329c0648769A73afAc7F9381E08FB43dBEA72 --password ./password

Что должно привести к чему-то вроде этого:

Узел четности готов! :)

Создание и тестирование смарт-контракта — Truffle

Самый быстрый и простой известный мне способ создания, тестирования и создания смарт-контрактов — это использование инструмента трюфель. Вы можете установить truffle с помощью менеджера пакетов npm (версия узла 6.11.4):
npm install -g [email protected]

Теперь подготовьте пустую папку для вашего нового проекта и выполните следующую команду, чтобы инициализировать структуру проекта truffle:

truffle init

затем откройте и отредактируйте файл конфигурации truffle.js, параметр from - это адрес, с которого по умолчанию должны выполняться все транзакции трюфелей, пожалуйста, установите в качестве значения адрес уже созданной/восстановленной учетной записи.

module.exports = {  
  // See <http://truffleframework.com/docs/advanced/configuration>  
    networks: { 
        development: {  
            host: "localhost",  
            port: 8545, 
            network_id: "*",    
            from: "0x00a329c0648769A73afAc7F9381E08FB43dBEA72", 
            gas: 5959115    
        }   
    }   
};

Для этой статьи я решил создать смарт-контракт, в котором хранится сумма всех значений, добавленных путем вызова метода add. Метод add может вызываться только владельцем смарт-контракта.

pragma solidity ^0.4.17;    
    
contract TestSmartContract {    
    address public owner;   
    uint public total;  
    
    modifier restricted() { 
        if (msg.sender == owner) _; 
    }   
    
    function TestSmartContract() public {   
        owner = msg.sender; 
    }   
    
    function add(uint amount) public restricted {   
        total = total + amount; 
    }   
}

Имея смарт-контракт, нам нужно создать миграцию, которая развернет этот смарт-контракт. Для этого нам нужно создать новый файл: 2_test_smart_contract.js внутри папки migrations:

var TestSmartContract = artifacts.require("./TestSmartContract.sol");      
module.exports = function(deployer) {   
    deployer.deploy(TestSmartContract); 
};

Теперь нам нужно выполнить миграцию, выполнив:

truffle migrate

Мы готовы приступить к написанию и выполнению модульных тестов. Ниже вы можете найти два юнит-теста, первый утверждает, что если мы вызовем метод add со значением 4, то сумма будет равна 4, а второй — если мы добавим: 6, 4, 20, сумма будет равна 30. В beforeEach Блок мы создаем новый смарт-контракт и читаем адрес владельца контракта.

const TestContract = artifacts.require('TestSmartContract');

let TestContractDeployed;
let ContractOwner;

contract('TestContract', (accounts) => {

    beforeEach('prepare', () => {
        return TestContract.new().then((instance) => {
            TestContractDeployed = instance;
            return TestContractDeployed.owner();
        }).then(function (owner) {
            ContractOwner = owner;
        });
    });

    describe('test add method', () => {

        it('total should be 4 if add(4)', (done) => {
            TestContractDeployed.add(4, {from: ContractOwner}).then(function () {
                TestContractDeployed.total({from: ContractOwner}).then(function (res) {
                    assert.equal(res.valueOf(), 4);
                    done();
                });
            });
        });

        it('total should be 30 if add(6);add(4);add(20);', (done) => {
            Promise.all([
                TestContractDeployed.add(6, {from: ContractOwner}),
                TestContractDeployed.add(4, {from: ContractOwner}),
                TestContractDeployed.add(20, {from: ContractOwner})
            ]).then(() => {
                TestContractDeployed.total({from: ContractOwner}).then(function (res) {
                    assert.equal(res.valueOf(), 30);
                    done();
                });
            });
        });

    });

});

Для получения дополнительной информации определенно стоит посетить truffle docs

Надеюсь, вам понравилось! :)

Даниэль Макурат

Создание приложений @ Bright Inventions

Электронная почта Гитхаб