Нажмите здесь, чтобы опубликовать эту статью в LinkedIn

Децентрализованное приложение Ethereum - это любое клиентское приложение, которое взаимодействует с блокчейном Ethereum. Этот документ предоставляет вам руководство по созданию децентрализованного приложения и тестированию на блокчейне Ethereum.

Инструменты и платформы

Я использую следующие инструменты и фреймворки для этого приложения на платформе Windows.

  • NodeJs и NPM
  • Трюфель - как инструмент развития.
  • Ганаш - как тестовая сеть разработки Ethereum.
  • Метамаск - как инжектор Web3 Api
  • Angular-cli - как фреймворк для веб-клиентского приложения.

Шаги

  • Скачайте и установите Ganache
  • Установить трюфель
  • Создать структуру проекта трюфелей
  • Создать смарт-контракт
  • Скомпилируйте и разверните смарт-контракт
  • Создать приложение angular 5
  • Взаимодействие с блокчейном с помощью вызова метода смарт-контракта

1. Установите Ganache.

Скачайте и установите ганаш на основе вашей ОС. ganache имеет графический интерфейс и режим командной строки. давайте использовать GUI один сейчас.



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

2. Трюфельный проект

Установите трюфель, используя npm install -g truffle

Создайте каталог ethereumdapp mkdir ethereumdapp

Создайте проект трюфеля, используя truffle init.

D:\blockchain\ethereum>npm install -g truffle
D:\blockchain\ethereum>mkdir ethereumdapp
D:\blockchain\ethereum>cd ethereumdapp
D:\blockchain\ethereum\ethereumdapp>truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
D:\blockchain\ethereum\ethereumdapp>dir
03/24/2018 05:15 PM <DIR> .
03/24/2018 05:15 PM <DIR> ..
03/24/2018 05:15 PM <DIR> contracts
03/24/2018 05:15 PM <DIR> migrations
03/24/2018 05:15 PM <DIR> test
03/24/2018 05:15 PM 135 truffle-config.js
03/24/2018 05:15 PM 135 truffle.js
2 File(s) 270 bytes
5 Dir(s) 222,028,505,088 bytes free

3. Создайте простой смарт-контракт.

Теперь создадим файл смарт-контракта. мы используем Solidity в качестве контрактного языка программирования версии 0.4.19. Цель этого контракта - инициировать переменную состояния с именем «name» в цепочке блоков и управлять этим значением этой переменной, вызывая наш метод смарт-контракта из децентрализованного приложения. Пользователь изменяет значение переменной имени и показывает изменение на странице.

Название контракта - «NameChange»

Метод имени представления - "showName ()"

Метод изменения имени - changename (строка)

Давайте создадим файл NameChange.sol в папке «контракты» в папке нашего проекта (ethereumdapp). добавить это содержимое в NameChange.sol

pragma solidity ^0.4.19;

contract NameChange{
	string name;
	function NameChange(string initialname) public {
		name = initialname;
	}
	function showName() public constant returns(string) {
		return name;
	}	
	function changename(string newname)public { 
		name = newname;
    }
}

4. Составить договор.

Используйте "truffle compile" для составления контракта.

D:\blockchain\ethereum\ethereumdapp>truffle compile
Compiling .\contracts\Migrations.sol...
Compiling .\contracts\NameChange.sol...
Writing artifacts to .\build\contracts

Он создает NameChange.json в папке / build, эти файлы содержат сведения о ABI для контракта, то есть двоичный интерфейс приложения. Двоичный интерфейс приложения (ABI) - это схема кодирования данных, используемая в Ethereum для работы со смарт-контрактами. Это можно использовать на более позднем этапе этого процесса.

5. Разверните контракт.

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

Мы можем предоставить эту информацию truffle.js или truffle-config.js в папке проекта.

module.exports = {
  networks: {
    development: {
      host: '127.0.0.1',
      port: 7545,
      network_id: '*' // Match any network id
    }
  }};

Приведенная выше конфигурация сообщает этой команде развертывания о развертывании контракта в ganache. Для развертывания используйте команду «truffle migrate» для переноса / развертывания контракта. И нам нужно указать, как создать экземпляр для контракта и отправить начальные параметры, если они требуются конструктору контракта. для этого нам нужно создать 2_deploy_namechange.js в папке migrations в проекте

var NameChange = artifacts.require("./NameChange.sol");
module.exports = function(deployer) {
  deployer.deploy(NameChange,"initial name from chain");
};

Все готово к развертыванию контракта.

D:\blockchain\ethereum\ethereumdapp> truffle migrate
Using network 'development'.
Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0xd0b495e94047c454c62eaa31533491d559de11c84914b5d4a9ce0f7b5703ef57
  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_namechange.js
  Replacing NameChange...
  ... 0x4dcf9df45f91b76d204eb86f3e839d9257c7b15008fc5efb6b14abbe0bbdfdf2
  NameChange: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network...
  ... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts...

На этом этапе контракт развертывается в ганаше и генерируется адрес контракта.

Это можно подтвердить в списке транзакций ганаша.

6. приложение

Это приложение angular 5, в котором мы предоставляем пользователю интерфейс для взаимодействия с блокчейном t. Мы используем команды angular-cli для создания / запуска приложения.

Смените каталог на предыдущий уровень и выполните «ng new ethereumdapp»

D:\blockchain\ethereum\ethereumdapp>cd..
D:\blockchain\ethereum>ng new ethereumdapp

Давайте добавим пользовательский интерфейс для просмотра значения переменной состояния цепочки блоков на странице и возможность изменения значения.

