---
title: "ERC-7730 এর মাধ্যমে আপনার প্রোটোকলে ক্লিয়ার সাইনিং যুক্ত করুন"
description: "কীভাবে একটি ERC-7730 ডেসক্রিপ্টর লিখতে হয় তা শিখুন যাতে ব্যবহারকারীরা স্বাক্ষর করার আগে ওয়ালেটে আপনার স্মার্ট কন্ট্রাক্ট ইন্টারঅ্যাকশনগুলোর মানুষের পাঠযোগ্য বিবরণ প্রদর্শিত হয়।"
author: "হেস্টার ব্রুইকম্যান"
lang: bn
tags: ["ERC-7730", "নিরাপত্তা", "স্বাক্ষরকরণ", "স্মার্ট কন্ট্রাক্ট", "ওয়ালেট"]
skill: intermediate
breadcrumb: "ক্লিয়ার সাইনিং"
published: 2026-05-11
---

বেশিরভাগ বড় ইথেরিয়াম এক্সপ্লয়েটের (exploits) চূড়ান্ত ধাপ একই ছিল: একজন ব্যবহারকারী এমন একটি ট্রানজ্যাকশন অনুমোদন করছেন যা তারা অর্থপূর্ণভাবে বুঝতে পারেননি। হার্ডওয়্যার ওয়ালেটগুলো র (raw) হেক্স কল ডেটা দেখায় এবং আরও খারাপ ব্যাপার হলো, এগুলো আপনাকে ব্লাইন্ড সাইনিং (blind signing) চালু রাখতে বাধ্য করে। সফটওয়্যার ওয়ালেটগুলো ডিকোড করা ফিল্ড দেখায়, তবে শুধুমাত্র তখনই যখন তারা কন্ট্রাক্টটি চিনতে পারে। যখন তারা চিনতে পারে না, তা প্রোটোকলটি নতুন হওয়ার কারণেই হোক, অ্যাপটি আপস (compromised) হওয়ার কারণেই হোক, বা ডিভাইসটি অফলাইনে থাকার কারণেই হোক, ব্যবহারকারীরা অন্ধভাবে স্বাক্ষর করেন।

