Децентрализованное приложение 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
За помощью: обращайтесь
- Шринивас Чинни
- [email protected]