Добавьте следующий код в src \ app \ app.component.html

<section class="hero is-medium is-info is-bold">
  <div class="hero-body">
    <div class="container">
      <h1 class="title is-1">
        Name change dapp
      </h1>
      <h2 class="title">
        Your Name is: <span class="is-medium has-underline">{{name}}</span>
      </h2>
    </div>
  </div>
</section>
<br>
<div class="container">
  <h1 class="title">Change Name</h1>
  <h1 class="title is-4 is-info help">{{status}}</h1>

  <form #nameForm="ngForm">
    <div class="field">
      <label class="label">New Name</label>
      <p class="control">
        <input
          [(ngModel)]="NewName"
          class="input"
          type="text"
          placeholder="New Name"
          name="NewName"
          required
          #nameChangeModel="ngModel">
      </p>
      <div *ngIf="nameChangeModel.errors && (nameChangeModel.dirty || nameChangeModel.touched)"
           class="help is-danger">
          <p [hidden]="!nameChangeModel.errors.required">
            This field is required
          </p>
      </div>
    </div>
    
    <div class="field is-grouped">
      <p class="control">
        <button
          [disabled]="!nameForm.valid"
          (click)="changeName()"
          class="button is-primary">
          Send
        </button>
      </p>
    </div>
  </form>
</div>

Код компонента / контроллера пользовательского интерфейса в src \ app \ app.component.ts

import { Component, HostListener, NgZone } from '@angular/core';
const Web3 = require('web3');
const contract = require('truffle-contract');
const nameChangeArtifacts = require('../../build/contracts/NameChange.json');

declare var window: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Initial name from component';
  NewName : string;
  nameChange = contract(nameChangeArtifacts);

  account: any;
  accounts: any;
  web3: any;
  status: string;
  constructor(private _ngZone: NgZone) {

  }
  @HostListener('window:load')
  windowLoaded() {
    this.checkAndInstantiateWeb3();
    this.onReady();
  }

  checkAndInstantiateWeb3 = () => {
    // Checking if Web3 has been injected by the browser (Mist/MetaMask)
    if (typeof window.web3 !== 'undefined') {
      console.warn(
        'Using web3 detected from external source. If you find that your accounts don\'t appear or you have 0 MetaCoin, ensure you\'ve configured that source properly. If using MetaMask, see the following link. Feel free to delete this warning. :) http://truffleframework.com/tutorials/truffle-and-metamask'
      );
      // Use Mist/MetaMask's provider
      this.web3 = new Web3(window.web3.currentProvider);
    } else {
      console.warn(
        'No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live, as it\'s inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask'
      );
      // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
      this.web3 = new Web3(
        new Web3.providers.HttpProvider('http://127.0.0.1:7545')
      );
    }
  };

  onReady = () => {
    // Bootstrap the MetaCoin abstraction for Use.
    this.nameChange.setProvider(this.web3.currentProvider);

    // Get the initial account balance so it can be displayed.
    this.web3.eth.getAccounts((err, accs) => {
      if (err != null) {
        alert('There was an error fetching your accounts.');
        return;
      }

      if (accs.length === 0) {
        alert(
          'Couldn\'t get any accounts! Make sure your Ethereum client is configured correctly.' 
        );
        return;
      }
      console.log(accs);
      this.accounts = accs;
      this.account = this.accounts[0];

      // This is run from window:load and ZoneJS is not aware of it we
      // need to use _ngZone.run() so that the UI updates on promise resolution
      this._ngZone.run(() =>
        this.refreshName()
      );
    });
  };

  refreshName = () => {
    let nc;
    this.nameChange
      .deployed()
      .then(instance => {
        nc = instance;
        return nc.showName.call({
          from: this.account
        });
      })
      .then(value => {
        this.name = value;
      })
      .catch(e => {
        console.log(e);
        this.setStatus('Error getting name; see log.');
      });
  };

  changeName = () => {
    const nawname = this.NewName;
    let nc;

    this.setStatus('Initiating transaction... (please wait)');

    this.nameChange
      .deployed()
      .then(instance => {
        nc = instance;
        return nc.changename(nawname,{from: this.account})
      })
      .then(() => {
        this.setStatus('Transaction complete!');
        this.refreshName();
      })
      .catch(e => {
        console.log(e);
        this.setStatus('Error changing name; see log.');
      });
  };
  setStatus = message => {
    this.status = message;
  };
}

7. Метамаск

Metamask действует как инжектор web3 на нашу страницу.

  • Добавьте расширение в свой браузер Chrome
  • Добавьте собственный RPC с вашим URL-адресом ganache rpc, который будет http: // localhost: 7545

  • Вы можете увидеть свою первую учетную запись, сгенерированную ганашем, в списке учетных записей метамасков.
  • Пользователь отправляет изменение имени со страницы, которая вызывает метод контракта.
  • Метамаск запрашивает подтверждение, нажмите «Отправить» при подтверждении метамаска.

Теперь готово к работе с приложением. Измените каталог на ethereumdapp.

D:\blockchain\ethereum>cd ethereumdapp
D:\blockchain\ethereum\ethereumdapp>ng serve -o

Он открывает браузер с http: // localhost: 4200 и показывает нашу страницу.

Введите имя в текстовое поле новое имя и нажмите кнопку отправки. Metamask принимает подтверждение для отправки транзакции в блокчейн, нажмите «Отправить».

после отправки на вашей странице отображается новое имя

8. Заключение

Спасибо

загрузите исходный код с https://github.com/cnu-online/ethereum-dapp

За помощью: обращайтесь