אנו מפתחים מפיצי Merkle לתשלומים המוניים של טוקנים – חוזי airdrop חסכוניים בגז המשתמשים בעצי Merkle. מיפוי ישיר של 50,000 כתובות עולה כ-2.5 ETH בגז פריסה, בעוד שהפתרון המבוסס על Merkle עולה רק כ-0.08 ETH – הפחתה של פי 32. במחיר ETH של $2000, מדובר ב-$5000 לעומת $160, חיסכון של $4840. כל תביעה עולה 80k גז קבוע, בהשוואה ל-300k+ למיפוי אצווה. זו הסיבה שמפיץ Merkle הוא התקן התעשייתי ל-airdrops בקנה מידה גדול.
כיצד פועל מפיץ ה-Merkle?
החוזה מאחסן רק mapping(address => uint256) אחד – שורש העץ. כל טבלת התשלומים (כתובת → סכום) נשארת מחוץ לשרשרת. מקבלים תובעים את הטוקנים שלהם על ידי מתן bytes32 merkleRoot – קבוצת hashes המוכיחה את הכללתם בעץ.
אימות על השרשרת:
function claim(
uint256 index,
address account,
uint256 amount,
bytes32[] calldata merkleProof
) external {
require(!isClaimed(index), "Already claimed");
bytes32 node = keccak256(abi.encodePacked(index, account, amount));
require(MerkleProof.verify(merkleProof, merkleRoot, node), "Invalid proof");
_setClaimed(index);
require(IERC20(token).transfer(account, amount), "Transfer failed");
emit Claimed(index, account, amount);
}merkleProof בודק bit אחד ב-function claim( uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof ) external { require(!isClaimed(index), "Already claimed"); bytes32 node = keccak256(abi.encodePacked(index, account, amount)); require(MerkleProof.verify(merkleProof, merkleRoot, node), "Invalid proof"); _setClaimed(index); require(IERC20(token).transfer(account, amount), "Transfer failed"); emit Claimed(index, account, amount); } – bitmask ארוז. 50,000 מקבלים = ~1,563 משבצות uint256 במקום 50,000. חיסכון באחסון – בסדרי גודל. אנו משתמשים באופטימיזציות assembly לפעולות bitmask כדי להפחית עוד יותר את הגז.
מדוע השיטה מבוססת העץ היא התקן ל-airdrops
השווה עלויות פריסה עבור 50,000 מקבלים:
| גישה | משבצות אחסון | עלות גז משוערת | בדולרים במחיר ETH של $2000 |
|---|---|---|---|
| מיפוי ישיר | 50,000 | ~2.5 ETH | $5,000 |
| מפיץ Merkle | ~1,563 | ~0.08 ETH | $160 |
חיסכון של מעל 95%. בנוסף, הטבלה מחוץ לשרשרת מתעדכנת בקלות ללא פריסה מחדש של החוזה. עלויות לכל תביעה נמוכות גם הן:
| שיטה | גז לכל תביעה | הערות |
|---|---|---|
| מיפוי + אצווה | ~300k+ | תלוי במספר המקבלים |
| מפיץ Merkle | ~80k | עלות קבועה |
עם 50,000 תביעות, החיסכון מסתכם בעשרות ETH. המפיץ מבוסס העץ עולה על אחסון ישיר פי 32 בגז פריסה.
כיצד לבנות עץ Merkle: מדריך שלב אחר שלב
הוראות בנייה מפורטות לעץ
- הכן נתונים: רשימת מקבלים עם אינדקסים, כתובות וסכומים.
-
צור עלים:
isClaimed(index)– hashing כפול מגן מפני התקפות preimage שניות. -
בנה את העץ: השתמש בספריית
mapping(uint256 => uint256)(JS/TS) אוleaf = keccak256(abi.encodePacked(index, address, amount))(Rust). כל צומת פנימי =@openzeppelin/merkle-treeעם סידור קנוני (ה-hash הקטן יותר משמאל). - קבל את השורש:
rs_merkle– הערך היחיד המאוחסן בחוזה. - צור הוכחות: עבור כל מקבל באמצעות
keccak256(abi.encodePacked(left, right)). הפץ הוכחות דרך API או פרסם אותן ב-IPFS יחד עם הטבלה המלאה.
סקריפט טיפוסי:
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
const values = recipients.map(([address, amount], index) => [
index,
address,
amount,
]);
const tree = StandardMerkleTree.of(values, ["uint256", "address", "uint256"]);
console.log("Root:", tree.root);
// proof для конкретного получателя
const proof = tree.getProof([index, address, amount]);
טעויות נפוצות ביישום מפיץ Merkle
הטעות הראשונה והנפוצה ביותר היא bitmask שגוי להגנה מפני תביעה כפולה. אם tree.root מגדיר את ה-bit בצורה לא נכונה, תיתכן תביעה חוזרת. השתמש בתבנית המוכחת מ-OpenZeppelin MerkleDistributor. הבעיה השנייה – התנגשות עלים: אם עלים נוצרים ללא tree.getProof(...) (import { StandardMerkleTree } from "@openzeppelin/merkle-tree"; const values = recipients.map(([address, amount], index) => [ index, address, amount ]); const tree = StandardMerkleTree.of(values, ["uint256", "address", "uint256"]); console.log("Root:", tree.root); // proof для конкретного получателя const proof = tree.getProof([index, address, amount]); ), שני מקבלים עם אותו סכום עלולים להוכיח תביעה זה על זה – אף שזה נותן להם כתובת שונה, בפועל ההתנגשות אינה בטוחה. הוספת _setClaimed מבטיחה ייחודיות. הטעות השלישית – אי-התאמה בקידוד: index מחוץ לשרשרת ו-keccak256(abi.encodePacked(address, amount)) ב-Solidity חייבים להתאים. Uniswap ו-Optimism משתמשות ב-index עבור עלים.
תבניות מתקדמות
מפיץ רב-סבבי. merkleRoot חדש בכל שבוע/תקופה. במקום פריסת חוזה חדש, שורש ניתן לעדכון דרך abi.encodePacked עם onlyOwner או governance. ה-bitmask של התביעות מתאפס לתקופה החדשה או מתווסף אינדקס לפי תקופה: abi.encodePacked.
תביעה באמצעות שליח. המקבל חותם על הרשאה לתבוע בשמו – שימושי לחוויית משתמש ללא גז דרך relayer או meta-transactions של ERC-2771. תבנית: abi.encodePacked.
בדיקות עם Foundry
function test_ClaimValidProof() public {
// строим дерево в тесте
bytes32[] memory leaves = new bytes32[](3);
leaves[0] = keccak256(abi.encodePacked(uint256(0), alice, uint256(100e18)));
// merkle proof вычисляем вручную или через FFI к JS скрипту
distributor.claim(0, alice, 100e18, proof);
assertEq(token.balanceOf(alice), 100e18);
vm.expectRevert("Already claimed");
distributor.claim(0, alice, 100e18, proof); // double claim
}כדי ליצור הוכחות בבדיקות Foundry: updateMerkleRoot(bytes32) קריאה לסקריפט TypeScript עם mapping(uint256 epoch => mapping(uint256 wordIndex => uint256 bitmask)). או כתוב יישום Solidity טהור ב-setUp() – איטי יותר אך ללא תלות חיצונית.
מה הפיתוח שלנו כולל
עם למעלה מ-5 שנות ניסיון בפיתוח blockchain ו-20+ חוזי מפיץ שנפרסו, אנו מספקים פתרונות חזקים. החבילה שלנו כוללת:
- קוד מקור של חוזה חכם ב-Solidity (נבדק עם Foundry, כולל בדיקות fuzz).
- סקריפטים מחוץ לשרשרת: בניית עץ, יצירת הוכחות, פריסה ואימות (TypeScript, ethers.js).
- תיעוד: תיאור ארכיטקטורה, הוראות פריסה, תיאור API.
- התאמה לטוקן שלך: ERC-20, ERC-721, ERC-1155, או חוצה שרשרת דרך גשר.
- חודש אחד של תמיכה לאחר השקה: תיקוני באגים, ייעוץ אינטגרציה.
ציר זמן ועלות
מפיץ Merkle בסיסי עם שורש יחיד: 2-3 ימים כולל סקריפטים מחוץ לשרשרת. רב-סבבי עם governance ותביעה ללא גז: 4-5 ימים. פריסת חוזה ואימות ברשת הראשית – מספר שעות נוספות. העלות מחושבת באופן אישי לאחר הבהרת פרטים. צור קשר להערכת פרויקט שלך – ננתח את מספר המקבלים, דרישות התקופות וחוויית המשתמש. הזמן פיתוח מפיץ Merkle ואנו נעזור לך לחסוך אלפי דולרים בגז. קבל ייעוץ עכשיו.







