Создайте ваш первый dApp и смарт-контракт

Добрый день, читатели Хабра, представляю перевод статьи по разработке dApp. Приятного чтения.
Мир онлайн-технологий быстро переходит к веб 3.0 (перевод этой статьи можете найти здесь). Похоже, что люди устали от централизованных систем, где их цифровая конфиденциальность ежедневно нарушается огромными организациями. Также хочется найти решение этой проблемы, и веб 3.0, похоже, на данный момент является ответом.
Эта статья в блоге не предназначена для освещения ноу-хау блокчейна и децентрализованных систем. Вместо этого он предназначен для тех, кто хотел бы создать онлайн-решения для пользователей, клиентов и покупателей, чтобы гарантировать им лучшую конфиденциальность и безопасность их данных.
Прояснив это, в данной статье я собираюсь показать вам азбуку того, как создать децентрализованное приложение с нуля и настроить среду разработки. Ниже перечислены некоторые темы, которые мы рассмотрим.
-
Инструменты
-
Настройка инструментов
-
Написание кода
Инструменты
b. Ganache
d. Metamask
e. React 17.0.2
Чтобы перейти к делу, я хотел бы вкратце рассказать о вышеупомянутых инструментах.
Первый из них, Truffle Framework, предлагает набор инструментов для разработки смарт-контрактов Ethereum. Он предлагает такие инструменты, как управление смарт-контрактами, развертывание и миграция, управление сетью, консоль разработки и т.д.
Ganache — это персональный блокчейн, который представляет собой локальный блокчейн для разработки, который можно использовать для имитации поведения публичного блокчейна.
Solidity — объектно-ориентированный язык высокого уровня для реализации смарт-контрактов. Узнать больше о Solidity можно тут.
Большинство браузеров в настоящее время не позволяют нам подключаться к сети блокчейн, поэтому я бы использовал расширение Metamask chrome, которое позволит нам подключить наш браузер chrome к сети блокчейн.
Для разработки пользовательского интерфейса или фронт-энда мы будем использовать библиотеку React, которая является одной из наиболее широко используемых библиотек JavaScript среди фронт-эндовых сообществ.
Web3.js — это библиотека JavaScript, которая позволяет нам общаться с блокчейном Ethereum. Она превращает наше приложение React в приложение с поддержкой блокчейна.
Настройка инструментов
Теперь, когда я кратко рассказал о наборе инструментов, которые будут использоваться в этой статье блога, пришло время разобраться и настроить инструменты.
Прежде всего, я хотел бы, чтобы вы скачали Truffle Framework и установили его с помощью следующей команды:
npm install -g truffle
Затем загрузите и установите Ganache. Когда вы это сделаете и откроете его, то увидите следующее окно:

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

Написание кода
Теперь, когда инструменты настроены, перейдем к следующему шагу — написанию смарт-контрактов. Для этого откройте терминал и создайте папку в папке projects с помощью следующей команды:
mkdir blockchain
Теперь создайте папку внутри папки blockchain с помощью следующих команд:
cd blockchain
mkdir contracts
cd contracts
Теперь выполните приведенную ниже команду для создания проекта truffle, который позволит нам разрабатывать смарт-контракты:
truffle init
Выполнив вышеуказанную команду, вы должны получить результат, как показано ниже:

Теперь откройте ваш проект truffle в вашем любимом текстовом редакторе. Я собираюсь использовать Sublime Text. Вы должны увидеть следующую структуру папок и файлов:

