מערכת מנוי תוכן מוגבל-אסימון עם חידוש אוטומטי

אנו מפתחים מערכות תוכן מוגבל-אסימון מוכנות לשימוש. בניגוד למנויים מסורתיים (Patreon, Medium) שבהם בקרת הגישה היא מרכזית והיוצר משלם עמלת פלטפורמה (עד 12%), הפתרון שלנו מבוסס על חוזים חכמים. התשלומים עוברים ישירות מהמנוי למחבר, וגישת התוכן

שירותי פיתוח בלוקצ'יין

שאלות נפוצות

העבודות האחרונות

  • image_website-b2b-advance_0.webp
    פיתוח אתר חברה B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    פיתוח אפליקציית ווב עבור FEEDME
    1308
  • image_websites_belfingroup_462_0.webp
    פיתוח אתר עבור BELFINGROUP
    1003
  • image_ecommerce_furnoro_435_0.webp
    פיתוח חנות מקוונת לחברת FURNORO
    1269
  • image_logo-advance_0.webp
    עיצוב לוגו לחברת B2B Advance
    717
  • image_crm_enviok_479_0.webp
    פיתוח אפליקציית ווב עבור Enviok
    1008

אנו מפתחים מערכות תוכן עם גישה מבוססת אסימונים (Token-Gated) במתכונת turnkey. בניגוד למנויים מסורתיים (Patreon, Medium) שבהם בקרת הגישה היא מרכזית והיוצר משלם עמלת פלטפורמה (עד 12%), הפתרון שלנו מבוסס על חוזים חכמים. התשלומים עוברים ישירות מהמנוי למחבר, ואימות הגישה לתוכן נעשה על גבי הבלוקצ'יין. יישום סכמה כזו דורש פתרון של מספר אתגרים טכניים: הצפנת תוכן הנגיש רק למנויים, חידוש אוטומטי של מנויים, וארגון גישה מדורגת ללא עלויות גז מופרזות. להלן אנו בוחנים את הארכיטקטורה שבה אנו משתמשים בסביבת ייצור—מבחירת תקן האסימונים ועד לשילוב הצפנה מבוזרת. הערימה הטכנולוגית שלנו: Solidity 0.8.x, Foundry, Lit Protocol, IPFS, Chainlink Automation. דוגמאות קוד ותצורות ספציפיות מסופקות.

כיצד לבחור את תקן האסימונים האופטימלי למנויים?

כל תקן פותר משימה ספציפית. ERC-1155 הפך לתקן התעשייתי למנויים מבוססי זמן: הוא משתמש בהעברות אצווה וביצירה דינמית של tokenId בהתבסס על התקופה, מה שמפחית את עלויות הגז ב-30–50% בהשוואה ל-ERC-721 עבור חידושים המוניים. ERC-721 מתאים יותר למנויי NFT לכל החיים עם מכירה חוזרת ותמלוגים דרך ERC-2981. Staking של ERC-20 הוא האפשרות הפשוטה ביותר אך קופא על נזילות המשתמש.

מודל סוג מנוי מכירה חוזרת גז בעת Mint תמלוגים
ERC-721 לכל החיים / מוגבל כן גבוה ERC-2981
ERC-1155 מבוסס זמן (לפי תקופות) לא בינוני (אצווה - נמוך) לא
ERC-20 staking רציף לא (רק unstake) נמוך מאוד לא

דוגמה למבנה חוזה מנוי:

