0% found this document useful (0 votes)
122 views38 pages

Ether - JS

Ether . js Library Mannual

Uploaded by

faizanshk978
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
122 views38 pages

Ether - JS

Ether . js Library Mannual

Uploaded by

faizanshk978
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Ether.js is a JavaScript library for interacting with Ethereum blockchain.

It's
lightweight, secure, and commonly used for building decentralized applications
(dApps). Here's a quick breakdown:

Key Features:

1. Wallet Management:
1. Create wallets (mnemonic or private key).
2. Sign transactions/messages.
2. Provider API:

1. Connect to Ethereum nodes (e.g., Infura, Alchemy).


2. Fetch blockchain data like block numbers, gas prices, and balances.

3. Contract Interaction:

1. Deploy smart contracts.


2. Call functions and listen to contract events.

4. Utilities:

1. Encode/decode data.
2. Work with Ethereum addresses, BigNumber, and more.

Installation:

bash
Copy code
npm install ethers

Example Use:

1.

Connect to Ethereum:

2.
3.

javascript

4.
5.

Copy code

6.
7.
const { ethers } = require("ethers");const provider = new
ethers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_API_K
EY");

8.
9.
10.

Wallet Interaction:

11.
12.

javascript

13.
14.

Copy code

15.
16.

const wallet = new ethers.Wallet("PRIVATE_KEY",


provider);console.log(wallet.address);

17.
18.
19.

Smart Contract Interaction:

20.
21.

javascript

22.
23.

Copy code

24.
25.
const abi = [ /* Contract ABI */ ];const contractAddress =
"0x...";const contract = new ethers.Contract(contractAddress,
abi, wallet);const value = await contract.someFunction();

26.
27.
28.

Event Listening:

29.
30.

javascript

31.
32.

Copy code

33.
34.

contract.on("EventName", (args) => {


console.log(args);
});

35.
36.

Advantages:

 Simplicity.
 Extensive documentation.
 Compatible with browser and Node.js.

Alternatives:

 Web3.js.
 Web3.py (Python).

Here’s a deeper dive into Ether.js:

Modules in Ether.js
1.

Providers:

2.

o Connect to Ethereum networks.


o Types:

 JsonRpcProvider (Infura, Alchemy, custom node).


 WebSocketProvider (for real-time updates).
 EtherscanProvider (read-only).

javascript

Copy code

const provider = new


ethers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR
_API_KEY");const balance = await
provider.getBalance("0xAddress");console.log(ethers.forma
tEther(balance));

3.

Wallets:

4.

o Manage Ethereum accounts.


o Generate wallets, sign transactions, or connect with hardware wallets.

javascript

Copy code
const wallet = ethers.Wallet.createRandom(); // Generates
a new walletconsole.log(wallet.privateKey,
wallet.address);

5.

Contracts:

6.

o Interact with deployed smart contracts.


o Deploy new contracts.

javascript

Copy code

const abi = [ /* Contract ABI */ ];const contract = new


ethers.Contract(contractAddress, abi, provider);const
data = await contract.someFunction();

7.

Utils:

8.

o Provides cryptographic utilities, BigNumber handling, and encoding tools.

javascript
Copy code

console.log(ethers.isAddress("0xAddress")); // Validate
Ethereum addressconst value = ethers.parseEther("1.0");
// Convert ETH to Weiconsole.log(value.toString());

9.

Signers:

10.

o Represents an Ethereum account capable of signing transactions.


o Types:

 Wallet: Private key signer.


 JsonRpcSigner: Connected to a provider.
 VoidSigner: Non-signing address for read-only operations.

javascript

Copy code

const signer = provider.getSigner();const tx = await


signer.sendTransaction({
to: "0xRecipientAddress",
value: ethers.parseEther("0.1"),
});
Advanced Features

1.

Custom Gas Handling:

2.

mate gas:

javascript

Copy code

const gasEstimate = await


contract.estimateGas.someFunction();

o Set custom gas limits or prices.

3.

Event Filters:

4.

o Listen to blockchain events efficiently.

javascript

