শার্দিয়াম স্বয়ংক্রিয় ইআইপি-২৯৩০ – একটি ব্যাপক শিক্ষাগত গাইড
Tags: webdev, blockchain, web3, shardeum
Published: 2024-02-02 03:22:07

## বহুমুখী চুক্তি

## ইআইপি-২৯৩০ কি?
ইআইপি-২৯৩০ ব্যবহারকারীদের একটি লেনদেনের জন্য ঠিকানা এবং স্টোরেজ স্লট সংজ্ঞায়িত করতে দেয়।

[https://eips.ethereum.org/EIPS/eip-2930](https://eips.ethereum.org/EIPS/eip-2930)

## কেন ইআইপি-২৯৩০ গুরুত্বপূর্ণ?
স্ফিংস ১.এক্স রুট শার্ডের জন্য শার্দিয়াম আরপিসি নোডের অ্যাক্সেসলিস্টকে স্বয়ংক্রিয়ভাবে দিয়েছে। অতএব, স্বয়ংক্রিয় অ্যাক্সেসলিস্ট জেনারেশন সহ এই নেটওয়ার্কগুলির জন্য আপনাকে আর অ্যাক্সেসলিস্ট নির্দিষ্ট করতে হবে না।

**এই নথিটির জন্য দরকারী:**
- শিক্ষাগত উদ্দেশ্যে
- পরিস্থিতি যেখানে স্বয়ংক্রিয় অ্যাক্সেসলিস্ট ব্যর্থ হয় এবং আপনাকে সরাসরি অ্যাক্সেসলিস্ট নির্দিষ্ট করতে হবে

## একটি লেনদেনের জন্য ইআইপি-২৯৩০ ডেটা কোথায় অবস্থিত?
অ্যাক্সেসলিস্ট লেনদেনের পরামিতি হল যেখানে ইআইপি-২৯৩০ ঠিকানা এবং স্টোরেজ স্লট ডেটা যায়৷

## আমি কিভাবে একটি ইআইপি-২৯৩০ লেনদেনের জন্য একটি অ্যাক্সেসলিস্ট সংজ্ঞায়িত করব?
ইআইপি-২৯৩০ স্পেসিফিকেশনের উপর ভিত্তি করে, সাধারণ সিনট্যাক্স হওয়া উচিত:
- ঠিকানা [২০ বাইট]
- তারপর সেই ঠিকানায় স্টোরেজ স্লটগুলি অ্যাক্সেস করা হচ্ছে [৩২ বাইট]

উদাহরণ:

`[
        [
            "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
            [
                "0x0000000000000000000000000000000000000000000000000000000000000003",
                "0x0000000000000000000000000000000000000000000000000000000000000007"
            ]
        ],
        [
            "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
            []
        ]
    ]`

## ইআইপি-২৯৩০ ঐচ্ছিক:
ওয়ালেটের মধ্যে শার্দিয়াম-এ SHM স্থানান্তর করুন:
একটি অ্যাক্সেস তালিকা ঠিকানা সহ একটি ইআইপি-২৯৩০ লেনদেন পাঠান যার কোনো স্টোরেজ নেই:

**- জাভাস্ক্রিপ্ট**

`const Web3 = require('web3')
const ethers = require("ethers")

const rpcURL = "https://dapps.shardeum.org"
const web3 = new Web3(rpcURL)

const provider = new ethers.providers.JsonRpcProvider(rpcURL)
const signer = new ethers.Wallet(Buffer.from(process.env.devTestnetPrivateKey, 'hex'), provider);
console.log("User wallet address: " + signer.address)

const transferToWallet = new ethers.Wallet(Buffer.from(process.env.devTestnetPrivateKeyTwo, 'hex'), provider);
console.log("transferToWallet address: " + transferToWallet.address)

createAndSendTx();

async function createAndSendTx() {

    const chainIdConnected = await web3.eth.getChainId();
    console.log("chainIdConnected: "+ chainIdConnected)

    const oneEtherInWeiSHM = "1000000000000000000"
    console.log("oneEtherInWeiSHM: " + oneEtherInWeiSHM)

    const userBalance = await provider.getBalance(signer.address);
    console.log("User Balance [Shardeum SHM]" )
    console.log(ethers.utils.formatEther(userBalance))

    const receiverBalance = await provider.getBalance(transferToWallet.address);
    console.log("Receiver Balance [Shardeum SHM]" )
    console.log(ethers.utils.formatEther(receiverBalance))

    const txCount = await provider.getTransactionCount(signer.address);

    const tx = signer.sendTransaction({
          chainId: chainIdConnected,
          to: transferToWallet.address,
          nonce:    web3.utils.toHex(txCount),
          gasLimit: web3.utils.toHex(300000), // Raise the gas limit to a much higher amount
          gasPrice: web3.utils.toHex(web3.utils.toWei('30', 'gwei')),
          value: oneEtherInWeiSHM,
          type: 1,
          accessList: [
            {
              address: transferToWallet.address,
              storageKeys: []
            }
          ]

    });

    console.log("WAIT FOR TX RECEIPT: ")
    await tx
    console.log("TX RECEIPT: ")
    console.log(tx)

}`

**- পাইথন**

`from web3 import Web3
import json
import os
import time

ShardeumConnectionHTTPS = "https://dapps.shardeum.org/";
web3 = Web3(Web3.HTTPProvider(ShardeumConnectionHTTPS))

chainIdConnected = web3.eth.chain_id
print("chainIdConnected: " + str(chainIdConnected))

devTestnetPrivateKey = str(os.environ['devTestnetPrivateKey']);

userWallet = (web3.eth.account.from_key(devTestnetPrivateKey)).address
print("User Wallet Address: " + userWallet)

devTestnetPrivateKeyTwo = str(os.environ['devTestnetPrivateKeyTwo']);

transferToWallet = (web3.eth.account.from_key(devTestnetPrivateKeyTwo)).address
print("transferToWallet address: " + transferToWallet)

oneEtherInWeiSHM = "1000000000000000000"
print("weiMsgValueToSend: " + oneEtherInWeiSHM)

userBalance =  web3.eth.getBalance(userWallet);
print("User Balance [Shardeum SHM]" )
print(web3.fromWei(userBalance, "ether"))

receiverBalance =  web3.eth.getBalance(transferToWallet);
print("Receiver Balance [Shardeum SHM]" )
print(web3.fromWei(receiverBalance, "ether"))

transferTx = {
    'chainId' : chainIdConnected,
    'nonce':  web3.eth.getTransactionCount(userWallet)       ,
    'to': transferToWallet, #WORKS WITH REGULAR WALLETS BUT CANNOT SEND TO CONTRACT FOR SOME REASON?
    'gas': 2100000, #WORKS WITH 1000000. If not try : Remix > deploy and run transactions
    'gasPrice': web3.toWei('30', 'gwei'), # https://etherscan.io/gastracker
    'value': int(oneEtherInWeiSHM),
    'accessList' :
                [
                    {
                        "address" : transferToWallet,
                        "storageKeys": []
                    }
                ]
}

signed_tx = web3.eth.account.signTransaction(transferTx, devTestnetPrivateKey)
tx_hash = web3.toHex(web3.eth.sendRawTransaction(signed_tx.rawTransaction))
print("TX HASH: " + tx_hash)

time.sleep(15)

receipt = web3.eth.getTransactionReceipt(tx_hash)
print("TX RECEIPT: " + str(receipt) )`

## চুক্তি কন্ট্রাক্টটুকল এবং মাল্টিকল:

**- সলিডিটি**

`// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

contract contractToCall {

    uint public slot0; //uint is 32 bytes and fills a 32 byte slot. //Do not set 0 manually it wastes gas!

    function set(uint x) public {
        slot0 = x;
    }

}

contract Multicall {

    contractToCall public callContractToCall;

    constructor(address setCallOne) {
        callContractToCall = contractToCall(setCallOne);
    }

    function multiCallRead() public view returns(uint) {
        return callContractToCall.slot0();
    }

    function multiCallWrite(uint x) public {
        callContractToCall.set(x);
    }

}`

## কন্ট্রাক্টটুকল (একক ঠিকানা)
অ্যাক্সেসলিস্ট সহ একটি ইআইপি-২৯৩০ লেনদেন পাঠান। অ্যাক্সেসলিস্টে চুক্তির ঠিকানা এবং অ্যাক্সেস করা স্টোরেজ স্লট (বা স্লট) রয়েছে। এই ক্ষেত্রে, এটি স্টোরেজ স্লট০ হবে, কারণ এটি একটি একক uint স্টোরেজ ভেরিয়েবল (uint = ২৫৬ বিট = ৩২ বাইট) যা আমরা যখন "set(unit)" বলি তখন পরিবর্তন করা হয়।

**- জাভাস্ক্রিপ্ট**

`const Web3 = require('web3')
const ethers = require("ethers")

const rpcURL = "https://dapps.shardeum.org/"
const web3 = new Web3(rpcURL)

const provider = new ethers.providers.JsonRpcProvider(rpcURL)
const signer = new ethers.Wallet(Buffer.from(process.env.devTestnetPrivateKey, 'hex'), provider);
console.log("User wallet address: " + signer.address)

const simpleStorageAddress = '0xE8eb488bEe284ed5b9657D5fc928f90F40BC2d57'
const simpleStorageABI = [{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slot0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

const simpleStorageDeployed = new web3.eth.Contract(simpleStorageABI, simpleStorageAddress)

createAndSendTx();

async function createAndSendTx() {

    const chainIdConnected = await web3.eth.getChainId();
    console.log("chainIdConnected: "+ chainIdConnected)

    const slot0 = await simpleStorageDeployed.methods.slot0().call()
    console.log("slot0: "+ slot0)

    const unixTime = Date.now();
    console.log("UNIX TIME: " + unixTime)

    const txCount = await provider.getTransactionCount(signer.address);

    const tx = signer.sendTransaction({
          chainId: chainIdConnected,
          to: simpleStorageAddress,
          nonce:    web3.utils.toHex(txCount),
          gasLimit: web3.utils.toHex(300000), // Raise the gas limit to a much higher amount
          gasPrice: web3.utils.toHex(web3.utils.toWei('30', 'gwei')),
          data: simpleStorageDeployed.methods.set(unixTime).encodeABI(),
          type: 1,
          accessList: [
            {
              address: simpleStorageAddress,
              storageKeys: [
                "0x0000000000000000000000000000000000000000000000000000000000000000",
              ]
            }
          ]

    });

    console.log("WAIT FOR TX RECEIPT: ")
    await tx
    console.log("TX RECEIPT: ")
    console.log(tx)

}`

**- পাইথন**

`from web3 import Web3
import json
import os
import math
import time

ShardeumConnectionHTTPS = "https://dapps.shardeum.org/";
web3 = Web3(Web3.HTTPProvider(ShardeumConnectionHTTPS))

chainIdConnected = web3.eth.chain_id
print("chainIdConnected: " + str(chainIdConnected))

devTestnetPrivateKey = str(os.environ['devTestnetPrivateKey']);

userWallet = (web3.eth.account.from_key(devTestnetPrivateKey)).address
print("User Wallet Address: " + userWallet)

Contract_At_Address= web3.toChecksumAddress("0xE8eb488bEe284ed5b9657D5fc928f90F40BC2d57");
abi_Contract = json.loads('[{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slot0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]')
contract_Call = web3.eth.contract(address = Contract_At_Address , abi = abi_Contract);

print(contract_Call.functions.slot0().call());

unixTime = int(math.floor( time.time()*(10**3)) )
print("UNIX TIME: " + str(unixTime) )

EIP_2930_tx = {
    'chainId' : chainIdConnected,
    'nonce':  web3.eth.getTransactionCount(userWallet)       ,
    'to': Contract_At_Address, #WORKS WITH REGULAR WALLETS BUT CANNOT SEND TO CONTRACT FOR SOME REASON?
    'gas': 2100000, #WORKS WITH 1000000. If not try : Remix > deploy and run transactions
    'gasPrice': web3.toWei('30', 'gwei'), # https://etherscan.io/gastracker
    'data' : contract_Call.encodeABI(fn_name='set', args=[unixTime]) ,
    'accessList' :
                [
                    {
                        "address" : Contract_At_Address,
                        "storageKeys": [
                            "0x0000000000000000000000000000000000000000000000000000000000000000",
                        ]
                    }
                ]
}

signed_tx = web3.eth.account.signTransaction(EIP_2930_tx, devTestnetPrivateKey)
tx_hash = web3.toHex(web3.eth.sendRawTransaction(signed_tx.rawTransaction))
print("TX HASH: " + tx_hash)

time.sleep(15)

receipt = web3.eth.getTransactionReceipt(tx_hash)
print("TX RECEIPT: " + str(receipt) )`

## মাল্টিকল স্টোরেজ পড়ুন:
রিডিং কন্ট্রাক্ট বলে যে ক্রস শার্ডের অ্যাক্সেস লিস্টের প্রয়োজন নেই।

উদাহরণস্বরূপ, ইয়ারসি২০ মাল্টিকল:

**
- সলিডিটি
**

`tokenObject.totalSupply()`

কোনো অ্যাক্সেসলিস্ট ক্রস শার্ড ছাড়াই কাজ করবে।

## ইআইপি-২৯৩০ আবশ্যক:

## মাল্টিকল স্টোরেজ লিখুন:
চুক্তি লেখার জন্য ক্রস শার্ডের জন্য একটি অ্যাক্সেস তালিকা প্রয়োজন।

উদাহরণস্বরূপ, ইয়ারসি২০ মাল্টিকল:

**- সলিডিটি**

`tokenObject.transfer(recipient, amount)`

ক্রস শার্ড কাজ করার জন্য একটি অ্যাক্সেসলিস্টের প্রয়োজন হবে।

চুক্তি মাল্টিকল অন্যান্য চুক্তির রাজ্যগুলি পরিবর্তন করতে পারে (এই ক্ষেত্রে ContractToCall)। শার্ডেড শার্ডিয়াম নেটওয়ার্কগুলির জন্য (যেমন স্বাধীনতা ২.এক্স এবং স্ফিংক্স), আমাদের লেনদেনে "from" এবং "to" এর বাইরে যে ঠিকানাগুলি এবং স্টোরেজ স্লটগুলিকে ডাকা হচ্ছে তা নির্দিষ্ট করতে হবে৷

## স্টোরেজ স্লটে স্ফিংস ড্যাপ ঠিকানা কোডহ্যাশ:
স্ফিংস (বেটানেট) প্রতিটি সংশ্লিষ্ট বাহ্যিকভাবে বলা ঠিকানার জন্য স্টোরেজ স্লটে কোডহ্যাশের প্রয়োজন হবে না।

সলিডিটিতে, আপনি ম্যাচিং নেটওয়ার্কে স্থাপন করা চুক্তি থেকে একটি ঠিকানা কোডহ্যাশ পেতে পারেন [একটি ঠিকানা একটি চুক্তি কিনা তা পরীক্ষা করার সাথে সাথে]। আপনি ইথার লাইব্রেরির সাথে একটি ঠিকানা কোডহ্যাশও পেতে পারেন।

## সলিডিটি কোডহ্যাশ উদাহরণ:

**- সলিডিটি**

`// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

contract addressCodeHash { //From https://soliditydeveloper.com/extcodehash

    function getCodeHash(address account) public view returns (bytes32) {

        bytes32 codeHash;    
        assembly { codeHash := extcodehash(account) }

        return (codeHash);
    }

    function isContractBasedOnHash(address account) public view returns (bool) {
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

        bytes32 codeHash;    
        assembly { codeHash := extcodehash(account) }

        return (codeHash != accountHash && codeHash != 0x0);
    }

    function isContractBasedOnSize(address addr) public view returns (bool) {
        uint size;
        assembly { size := extcodesize(addr) }
        return size > 0;
    }

}`

## ইআইপি-২৯৩০ অ্যাকসেসলিস্ট লেনদেনের জন্য মাল্টিকল কন্ট্রাক্টের জন্য কন্ট্রাক্টটুকল-এ স্লট০ পরিবর্তন করুন:

**- জাভাস্ক্রিপ্ট**

`const Web3 = require('web3')
const ethers = require("ethers")

const rpcURL = "https://dapps.shardeum.org/"
const web3 = new Web3(rpcURL)

const provider = new ethers.providers.JsonRpcProvider(rpcURL)
const signer = new ethers.Wallet(Buffer.from(process.env.devTestnetPrivateKey, 'hex'), provider);
console.log("User wallet address: " + signer.address)

const contractAddress_JS = '0xb1fEf690f84241738b188eF8b88e52B2cc59AbD2'
const contractABI_JS = [{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"multiCallWrite","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"setCallOne","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"callContractToCall","outputs":[{"internalType":"contractcontractToCall","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiCallRead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

const contractDefined_JS = new web3.eth.Contract(contractABI_JS, contractAddress_JS)

createAndSendTx();

async function createAndSendTx() {

    const chainIdConnected = await web3.eth.getChainId();
    console.log("chainIdConnected: "+ chainIdConnected)

    const slot0 = await contractDefined_JS.methods.multiCallRead().call()
    console.log("slot0: "+ slot0)

    const contractOneAddress = await contractDefined_JS.methods.callContractToCall().call()
    console.log("contractOneAddress: "+ contractOneAddress)

    const codeHash = await provider.getCode(contractOneAddress)
    console.log("contractOneAddress codeHash: " + codeHash)

    const unixTime = Date.now();
    console.log("UNIX TIME: " + unixTime)

    const txCount = await provider.getTransactionCount(signer.address);

    const tx = signer.sendTransaction({
        chainId: chainIdConnected,
        to: contractAddress_JS,
        nonce:    web3.utils.toHex(txCount),
        gasLimit: web3.utils.toHex(2100000), // Raise the gas limit to a much higher amount
        gasPrice: web3.utils.toHex(web3.utils.toWei('30', 'gwei')),
        data: contractDefined_JS.methods.multiCallWrite(unixTime).encodeABI(),
        type: 1,
        accessList: [
          {
            address: contractOneAddress, //Contract address we are calling from the "to" contract at some point.
            storageKeys: [
              "0x0000000000000000000000000000000000000000000000000000000000000000",
              codeHash, //Code hash from EXTCODEHASH https://blog.finxter.com/how-to-find-out-if-an-ethereum-address-is-a-contract/
            ]
          }
        ]

    });

    console.log("WAIT FOR TX RECEIPT: ")
    await tx
    console.log("TX RECEIPT: ")
    console.log(tx)

}`

**- পাইথন**

`from web3 import Web3
import json
import os
import time
import math

ShardeumConnectionHTTPS = "https://dapps.shardeum.org/";
web3 = Web3(Web3.HTTPProvider(ShardeumConnectionHTTPS))

chainIdConnected = web3.eth.chain_id
print("chainIdConnected: " + str(chainIdConnected))

devTestnetPrivateKey = str(os.environ['devTestnetPrivateKey']);

userWallet = (web3.eth.account.from_key(devTestnetPrivateKey)).address
print("User Wallet Address: " + userWallet)

multicallContractAddress= web3.toChecksumAddress("0xb1fEf690f84241738b188eF8b88e52B2cc59AbD2");
multicallContractABI = json.loads('[{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"multiCallWrite","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"setCallOne","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"callContractToCall","outputs":[{"internalType":"contractcontractToCall","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiCallRead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]')
multicallContractDeployed = web3.eth.contract(address = multicallContractAddress , abi = multicallContractABI);

contractOneAddress = multicallContractDeployed.functions.callContractToCall().call()
print("contractOneAddress: "+contractOneAddress)

slot0 = multicallContractDeployed.functions.multiCallRead().call()
print("slot0: "+ str(slot0) )

codeHashBytes32 =  (web3.eth.get_code(contractOneAddress))
codeHashString = codeHashBytes32.hex()
print("contractOneAddress codeHash: " + codeHashString )

unixTime = int(math.floor( time.time()*(10**3)) )
print("UNIX TIME: " + str(unixTime) )

EIP_2930_tx = {
  'chainId' : chainIdConnected,
  'to': multicallContractAddress, #WORKS WITH REGULAR WALLETS BUT CANNOT SEND TO CONTRACT FOR SOME REASON?
  'nonce':  web3.eth.getTransactionCount(userWallet)       ,
  'gas': 2100000, #WORKS WITH 1000000. If not try : Remix > deploy and run transactions
  'gasPrice': web3.toWei('30', 'gwei'), # https://etherscan.io/gastracker
  'data' : multicallContractDeployed.encodeABI(fn_name='multiCallWrite', args=[unixTime]) ,
  'type' : 1,
  'accessList' :
              [
                  {
                      "address" : contractOneAddress,
                      "storageKeys": [
                          "0x0000000000000000000000000000000000000000000000000000000000000000",
                          codeHashString  ##Code hash from EXTCODEHASH https://blog.finxter.com/how-to-find-out-if-an-ethereum-address-is-a-contract/
                      ]
                  }
              ]
}

signed_tx = web3.eth.account.signTransaction(EIP_2930_tx, devTestnetPrivateKey)
tx_hash = web3.toHex(web3.eth.sendRawTransaction(signed_tx.rawTransaction))
print("TX HASH: " + tx_hash)

time.sleep(15)

receipt = web3.eth.getTransactionReceipt(tx_hash)
print("TX RECEIPT: " + str(receipt) )`

## কিভাবে আমি সহজে একটি ইআইপি-২৯৩০ অ্যাক্সেসলিস্ট তৈরি করতে পারি?
ইআইপি-২৯৩০ অ্যাক্সেসলিস্ট সিমুলেটর
টুল ৯১% নির্ভুলতার সাথে অ্যাক্সেসলিস্ট তৈরি করে:

[https://github.com/alexchenzl/predict-al](https://github.com/alexchenzl/predict-al)

অদলবদল লেনদেনের জন্য ইআইপি-২৯৩০ অ্যাক্সেসলিস্ট জেনারেশন এই গিটহাব সংগ্রহস্থলে পাওয়া যাবে:

[https://github.com/shardeum-globalswap/interface/tree/support-eip2930](https://github.com/shardeum-globalswap/interface/tree/support-eip2930)

## সলিডিটি ইন্টারফেস

## সলিডিটি ইন্টারফেস কি?
সলিডিটি ইন্টারফেসগুলি স্মার্ট চুক্তিগুলিকে একে অপরের সাথে যোগাযোগ করার অনুমতি দেয়।

## কেন সলিডিটি ইন্টারফেস দরকারী?
সলিডিটি ইন্টারফেসগুলি করতে পারে:

- বিভিন্ন সলিডিটি সংস্করণের সাথে কল চুক্তি
- শুধুমাত্র তাদের ব্যবহারের ক্ষেত্রে প্রয়োজনীয় ফাংশন ব্যবহার করুন

## আমি কিভাবে একটি সলিডিটি ইন্টারফেস সংজ্ঞায়িত করব?
চুক্তি ইন্টারফেস চুক্তির উপরে সংজ্ঞায়িত করা হয়েছে যা চুক্তি ইন্টারফেস কল করা হবে। নাম, ইনপুট এবং মডিফায়ারের উপর ভিত্তি করে ইন্টারফেসের ভিতরে ফাংশনগুলি সংজ্ঞায়িত করা হয়।

## সলিডিটি ইন্টারফেস ফাংশন কোথায় সংজ্ঞায়িত করা হয়?
চুক্তিতে একটি চুক্তি ইন্টারফেস উদাহরণ তৈরি করা দরকার যা ইন্টারফেসটি ব্যবহার করবে। চুক্তি ইন্টারফেস তারপর সংজ্ঞায়িত করা হয় যখন ইন্টারফেস ব্যবহার করে চুক্তির জন্য কনস্ট্রাক্টরের ভিতরে তার ঠিকানা সেট করা হয়।

## আমি কখন সলিডিটি ইন্টারফেস ব্যবহার করব?
ইন্টারফেসের সাথে উপযোগী একটি জনপ্রিয় চুক্তি হল WETH (রেপড ইথার)। এই চুক্তিটি MSG.VALUE কে একটি ইআরসি-২০ উদাহরণে রূপান্তরিত করে৷ শার্দিয়াম-এ, SHM হল MSG.VALUE৷ অতএব, WETH হল শার্দিয়াম-এ WSHM। এই চুক্তিতে মোড়ানো এবং মোড়ানো ফাংশন রয়েছে:

জমা (মোড়ানো): SHM => WSHM।

প্রত্যাহার (আনওর্যাপ): WSHM => SHM।

একটি WSHM ইন্টারফেস ব্যবহার করে, আমরা একটি সলিডিটি ০.৮.০ চুক্তি তৈরি করতে পারি যা WSHM (সলিডিটি ০.৪.০) এর সাথে যোগাযোগ করতে পারে।

## WSHM সলিডিটি ০.৪.০

**- সলিডিটি**

`// SPDX-License-Identifier: MIT
pragma solidity ^0.4.18;

contract WSHM {
    string public name     = "Wrapped SHM";
    string public symbol   = "WSHM";
    uint8  public decimals = 18;

    event  Approval(address indexed src, address indexed guy, uint wad);
    event  Transfer(address indexed src, address indexed dst, uint wad);
    event  Deposit(address indexed dst, uint wad);
    event  Withdrawal(address indexed src, uint wad);

    mapping (address => uint)                       public  balanceOf;
    mapping (address => mapping (address => uint))  public  allowance;

    function() public payable {
        deposit();
    }
    function deposit() public payable {
        balanceOf[msg.sender] += msg.value;
        Deposit(msg.sender, msg.value);
    }
    function withdraw(uint wad) public {
        require(balanceOf[msg.sender] >= wad);
        balanceOf[msg.sender] -= wad;
        msg.sender.transfer(wad);
        Withdrawal(msg.sender, wad);
    }

    function totalSupply() public view returns (uint) {
        return this.balance;
    }

    function approve(address guy, uint wad) public returns (bool) {
        allowance[msg.sender][guy] = wad;
        Approval(msg.sender, guy, wad);
        return true;
    }

    function transfer(address dst, uint wad) public returns (bool) {
        return transferFrom(msg.sender, dst, wad);
    }

    function transferFrom(address src, address dst, uint wad)
        public
        returns (bool)
    {
        require(balanceOf[src] >= wad);

        if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
            require(allowance[src][msg.sender] >= wad);
            allowance[src][msg.sender] -= wad;
        }

        balanceOf[src] -= wad;
        balanceOf[dst] += wad;

        Transfer(src, dst, wad);

        return true;
    }
}`

## WSHM ইন্টারফেস সলিডিটি ০.৮.০ মাল্টিকল কন্ট্রাক্ট সহ

**- সলিডিটি**

`// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

interface interfaceWSHM {

    function transfer(address dst, uint wad) external returns (bool);

    function transferFrom(address src, address dst, uint wad) external returns (bool);

    function withdraw(uint wad) external;

    function deposit() external payable;

}

contract multicallWSHM {

    interfaceWSHM public WSHM;

    receive() external payable {}

    fallback() external payable {}

    constructor() {
        WSHM = interfaceWSHM(0xa80d5d2C8Cc0d06fBC1F1A89A05d76f86082C20e); // WSHM address.
    }

    function multicallDeposit() public payable {
        WSHM.deposit{value: msg.value}();
        WSHM.transfer(msg.sender, msg.value);
    }

    function multicallWithdraw(uint256 amount) public {
        WSHM.transferFrom(msg.sender,address(this),amount);
        WSHM.withdraw(amount);
        payable(msg.sender).transfer(address(this).balance);
    }

}`

@shardeum #ShardeumIsBorderless