contract ContentSubscription { struct SubscriptionTier { uint256 pricePerMonth; // в wei или ERC-20 токенах address paymentToken; // address(0) = native ETH uint256 maxSubscribers; // 0 = unlimited string contentCID; // IPFS CID для шифрованного контента bytes32 encryptionKeyHash; // хеш ключа шифрования для этого тира } struct Subscription { uint256 tierId; uint256 expiresAt; uint256 startedAt; bool autoRenew; } mapping(uint256 => SubscriptionTier) public tiers; mapping(address => mapping(uint256 => Subscription)) public subscriptions; address public creator; uint256 public platformFeeBps = 250; // 2.5% modifier onlyCreator() { require(msg.sender == creator, "Not creator"); _; } function subscribe(uint256 tierId, uint256 months, bool autoRenew) external payable { SubscriptionTier memory tier = tiers[tierId]; uint256 totalCost = tier.pricePerMonth * months; if (tier.paymentToken == address(0)) { require(msg.value >= totalCost, "Insufficient ETH"); } else { IERC20(tier.paymentToken).transferFrom(msg.sender, address(this), totalCost); } Subscription storage sub = subscriptions[msg.sender][tierId]; // Продление существующей или новая подписка uint256 currentExpiry = sub.expiresAt > block.timestamp ? sub.expiresAt : block.timestamp; sub.expiresAt = currentExpiry + months * 30 days; sub.tierId = tierId; sub.autoRenew = autoRenew; if (sub.startedAt == 0) sub.startedAt = block.timestamp; _distributeRevenue(tier, totalCost); emit Subscribed(msg.sender, tierId, sub.expiresAt); } function isSubscribed(address user, uint256 tierId) external view returns (bool) { return subscriptions[user][tierId].expiresAt > block.timestamp; } function _distributeRevenue(SubscriptionTier memory tier, uint256 amount) internal { uint256 platformFee = amount * platformFeeBps / 10000; uint256 creatorAmount = amount - platformFee; if (tier.paymentToken == address(0)) { payable(creator).transfer(creatorAmount); payable(platform).transfer(platformFee); } else { IERC20(tier.paymentToken).transfer(creator, creatorAmount); IERC20(tier.paymentToken).transfer(platform, platformFee); } } } 

כיצד להגן על תוכן מפני גישה לא מורשית?

אחסון תוכן על גבי הבלוקצ'יין הוא בלתי אפשרי וחסר טעם. הסכמה הסטנדרטית: התוכן מוצפן ומועלה ל-IPFS, ומפתח ההצפנה ניתן רק למנויים מאומתים. הבעיה: מי מנפיק את המפתח? אם משתמשים בשרת מרכזי, אין טעם בבלוקצ'יין. הפתרון הוא Lit Protocol או Threshold Network: רשת מבוזרת של צמתים מאחסנת חלקי מפתח ומעניקה גישה רק כאשר מתקיים תנאי על גבי הבלוקצ'יין. יישום ב-JavaScript:

import { LitNodeClient, checkAndSignAuthMessage } from '@lit-protocol/lit-node-client'; // Условие доступа: активная подписка на тир 1 const accessControlConditions = [ { contractAddress: SUBSCRIPTION_CONTRACT_ADDRESS, standardContractType: '', chain: 'ethereum', method: 'isSubscribed', parameters: [':userAddress', '1'], // tierId = 1 returnValueTest: { comparator: '=', value: 'true' } } ]; // Шифрование контента (выполняется creator'ом при загрузке) async function encryptContent(content) { const client = new LitNodeClient(); await client.connect(); const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' }); const { encryptedString, symmetricKey } = await LitJsSdk.encryptString(content); const encryptedSymmetricKey = await client.saveEncryptionKey({ accessControlConditions, symmetricKey, authSig, chain: 'ethereum' }); return { encryptedContent: encryptedString, encryptedKey: encryptedSymmetricKey }; } // Расшифровка (пользователь при чтении) async function decryptContent(encryptedContent, encryptedKey) { const client = new LitNodeClient(); await client.connect(); const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' }); const symmetricKey = await client.getEncryptionKey({ accessControlConditions, toDecrypt: encryptedKey, chain: 'ethereum', authSig }); return await LitJsSdk.decryptString(encryptedContent, symmetricKey); } 

מדוע Chainlink Automation הוא התקן לחידוש אוטומטי?

חידוש אוטומטי דורש טריגר חיצוני—חוזה חכם אינו יכול לקרוא לעצמו לפי לוח זמנים. Chainlink Automation (לשעבר Keepers) בודק את התנאי contract ContentSubscription { struct SubscriptionTier { uint256 pricePerMonth; // в wei или ERC-20 токенах address paymentToken; // address(0) = native ETH uint256 maxSubscribers; // 0 = unlimited string contentCID; // IPFS CID для шифрованного контента bytes32 encryptionKeyHash; // хеш ключа шифрования для этого тира } struct Subscription { uint256 tierId; uint256 expiresAt; uint256 startedAt; bool autoRenew; } mapping(uint256 => SubscriptionTier) public tiers; mapping(address => mapping(uint256 => Subscription)) public subscriptions; address public creator; uint256 public platformFeeBps = 250; // 2.5% modifier onlyCreator() { require(msg.sender == creator, "Not creator"); _; } function subscribe(uint256 tierId, uint256 months, bool autoRenew) external payable { SubscriptionTier memory tier = tiers[tierId]; uint256 totalCost = tier.pricePerMonth * months; if (tier.paymentToken == address(0)) { require(msg.value >= totalCost, "Insufficient ETH"); } else { IERC20(tier.paymentToken).transferFrom(msg.sender, address(this), totalCost); } Subscription storage sub = subscriptions[msg.sender][tierId]; // Продление существующей или новая подписка uint256 currentExpiry = sub.expiresAt > block.timestamp ? sub.expiresAt : block.timestamp; sub.expiresAt = currentExpiry + months * 30 days; sub.tierId = tierId; sub.autoRenew = autoRenew; if (sub.startedAt == 0) sub.startedAt = block.timestamp; _distributeRevenue(tier, totalCost); emit Subscribed(msg.sender, tierId, sub.expiresAt); } function isSubscribed(address user, uint256 tierId) external view returns (bool) { return subscriptions[user][tierId].expiresAt > block.timestamp; } function _distributeRevenue(SubscriptionTier memory tier, uint256 amount) internal { uint256 platformFee = amount * platformFeeBps / 10000; uint256 creatorAmount = amount - platformFee; if (tier.paymentToken == address(0)) { payable(creator).transfer(creatorAmount); payable(platform).transfer(platformFee); } else { IERC20(tier.paymentToken).transfer(creator, creatorAmount); IERC20(tier.paymentToken).transfer(platform, platformFee); } } } וקורא ל-import { LitNodeClient, checkAndSignAuthMessage } from '@lit-protocol/lit-node-client'; // Условие доступа: активная подписка на тир 1 const accessControlConditions = [ { contractAddress: SUBSCRIPTION_CONTRACT_ADDRESS, standardContractType: '', chain: 'ethereum', method: 'isSubscribed', parameters: [':userAddress', '1'], // tierId = 1 returnValueTest: { comparator: '=', value: 'true' } } ]; // Шифрование контента (выполняется creator'ом при загрузке) async function encryptContent(content) { const client = new LitNodeClient(); await client.connect(); const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' }); const { encryptedString, symmetricKey } = await LitJsSdk.encryptString(content); const encryptedSymmetricKey = await client.saveEncryptionKey({ accessControlConditions, symmetricKey, authSig, chain: 'ethereum' }); return { encryptedContent: encryptedString, encryptedKey: encryptedSymmetricKey }; } // Расшифровка (пользователь при чтении) async function decryptContent(encryptedContent, encryptedKey) { const client = new LitNodeClient(); await client.connect(); const authSig = await checkAndSignAuthMessage({ chain: 'ethereum' }); const symmetricKey = await client.getEncryptionKey({ accessControlConditions, toDecrypt: encryptedKey, chain: 'ethereum', authSig }); return await LitJsSdk.decryptString(encryptedContent, symmetricKey); } בעת הצורך:

contract AutoRenewSubscription is AutomationCompatibleInterface { function checkUpkeep(bytes calldata) external view override returns (bool upkeepNeeded, bytes memory performData) { // Найти истекающие подписки с autoRenew=true address[] memory toRenew = _findExpiringSubscriptions(); upkeepNeeded = toRenew.length > 0; performData = abi.encode(toRenew); } function performUpkeep(bytes calldata performData) external override { address[] memory toRenew = abi.decode(performData, (address[])); for (uint256 i = 0; i < toRenew.length; i++) { _attemptRenewal(toRenew[i]); } } function _attemptRenewal(address subscriber) internal { // Попытка списать средства, если баланс достаточен // При неудаче — событие, уведомление пользователя } } 

Chainlink Automation זול ואמין יותר מקריאות ידניות—הוא הופך את החידוש לאוטומטי, ומפחית חיכוך עבור המשתמש. חלופות (Gelato) עובדות גם הן, אך Chainlink מספקת אינטגרציה הדוקה יותר עם מערכת האקוסיסטם של Ethereum.

מודלי מונטיזציה ליוצרים: השוואה

מודל הכנסה מורכבות יישום דוגמת שימוש
קבוע (Flat) צפויה נמוכה ניוזלטרים
גישה מדורגת מקסימלית עם פילוח בינונית פלטפורמות חינוכיות
תשלום לפי תוכן מחסום כניסה נמוך גבוהה מאמרים פרימיום
חברות NFT תמלוגים על מכירה חוזרת בינונית קהילות סגורות

בחירת המודל תלויה בקהל. לדוגמה, עבור קהילה מגובשת עם נאמנות גבוהה, חברות NFT עובדת הכי טוב; עבור תוכן המוני, גישה מדורגת היא אופטימלית.

מה כוללת העבודה שלנו

  • ניתוח מודל מונטיזציה ובחירת תקן אסימונים אופטימלי.
  • פיתוח וביקורת חוזים חכמים (Solidity, Foundry) עם כיסוי בדיקות, כולל fuzzing באמצעות Echidna.
  • שילוב הצפנה מבוזרת (Lit Protocol / Threshold).
  • הגדרת שער IPFS ומערכת הפצת מפתחות.
  • יצירת ממשק משתמש (React + wagmi/viem, RainbowKit).
  • חיבור חידוש אוטומטי דרך Chainlink Automation.
  • פריסה ברשת הנבחרת (Ethereum, Polygon, Arbitrum, Base).
  • תיעוד טכני והכשרת צוות.
  • תמיכה לאחר ההשקה.
ניסיון ואחריות

יישמנו 15+ פרויקטים ב-DeFi, NFT וטוקניזציה של תוכן. אנו משתמשים בספריות משלנו של חוזים חכמים מנוסים, מה שמפחית סיכונים וזמן פיתוח. אנו מבטיחים פעולה יציבה הודות לבדיקות fuzz (Echidna) וניטור על גבי הבלוקצ'יין. לפי הסטטיסטיקות שלנו, לקוחות חוסכים עד 30% בגז באמצעות אופטימיזציה של פעולות אצווה—עם נפח של $10,000 בעסקאות חודשיות, מדובר בחיסכון של $3,000.

לוח זמנים לפיתוח

מערכת מנויים בסיסית עם שכבה אחת, אינטגרציה של Lit Protocol וממשק פשוט אורכת 4 עד 6 שבועות. פלטפורמה מלאה עם גישה מדורגת, חברות NFT, חידוש אוטומטי ואנליטיקה ליוצרים אורכת 10 עד 14 שבועות. לוחות זמנים מדויקים תלויים במורכבות האינטגרציות ובהיקף התכונות.

צרו קשר לייעוץ והערכת פרויקט. נעזור לתכנן וליישם מערכת מנויים המותאמת למקרה שלכם. בקשו ניתוח של מודל המונטיזציה שלכם—זה לוקח לא יותר משעה. פרטים נוספים על התקנים ניתן למצוא בערך הוויקיפדיה על ERC-1155.