Copy code
const filter = contract.filters.Transfer("0xFromAddress",
"0xToAddress");
contract.on(filter, (from, to, amount) => {
console.log({ from, to, amount });
});

5.

ENS (Ethereum Name Service):

6.

o Resolve ENS names to addresses or vice versa.

javascript

Copy code

const address = await


provider.resolveName("vitalik.eth");console.log(address);

7.

Transaction Overrides:

8.

o Customize nonce, gas price, etc., in transactions.

javascript
Copy code

const tx = await wallet.sendTransaction({


to: "0xRecipientAddress",
value: ethers.parseEther("0.5"),
gasLimit: 21000,
gasPrice: ethers.parseUnits("50", "gwei"),
});

Ether.js vs Web3.js

Feature Ether.js Web3.js


Lightweight (smaller
Size Heavier bundle size
bundle)
Comprehensive but
Documentation Well-organized
cluttered
BigNumber Requires external
Built-in
Handling libraries
Modern async/await Uses callbacks (older
Promises
syntax syntax)
Browser Support Excellent Good

Common Use Cases

1.

dApp Development:

2.

o Use Ether.js with frontend frameworks like React, Angular, or Vue.

javascript
Copy code

const provider = new


ethers.BrowserProvider(window.ethereum);await
provider.send("eth_requestAccounts", []);const signer =
provider.getSigner();console.log(await
signer.getAddress());

3.

Backend Services:

4.

o Fetch Ethereum blockchain data for analytics or services.

5.

Token Interaction:

javascript

Copy code

const tokenContract = new ethers.Contract(tokenAddress,


erc20Abi, wallet);const tx = await
tokenContract.transfer("0xRecipient",
ethers.parseUnits("10", 18));console.log(tx.hash);

6.
NFT Handling:

7.

o Read or transfer ERC-721/1155 tokens.

Ethers.js Ecosystem

 Integrations:

o Works seamlessly with Infura, Alchemy, Hardhat, Truffle, etc.

 Testing:

o Commonly used with testing frameworks like Hardhat for smart contracts.

Here’s an in-depth guide on Ether.js with detailed topics and advanced concepts:

Core Concepts in Ether.js

1. Providers

Providers act as the interface to the Ethereum blockchain, enabling data retrieval and
transactions.

Types of Providers:

o JsonRpcProvider: Connects to a node via JSON-RPC.


o AlchemyProvider: Alchemy-specific provider.
o InfuraProvider: Infura-specific provider.
o WebSocketProvider: Supports real-time event listening.

Code Example:



javascript


Copy code


const { ethers } = require("ethers");const provider = new


ethers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_API_K
EY");
const blockNumber = await
provider.getBlockNumber();console.log("Current Block:",
blockNumber);


2. Wallets

Wallets handle private keys for signing and account management.

Wallet Operations:

javascript

Copy code

const wallet =
ethers.Wallet.createRandom();console.log("Address:",
wallet.address);console.log("Private Key:",
wallet.privateKey);
javascript

Copy code

const connectedWallet = wallet.connect(provider);

Encrypted Wallets:

javascript

Copy code

const encryptedJson = await


wallet.encrypt("strongPassword");console.log(encryptedJso
n);

javascript

Copy code
const decryptedWallet = await
ethers.Wallet.fromEncryptedJson(encryptedJson,
"strongPassword");

3. Contracts

Used for interacting with smart contracts via ABI and addresses.

Example:


javascript


Copy code


const abi = [ /* Contract ABI */ ];const address =


"0xContractAddress";const contract = new
ethers.Contract(address, abi, wallet);
// Call a read-only functionconst result = await
contract.someViewFunction();console.log(result);
// Send a transactionconst tx = await
contract.someFunction(arg1, arg2, { gasLimit:
300000 });console.log("Transaction Hash:", tx.hash);



Deploy a Contract:


javascript

Copy code


const factory = new ethers.ContractFactory(abi, bytecode,


wallet);const deployedContract = await factory.deploy(arg1,
arg2, { gasLimit: 4000000 });console.log("Deployed Address:",
deployedContract.address);


4. BigNumber Operations