[ERC-7730](https://eips.ethereum.org/EIPS/eip-7730) আপনার কন্ট্রাক্টের ফাংশন কলগুলোর *অর্থ* বর্ণনা করার জন্য একটি স্ট্যান্ডার্ড JSON ফরম্যাট নির্ধারণ করে। 

একটি ওয়ালেট যা ERC-7730 সমর্থন করে, সেটি আপনার ডেসক্রিপ্টর পড়ে এবং দেখায়:

> **সোয়াপ**  
> পাঠানো হবে: 1,000 USDC  
> সর্বনিম্ন প্রাপ্তি: 0.42 WETH  
> প্রোটোকল: ইউনিসোয়াপ V3

অথবা মানুষ এবং এজেন্ট উভয়েরই পাঠযোগ্য একটি একক গঠিত বাক্য:

> কমপক্ষে 0.42 WETH এর জন্য 1,000 USDC সোয়াপ করুন

একটি ফাংশন সিলেক্টর এবং র (raw) ইন্টিজার মানগুলোর তালিকার পরিবর্তে।

এটি হলো [ক্লিয়ার সাইনিং](https://clearsigning.org/) — "আপনি যা দেখছেন, তাতেই আপনি স্বাক্ষর করছেন।" এই টিউটোরিয়ালটি আপনাকে আপনার নিজের কন্ট্রাক্টের জন্য একটি ডেসক্রিপ্টর লেখা, অফিসিয়াল CLI টুলের সাহায্যে এটি যাচাই করা এবং ওপেন রেজিস্ট্রিতে জমা দেওয়ার প্রক্রিয়াটি ধাপে ধাপে দেখাবে।

## পূর্বশর্ত {#prerequisites}

- Solidity এবং স্মার্ট কন্ট্রাক্ট ABI সম্পর্কে ধারণা
- একটি যাচাইকৃত ABI সহ একটি ডিপ্লয় করা স্মার্ট কন্ট্রাক্ট (রেজিস্ট্রিতে কোনো ডেসক্রিপ্টর গৃহীত হওয়ার আগে [Sourcify](https://sourcify.dev) ভেরিফিকেশন প্রয়োজন) 
- ভ্যালিডেশন CLI-এর জন্য Python 3.12+ 
- JSON সম্পর্কে প্রাথমিক জ্ঞান

## ERC-7730 ডেসক্রিপ্টর কী? {#what-is-an-erc-7730-descriptor}

ডেসক্রিপ্টর হলো তিনটি বিভাগ (section) বিশিষ্ট একটি একক JSON ফাইল:

| বিভাগ | উদ্দেশ্য |
| :---- | :---- |
| `context` | চেইন আইডি এবং ঠিকানার মাধ্যমে ডেসক্রিপ্টরটিকে নির্দিষ্ট কন্ট্রাক্ট ডিপ্লয়মেন্টের সাথে যুক্ত করে |
| `metadata` | প্রজেক্টের নাম দেয় এবং পুনরায় ব্যবহারযোগ্য ধ্রুবক (constants) সংজ্ঞায়িত করে |
| `display` | প্রতিটি ফাংশন স্বাক্ষরকে মানুষের পাঠযোগ্য লেবেল এবং ফিল্ড ফরম্যাটের সাথে ম্যাপ করে |

যেহেতু ডেসক্রিপ্টরটি কন্ট্রাক্ট থেকে আলাদা, তাই আপনি পুনরায় ডিপ্লয়মেন্ট ছাড়াই যেকোনো বিদ্যমান প্রোটোকলে ক্লিয়ার সাইনিং সমর্থন যুক্ত করতে পারেন। ওয়ালেটগুলো রেজিস্ট্রি থেকে ডেসক্রিপ্টরগুলো পুনরুদ্ধার করে এবং স্বাক্ষরকরণের সময় সেগুলো ব্যবহার করে।

## ধাপ 1: ফাইলের কাঠামো তৈরি করুন {#step-1-create-the-file-skeleton}

`calldata-<contractname>-<descriptorversion>.json` নামের একটি ফাইল তৈরি করুন। `calldata-` প্রিফিক্সটি রেজিস্ট্রিকে বলে যে এই ডেসক্রিপ্টরটি কন্ট্রাক্ট ফাংশন কলগুলোকে কভার করে, যা টাইপড-ডেটা মেসেজগুলোর জন্য ব্যবহৃত `eip712-` এর বিপরীত। `descriptorversion` রেজিস্ট্রিকে ডেসক্রিপ্টর ফাইলের সংস্করণ সম্পর্কে জানায়, কোনো সংস্করণ প্রদান করা না হলে ডিফল্টরূপে এটি 0 হয়।


```json
{
  "$schema": "https://eips.ethereum.org/assets/eip-7730/erc7730-v2.schema.json",
  "context": {},
  "metadata": {},
  "display": {
    "formats": {}
  }
}
```

## ধাপ 2: কনটেক্সট (context) বিভাগটি লিখুন {#step-2-write-the-context-section}

`context` বিভাগটি ডেসক্রিপ্টরটিকে এক বা একাধিক কন্ট্রাক্ট ডিপ্লয়মেন্টের সাথে যুক্ত করে। ওয়ালেটগুলো একটি আগত ট্রানজ্যাকশনকে সঠিক ডেসক্রিপ্টরের সাথে মেলাতে এটি ব্যবহার করে।

```json
"context": {
  "$id": "uniswap-v3-router-mainnet",
  "contract": {
    "deployments": [
      { "chainId": 1, "address": "0xYourContractAddressOnMainnet" },
      { "chainId": 137, "address": "0xYourContractAddressOnPolygon" }
    ]
  }
}
```

### কনটেক্সট ফিল্ডসমূহ {#context-fields}

- `context.$id` — এই ডেসক্রিপ্টর ডকুমেন্ট বা ডিপ্লয়মেন্ট কনফিগারেশনের জন্য একটি অনন্য আইডেন্টিফায়ার।
- `contract.deployments` — ডিপ্লয়মেন্টের সেট যার উপর এই ডেসক্রিপ্টরটি প্রযোজ্য।
- `deployments[].chainId` — একটি ডিপ্লয়মেন্টের জন্য EVM চেইন আইডি। আপনার কন্ট্রাক্টটি যেখানে ডিপ্লয় করা হয়েছে এমন প্রতিটি চেইন অন্তর্ভুক্ত করুন।
- `deployments[].address` — কন্ট্রাক্টের ঠিকানা যা ওয়ালেটগুলোর এই ডেসক্রিপ্টরের সাথে যুক্ত করা উচিত। এক্সিকিউশন লজিক ধারণকারী ইমপ্লিমেন্টেশন ঠিকানাটি ব্যবহার করুন।

## ধাপ 3: মেটাডেটা বিভাগটি লিখুন {#step-3-write-the-metadata-section}

মেটাডেটা বিভাগটি এই ফাইলের দ্বারা বর্ণিত প্রজেক্ট এবং কন্ট্রাক্ট সম্পর্কে মানুষের পাঠযোগ্য তথ্য প্রদান করে। ওয়ালেটগুলো স্বাক্ষরকরণের সময় প্রোটোকলের নাম, লিঙ্ক এবং অন্যান্য প্রাসঙ্গিক বিবরণ প্রদর্শন করতে এই তথ্য ব্যবহার করতে পারে।

```json
"metadata": {
  "owner": "Example Swap Protocol",
  "info": { "url": "https://example.xyz" },
  "contractName": "SwapRouter"
}
```

### মেটাডেটা ফিল্ডসমূহ {#metadata-fields}

- `owner` — এই ডেসক্রিপ্টরের জন্য দায়ী প্রজেক্ট, প্রোটোকল, সংস্থা বা মেইনটেইনার।
- `info.url` — একটি ক্যানোনিকাল প্রজেক্ট বা ডকুমেন্টেশন URL যা ওয়ালেটগুলো অতিরিক্ত প্রসঙ্গের জন্য ব্যবহারকারীদের দেখাতে পারে।
- `contractName` — এই ফাইলের দ্বারা বর্ণিত কন্ট্রাক্ট বা ইমপ্লিমেন্টেশনের নাম, যা সাধারণত যাচাইকৃত সোর্স কোড বা ABI-এর সাথে মিলে যায়।

যদি আপনার ERC-7730 ফাইলটি একটি ERC-20 কন্ট্রাক্ট বর্ণনা করে, তবে আপনার একটি টোকেন অবজেক্টও যুক্ত করা উচিত। 

## ধাপ 4: ডিসপ্লে ফরম্যাট বিভাগটি লিখুন {#step-4-write-the-displayformats-section}

`display.formats` অবজেক্টটি ফাংশন স্বাক্ষরগুলোকে মানুষের পাঠযোগ্য স্বাক্ষরকরণের নির্দেশাবলীর সাথে ম্যাপ করে। এভাবেই ওয়ালেটগুলো ব্যবহারকারীদের কোনো ট্রানজ্যাকশন অনুমোদন করার আগে আপনার ফাংশনটি দেখায়!

প্রতিটি কী (key) হলো মানুষের পাঠযোগ্য একটি ABI ফ্র্যাগমেন্ট — ফাংশন স্বাক্ষর, যার মধ্যে প্যারামিটারের নাম এবং প্যারামিটারের ধরন উভয়ই ঠিক সেভাবেই থাকে যেভাবে সেগুলো আপনার ABI-তে উপস্থিত থাকে।


### উদাহরণ: একটি টোকেন সোয়াপ বর্ণনা করা {#eg-describing-token-swap}

```json
"display": {
  "formats": {
    "swapExactTokensForTokens(uint256 amountIn,uint256 amountOutMin,address[] path,address to,uint256 deadline)": {
      "intent": "Swap",
      "interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}",
      "fields": [
        {
          "path": "#.amountIn",
          "label": "Send",
          "format": "tokenAmount",
          "params": {
            "tokenPath": "#.path[0]"
          }
        },
        {
          "path": "#.amountOutMin",
          "label": "Receive minimum",
          "format": "tokenAmount",
          "params": {
            "tokenPath": "#.path[1]"
          }
        },
        {
          "path": "#.to",
          "label": "Recipient",
          "format": "addressName",
          "params": {
            "types": ["eoa", "contract"],
            "sources": ["local", "ens"]
          }
        },
        {
          "path": "#.deadline",
          "label": "Expires",
          "format": "date",
          "params": {
            "encoding": "timestamp"
          }
        }
      ]
    }
  }
}

```

### ডিসপ্লে ফিল্ডসমূহ {#display-fields}

- **`intent`** — **(প্রয়োজনীয়)** অ্যাকশনটির একটি সংক্ষিপ্ত, ব্যবহারকারী-বান্ধব বিবরণ, যেমন "Swap"।
- **`interpolatedIntent`** — **(প্রস্তাবিত)** একটি সমৃদ্ধ বাক্য টেমপ্লেট যা ফরম্যাট করা ফিল্ডের মানগুলোকে এম্বেড করে, যেমন `"Swap {amountIn} for at least {amountOutMin}"`। ওয়ালেটগুলো যাতে যেকোনো ডিসপ্লে সীমাবদ্ধতা থাকা সত্ত্বেও আরও বেশি ব্যবহারকারী-বান্ধব ডেসক্রিপ্টর দেখাতে পারে, সেজন্য `intent` এর পাশাপাশি এটি অন্তর্ভুক্ত করুন।
- **`fields`** — **(প্রয়োজনীয়)** ট্রানজ্যাকশন ফিল্ডগুলোর ক্রমানুসারে সাজানো তালিকা যা ওয়ালেটগুলোর ব্যবহারকারীদের দেখানো উচিত।
  - **`path`** — **(প্রয়োজনীয়)** ট্রানজ্যাকশন ডেটার একটি রেফারেন্স। `#.fieldName` ABI-তে থাকা নাম অনুযায়ী একটি ডিকোড করা কল ডেটা প্যারামিটারকে নির্দেশ করে। `@.value` ট্রানজ্যাকশনের সাথে পাঠানো ETH মানকে বোঝায়।
  - **`label`** — **(প্রয়োজনীয়)** মানের পাশে দেখানো মানুষের পাঠযোগ্য লেবেল।
  - **`format`** — **(প্রস্তাবিত)** মানটি কীভাবে রেন্ডার করা উচিত তা নিয়ন্ত্রণ করে। সাধারণ ফরম্যাটগুলোর মধ্যে রয়েছে:
    - `tokenAmount`
    - `addressName`
    - `date`

    যখন কোনো অতিরিক্ত ফরম্যাটিংয়ের প্রয়োজন হয় না তখন `raw` ব্যবহার করুন। কিছু ফরম্যাট অতিরিক্ত **`params`** কনফিগারেশন গ্রহণ করে। উদাহরণস্বরূপ:

    - `tokenAmount` কোন টোকেন ঠিকানাটি ডেসিমাল এবং টিকার মেটাডেটা প্রদান করে তা শনাক্ত করতে `tokenPath` ব্যবহার করতে পারে।
    - `date` টাইমস্ট্যাম্পটি কীভাবে এনকোড করা হয়েছে তা বর্ণনা করতে `encoding` ব্যবহার করতে পারে।

    যদি নির্বাচিত ফরম্যাটের জন্য অতিরিক্ত তথ্যের প্রয়োজন না হয়, তবে `params` বাদ দিন।

## সম্পূর্ণ ডেসক্রিপ্টর {#the-complete-descriptor}

```json
{
  "$schema": "https://eips.ethereum.org/assets/eip-7730/erc7730-v2.schema.json",
  "context": {
    "$id": "uniswap-v3-router-mainnet",
    "contract": {
      "deployments": [
        {
          "chainId": 1,
          "address": "0xYourContractAddressOnMainnet"
        },
        {
          "chainId": 137,
          "address": "0xYourContractAddressOnPolygon"
        }
      ]
    }
  },
  "metadata": {
    "owner": "Example Swap Protocol",
    "info": {
      "url": "https://example.xyz"
    },
    "contractName": "SwapRouter"
  },
  "display": {
    "formats": {
      "swapExactTokensForTokens(uint256 amountIn,uint256 amountOutMin,address[] path,address to,uint256 deadline)": {
        "intent": "Swap",
        "interpolatedIntent": "Swap {amountIn} for at least {amountOutMin}",
        "fields": [
          {
            "path": "#.amountIn",
            "label": "Send",
            "format": "tokenAmount",
            "params": {
              "tokenPath": "#.path[0]"
            }
          },
          {
            "path": "#.amountOutMin",
            "label": "Receive minimum",
            "format": "tokenAmount",
            "params": {
              "tokenPath": "#.path[1]"
            }
          },
          {
            "path": "#.to",
            "label": "Recipient",
            "format": "addressName",
            "params": {
              "types": ["eoa", "contract"],
              "sources": ["local", "ens"]
            }
          },
          {
            "path": "#.deadline",
            "label": "Expires",
            "format": "date",
            "params": {
              "encoding": "timestamp"
            }
          }
        ]
      }
    }
  }
}
```

## ধাপ 5: রেজিস্ট্রিতে জমা দিন {#step-5-submit-to-the-registry}

[ERC-7730 রেজিস্ট্রি](https://github.com/ethereum/clear-signing-erc7730-registry) হলো একটি ওপেন রিপোজিটরি যা একটি নিরপেক্ষ স্টুয়ার্ড হিসেবে [ইথেরিয়াম ফাউন্ডেশন](/foundation/) দ্বারা হোস্ট করা হয়। যে কেউ এটি ক্লোন এবং সেলফ-হোস্ট করতে স্বাধীন — ওয়ালেটগুলো স্বাধীনভাবে সিদ্ধান্ত নেয় যে তারা কোন রেজিস্ট্রি ইনস্ট্যান্সগুলোকে বিশ্বাস করবে।

1. গিটহাবে (GitHub) রিপোজিটরিটি ফর্ক করুন  
2. `registry/<your-project-name>/` এ একটি ফোল্ডার তৈরি করুন  
3. এর ভিতরে আপনার ফাইলটি রাখুন: `registry/myproject/calldata-mycontract-0_0.json`  
4. রিপোর মধ্যে ব্যবহৃত আপেক্ষিক পাথে (relative path) `$schema` ফিল্ডটি আপডেট করুন: `"../../specs/erc7730-v2.schema.json"`  
5. একটি পুল রিকোয়েস্ট (pull request) খুলুন

যখন আপনি PR খুলবেন, তখন CI স্বয়ংক্রিয়ভাবে স্কিমা ভ্যালিডেশন চালায়, ফাংশন স্বাক্ষরগুলো বৈধ সিলেক্টর তৈরি করে কিনা তা পরীক্ষা করে, Sourcify-তে কন্ট্রাক্টের ঠিকানা যাচাই করা হয়েছে কিনা তা নিশ্চিত করে এবং ABI-এর অসঙ্গতিগুলো চিহ্নিত করে। চেক করার ফলাফলগুলো PR-এ ইনলাইনে প্রদর্শিত হয়। রেজিস্ট্রি মেইনটেইনাররা ত্রুটিপূর্ণ বা সম্ভাব্য ক্ষতিকারক ডেসক্রিপ্টরগুলোর জন্য সাবমিশনগুলো স্ক্রিন করেন। রেজিস্ট্রিতে অন্তর্ভুক্তির অর্থ এই নয় যে এটি অডিট করা হয়েছে বা অনুমোদন দেওয়া হয়েছে।

<Alert variant="info">
<AlertContent>
<AlertDescription>
**দ্রষ্টব্য:** আপনার PR গৃহীত হওয়ার আগে আপনার কন্ট্রাক্টটি অবশ্যই <a href="https://repo.sourcify.dev">Sourcify</a>-তে যাচাই করা থাকতে হবে। যদি এটি এখনও যাচাই করা না হয়ে থাকে, তবে প্রথমে <a href="https://verify.sourcify.dev/">ভেরিফিকেশন জমা দিন</a>।
</AlertDescription>
</AlertContent>
</Alert>

## মার্জ করার পর কী হয়? {#what-happens-after-merging}

রেজিস্ট্রিতে থাকা সমস্ত ডেসক্রিপ্টর অডিটরদের জন্য উন্মুক্ত। আপনার PR মার্জ হওয়ার পর, যেকোনো অডিটর আপনার ডেসক্রিপ্টর পর্যালোচনা করতে পারেন এবং এর নির্ভুলতা নিশ্চিত করে একটি ক্রিপ্টোগ্রাফিক সত্যায়ন ([ERC-8176](https://github.com/ethereum/ERCs/pull/1576) এর অধীনে) প্রকাশ করতে পারেন। 

এই সত্যায়ন সিগন্যালগুলো ওয়ালেটগুলোকে তাদের নিজস্ব ট্রাস্ট পলিসি প্রয়োগ করতে দেয় — একাধিক স্বাধীন সত্যায়ন থাকা একটি ডেসক্রিপ্টর, সত্যায়ন না থাকা ডেসক্রিপ্টরের চেয়ে বেশি গুরুত্ব বহন করে। আপনি [clearsigning.org](https://clearsigning.org) এর মাধ্যমে অডিটর কমিউনিটির সাথে যোগাযোগ করতে পারেন।

ওয়ালেটগুলো বেছে নেয় যে তারা কোন রেজিস্ট্রি সমর্থন করবে। একবার আপনার ডেসক্রিপ্টর রেজিস্ট্রিতে যুক্ত হয়ে গেলে, যে ওয়ালেটগুলো ERC-7730 সমর্থন করে সেগুলো যদি তাদের রেজিস্ট্রিতে থাকে তবে এটি ফেচ (fetch) করা শুরু করবে এবং ব্যবহারকারীরা যখন আপনার কন্ট্রাক্টের সাথে ইন্টারঅ্যাক্ট করবে তখন মানুষের পাঠযোগ্য ডেটা প্রদর্শন করবে।

## আরও পড়ুন {#further-reading}

- [ERC-7730 স্পেসিফিকেশন](https://eips.ethereum.org/EIPS/eip-7730)  
- [ERC-7730 রেজিস্ট্রি](https://github.com/ethereum/clear-signing-erc7730-registry)  
- [clearsigning.org](https://clearsigning.org) — টুলিং, ইকোসিস্টেম স্ট্যাটাস এবং গভর্ন্যান্স  
- [Sourcify কন্ট্রাক্ট ভেরিফিকেশন](https://sourcify.dev)  
- [ট্রিলিয়ন ডলার সিকিউরিটি ইনিশিয়েটিভ](https://trilliondollarsecurity.org)