אנו בונים את צד השרת של dApps על Node.js עבור פרויקטים שבהם הלוגיקה על השרשרת בלבד אינה מספיקה. אם אתם צריכים פרוקסי RPC פרטי, אימות SIWE, אינדקסר אירועים, או relayer ללא גז—אנו נבנה את כל התשתית מאפס, מוכנה לשימוש. צד השרת הופך לחיוני כאשר אתם צריכים: איגוד נתונים ממספר מקורות, שמירה במטמון של שאילתות on-chain יקרות (חיסכון של עד 40% בעלויות RPC), עסקאות ללא גז (relayer), ואימות חתימות. הערימה הטכנולוגית שלנו מודרנית: Fastify, ethers.js/viem, Redis, Prisma. יש לנו מעל 10 שנות ניסיון בפיתוח בלוקצ'יין ויותר מ-50 פרויקטי dApp שהושלמו. חברות סטארטאפ וארגונים סומכים עלינו, והצוות שלנו מספק פתרונות אמינים עם אחוז הצלחה של 100%. עלות פיתוח צד שרת טיפוסית מתחילה ב-$5,000 עבור פרויקט בסיסי. אם אתם צריכים צד שרת dApp אמין, בקשו ייעוץ—אנו נחשב את ההיקף ואת לוח הזמנים.
רכיבי מפתח של צד שרת dApp ב-Node.js
שכבת הפשטה של RPC
קריאה ישירה ל-Infura/Alchemy מהפרונטאנד חושפת את מפתח ה-API שלכם. צד שרת מתווך בין קריאות RPC, ומוסיף שמירה במטמון והגבלת קצב:
import { JsonRpcProvider, Contract } from 'ethers';
import Fastify from 'fastify';
const provider = new JsonRpcProvider(process.env.RPC_URL);
const app = Fastify();
// Кэшированный endpoint для данных контракта
app.get('/contract/:address/balance/:account', { config: { rateLimit: { max: 100, timeWindow: '1 minute' } } }, async (req, reply) => {
const { address, account } = req.params as { address: string; account: string };
const cacheKey = `balance:${address}:${account}`;
const cached = await redis.get(cacheKey);
if (cached) return { balance: cached, cached: true };
const contract = new Contract(address, ERC20_ABI, provider);
const balance = await contract.balanceOf(account);
await redis.setex(cacheKey, 12, balance.toString()); // кэш на ~1 блок (12 сек)
return { balance: balance.toString(), cached: false };
});
יישום אימות מאובטח ללא סיסמה
Sign-In With Ethereum (EIP-4361) הוא תקן אימות ללא סיסמה המתואר במפרט EIP-4361. המשתמש חותם על הודעת SIWE, צד השרת מאמת את החתימה ומנפיק JWT:
import { SiweMessage } from 'siwe';
import jwt from 'jsonwebtoken';
app.post('/auth/verify', async (req, reply) => {
const { message, signature } = req.body;
const siweMessage = new SiweMessage(message);
const result = await siweMessage.verify({ signature });
if (!result.success) {
return reply.code(401).send({ error: 'Invalid signature' });
}
const token = jwt.sign(
{
address: result.data.address,
chainId: result.data.chainId,
},
process.env.JWT_SECRET!,
{ expiresIn: '7d' }
);
return { token };
});
Nonce להגנה מפני התקפות replay: אנו מייצרים nonce אקראי, שומרים אותו ב-Redis עם TTL של 5 דקות, ומאמתים שה-nonce בהודעת SIWE תואם לזה שהונפק. לאחר השימוש, אנו מוחקים אותו.
איך להקים פרוקסי RPC?
- התקינו Fastify ו-ethers.js:
import { JsonRpcProvider, Contract } from 'ethers'; import Fastify from 'fastify'; const provider = new JsonRpcProvider(process.env.RPC_URL); const app = Fastify(); // Кэшированный endpoint для данных контракта app.get('/contract/:address/balance/:account', { config: { rateLimit: { max: 100, timeWindow: '1 minute' } } }, async (req, reply) => { const { address, account } = req.params as { address: string; account: string }; const cacheKey = `balance:${address}:${account}`; const cached = await redis.get(cacheKey); if (cached) return { balance: cached, cached: true }; const contract = new Contract(address, ERC20_ABI, provider); const balance = await contract.balanceOf(account); await redis.setex(cacheKey, 12, balance.toString()); // кэш на ~1 блок (12 сек) return { balance: balance.toString(), cached: false }; }); - צרו קובץ
import { SiweMessage } from 'siwe'; import jwt from 'jsonwebtoken'; app.post('/auth/verify', async (req, reply) => { const { message, signature } = req.body; const siweMessage = new SiweMessage(message); const result = await siweMessage.verify({ signature }); if (!result.success) { return reply.code(401).send({ error: 'Invalid signature' }); } const token = jwt.sign( { address: result.data.address, chainId: result.data.chainId }, process.env.JWT_SECRET!, { expiresIn: '7d' } ); return { token }; });והגדירו מגביל קצב (למשל,npm install fastify ethers) - חברו Redis לשמירה במטמון: השתמשו בספריית
server.ts - יישמו ספק גיבוי: עברו לכתובת RPC חלופית במקרה של שגיאה
- הוסיפו נקודות קצה לקריאת נתונים (balance, symbol, decimals) עם שמירה במטמון
- הגדירו בדיקות תקינות ורישום לוגים (pino)
איך לעבד אירועי on-chain ללא עיכובים?
אירועי on-chain נחוצים להצגת היסטוריית עסקאות, התראות, וניתוחים. שתי גישות:
| גישה | זמן השהיה | עומס RPC | אמינות |
|---|---|---|---|
| Polling | ~12-15 שניות | CUPS גבוה | נמוכה יותר (דילוג על בלוקים) |
| מנוי WebSocket | <1 שנייה | נמוך | דורש לוגיקת חיבור מחדש |
מנוי WebSocket (הדרך הנכונה)—מה שאנו משתמשים בו בפועל:
const wsProvider = new WebSocketProvider(process.env.WSS_RPC_URL);
const contract = new Contract(CONTRACT_ADDRESS, ABI, wsProvider);
contract.on('Transfer', async (from, to, value, event) => {
await db.transfers.insert({
from,
to,
value: value.toString(),
blockNumber: event.log.blockNumber,
txHash: event.log.transactionHash,
timestamp: new Date(),
});
// Уведомить подписчиков через WebSocket/SSE
eventBus.emit('transfer', { from, to, value: value.toString() });
});
// Обработка разрыва соединения
wsProvider.on('error', async () => {
console.error('WS disconnected, reconnecting...');
setTimeout(setupSubscriptions, 5000);
});
חיבורי WebSocket אינם יציבים—לוגיקת חיבור מחדש היא חובה. חלופות לסביבת ייצור: Alchemy webhooks, QuickNode Streams—הספק שולח אירועים ישירות לנקודת הקצה HTTP שלכם.
עסקאות ללא גז (Meta-Transactions)
EIP-2771 + ERC-2612 מאפשרים למשתמש לחתום על עסקה מחוץ לשרשרת, בעוד relayer משלם את הגז. צד השרת פועל כ-relayer, ומפחית את עלויות הגז למשתמש ב-30-50%:
app.post('/relay/transfer', authenticateJWT, async (req, reply) => {
const { permit, signature } = req.body;
// ERC-2612 permit
// Верифицируем permit signature
const tokenContract = new Contract(TOKEN_ADDRESS, ERC20_ABI, wallet);
// Проверяем что permit валиден и не истёк
const nonce = await tokenContract.nonces(permit.owner);
if (BigInt(permit.nonce) !== nonce) {
return reply.code(400).send({ error: 'Invalid nonce' });
}
// Выполняем permit + transferFrom за пользователя
const tx = await tokenContract.permit(
permit.owner,
permit.spender,
permit.value,
permit.deadline,
permit.v,
permit.r,
permit.s
);
await tx.wait();
return { txHash: tx.hash };
});
לעסקאות ללא גז בסביבת ייצור: OpenZeppelin Defender Relayer או Biconomy—הם מנהלים nonces, לוגיקת ניסיונות חוזרים, וניטור של עסקאות תקועות, ומבטיחים זמינות של 99.9%.
איך להבטיח סובלנות לתקלות בפרוקסי RPC?
אנו משתמשים בספקי RPC חלופיים עם circuit breaker. אם הספק הראשי מחזיר שגיאות (למשל, 429 Too Many Requests), אנו עוברים אוטומטית לספק הגיבוי. תבנית circuit breaker דרך ספריית @fastify/rate-limit: ניתוק לאחר 5 שגיאות רצופות למשך 30 שניות.
ניטור ואמינות
בעיות טיפוסיות והפתרונות שלהן
-
עסקאות תקועות: עסקה עם gasPrice נמוך נתקעת ב-mempool. אנו מנטרים באמצעות polling
ioredis. לאחר N דקות, אנו מעלים את הגז (שליחה חוזרת עם אותו nonce, gasPrice * 1.1). - ניהול nonce: עם עסקאות מקבילות מאותו ארנק, יש צורך במונה nonce אטומי. אנו משתמשים ב-Redis INCR + מעקב אחר nonces ממתינים.
- Circuit breaker ל-RPC: אם ספק מחזיר שגיאות, אנו עוברים לספק הגיבוי.
מבנה הפרויקט
src/
api/ # HTTP routes (Fastify/Express)
blockchain/ # Provider, contracts, event listeners
services/ # Бизнес-логика
workers/ # BullMQ workers для фоновых задач
db/ # Prisma schema, migrations
cache/ # Redis client
middleware/ # Auth, rate limiting, validation
Fastify מהיר בכ-15-20% מ-Express בתפוקה ויש לו אימות סכמת JSON מובנה. עבור צדי שרת של dApp, ההבדל רק לעתים נדירות קריטי, אבל מערכת התוספים של fastify-plugin נוחה.
השוואת אסטרטגיות פריסה
| אסטרטגיה | זמן פריסה | סובלנות לתקלות | עלות |
|---|---|---|---|
| שרת יחיד | 1-2 שעות | נמוכה | נמוכה |
| Docker + compose | 3-4 שעות | בינונית | בינונית |
| Kubernetes | 1-2 ימים | גבוהה | גבוהה |
מה כלול בעבודה
אנו מספקים חבילת תיעוד מלאה: תיאור API (OpenAPI/Swagger), דיאגרמת ארכיטקטורה, הוראות פריסה. קוד המקור נשמר במאגר פרטי עם CI/CD מוגדר (GitHub Actions). גישה לספקי RPC, Redis, ומסד הנתונים מועברת דרך מנהל סיסמאות. אנו מקיימים מפגש הדרכה לצוות (1-2 שעות). תמיכה למשך חודש לאחר המסירה כלולה. כל פרויקט נמסר עם ביקורת אבטחה מובטחת ותמיכה חינמית למשך חודש. בקשו הצעת מחיר לפיתוח צד שרת dApp—קבלו פתרון מוכן עם ניטור ותמיכה.
הערכות לוח זמנים
צד שרת בסיסי (פרוקסי RPC + אימות SIWE + שמירה במטמון): 2-3 ימים. אינדקסר אירועים + שליחת WebSocket + relayer ללא גז: עוד 3-4 ימים. מוכן לייצור עם ניטור, לוגיקת ניסיונות חוזרים, ו-RPC חלופי: 1.5-2 שבועות.
צרו קשר להערכת הפרויקט שלכם—אנו נעריך את לוח הזמנים ואת ההיקף. קבלו ייעוץ מהנדס.







