ప్రధాన కంటెంట్‌కి స్కిప్ చేయండి

వెబ్3 యాప్‌ల కోసం సర్వర్ భాగాలు మరియు ఏజెంట్లు

ఏజెంట్
సర్వర్
ఆఫ్‌చైన్
ప్రారంభ
Ori Pomerantz
15 జులై, 2024
7 నిమిషం పఠనం

పరిచయం

చాలా సందర్భాలలో, ఒక వికేంద్రీకృత యాప్ సాఫ్ట్‌వేర్‌ను పంపిణీ చేయడానికి సర్వర్‌ను ఉపయోగిస్తుంది, కానీ వాస్తవ పరస్పర చర్య అంతా క్లయింట్ (సాధారణంగా, వెబ్ బ్రౌజర్) మరియు బ్లాక్‌చైన్ మధ్య జరుగుతుంది.

వెబ్ సర్వర్, క్లయింట్ మరియు బ్లాక్‌చైన్ మధ్య సాధారణ పరస్పర చర్య

అయినప్పటికీ, స్వతంత్రంగా నడిచే సర్వర్ భాగం ఉండటం వల్ల ఒక అప్లికేషన్ ప్రయోజనం పొందే కొన్ని సందర్భాలు ఉన్నాయి. అలాంటి సర్వర్ లావాదేవీలను జారీ చేయడం ద్వారా, ఈవెంట్‌లకు మరియు API వంటి ఇతర వనరుల నుండి వచ్చే అభ్యర్థనలకు స్పందించగలదు.

సర్వర్‌ను జోడించడంతో పరస్పర చర్య

అటువంటి సర్వర్ నెరవేర్చగల అనేక సంభావ్య పనులు ఉన్నాయి.

  • రహస్య స్థితిని కలిగి ఉండటం. గేమింగ్‌లో ఆటకు తెలిసిన మొత్తం సమాచారం ఆటగాళ్లకు అందుబాటులో లేకుండా ఉండటం తరచుగా ఉపయోగకరంగా ఉంటుంది. అయినప్పటికీ, బ్లాక్‌చైన్‌లో రహస్యాలు లేవు, బ్లాక్‌చైన్‌లో ఉన్న ఏ సమాచారమైనా ఎవరైనా సులభంగా కనుక్కోగలరు. అందువల్ల, గేమ్ స్థితిలో కొంత భాగాన్ని రహస్యంగా ఉంచాలంటే, దాన్ని మరెక్కడైనా నిల్వ చేయాలి (మరియు బహుశా ఆ స్థితి యొక్క ప్రభావాలను జీరో-నాలెడ్జ్ ప్రూఫ్స్ ఉపయోగించి ధృవీకరించాలి).

  • కేంద్రీకృత ఒరాకిల్. స్టేక్స్ తగినంత తక్కువగా ఉంటే, ఆన్‌లైన్‌లో కొంత సమాచారాన్ని చదివి, ఆ తర్వాత చైన్‌కు పోస్ట్ చేసే బాహ్య సర్వర్ ఒరాకిల్గా ఉపయోగించడానికి సరిపోతుంది.

  • ఏజెంట్. దాన్ని యాక్టివేట్ చేయడానికి లావాదేవీ లేకుండా బ్లాక్‌చైన్‌లో ఏమీ జరగదు. అవకాశం వచ్చినప్పుడు ఆర్బిట్రేజ్ వంటి చర్యలను నిర్వహించడానికి ఒక సర్వర్ వినియోగదారుడి తరఫున పని చేయగలదు.

నమూనా ప్రోగ్రామ్

మీరు githubలోopens in a new tab ఒక నమూనా సర్వర్‌ను చూడవచ్చు. ఈ సర్వర్ ఈ కాంట్రాక్ట్opens in a new tab నుండి వచ్చే ఈవెంట్‌లను వింటుంది, ఇది Hardhat యొక్క గ్రీటర్ యొక్క సవరించిన వెర్షన్. గ్రీటింగ్ మార్చబడినప్పుడు, అది దానిని తిరిగి మారుస్తుంది.