В папке contracts мы будем писать наши смарт-контракты.
В папке migrations мы будем мигрировать наши вновь созданные смарт-контракты.
В папке test мы обычно пишем тесты для проверки нашего смарт-контракта, однако это выходит за рамки данной статьи, поэтому мы не будем углубляться в эту тему. Я бы настоятельно рекомендовал писать тесты для ваших смарт-контрактов перед их развертыванием на публичных узлах блокчейна.
Файл truffle-config.js содержит всю конфигурацию проекта truffle.
Теперь давайте напишем наш смарт-контракт. Создайте новый файл и назовите его contacts.sol в папке contracts. Теперь откройте этот файл и напишите в нем следующий код:
pragma solidity >=0.4.22 <0.9.0;
Это всегда должна быть первая строка в файле смарт-контракта. Этим мы указываем версию Solidity.
Теперь давайте создадим наш первый смарт-контракт:
pragma solidity >=0.4.22 <0.9.0; contract Contacts { }
Мы можем написать смарт-контракт, используя ключевое слово contract, за которым следует название контракта, в данном случае Contacts.
Теперь, чтобы отслеживать количество контактов внутри нашего смарт-контракта, мы создадим переменную состояния.
pragma solidity >=0.4.22 <0.9.0; contract Contacts { uint public count = 0; // state variable }
Это специальная переменная, и любые данные, которые мы записываем в эту переменную, будут храниться в хранилище блокчейна. Мы используем специальное ключевое слово-модификатор, т.е. public, чтобы иметь доступ к этой переменной за пределами смарт-контракта. Затем мы присваиваем этой переменной значение 0.
Теперь у нас есть переменная состояния, и в ней есть значение. Давайте перейдем к фронт-энду и попробуем сначала получить доступ к этой публичной переменной состояния. С помощью этого подхода мы установим связь между приложением React и нашим смарт-контрактом.
Выполните следующие команды в папке blockchain, чтобы создать приложение React.
npx create-react-app contacts
cd contacts
если используете yarn
yarn add web3
если используете npm
npm install web3
Как вы можете видеть, мы также добавили web3.js в качестве зависимости для этого проекта, чтобы наше приложение react взаимодействовало с нашим смарт-контрактом.
Теперь откройте папку contacts в вашем любимом редакторе. Я использую Sublime Text.
Мы не будем настраивать структуру папок и реализовывать сложную архитектуру, потому что это выходит за рамки данной статьи в блоге.
Мы напишем весь наш код в файле App.js. Поэтому откройте этот файл в редакторе.
Напишите приведенный ниже код в файле App.js:
import { useEffect, useState } from 'react'; import Web3 from 'web3'; function App() { return ( <div> </div> ); } export default App;
Мы импортируем пару хуков из React и Web3 из Web3.js. Теперь создадим переменную состояния, как показано ниже:
import { useEffect, useState } from 'react'; import Web3 from 'web3'; function App() { const [account, setAccount] = useState(); // state variable to set account. return ( <div> </div> ); } export default App;
Теперь внутри хука useEffect мы создадим наш смарт-контракт, как показано ниже:
import { useEffect, useState } from 'react'; import Web3 from 'web3'; function App() { const [account, setAccount] = useState(); // state variable to set account. useEffect(() => { async function load() { const web3 = new Web3(Web3.givenProvider || 'http://localhost:7545'); const accounts = await web3.eth.requestAccounts(); setAccount(accounts[0]); } load(); }, []); return ( <div> Your account is: {account} </div> ); } export default App;
Теперь, чтобы успешно запустить эту клиентскую часть, нам нужно сделать несколько шагов в бэкенде. Давайте вернемся в папку contracts. Во-первых, откройте файл truffle-config.js и добавьте следующие свойства:
module.exports = { networks: { development: { host: "127.0.0.1", port: 7545, network_id: "*" } }, compilers: { solc: { optimizer: { enabled: true, runs: 200 } } } }
Теперь внутри папки migrations создайте новый файл и назовите его 2_deploy_contracts.js и вставьте приведенный ниже код:
const Contacts = artifacts.require("./Contacts.sol"); module.exports = function(deployer) { deployer.deploy(Contacts); };
Теперь в терминале введите приведенный ниже код для миграции вашего контракта:
truffle migrate
Вы должны увидеть результат, подобный приведенному ниже:

Теперь вернитесь в папку фронт-энда (папка contracts) и выполните приведенную ниже команду для запуска приложения:
yarn start
или
npm start
Это откроет ваше приложение React в браузере и запустит Metamask для взаимодействия с вашей блокчейн-сетью. Вы должны увидеть экран, как показано ниже:

В открывшемся окне нажмите кнопку Next, и перед вами откроется следующее окно.

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

Теперь, когда мы успешно подключились к нашему смарт-контракту и получили идентификатор счета. Давайте приступим к созданию новой функции внутри нашего смарт-контракта для получения списка контактов и передачи его на фронт-энд, чтобы отобразить их на экране.
Вернемся в папку contracts, откроем файл Contracts.sol и добавим следующую функцию.
pragma solidity >=0.4.22 <0.9.0; contract Contacts { uint public count = 0; // state variable struct Contact { uint id; string name; string phone; } constructor() public { createContact('Zafar Saleem', '123123123'); } mapping(uint => Contact) public contacts; function createContact(string memory _name, string memory _phone) public { count++; contacts[count] = Contact(count, _name, _phone); } }
Теперь снова мигрируйте этот контракт, поскольку мы внесли в него изменения, так как смарт-контракты иммутабельны.
truffle migrate
Теперь давайте вернемся к фронт-энду, то есть к папке contacts. Создайте новый файл config.js внутри папки src/ и вставьте в него приведенный ниже код.
export const CONTACT_ADDRESS = '0xfAd567EBdCb36f49F3a509FEDF9e72E3ad75ca59'; export const CONTACT_ABI = [ { "constant": true, "inputs": [], "name": "count", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0x06661abd" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "contacts", "outputs": [ { "name": "id", "type": "uint256" }, { "name": "name", "type": "string" }, { "name": "phone", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function", "signature": "0xe0f478cb" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor", "signature": "constructor" }, { "constant": false, "inputs": [ { "name": "_name", "type": "string" }, { "name": "_phone", "type": "string" } ], "name": "createContact", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function", "signature": "0x3dce4920" } ];
Теперь импортируйте адрес смарт-контракта и ABI в файл App.js, как показано ниже, а также обновите функцию load следующим кодом:
import { useEffect, useState } from 'react'; import Web3 from 'web3'; import { CONTACT_ABI, CONTACT_ADDRESS } from './config'; function App() { const [account, setAccount] = useState(); const [contactList, setContactList] = useState(); const [contacts, setContacts] = useState([]); useEffect(() => { async function load() { const web3 = new Web3(Web3.givenProvider || 'http://localhost:7545'); const accounts = await web3.eth.requestAccounts(); setAccount(accounts[0]); // Instantiate smart contract using ABI and address. const contactList = new web3.eth.Contract(CONTACT_ABI, CONTACT_ADDRESS); // set contact list to state variable. setContactList(contactList); // Then we get total number of contacts for iteration const counter = await contactList.methods.count().call(); // iterate through the amount of time of counter for (var i = 1; i <= counter; i++) { // call the contacts method to get that particular contact from smart contract const contact = await contactList.methods.contacts(i).call(); // add recently fetched contact to state variable. setContacts((contacts) => [...contacts, contact]); } } load(); }, []); return ( <div> Your account is: {account} </div> ); } export default App;
Приведенный выше код получит все контакты из нашего смарт-контракта и установит их в переменную состояния contacts. Код очень хорошо прокомментирован и объяснен.
Теперь давайте отобразим все контакты через тэг ul, как показано ниже.
import { useEffect, useState } from 'react'; import Web3 from 'web3'; import { CONTACT_ABI, CONTACT_ADDRESS } from './config'; function App() { const [account, setAccount] = useState(); const [contactList, setContactList] = useState(); const [contacts, setContacts] = useState([]); useEffect(() => { async function load() { const web3 = new Web3(Web3.givenProvider || 'http://localhost:7545'); const accounts = await web3.eth.requestAccounts(); setAccount(accounts[0]); // Instantiate smart contract using ABI and address. const contactList = new web3.eth.Contract(CONTACT_ABI, CONTACT_ADDRESS); // set contact list to state variable. setContactList(contactList); // Then we get total number of contacts for iteration const counter = await contactList.methods.count().call(); // iterate through the amount of time of counter for (var i = 1; i <= counter; i++) { // call the contacts method to get that particular contact from smart contract const contact = await contactList.methods.contacts(i).call(); // add recently fetched contact to state variable. setContacts((contacts) => [...contacts, contact]); } } load(); }, []); return ( <div> Your account is: {account} <h1>Contacts</h1> <ul> { Object.keys(contacts).map((contact, index) => ( <li key={`${contacts[index].name}-${index}`}> <h4>{contacts[index].name}</h4> <span><b>Phone: </b>{contacts[index].phone}</span> </li> )) } </ul> </div> ); } export default App;
Как вы можете увидеть обновленный код внутри return — отображает информацию о контакте. Вы должны увидеть что-то вроде следующего:

Если вы видите именно это, то поздравляем, вы только что создали свой первый dApp со смарт-контрактом и веб-приложением, которое взаимодействует с вашим смарт-контрактом на блокчейне.
Теперь, когда вы знаете, как получать информацию из смарт-контракта, продолжайте совершенствовать его, добавляя новые контакты, обновляя их и удаляя с помощью полных CRUD-операций.
На этом в данной статье все. Весь проект можно найти в репозитории.
Ниже приведены профили в социальных сетях, если захотите связаться с автором статьи.
ссылка на оригинал статьи https://habr.com/ru/post/653679/
Добавить комментарий