Ether.js uses BigNumber to handle large integers like balances.

 Examples:

javascript


Copy code


const balance = ethers.parseEther("1.5"); // Convert ETH to


Weiconsole.log(balance.toString());
const total =
balance.add(ethers.parseEther("0.5"));console.log("Total:",
ethers.formatEther(total)); // Convert Wei back to ETH


Advanced Topics

1. Event Filters and Listeners


Monitor blockchain events efficiently.

Create a Filter:


javascript


Copy code


const filter = contract.filters.Transfer("0xFromAddress", null);


contract.on(filter, (from, to, value) => {
console.log(`Transfer from ${from} to ${to}:
${ethers.formatEther(value)}`);
});



Listening to Blocks:


javascript


Copy code


provider.on("block", (blockNumber) => {


console.log("New Block:", blockNumber);
});



2. Transaction Handling

Customize transactions by overriding gas, nonce, etc.

Send ETH:


javascript


Copy code


const tx = await wallet.sendTransaction({


to: "0xRecipientAddress",
value: ethers.parseEther("0.1"),
gasPrice: ethers.parseUnits("50", "gwei"),
gasLimit: 21000,
});console.log("Transaction Hash:", tx.hash);



Estimate Gas:


javascript


Copy code



const gasEstimate = await
contract.estimateGas.someFunction(arg1, arg2);console.log("Gas
Estimate:", gasEstimate.toString());


3. ENS (Ethereum Name Service)

Simplify address handling using ENS domains.

Resolve ENS Name to Address:


javascript


Copy code


const address = await


provider.resolveName("vitalik.eth");console.log("Address:",
address);



Reverse Lookup:


javascript


Copy code

const ensName = await


provider.lookupAddress("0xAddress");console.log("ENS Name:",
ensName);


4. Interacting with ERC-20 and ERC-721 Tokens

Predefined ABIs make working with tokens straightforward.

ERC-20 Token Example:


javascript


Copy code


const erc20Abi = [ /* Minimal ERC-20 ABI */ ];const


tokenContract = new ethers.Contract(tokenAddress, erc20Abi,
wallet);
// Get Token Balanceconst balance = await
tokenContract.balanceOf("0xAddress");console.log("Token
Balance:", ethers.formatUnits(balance, 18));
// Transfer Tokensconst tx = await
tokenContract.transfer("0xRecipient", ethers.parseUnits("10",
18));console.log("Transaction Hash:", tx.hash);



ERC-721 (NFT) Example:


javascript


Copy code


const erc721Abi = [ /* Minimal ERC-721 ABI */ ];const


nftContract = new ethers.Contract(nftAddress, erc721Abi,
wallet);
const owner = await nftContract.ownerOf(1); // Token ID
1console.log("Owner:", owner);


Common Patterns

1.

Connecting to MetaMask:

2.
3.

javascript

4.
5.

Copy code

6.
7.

const provider = new


ethers.BrowserProvider(window.ethereum);await
provider.send("eth_requestAccounts", []);const signer =
provider.getSigner();console.log("Connected Address:", await
signer.getAddress());
8.
9.
10.

Error Handling:

11.

o Catch errors for invalid transactions or failed calls.

javascript
Copy code
try {
const tx = await wallet.sendTransaction(txData);
} catch (error) {
console.error("Transaction failed:", error.message);
}

12.

Testing with Hardhat:

13.

o Use Ether.js in combination with Hardhat for contract testing.

javascript
Copy code
const { ethers } = require("hardhat");const [deployer] = await
ethers.getSigners();
const contract = await ethers.deployContract("MyContract",
[arg1, arg2]);console.log("Deployed at:", contract.address);

Here’s everything else you need to know about Ether.js:

Deeper Insights into Ether.js

1. Transaction Lifecycle

Understanding Ethereum transactions in Ether.js:


Steps:

1. Build the transaction object.


2. Sign the transaction.
3. Broadcast the transaction.
4. Wait for confirmation.

Code Example:


javascript


Copy code


const tx = {
to: "0xRecipientAddress",
value: ethers.parseEther("0.1"),
gasLimit: 21000,
gasPrice: ethers.parseUnits("30", "gwei"),
};
const signedTx = await wallet.signTransaction(tx);const sentTx
= await provider.sendTransaction(signedTx);const receipt =
await sentTx.wait(); // Wait for
confirmationconsole.log("Transaction Receipt:", receipt);


2. Offline Signing

Sign transactions without exposing the private key online.

 Example:

javascript


Copy code


const unsignedTx = {
to: "0xRecipientAddress",
value: ethers.parseEther("0.1"),
nonce: 0,
gasLimit: 21000,
gasPrice: ethers.parseUnits("20", "gwei"),
};
const signedTx = await
wallet.signTransaction(unsignedTx);console.log("Signed
Transaction:", signedTx);
// Broadcast the signed transaction laterconst txResponse =
await
provider.sendTransaction(signedTx);console.log("Transaction
Hash:", txResponse.hash);


3. Meta-Transactions

Allow users to send transactions without paying gas directly.

Flow:

o User signs a message with their wallet.


o A relayer pays the gas and broadcasts the transaction.

Example:



javascript


Copy code


const domain = {
name: "MyDApp",
version: "1",
chainId: 1, // Mainnet
verifyingContract: "0xContractAddress",
};
const types = {
MetaTransaction: [
{ name: "nonce", type: "uint256" },
{ name: "functionSignature", type: "bytes" },
],
};
const message = {
nonce: 1,
functionSignature: "0xFunctionData",
};
const signature = await wallet._signTypedData(domain, types,
message);console.log("Signature:", signature);


4. Handling Nonces

Nonces ensure transactions are processed in order.

Get Current Nonce:


javascript


Copy code


const nonce = await


provider.getTransactionCount(wallet.address);console.log("Curre
nt Nonce:", nonce);



Manually Set Nonce:


javascript


Copy code


const tx = {
to: "0xRecipient",
value: ethers.parseEther("1"),
nonce: nonce + 1, // Use next nonce
};


Gas Optimization

1. Gas Estimation

 Estimate gas usage before


sending a transaction:

javascript

Copy code


const gasEstimate = await


contract.estimateGas.someFunction(arg1, arg2);console.log("Gas
Estimate:", gasEstimate.toString());


2. Dynamic Gas Fees (EIP-1559)

 EIP-1559 introduces
maxFeePerGas and
maxPriorityFeePerGas:

javascript


Copy code


const tx = {
to: "0xRecipient",
value: ethers.parseEther("0.1"),
maxFeePerGas: ethers.parseUnits("100", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("2", "gwei"),
};
const txResponse = await
wallet.sendTransaction(tx);console.log("Transaction Hash:",
txResponse.hash);


Interacting with Ethereum Layer 2 (L2) Solutions


Ether.js supports L2 networks like Arbitrum, Optimism, and Polygon.

Switching Networks:


javascript


Copy code


const provider = new ethers.JsonRpcProvider("https://polygon-


rpc.com");const balance = await
provider.getBalance("0xYourAddress");console.log("Polygon
Balance:", ethers.formatEther(balance));



L2-Specific Transactions:

o Transactions work similarly but are faster and cheaper.

Security Practices

1.

Avoid Exposing Private Keys:

2.

o Use .env files for sensitive data.

javascript
Copy code
require("dotenv").config();const wallet = new
ethers.Wallet(process.env.PRIVATE_KEY);
3.

Verify Contract Interactions:

4.

o Double-check contract ABIs and addresses.

5.

Error Handling:

6.

o Catch errors to avoid app crashes.

javascript
Copy code
try {
const result = await contract.someFunction();
} catch (error) {
console.error("Error:", error.message);
}

Custom Utilities with Ether.js

1. Create Custom ABI Encoders/Decoders

Encode or decode data for lower-level operations.

 Example:

javascript


Copy code


const encodedData = ethers.AbiCoder.defaultAbiCoder().encode(


["uint256", "string"],
[123, "Hello"]
);console.log("Encoded Data:", encodedData);
const decodedData = ethers.AbiCoder.defaultAbiCoder().decode(
["uint256", "string"],
encodedData
);console.log("Decoded Data:", decodedData);


Testing with Ether.js

1.

Hardhat Integration:

2.

o Deploy and test contracts with Hardhat.

javascript
Copy code
const { ethers } = require("hardhat");
const MyContract = await
ethers.deployContract("MyContract");console.log("Contract
Address:", MyContract.address);
const result = await
MyContract.someFunction();console.log("Result:", result);

3.

Mocking Blockchain State:

4.

o Use Hardhat to fork the Ethereum mainnet for testing.

Ether.js Ecosystem Tools

1.

Hardhat:

2.

o Development environment for testing and deploying smart contracts.


3.

Etherscan Plugin:

4.

o Verify contracts directly on Etherscan.

5.

Alchemy/Infura:

6.

o Reliable Ethereum node services.

7.

Web3Modal:

8.

o Simplify wallet connections in dApps.

Common Debugging Tips

1.

Transaction Errors:

2.

o Check if your contract requires exact gas values.

3.

Invalid Signatures:

4.

o Ensure you’re signing the correct payload.

5.

Network Mismatch:

6.
o Verify the provider and network chain ID match.

Here’s even more on Ether.js, diving into specialized topics and advanced usage:

Specialized Topics

1. Gasless Transactions (Relay/MetaTx)

 Gasless transactions allow users to interact without owning ETH (a relayer pays the gas).

Workflow:

 User signs a message with wallet.


 Relayer sends the signed transaction to the blockchain.

Code Example:

javascript
Copy code
const messageHash =
ethers.utils.keccak256(ethers.utils.toUtf8Bytes("Message for
MetaTx"));const signature = await
wallet.signMessage(ethers.utils.arrayify(messageHash));
console.log("Signature:", signature);// Relayer broadcasts the signed
message to the smart contract

2. EIP-2771 (Trusted Forwarder for Gasless Transactions)

Ether.js supports EIP-2771 for handling meta-transactions using forwarders.

Example Integration:

javascript
Copy code
const forwarderAddress = "0xForwarderAddress";const forwarderAbi =
[/* Minimal Forwarder ABI */];const forwarder = new
ethers.Contract(forwarderAddress, forwarderAbi, provider);
const forwarderNonce = await
forwarder.getNonce(wallet.address);console.log("Nonce:",
forwarderNonce);
// Prepare a meta-transactionconst txData = {
from: wallet.address,
to: "0xTargetContract",
data: "0xFunctionData",
nonce: forwarderNonce,
};const signature = await
wallet.signMessage(ethers.utils.keccak256(txData));

3. MEV (Miner Extractable Value) Transactions

 Flashbots (for private transactions):


Prevent front-running by sending private transactions through Flashbots.

Setup Example:

javascript
Copy code
const flashbotsProvider = await
ethers.FlashbotsBundleProvider.create(
provider,
ethers.Wallet.createRandom() // Flashbots signer
);
const bundle = [
{
signer: wallet,
transaction: {
to: "0xRecipient",
value: ethers.parseEther("0.5"),
gasLimit: 21000,
},
},
];
const tx = await flashbotsProvider.sendBundle(bundle,
targetBlockNumber);console.log("Flashbots Bundle Sent:", tx);

4. Multisig Wallets

Interact with Gnosis Safe or other multisig wallets:

 Use the Gnosis Safe ABI to call functions like submitTransaction.

javascript
Copy code
const safeAbi = [/* Gnosis Safe ABI */];const safeAddress =
"0xGnosisSafeAddress";const safe = new ethers.Contract(safeAddress,
safeAbi, wallet);
const tx = await safe.submitTransaction("0xTarget",
ethers.parseEther("1"), "0xData");console.log("Multisig Transaction
Hash:", tx.hash);

5. Layer 3 Solutions

 Interact with zkRollups, StarkNet, or other advanced scaling solutions.

Example with zkSync:

javascript
Copy code
const zkSyncProvider = new ethers.JsonRpcProvider("https://zksync2-
rpc.zksync.io");const balance = await
zkSyncProvider.getBalance("0xYourAddress");console.log("zkSync
Balance:", ethers.formatEther(balance));

Error Debugging in Ether.js

1. Common Errors:

"insufficient funds":
Happens when sending a transaction with insufficient ETH.
Fix: Ensure wallet balance covers value + gas.


"invalid signer or provider":


Occurs if wallet isn’t connected to a provider.
Fix: Use wallet.connect(provider) before sending a transaction.


"gas required exceeds allowance":


Contract function may consume more gas than estimated.
Fix: Increase gasLimit.

2. Transaction Debugging:
 Simulate a transaction: Use
callStatic to run a
transaction locally without
broadcasting.

javascript


Copy code


const result = await contract.callStatic.someFunction(arg1,


arg2);console.log("Simulation Result:", result);


Optimized DApp Architecture with Ether.js

1. Provider Abstraction

Abstract providers to handle multiple networks:

javascript
Copy code
const getProvider = (network) => {
const rpcUrls = {
mainnet: "https://mainnet.infura.io/v3/YOUR_API_KEY",
polygon: "https://polygon-rpc.com",
};
return new ethers.JsonRpcProvider(rpcUrls[network]);
};
const provider = getProvider("polygon");

2. Batch Calls with Multicall

Avoid multiple network requests using the Multicall contract.

Example:

javascript
Copy code
const multicallAbi = [/* Minimal Multicall ABI */];const
multicallAddress = "0xMulticallAddress";
const multicall = new ethers.Contract(multicallAddress, multicallAbi,
provider);const calls = [
{ target: "0xContract1", callData:
contract1.interface.encodeFunctionData("method1", []) },
{ target: "0xContract2", callData:
contract2.interface.encodeFunctionData("method2", []) },
];
const { returnData } = await multicall.aggregate(calls);const decoded
= returnData.map((data, i) =>
ethers.AbiCoder.defaultAbiCoder().decode(["type"],
data));console.log(decoded);

3. Optimized Contract ABI Usage

 Import only the necessary part of an ABI to reduce bundle size:

javascript
Copy code
const minimalAbi = ["function balanceOf(address) view returns
(uint256)"];const erc20 = new ethers.Contract(tokenAddress,
minimalAbi, provider);
const balance = await
erc20.balanceOf("0xAddress");console.log("Balance:",
ethers.formatUnits(balance, 18));

Performance Tips

1.

Use WebSocketProvider for real-time updates instead of polling:

2.
3.

javascript

4.
5.

Copy code
6.
7.

const wsProvider = new


ethers.WebSocketProvider("wss://mainnet.infura.io/ws/v3/YOUR_AP
I_KEY");
wsProvider.on("block", (blockNumber) => console.log("New
Block:", blockNumber));

8.
9.
10.

Cache Frequent Calls: Avoid redundant network requests for static data like
contract ABIs or token metadata.

11.
12.

Batch Processing: Process large datasets using batching:

13.
14.

javascript

15.
16.

Copy code

17.
18.

const addresses = [...Array(100).keys()].map((i) =>


`0xAddress${i}`);const balances = await
Promise.all(addresses.map((addr) =>
provider.getBalance(addr)));console.log("Balances:", balances);

19.
20.

Extending Ether.js

1. Custom Plugins
You can create custom modules to extend Ether.js functionality:

javascript
Copy code
class MyCustomProvider extends ethers.JsonRpcProvider {
async getCustomData(address) {
const balance = await this.getBalance(address);
return ethers.formatEther(balance) + " ETH";
}
}const customProvider = new
MyCustomProvider("https://mainnet.infura.io/v3/YOUR_API_KEY");const
data = await
customProvider.getCustomData("0xAddress");console.log(data);

2. Combining with Other Libraries

 Use GraphQL (via The Graph) for efficient subgraph queries.


 Example:

javascript


Copy code


const query = `
{
transfers(where: { to: "0xRecipient" }) {
from
to
value
}
}
`;const response = await
fetch("https://api.thegraph.com/subgraphs/name/example", {
method: "POST",
body: JSON.stringify({ query }),
});const data = await
response.json();console.log(data.data.transfers);


You might also like