దానిని నడపడానికి:

  1. రిపోజిటరీని క్లోన్ చేయండి.

    1git clone https://github.com/qbzzt/20240715-server-component.git
    2cd 20240715-server-component
  2. అవసరమైన ప్యాకేజీలను ఇన్‌స్టాల్ చేయండి. మీకు ఇప్పటికే అది లేకపోతే, మొదట Nodeను ఇన్‌స్టాల్ చేయండిopens in a new tab.

    1npm install
  3. Holesky టెస్టునెట్‌లో ETH ఉన్న ఖాతా యొక్క ప్రైవేట్ కీని పేర్కొనడానికి .envను సవరించండి. మీకు Holeskyలో ETH లేకపోతే, మీరు ఈ ఫాసెట్‌ను ఉపయోగించవచ్చుopens in a new tab.

    1PRIVATE_KEY=0x <private key goes here>
  4. సర్వర్‌ను ప్రారంభించండి.

    1npm start
  5. ఒక బ్లాక్ ఎక్స్‌ప్లోరర్‌కుopens in a new tab వెళ్లి, ప్రైవేట్ కీ ఉన్న చిరునామా కాకుండా వేరే చిరునామాను ఉపయోగించి గ్రీటింగ్‌ను సవరించండి. గ్రీటింగ్ ఆటోమేటిక్‌గా తిరిగి సవరించబడిందని చూడండి.

ఇది ఎలా పనిచేస్తుంది?

సర్వర్ భాగాన్ని ఎలా వ్రాయాలో అర్థం చేసుకోవడానికి సులభమైన మార్గం నమూనాను లైన్ బై లైన్ పరిశీలించడం.

src/app.ts

ప్రోగ్రామ్ యొక్క అధిక భాగం src/app.tsopens in a new tabలో ఉంది.

అవసరమైన ఆబ్జెక్ట్‌లను సృష్టించడం
1import {
2 createPublicClient,
3 createWalletClient,
4 getContract,
5 http,
6 Address,
7} from "viem"

ఇవి మనకు అవసరమైన Viemopens in a new tab ఎంటిటీలు, ఫంక్షన్‌లు మరియు Address రకంopens in a new tab. ఈ సర్వర్ TypeScriptopens in a new tabలో వ్రాయబడింది, ఇది జావాస్క్రిప్ట్‌కు ఒక పొడిగింపు, ఇది దానిని స్ట్రాంగ్లీ టైప్డ్opens in a new tab చేస్తుంది.

1import { privateKeyToAccount } from "viem/accounts"

ఈ ఫంక్షన్opens in a new tab ఒక ప్రైవేట్ కీకి సంబంధించిన చిరునామాతో సహా వాలెట్ సమాచారాన్ని రూపొందించడానికి మనకు అనుమతిస్తుంది.

1import { holesky } from "viem/chains"

Viemలో బ్లాక్‌చైన్‌ను ఉపయోగించడానికి మీరు దాని నిర్వచనాన్ని ఇంపోర్ట్ చేయాలి. ఈ సందర్భంలో, మేము Holeskyopens in a new tab టెస్ట్ బ్లాక్‌చైన్‌కు కనెక్ట్ కావాలనుకుంటున్నాము.

1// This is how we add the definitions in .env to process.env.
2import * as dotenv from "dotenv"
3dotenv.config()

ఈ విధంగా మనం .envను ఎన్విరాన్‌మెంట్‌లోకి చదువుతాము. ప్రైవేట్ కీ కోసం మాకు ఇది అవసరం (తర్వాత చూడండి).

1const greeterAddress : Address = "0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6"
2const greeterABI = [
3 {
4 "inputs": [
5 {
6 "internalType": "string",
7 "name": "_greeting",
8 "type": "string"
9 }
10 ],
11 "stateMutability": "nonpayable",
12 "type": "constructor"
13 },
14 .
15 .
16 .
17 {
18 "inputs": [
19 {
20 "internalType": "string",
21 "name": "_greeting",
22 "type": "string"
23 }
24 ],
25 "name": "setGreeting",
26 "outputs": [],
27 "stateMutability": "nonpayable",
28 "type": "function"
29 }
30] as const
అన్నీ చూపించు

ఒక కాంట్రాక్ట్‌ను ఉపయోగించడానికి మనకు దాని చిరునామా మరియు దాని కోసం అవసరం. మేము ఇక్కడ రెండింటినీ అందిస్తాము.

జావాస్క్రిప్ట్ (మరియు అందువల్ల టైప్‌స్క్రిప్ట్)లో మీరు ఒక కాన్స్టాంట్‌కు కొత్త విలువను కేటాయించలేరు, కానీ మీరు దానిలో నిల్వ చేసిన ఆబ్జెక్ట్‌ను మార్చవచ్చు. as const ప్రత్యయాన్ని ఉపయోగించడం ద్వారా, జాబితా కూడా కాన్స్టాంట్ అని మరియు మార్చబడదని మేము టైప్‌స్క్రిప్ట్‌కు చెబుతున్నాము.

