pengantar
Pada artikel ini, saya akan mencoba membahas semua poin untuk membuat aplikasi Terdesentralisasi lengkap di jaringan Ethereum sesingkat dan seinformatif mungkin menggunakan kerangka kerja JavaScript - Vue untuk membuat aplikasi web dan perpustakaan ethers.js untuk berkomunikasi dengan kontrak pintar. Kami juga akan mempertimbangkan beberapa poin tentang cara memasang dan menghubungkan dompet, cara menerapkan kontrak ke jaringan menggunakan truffle , dll.
Beberapa poin mungkin tampak sangat jelas dan tidak sulit, jadi Anda dapat melewatinya.
Yang perlu Anda ketahui sebelum memulai:
Pengetahuan yang baik tentang js, khususnya Vue.js
Memahami prinsip-prinsip Blockchain (kontrak pintar)
Pengetahuan dasar bahasa pr. Soliditas
Memasang dompet
Kami akan menggunakan dompet Metamask untuk mengonfirmasi transaksi, berkomunikasi dengan kontrak dan memeriksa beberapa parameter transaksi ini . Dia cukup bagus dan saya hampir tidak pernah punya masalah dengan pekerjaannya. Saya tidak akan menunjukkan proses instalasi, semuanya jelas di sana.
Saat ekstensi dipasang, Anda akan diminta untuk membuat dompet atau mengimpor jika tersedia. Setelah membuat akun, frase mnemonik akan dibuatkan untuk Anda. JANGAN PERNAH mengungkapkannya kepada SIAPA PUN. Dan voila - kami memiliki alamat dompet yang sudah jadi)
Karena kami akan mengembangkan aplikasi contoh, lebih baik menggunakan jaringan uji, agar tidak menghabiskan uang sungguhan untuk menerapkan kontrak dan melaksanakan transaksi. Ropsten sempurna untuk tugas kita.
-. . README ( ). - -. - , . , . IDE Remix.
Truffle.js. node.js. npm ( ): npm install -g truffle
npm install -g @truffle/hdwallet-provider
, Truffle truffle init.
truffle-config.js. . Infura Ethereum -> Create New Project (UI) dApps - Ethereum. Infura , Ethereum , . -> Settings -> Endpoints Ropsten .
, , truffle-config.js. -, .secret . dotenv, , truffle. -, :
const HDWalletProvider = require('@truffle/hdwallet-provider');
const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
ropsten: {
provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
network_id: 3, // Ropsten's id
gas: 5500000, // Ropsten has a lower block limit than mainnet
confirmations: 2, // # of confs to wait between deployments. (default: 0)
timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
},
HDWalletProvider
.
-, .sol contracts, . migrations js :
const SimpleMarketplace = artifacts.require("SimpleMarketplace");
module.exports = function (deployer) {
deployer.deploy(SimpleMarketplace, 'description', 1000);
};
, migrations 1_initial_migrations.js, 2.
- deploy : description price . , , SimpleMarketplace.
truffle compile
. : , @truffle/hdwallet-provider,(Error: Cannot find module '@truffle/hdwallet-provider')
, npm install @truffle/hdwallet-provider
. -g
. Compiled successfully using...
.
truffle migrate --network ropsten --reset
. ropsten
- , truffle-config.js, --reset , ( ).: : var e = new Error('ETIMEDOUT')
, truffle-config.js HDWalletProvider
, Infura - wss://ropsten.infura.io/ws/v3/YOUR-PROJECT-ID.
Etherscan , - , blockchain .
Vue.js
. assets ( Vue.js, ), HelloWorld.vue components App.vue ( HelloWorld.vue, components <div id="app">
).
<template>
<div id="app">
</div>
</template>
<script>
export default {
name: 'App',
components: {
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
npm run serve
, , , .
- UI -. components , , Marketplace.vue. core core.js , , ./build/contracts JSON - ( ). - - , . , . . - npm install ethers
.
core.js , JSON - :
const { ethers } = require('ethers')
const ContractArtifact = require('./SimpleMarketplace.json')
const CONTRACT_ADDRESS = ContractArtifact.networks['3'].address
ABI, , ( . public , public view returns ethers ):
const ABI = [
'function InstanceOwner () public view returns(address)',
'function Description () public view returns(string)',
'function AskingPrice () public view returns(int)',
'function InstanceBuyer () public view returns(address)',
'function OfferPrice () public view returns(int)',
'function MakeOffer(int offerPrice) public',
'function Reject() public',
'function AcceptOffer() public'
]
:
let provider = new ethers.providers.Web3Provider(window.ethereum)
// Blockcain
let readOnlyContract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider)
// view
let signer = provider.getSigner()
//
let contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer)
let contractSigner = contract.connect(signer)
//
Vue :
export default {
async getDescription() {
const description = await readOnlyContract.Description()
return {description: description}
}
}
, . - :
const { ethers } = require('ethers')
const ContractArtifact = require('./SimpleMarketplace.json')
const CONTRACT_ADDRESS = ContractArtifact.networks['3'].address
const ABI = [
'function InstanceOwner () public view returns(address)',
'function Description () public view returns(string)',
'function AskingPrice () public view returns(int)',
'function InstanceBuyer () public view returns(address)',
'function OfferPrice () public view returns(int)',
'function MakeOffer(int offerPrice) public',
'function Reject() public',
'function AcceptOffer() public'
]
let provider = new ethers.providers.Web3Provider(window.ethereum)
let readOnlyContract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider)
let signer = provider.getSigner()
let contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer)
let contractSigner = contract.connect(signer)
export default {
async getInstanceOwner() {
const instanceOwner = await readOnlyContract.InstanceOwner()
return {instanceOwner: instanceOwner}
},
async getDescription() {
const description = await readOnlyContract.Description()
return {description: description}
},
async getAskingPrice() {
const askingPrice = await readOnlyContract.AskingPrice()
return {askingPrice: askingPrice}
},
async getInstanceBuyer() {
const instanceBuyer = await readOnlyContract.InstanceBuyer()
return {instanceBuyer: instanceBuyer}
},
async getOfferPrice() {
const offerPrice = await readOnlyContract.OfferPrice()
return {offerPrice: offerPrice}
},
async makeOffer(offerPrice) {
const txResponse = await contractSigner.MakeOffer(offerPrice, {gasLimit: 300000})
const txReceipt = await txResponse.wait()
return {transaction: txReceipt.transactionHash}
},
async reject() {
const txResponse = await contractSigner.Reject({gasLimit: 300000})
const txReceipt = await txResponse.wait()
return {transaction: txReceipt.transactionHash}
},
async acceptOffer() {
const txResponse = await contractSigner.AcceptOffer({gasLimit: 300000})
const txReceipt = await txResponse.wait()
return {transaction: txReceipt.transactionHash}
}
}
App.vue mounted $root core.js:
const core = require('./core/core')
/*
-
*/
mounted() {
window.ethereum.request({ method: 'eth_requestAccounts' })
this.$root.core = core.default
}
, data details methods :
data() {
return {
instanceOwner: '',
description: '',
askingPrice: '',
instanceBuyer: '',
offerPrice: ''
}
},
methods: {
async details() {
this.instanceOwner = (await this.$root.core.getInstanceOwner()).instanceOwner
this.description = (await this.$root.core.getDescription()).description
this.askingPrice = (await this.$root.core.getAskingPrice()).askingPrice
this.instanceBuyer = (await this.$root.core.getInstanceBuyer()).instanceBuyer
this.offerPrice = (await this.$root.core.getOfferPrice()).offerPrice
}
},
:
<button v-on:click="details">Get details</button>
<h3>Instance owner: {{ instanceOwner }}</h3>
<h3>Description: {{ description }}</h3>
<h3>Asking price: {{ askingPrice }}</h3>
<h3>Instance buyer: {{ instanceBuyer }}</h3>
<h3>Offer price: {{ offerPrice }}</h3>
Anda dapat memeriksa kode komponen Marketplace.vue di repositori saya agar tidak mengacaukan artikel dengan kode yang tidak perlu.
Setelah memulai proyek, Anda akan melihat jendela koneksi dompet seperti ini:
Dan setelah itu, saat kami mengklik tombol Dapatkan detail , kami akan menerima data yang kami masukkan saat menerapkan kontrak.
Dan seperti inilah keluarannya jika Anda melakukan transaksi:
Kesimpulan
Ini artikel pertamaku. Saya akan senang jika memiliki beberapa pertanyaan dan bahkan kritik, karena saya sendiri belum ahli dalam semua ini.
Tautan ke kontrak tempat Anda dapat memeriksa transaksi.