สร้าง dapp บน Tezos (ฉบับปี 2023)
ส่วนที่ 1 จาก 4-> การตั้งค่า Dapp
เนื่องจาก Dapp จะถูกสร้างด้วยTypeScriptจึงจำเป็นต้องมีความรู้ที่ดีเกี่ยวกับภาษาโปรแกรมนี้ เราจะใช้ เฟรมเวิร์ก Svelteเพื่อพัฒนาแอปพลิเคชัน โดยไม่จำเป็นต้องมีความรู้มาก่อนเนื่องจากค่อนข้างใช้งานง่าย และฉันจะอธิบายวิธีการทำงานไปพร้อมกัน
เนื่องจาก 99% ของ dapps ในระบบนิเวศ dapp นี้จะใช้Taquitoซึ่งเป็นไลบรารี TypeScript ที่จะมอบประสบการณ์การใช้งาน Tezos blockchain ให้กับนักพัฒนาได้ดียิ่งขึ้น
สัญญาการอบสภาพคล่อง
มีสัญญาพิเศษบน Tezos ที่เรียกว่าสัญญาLiquidity Baking สัญญานี้เป็นการแลกเปลี่ยนแบบกระจายอำนาจ (หรือ DEX) ที่จัดการเพียง 3 โทเค็น: XTZ (โทเค็นดั้งเดิมของ Tezos), tzBTC (โทเค็นแบบรวมเพื่อใช้ Bitcoin บน Tezos) และ SIRS (สำหรับ Sirius โทเค็นที่แสดงถึงจำนวนที่เท่ากันของ เพิ่มสภาพคล่องใน XTZ และ tzBTC ในสัญญา)
ความพิเศษของสัญญานี้คือทุกครั้งที่มีการอบบล็อกใหม่บน Tezos 2.5 XTZ จะถูกเพิ่มเข้าไปในสัญญา ผู้ใช้คาดว่าจะนำ tzBTC มาใช้เพื่อรักษาสมดุลของสภาพคล่อง DEX และราคาของ SIRS ให้คงที่
สัญญายังเป็นแบบสาธารณะอย่างสมบูรณ์ ซึ่งหมายความว่าใครก็ตามที่มีกระเป๋าเงิน Tezos สามารถโต้ตอบกับมันเพื่อแลกเปลี่ยน XTZ เป็น tzBTC และในทางกลับกัน ให้สภาพคล่องหรือลบออก ซึ่งเป็นสิ่งที่เรากำลังจะทำในบทช่วยสอนนี้
เราจะสร้างอะไร
ในบทช่วยสอนนี้ เราจะสร้างอินเทอร์เฟซ dapp ที่โต้ตอบกับสัญญา LB เพื่อแลกเปลี่ยนโทเค็น เพิ่มสภาพคล่อง และลบออก Dapp จะจัดการการกระทำต่างๆ:
- แสดงข้อมูลผู้ใช้ เช่น ยอดคงเหลือ XTZ, tzBTC และ SIRS และอัปเดตหลังจากการทำธุรกรรมแต่ละครั้ง
- การเชื่อมต่อและตัดการเชื่อมต่อกระเป๋าเงินของผู้ใช้
- แสดงข้อมูลกระเป๋าเงิน เช่น สถานะการเชื่อมต่อและเครือข่ายที่เชื่อมต่ออยู่
- แสดงอินเทอร์เฟซต่างๆ เพื่อแลกเปลี่ยนโทเค็น เพิ่มและลบสภาพคล่อง
- อนุญาตให้ผู้ใช้แลกเปลี่ยน XTZ เป็น tzBTC และ tzBTC เป็น XTZ
- อนุญาตให้ผู้ใช้เพิ่มสภาพคล่องโดยให้ XTZ และ tzBTC และรับ SIRS ในการแลกเปลี่ยน
- อนุญาตให้ผู้ใช้ลบสภาพคล่อง เช่น แลกโทเค็น SIRS และรับโทเค็น XTZ และ tzBTC ในการแลกเปลี่ยน
เนื่องจากแอปพลิเคชันแบบกระจายอำนาจในท้ายที่สุดคือแอปพลิเคชันบนเว็บ เราจะใช้เครื่องมือต่อไปนี้เพื่อสร้างแอปพลิเคชันดังกล่าว:
- Svelte สำหรับเฟรมเวิร์ก JavaScript
- TypeScript เพื่อทำให้โค้ด JavaScript ของเราปลอดภัยและแสดงออกมากขึ้น
- Sass เป็นตัวประมวลผลล่วงหน้า CSS
- Vite เพื่อรวมแอปพลิเคชัน (ออกเสียงเหมือนveet )
- Taquito เพื่อโต้ตอบกับ Tezos blockchain
- Beacon และไลบรารี wrapper ที่ Taquito จัดหาให้ใช้กระเป๋าเงิน Tezos
- สเวลเต้ =>https://svelte.dev/
- TypeScript =>https://www.typescriptlang.org/
- สัส =>https://sass-lang.com/
- ไวท์ =>https://vitejs.dev/
- ทากีโต =>https://tezostaquito.io/
- สัญญาณ =>https://docs.walletbeacon.io/
- GitHub repo กับ dapp =>https://github.com/claudebarde/tezos-dev-portal-tutorial
ขณะที่เรากำลังสร้างเว็บแอปด้วยเฟรมเวิร์ก Svelte ขั้นตอนในการตั้งค่าโปรเจกต์จะคล้ายกันมากกับขั้นตอนที่คุณต้องทำเพื่อตั้งค่าเว็บแอปอื่นๆ
ในบทช่วยสอนนี้ เราจะสร้าง Svelte SPA ดังนั้นเราจึงไม่ต้องใช้ SvelteKit ซึ่งจะทำให้ชีวิตของเราง่ายขึ้นด้วย
สิ่งแรกที่ต้องทำคือติดตั้ง Svelte ด้วย TypeScript และ Vite:
npm create vite@latest lb-dex -- --template svelte-ts
cd lb-dex
npm install
npm install --save-dev sass
npm install @taquito/taquito @taquito/beacon-wallet
มีไลบรารีอื่นอีกสองสามรายการที่เราต้องติดตั้ง:
npm install --save-dev buffer events vite-compatible-readable-stream
เมื่อติดตั้งทุกอย่างเรียบร้อยแล้ว เราจะต้องตั้งค่าคอนฟิกให้ถูกต้อง
ในappโฟลเดอร์ของคุณ คุณจะเห็นvite.config.jsไฟล์ ซึ่งเป็นไฟล์ที่มีการกำหนดค่าที่ Vite จำเป็นต้องใช้เพื่อเรียกใช้และรวมแอพของคุณ ทำการเปลี่ยนแปลงต่อไปนี้:
import { defineConfig, mergeConfig } from "vite";
import path from "path";
import { svelte } from "@sveltejs/vite-plugin-svelte";
export default ({ command }) => {
const isBuild = command === "build";
return defineConfig({
plugins: [svelte()],
define: {
global: {}
},
build: {
target: "esnext",
commonjsOptions: {
transformMixedEsModules: true
}
},
server: {
port: 4000
},
resolve: {
alias: {
"@airgap/beacon-sdk": path.resolve(
path.resolve(),
`./node_modules/@airgap/beacon-sdk/dist/${
isBuild ? "esm" : "cjs"
}/index.js`
),
// polyfills
"readable-stream": "vite-compatible-readable-stream",
stream: "vite-compatible-readable-stream"
}
}
});
};
- เราตั้งค่า
globalเป็น{}และเราจะให้globalวัตถุในไฟล์ HTML ของเรา ในภายหลัง - เรามีเส้นทางไปยัง Beacon SDK
- เราให้บริการโพลีฟิลสำหรับ
readable-streamและstream
นี่คือสิ่งที่คุณควรมี:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script>
const global = globalThis;
</script>
<script type="module">
import { Buffer } from "buffer";
window.Buffer = Buffer;
</script>
<title>Liquidity Baking DEX</title>
</head>
<body>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
หมายเหตุ: การกำหนดค่านี้จำเป็นสำหรับการเรียกใช้ Beacon SDK ด้วยแอป Vite Taquito ทำงานนอกกรอบได้อย่างสมบูรณ์และไม่ต้องการการตั้งค่าใดๆ
เมื่อเราอัปเดตการกำหนดค่าในvite.config.jsไฟล์และในindex.htmlไฟล์แล้ว โปรเจ็กต์ของเราก็ตั้งค่าสำเร็จ! คุณสามารถเรียกใช้npm run devในเทอร์มินัลของคุณที่รูทของโปรเจ็กต์เพื่อตรวจสอบว่าทุกอย่างทำงานได้อย่างถูกต้อง dapp ควรทำงานอยู่http://localhost:4000
ตอนนี้มาเริ่มเขียนโค้ดและตั้งค่า dapp กันเถอะ!
การตั้งค่า Dapp
หากคุณทำสำเร็จแล้วและแอปของคุณทำงานอยู่http://localhost:4000ยินดีด้วย!
ตอนนี้เราต้องตั้งค่า dapp เพื่อใช้งาน Taquito และ Beacon
โครงสร้างไฟล์
จุดเริ่มต้นของแอป Svelte ทุกแอปคือไฟล์ที่เรียกว่าApp.svelteนี่คือที่ที่คุณจะนำเข้าส่วนประกอบทั้งหมดของคุณเพื่อรวมเข้าด้วยกันเป็นแอปสุดท้ายของคุณ โครงสร้างไฟล์ของโครงการของเรามีลักษณะดังนี้:
- src
- assets
- svelte.png
- lib
- AddLiquidityView.svelte
- Interface.svelte
- RemoveLiquidity.svelte
- Sidebar.svelte
- SirsStats.svelte
- SwapView.svelte
- Toast.svelte
- UserInput.svelte
- UserStats.svelte
- Wallet.svelte
- styles
- index.scss
- settings.scss
- App.svelte
- config.ts
- lbUtils.ts
- main.ts
- store.ts
- types.ts
- utils.ts
- index.html
- svelte.config.js
- tsconfig.json
- vite.config.js
- สินทรัพย์ -> มีไอคอน Favicon (นี่คือ Favicon เริ่มต้นของ Svelte แต่คุณสามารถเลือกไอคอนอื่นได้)
- lib -> มีส่วนประกอบต่าง ๆ ที่จะสร้างอินเทอร์เฟซของเรา นี่คือสิ่งที่แต่ละส่วนทำ:
-SwapView.svelte: อินเทอร์เฟซเพื่อแลกเปลี่ยนโทเค็น XTZ และ tzBTC
-AddLiquidityView.svelte: อินเทอร์เฟซเพื่อเพิ่มสภาพคล่องให้กับ LB DEX
-RemoveLiquidity.svelte: อินเทอร์เฟซเพื่อลบสภาพคล่องออกจาก LB DEX
-Interface.svelte: ส่วนประกอบลำดับที่สูงกว่าเพื่อเก็บมุมมองที่แตกต่างกันเพื่อโต้ตอบกับ LB DEX
-Sidebar.svelte: ส่วนประกอบเพื่อนำทางระหว่างอินเทอร์เฟซต่างๆ และเพื่อเชื่อมต่อหรือตัดการเชื่อมต่อกระเป๋าเงิน
-SirsStats.svelte: ส่วนประกอบเพื่อแสดงจำนวน XTZ, tzBTC, และ SIRS ที่มีอยู่ในสัญญา
-Toast.svelte: ส่วนประกอบง่ายๆ ในการแสดงความคืบหน้าของธุรกรรมและข้อความอื่นๆ เมื่อมีการโต้ตอบกับสัญญา
-UserInput.svelte: ส่วนประกอบยูทิลิตี้เพื่อให้ง่ายต่อการโต้ตอบและควบคุมฟิลด์อินพุต
-UserStats.svelte: ส่วนประกอบสำหรับแสดงยอดคงเหลือของผู้ใช้ใน XTZ, tzBTC และ SIRS
-Wallet.svelte: ส่วนประกอบสำหรับจัดการการโต้ตอบกับกระเป๋าเงิน - สไตล์ -> มีไฟล์ SASS เพื่อจัดรูปแบบองค์ประกอบต่างๆ ของอินเทอร์เฟซของเรา
- App.svelte -> จุดเริ่มต้นของแอปพลิเคชัน
- config.ts -> ค่าที่ไม่เปลี่ยนรูปแบบต่างๆ ที่จำเป็นสำหรับแอปพลิเคชัน และบันทึกไว้ในไฟล์แยกต่างหากเพื่อความสะดวก
- lbUtils.ts -> วิธีการต่างๆ ในการคำนวณมูลค่าที่จำเป็นในการโต้ตอบกับสัญญา Liquidity Baking
- main.ts -> นี่คือที่รวม JavaScript สำหรับแอปก่อนที่จะถูกแทรกลงในไฟล์ HTML
- store.ts -> ไฟล์ที่มีSvelte storeเพื่อจัดการสถานะ dapp
- types.ts -> ประเภท TypeScript ที่กำหนดเอง
- utils.ts -> วิธีการยูทิลิตี้ต่างๆ
import App from './App.svelte'
import "./styles/index.scss";
const app = new App({
target: document.body
});
export default app;
หมายเหตุ: ฉันต้องการกำหนดเป้าหมายbodyแท็กเพื่อแทรก HTML ที่สร้างโดย JavaScript แทนที่จะเป็น a divภายในbodyแต่นั่นเป็นทางเลือกส่วนบุคคล และคุณมีอิสระที่จะใช้ a divแทน
ก่อนดำเนินการต่อ นี่คือลักษณะของไฟล์ Svelte:
<script lang="ts">
... your TypeScript code
</script>
<style lang="scss">
... your SASS code
</style>
... your HTML code
มีscriptแท็กที่มีlangแอตทริบิวต์ที่ตั้งค่าtsเป็น TypeScript styleแท็กที่มีlangแอตทริบิวต์ที่ตั้งค่าscssเป็น SASS และโค้ดที่เหลือในไฟล์จะถูกตีความเป็น HTML
การกำหนดค่า Dapp
ตอนนี้มาตั้งค่าต่างๆ ในApp.svelteไฟล์ของเรากัน
ส่วน HTML เป็นเพียงการรวมส่วนประกอบลำดับที่สูงกว่าทั้งหมดเข้าด้วยกัน:
<main>
<Toast />
{#if $store.Tezos && $store.dexInfo}
<Sidebar />
<Interface />
{:else}
<div>Loading</div>
{/if}
</main>
ส่วน SASS จะนำเข้าการตั้งค่าต่างๆ และใช้สไตล์กับmainแท็ก:
@import "./styles/settings.scss";
main {
display: grid;
grid-template-columns: 250px 1fr;
gap: $padding;
padding: $padding;
height: calc(100% - (#{$padding} * 2));
}
@media screen and (max-height: 700px) {
main {
padding: 0px;
height: 100%;
}
}
import { onMount } from "svelte";
import { TezosToolkit } from "@taquito/taquito";
import store from "./store";
import { rpcUrl, dexAddress } from "./config";
import Sidebar from "./lib/Sidebar.svelte";
import Interface from "./lib/Interface.svelte";
import Toast from "./lib/Toast.svelte";
import type { Storage } from "./types";
import { fetchExchangeRates } from "./utils";
TezosToolkitเป็นคลาสที่ให้คุณเข้าถึงคุณสมบัติทั้งหมดของ Taquitostoreเป็นคุณสมบัติ Svelte เพื่อจัดการสถานะของ dapp- จาก
config.tsไฟล์ เรานำเข้าrpcUrl(URL ของโหนด Tezos RPC) และdexAddressที่อยู่ของสัญญา Liquidity Baking Storageเป็นประเภทกำหนดเองที่แสดงถึงประเภทลายเซ็นของพื้นที่จัดเก็บ LB DEXfetchExchangeRatesเป็นฟังก์ชั่นดึงอัตราแลกเปลี่ยนของ XTZ และ tzBTC (เพิ่มเติมด้านล่าง)
onMount(async () => {
const Tezos = new TezosToolkit(rpcUrl);
store.updateTezos(Tezos);
const contract = await Tezos.wallet.at(dexAddress);
const storage: Storage | undefined = await contract.storage();
if (storage) {
store.updateDexInfo({ ...storage });
}
// fetches XTZ and tzBTC prices
const res = await fetchExchangeRates();
if (res) {
store.updateExchangeRates([
{ token: "XTZ", exchangeRate: res.xtzPrice },
{ token: "tzBTC", exchangeRate: res.tzbtcPrice }
]);
} else {
store.updateExchangeRates([
{ token: "XTZ", exchangeRate: null },
{ token: "tzBTC", exchangeRate: null }
]);
}
});
หลังจากนั้นเราต้องการดึงที่เก็บข้อมูลของ LB DEX เพื่อรับจำนวน XTZ, tzBTC และ SIRS ในสัญญา เราสร้างContractAbstractionอินสแตนซ์ที่จัดทำโดย Taquito ซึ่งมีคุณสมบัติและวิธีการต่างๆ ที่เป็นประโยชน์ในการทำงานกับสัญญาอัจฉริยะของ Tezos จากContractAbstractionเราสามารถเรียกใช้storageเมธอดที่ส่งคืนออบเจกต์ JavaScript ที่แสดงถึงที่เก็บข้อมูลของสัญญาที่กำหนด จากนั้นเราจะส่งต่อที่เก็บข้อมูลไปยังupdateDexInfoวิธีการที่มีอยู่storeเพื่ออัปเดตข้อมูลนี้และแสดงให้ผู้ใช้เห็น
เพื่อให้เสร็จ เราต้องเรียกอัตราแลกเปลี่ยนสำหรับ XTZ และ tzBTC เพื่อทำการแปลงที่แอพประเภทนี้ต้องการ ไฟล์utils.tsมีฟังก์ชั่นที่จะช่วยเราที่นี่:
export const fetchExchangeRates = async (): Promise<{
tzbtcPrice: number;
xtzPrice: number;
} | null> => {
const query = `
query {
overview { xtzUsdQuote },
token(id: "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn") { price }
}
`;
const res = await fetch(`https://analytics-api.quipuswap.com/graphql`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query
})
});
if (res.status === 200) {
const resData = await res.json();
let xtzPrice = resData?.data?.overview?.xtzUsdQuote;
let tzbtcPrice = resData?.data?.token?.price;
// validates the 2 values
if (xtzPrice && tzbtcPrice) {
xtzPrice = +xtzPrice;
tzbtcPrice = +tzbtcPrice;
if (!isNaN(xtzPrice) && !isNaN(tzbtcPrice)) {
// tzBTC price is given in XTZ by the API
tzbtcPrice = tzbtcPrice * xtzPrice;
return { tzbtcPrice, xtzPrice };
}
} else {
return null;
}
} else {
return null;
}
};
ในส่วนที่สองกระเป๋าเงินและโทเค็นของผู้ใช้ =>





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)