1const publicClient = createPublicClient({
2 chain: holesky,
3 transport: http(),
4})

ఒక Viem పబ్లిక్ క్లయింట్‌నుopens in a new tab సృష్టించండి. పబ్లిక్ క్లయింట్‌లకు జోడించిన ప్రైవేట్ కీ ఉండదు, అందువల్ల అవి లావాదేవీలను పంపలేవు. అవి view ఫంక్షన్‌లనుopens in a new tab కాల్ చేయగలవు, ఖాతా బ్యాలెన్స్‌లను చదవగలవు, మొదలైనవి.

1const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)

ఎన్విరాన్‌మెంట్ వేరియబుల్స్ process.envopens in a new tabలో అందుబాటులో ఉంటాయి. అయినప్పటికీ, టైప్‌స్క్రిప్ట్ స్ట్రాంగ్లీ టైప్డ్. ఒక ఎన్విరాన్‌మెంట్ వేరియబుల్ ఏదైనా స్ట్రింగ్ లేదా ఖాళీగా ఉండవచ్చు, కాబట్టి ఒక ఎన్విరాన్‌మెంట్ వేరియబుల్ కోసం రకం string | undefined. అయినప్పటికీ, Viemలో ఒక కీ 0x${string} (0x తరువాత ఒక స్ట్రింగ్)గా నిర్వచించబడింది. ఇక్కడ PRIVATE_KEY ఎన్విరాన్‌మెంట్ వేరియబుల్ ఆ రకంగా ఉంటుందని మేము టైప్‌స్క్రిప్ట్‌కు చెబుతున్నాము. అది కాకపోతే, మనకు రన్‌టైమ్ ఎర్రర్ వస్తుంది.

privateKeyToAccountopens in a new tab ఫంక్షన్ ఈ ప్రైవేట్ కీని ఉపయోగించి పూర్తి ఖాతా ఆబ్జెక్ట్‌ను సృష్టిస్తుంది.

1const walletClient = createWalletClient({
2 account,
3 chain: holesky,
4 transport: http(),
5})

తర్వాత, మేము ఖాతా ఆబ్జెక్ట్‌ను ఉపయోగించి ఒక వాలెట్ క్లయింట్‌నుopens in a new tab సృష్టిస్తాము. ఈ క్లయింట్‌కు ఒక ప్రైవేట్ కీ మరియు చిరునామా ఉన్నాయి, కాబట్టి దీనిని లావాదేవీలను పంపడానికి ఉపయోగించవచ్చు.

1const greeter = getContract({
2 address: greeterAddress,
3 abi: greeterABI,
4 client: { public: publicClient, wallet: walletClient },
5})

ఇప్పుడు మనకు అన్ని అవసరాలు ఉన్నాయి కాబట్టి, మనం చివరకు ఒక కాంట్రాక్ట్ ఉదాహరణనుopens in a new tab సృష్టించగలము. ఆన్‌చైన్ కాంట్రాక్ట్‌తో కమ్యూనికేట్ చేయడానికి మేము ఈ కాంట్రాక్ట్ ఉదాహరణను ఉపయోగిస్తాము.

బ్లాక్‌చైన్ నుండి చదవడం
1console.log(`Current greeting:`, await greeter.read.greet())

చదవడానికి మాత్రమే ఉండే కాంట్రాక్ట్ ఫంక్షన్‌లు (viewopens in a new tab మరియు pureopens in a new tab) read క్రింద అందుబాటులో ఉంటాయి. ఈ సందర్భంలో, మేము దానిని గ్రీటింగ్‌ను తిరిగి ఇచ్చే greetopens in a new tab ఫంక్షన్‌ను యాక్సెస్ చేయడానికి ఉపయోగిస్తాము.

జావాస్క్రిప్ట్ సింగిల్-థ్రెడ్, కాబట్టి మనం సుదీర్ఘంగా నడిచే ప్రక్రియను ప్రారంభించినప్పుడు, దానిని అసమకాలికంగా చేస్తామని పేర్కొనాలిopens in a new tab. బ్లాక్‌చైన్‌ను కాల్ చేయడం, చదవడానికి మాత్రమే చేసే ఆపరేషన్ కోసం కూడా, కంప్యూటర్ మరియు బ్లాక్‌చైన్ నోడ్ మధ్య రౌండ్-ట్రిప్ అవసరం. ఫలితం కోసం కోడ్ await చేయాలని ఇక్కడ పేర్కొనడానికి ఇదే కారణం.

ఇది ఎలా పనిచేస్తుందో మీరు ఆసక్తి కలిగి ఉంటే, మీరు దాని గురించి ఇక్కడ చదవవచ్చుopens in a new tab, కానీ ఆచరణాత్మకంగా మీరు తెలుసుకోవలసినది ఏమిటంటే, మీరు ఎక్కువ సమయం తీసుకునే ఆపరేషన్‌ను ప్రారంభిస్తే, మీరు ఫలితాల కోసం await చేయాలి, మరియు ఇలా చేసే ఏ ఫంక్షన్‌ అయినా asyncగా ప్రకటించబడాలి.

లావాదేవీలను జారీ చేయడం
1const setGreeting = async (greeting: string): Promise<any> => {

గ్రీటింగ్‌ను మార్చే లావాదేవీని జారీ చేయడానికి మీరు కాల్ చేసే ఫంక్షన్ ఇది. ఇది సుదీర్ఘమైన ఆపరేషన్ కాబట్టి, ఫంక్షన్ asyncగా ప్రకటించబడింది. అంతర్గత అమలు కారణంగా, ఏ async ఫంక్షన్ అయినా Promise ఆబ్జెక్ట్‌ను తిరిగి ఇవ్వాలి. ఈ సందర్భంలో, Promise<any> అంటే Promiseలో కచ్చితంగా ఏమి తిరిగి ఇవ్వబడుతుందో మేము పేర్కొనడం లేదు.

1const txHash = await greeter.write.setGreeting([greeting])

కాంట్రాక్ట్ ఉదాహరణ యొక్క write ఫీల్డ్ బ్లాక్‌చైన్ స్థితికి వ్రాసే అన్ని ఫంక్షన్‌లను కలిగి ఉంటుంది (లావాదేవీని పంపడం అవసరమైనవి), setGreetingopens in a new tab వంటివి. పారామితులు, ఏవైనా ఉంటే, జాబితాగా అందించబడతాయి, మరియు ఫంక్షన్ లావాదేవీ యొక్క హాష్‌ను తిరిగి ఇస్తుంది.

1 console.log(`Working on a fix, see https://eth-holesky.blockscout.com/tx/${txHash}`)
2
3 return txHash
4}

లావాదేవీ యొక్క హాష్‌ను నివేదించండి (దానిని వీక్షించడానికి బ్లాక్ ఎక్స్‌ప్లోరర్‌కు URL భాగంగా) మరియు దానిని తిరిగి ఇవ్వండి.

ఈవెంట్‌లకు స్పందించడం
1greeter.watchEvent.SetGreeting({

watchEvent ఫంక్షన్opens in a new tab ఒక ఈవెంట్ విడుదల అయినప్పుడు ఒక ఫంక్షన్ నడవాలని పేర్కొనడానికి మిమ్మల్ని అనుమతిస్తుంది. మీరు ఒకే రకమైన ఈవెంట్ (ఈ సందర్భంలో, SetGreeting) గురించి మాత్రమే శ్రద్ధ వహిస్తే, ఆ ఈవెంట్ రకానికి మిమ్మల్ని పరిమితం చేయడానికి మీరు ఈ సింటాక్స్‌ను ఉపయోగించవచ్చు.

1 onLogs: logs => {

onLogs ఫంక్షన్ లాగ్ ఎంట్రీలు ఉన్నప్పుడు కాల్ చేయబడుతుంది. Ethereumలో "లాగ్" మరియు "ఈవెంట్" సాధారణంగా పరస్పరం మార్చుకోబడతాయి.

1console.log(
2 `Address ${logs[0].args.sender} changed the greeting to ${logs[0].args.greeting}`
3)

అనేక ఈవెంట్‌లు ఉండవచ్చు, కానీ సరళత కోసం మేము మొదటి దాని గురించి మాత్రమే శ్రద్ధ వహిస్తాము. logs[0].args ఈవెంట్ యొక్క ఆర్గ్యుమెంట్లు, ఈ సందర్భంలో sender మరియు greeting.

1 if (logs[0].args.sender != account.address)
2 setGreeting(`${account.address} insists on it being Hello!`)
3 }
4})

పంపినవారు ఈ సర్వర్ కాకపోతే, గ్రీటింగ్‌ను మార్చడానికి setGreeting ఉపయోగించండి.

package.json

ఈ ఫైల్opens in a new tab Node.jsopens in a new tab కాన్ఫిగరేషన్‌ను నియంత్రిస్తుంది. ఈ వ్యాసం ముఖ్యమైన నిర్వచనాలను మాత్రమే వివరిస్తుంది.

1{
2 "main": "dist/index.js",

ఈ నిర్వచనం ఏ జావాస్క్రిప్ట్ ఫైల్‌ను నడపాలో నిర్దేశిస్తుంది.

1 "scripts": {
2 "start": "tsc && node dist/app.js",
3 },

స్క్రిప్ట్‌లు వివిధ అప్లికేషన్ చర్యలు. ఈ సందర్భంలో, మనకు ఉన్న ఏకైకది start, ఇది సర్వర్‌ను కంపైల్ చేసి, ఆపై నడుపుతుంది. tsc కమాండ్ typescript ప్యాకేజీలో భాగం మరియు టైప్‌స్క్రిప్ట్‌ను జావాస్క్రిప్ట్‌లోకి కంపైల్ చేస్తుంది. మీరు దానిని మాన్యువల్‌గా నడపాలనుకుంటే, అది node_modules/.binలో ఉంది. రెండవ కమాండ్ సర్వర్‌ను నడుపుతుంది.

1 "type": "module",

అనేక రకాల జావాస్క్రిప్ట్ నోడ్ అప్లికేషన్‌లు ఉన్నాయి. module రకం టాప్ లెవల్ కోడ్‌లో await కలిగి ఉండటానికి మనకు అనుమతిస్తుంది, ఇది మీరు నెమ్మదిగా (మరియు అక్కడ అసమకాలిక) ఆపరేషన్‌లు చేసినప్పుడు ముఖ్యమైనది.

1 "devDependencies": {
2 "@types/node": "^20.14.2",
3 "typescript": "^5.4.5"
4 },

ఇవి అభివృద్ధికి మాత్రమే అవసరమైన ప్యాకేజీలు. ఇక్కడ మాకు typescript అవసరం మరియు మేము దానిని Node.jsతో ఉపయోగిస్తున్నందున, మేము process వంటి నోడ్ వేరియబుల్స్ మరియు ఆబ్జెక్ట్‌ల కోసం రకాలను కూడా పొందుతున్నాము. ^<version> సంజ్ఞామానంopens in a new tab అంటే ఆ వెర్షన్ లేదా బ్రేకింగ్ మార్పులు లేని అధిక వెర్షన్. వెర్షన్ నంబర్ల అర్థం గురించి మరింత సమాచారం కోసం ఇక్కడopens in a new tab చూడండి.

1 "dependencies": {
2 "dotenv": "^16.4.5",
3 "viem": "2.14.1"
4 }
5}

ఇవి dist/app.js నడుస్తున్నప్పుడు, రన్‌టైమ్‌లో అవసరమైన ప్యాకేజీలు.

ముగింపు

మేము ఇక్కడ సృష్టించిన కేంద్రీకృత సర్వర్ దాని పనిని చేస్తుంది, ఇది ఒక వినియోగదారుడికి ఏజెంట్‌గా పనిచేయడం. డాప్ పని చేస్తూనే ఉండాలని కోరుకునే మరియు గ్యాస్ ఖర్చు చేయడానికి ఇష్టపడే ఎవరైనా తమ సొంత చిరునామాతో సర్వర్ యొక్క కొత్త ఉదాహరణను నడపవచ్చు.

అయినప్పటికీ, కేంద్రీకృత సర్వర్ యొక్క చర్యలను సులభంగా ధృవీకరించగలిగినప్పుడు మాత్రమే ఇది పనిచేస్తుంది. కేంద్రీకృత సర్వర్‌లో ఏదైనా రహస్య స్థితి సమాచారం ఉంటే, లేదా కష్టమైన గణనలను నడిపితే, అది మీరు అప్లికేషన్‌ను ఉపయోగించడానికి నమ్మకం అవసరమైన కేంద్రీకృత ఎంటిటీ, ఇది ఖచ్చితంగా బ్లాక్‌చైన్‌లు నివారించడానికి ప్రయత్నిస్తాయి. భవిష్యత్ వ్యాసంలో ఈ సమస్యను అధిగమించడానికి జీరో-నాలెడ్జ్ ప్రూఫ్‌లను ఎలా ఉపయోగించాలో చూపించాలని నేను ప్లాన్ చేస్తున్నాను.

నా మరిన్ని పనుల కోసం ఇక్కడ చూడండిopens in a new tab.

పేజీ చివరి అప్‌డేట్: 9 సెప్టెంబర్, 2025

ఈ ట్యుటోరియల్ ఉపయోగపడిందా?