From 336edcf90ff04ceca23b71aca1c8bcd2e7b5c36c Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 7 Nov 2023 15:22:25 +0100 Subject: [PATCH 01/12] draft `Migration from ethers.js` --- .../migration_from_other_libs/_category_.yml | 4 + .../migration_from_other_libs/ethers/index.md | 129 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 docs/docs/guides/migration_from_other_libs/_category_.yml create mode 100644 docs/docs/guides/migration_from_other_libs/ethers/index.md diff --git a/docs/docs/guides/migration_from_other_libs/_category_.yml b/docs/docs/guides/migration_from_other_libs/_category_.yml new file mode 100644 index 00000000000..75eb4a3e92c --- /dev/null +++ b/docs/docs/guides/migration_from_other_libs/_category_.yml @@ -0,0 +1,4 @@ +label: 'Migration from Libraries' +collapsible: true +collapsed: false +link: null \ No newline at end of file diff --git a/docs/docs/guides/migration_from_other_libs/ethers/index.md b/docs/docs/guides/migration_from_other_libs/ethers/index.md new file mode 100644 index 00000000000..0b047687316 --- /dev/null +++ b/docs/docs/guides/migration_from_other_libs/ethers/index.md @@ -0,0 +1,129 @@ +--- +sidebar_position: 1 +sidebar_label: 'Migration from ethers.js' +title: 'Migration from ethers.js' +--- + +**[This is still a draft document]** + +If you're currently using the ethers.js library to interact with the Ethereum blockchain and want to migrate to web3.js version 4, follow this guide. + +However, migrating from a library to another would usually need careful changes. But, ethers.js have lots of similarities with web3.js and migration would usually be easy and strate forward. However, you still need to check your code for possible tweaks if needed. + +## Installation + +First, install the latest version of web3.js: + +```bash +npm install web3 +``` + +## Initialization + +With ethers.js, you would initialize like: + +```typescript +import { ethers } from 'ethers'; + +const provider = new ethers.providers.JsonRpcProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_KEY'); +``` + +With web3.js v4: + +```typescript +import { Web3 } from 'web3'; + +const web3 = new Web3('https://rinkeby.infura.io/v3/YOUR_INFURA_KEY'); +``` + + +## Fast takes **(needs review)** + +1. Replace all instances of `ethers` with `Web3` +2. Replace all instances of `ethers.providers` with `Web3.providers` +3. Replace all instances of `ethers.utils` with `Web3.utils` +4. Replace all instances of `ethers.Contract` with `Web3.eth.Contract` +5. Replace all instances of `ethers.Wallet` with `Web3.eth.accounts.wallet` +6. Replace all instances of `ethers.Signer` with `Web3.eth.accounts` +7. Replace all instances of `ethers.utils.formatEther` with `Web3.utils.fromWei` +8. Replace all instances of `ethers.utils.parseEther` with `Web3.utils.toWei` + + +## Wallets and Accounts + +To manage wallets and accounts in ethers.js: + +```typescript +const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider); +``` + +In web3.js v4: + +```typescript +web3.eth.accounts.wallet.add('YOUR_PRIVATE_KEY'); +// If you want to use the account for subsequent operations +const account = web3.eth.accounts.wallet[0]; +``` + +## Sending Transactions + +Sending a transaction with ethers.js: + +```typescript +const tx = await wallet.sendTransaction({ + to: 'RECIPIENT_ADDRESS', + value: ethers.utils.parseEther('1.0') +}); +``` + +In web3.js v4: + +```typescript +const tx = await web3.eth.sendTransaction({ + from: account.address, + to: 'RECIPIENT_ADDRESS', + value: web3.utils.toWei('1', 'ether') +}); +``` + +## Interacting with Contracts + +To interact with contracts in ethers.js: + +```typescript +const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, wallet); +const result = await contract.someFunction(); +``` + +In web3.js v4: + +```typescript +const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS); +const result = await contract.methods.someFunction().call(); +``` + +## Handling Events + +Handling events with ethers.js: + +```typescript +contract.on('SomeEvent', (arg1, arg2, event) => { + // event handling +}); +``` + +In web3.js v4: + +```typescript +const event = contract.events.SomeEvent({ + filter: { + filter: { val: 100 }, + }, + fromBlock: 0 +}); + +event.on('data', resolve); +event.on('error', reject); +``` + +This guide should provide a starting point for migrating from ethers.js to web3.js version 4.x. Remember to adapt the example code to your actual use case and verify the function arguments and setup as you migrate your application. The official documentation of web3.js [documentation](https://docs.web3js.org/) will be your go-to resource for detailed information and updates. From afa3d4332840fecea7751b8a23b6eeb6d3d1b88b Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:29:00 +0100 Subject: [PATCH 02/12] edit draft `Migration from ethers.js` --- .../migration_from_other_libs/ethers/index.md | 220 +++++++++++++++--- 1 file changed, 186 insertions(+), 34 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers/index.md b/docs/docs/guides/migration_from_other_libs/ethers/index.md index 0b047687316..05a791200c6 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers/index.md +++ b/docs/docs/guides/migration_from_other_libs/ethers/index.md @@ -4,11 +4,9 @@ sidebar_label: 'Migration from ethers.js' title: 'Migration from ethers.js' --- -**[This is still a draft document]** +Follow this guide, if you're currently using the ethers.js library to interact with the Ethereum blockchain and want to migrate to web3.js. -If you're currently using the ethers.js library to interact with the Ethereum blockchain and want to migrate to web3.js version 4, follow this guide. - -However, migrating from a library to another would usually need careful changes. But, ethers.js have lots of similarities with web3.js and migration would usually be easy and strate forward. However, you still need to check your code for possible tweaks if needed. +However, migrating from a library to another would usually need careful changes. But, ethers.js have lots of similarities with web3.js and migration would usually be easy and straightforward. However, you still need to check your code for possible tweaks as needed. ## Installation @@ -18,14 +16,22 @@ First, install the latest version of web3.js: npm install web3 ``` -## Initialization +## Initialization and getting the last block number With ethers.js, you would initialize like: -```typescript +```typescript import { ethers } from 'ethers'; -const provider = new ethers.providers.JsonRpcProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_KEY'); +async function getBlockNumber() { + const provider = new ethers.JsonRpcProvider( + 'https://mainnet.infura.io/v3/ec907b4a35c64ea1852711ba1cd42415', + ); + const ts = provider.getBlockNumber(); + ts.then(console.log); +} +// outputs something like: 18561956n +getBlockNumber(); ``` With web3.js v4: @@ -33,59 +39,205 @@ With web3.js v4: ```typescript import { Web3 } from 'web3'; -const web3 = new Web3('https://rinkeby.infura.io/v3/YOUR_INFURA_KEY'); +async function getBlockNumber() { + const web3 = new Web3('https://mainnet.infura.io/v3/ec907b4a35c64ea1852711ba1cd42415'); + const ts = web3.eth.getBlockNumber(); + ts.then(console.log); +} +// outputs something like: 18561956 +getBlockNumber(); ``` +## Use browser-injected provider + +With ethers.js: + +```typescript +// v5 +provider = new ethers.providers.Web3Provider(window.ethereum); -## Fast takes **(needs review)** +// v6: +provider = new ethers.BrowserProvider(window.ethereum); +``` -1. Replace all instances of `ethers` with `Web3` -2. Replace all instances of `ethers.providers` with `Web3.providers` -3. Replace all instances of `ethers.utils` with `Web3.utils` -4. Replace all instances of `ethers.Contract` with `Web3.eth.Contract` -5. Replace all instances of `ethers.Wallet` with `Web3.eth.accounts.wallet` -6. Replace all instances of `ethers.Signer` with `Web3.eth.accounts` -7. Replace all instances of `ethers.utils.formatEther` with `Web3.utils.fromWei` -8. Replace all instances of `ethers.utils.parseEther` with `Web3.utils.toWei` +With web3.js: +```typescript +const web3 = new Web3(window.ethereum); +``` -## Wallets and Accounts +## Generate Private Key -To manage wallets and accounts in ethers.js: +With ethers.js: ```typescript -const wallet = new ethers.Wallet('YOUR_PRIVATE_KEY', provider); +// this would generate a private key similar to: +// '0x286f65c4191759fc5c7e6083b8c275ac2238cc7abb5915bd8c905ae4404215c9' +// (Be sure to store it encrypted in a safe place) +const privateKey = ethers.Wallet.createRandom().privateKey; ``` -In web3.js v4: +With web3.js: + +```typescript +// this would generate a private key similar to: +// '0x286f65c4191759fc5c7e6083b8c275ac2238cc7abb5915bd8c905ae4404215c9' +// (Be sure to store it encrypted in a safe place) +const privateKey = web3.eth.accounts.create().privateKey; +``` + +## Wallets and Accounts + +### Create a wallet + +In ethers.js: -```typescript -web3.eth.accounts.wallet.add('YOUR_PRIVATE_KEY'); -// If you want to use the account for subsequent operations -const account = web3.eth.accounts.wallet[0]; +```typescript +async function createWallet() { + const wallet = new ethers.Wallet( + // A private key that you might had generated with: + // ethers.Wallet.createRandom().privateKey + privateKey, + ); + + console.log(wallet.address); +} +// outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 +createWallet(); +``` + +In web3.js: + +```typescript +async function createWallet() { + const web3 = new Web3(); + const wallet = web3.eth.accounts.wallet.add( + // you can generate a private key using web3.eth.accounts.create().privateKey + privateKey, + ); + + console.log(wallet[0].address); +} +// outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 +createWallet(); +``` + +### Get unlocked account + +In ethers.js: + +```typescript +const signer = await provider.getSigner(); +``` + +In web3.js: + +```typescript +const account = (await web3.eth.getAccounts())[0]; ``` + ## Sending Transactions Sending a transaction with ethers.js: ```typescript -const tx = await wallet.sendTransaction({ - to: 'RECIPIENT_ADDRESS', - value: ethers.utils.parseEther('1.0') -}); +async function sendTransaction() { + const signer = new ethers.Wallet(privateKey, provider); + + const tx = await signer.sendTransaction({ + to: '0x92d3267215Ec56542b985473E73C8417403B15ac', + value: ethers.parseUnits('0.001', 'ether'), + }); + console.log(tx); +} + +sendTransaction(); ``` In web3.js v4: +The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. Or, if you are using a local dev node, and you have some accounts already unlocked at the node. Note that it is highly risky and not recommended to unlock an account at a production or even a test node. + ```typescript -const tx = await web3.eth.sendTransaction({ - from: account.address, - to: 'RECIPIENT_ADDRESS', - value: web3.utils.toWei('1', 'ether') -}); +async function sendTransaction() { + const web3 = new Web3('http://localhost:8545'); + + // The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. + // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. + // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). + const account = (await web3.eth.getAccounts())[0]; + + const tx = await web3.eth.sendTransaction({ + from: account, + to: '0x92d3267215Ec56542b985473E73C8417403B15ac', + value: web3.utils.toWei('0.00000000001', 'ether'), + }); + console.log(tx); +} + +sendTransaction(); ``` +## Sending a Signed Transactions + +Posting a signed transaction to the node with ethers.js: + +```typescript +// v5 +// provider.sendTransaction(signedTx) + +// v6 +provider.broadcastTransaction(signedTx); +``` + +In web3.js v4: + +```typescript +async function sendSignedTransaction() { + const transaction: Transaction = { + from: senderPublicAddress, + to: receiverPublicAddress, + value: 1, + gas: 21000, + type: 1, + }; + const signedTransaction = await web3.eth.accounts.signTransaction( + transaction, + privateKey, + ); + const tx = await web3.eth.sendSignedTransaction( + signedTransaction.rawTransaction, + ); + + console.log(tx); +} + +sendTransaction(); +``` + +### Signing a string message +with ethers.js: + +```typescript +signature = await signer.signMessage('Some data') +``` + +In web3.js v4: + +```typescript + +// web3 (using a private key) +const signature = web3.eth.accounts.sign('Some data', privateKey).signature; + +// Using an unlocked account managed by connected RPC client or a browser-injected provider +const signature = await web3.eth.sign( + web3.utils.utf8ToHex('Some data'), // data to be signed (4.x only supports Hex Strings) + '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe' // the address that its private key would be used to sign + ); +``` + + ## Interacting with Contracts To interact with contracts in ethers.js: From 97d692d7948cd5b93376e121b4e9277ef2dc4946 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:49:42 +0100 Subject: [PATCH 03/12] add Utilities section to migrate from ethers guide --- .../migration_from_other_libs/ethers/index.md | 109 +++++++++++++++--- 1 file changed, 96 insertions(+), 13 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers/index.md b/docs/docs/guides/migration_from_other_libs/ethers/index.md index 05a791200c6..64d8b804506 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers/index.md +++ b/docs/docs/guides/migration_from_other_libs/ethers/index.md @@ -34,7 +34,7 @@ async function getBlockNumber() { getBlockNumber(); ``` -With web3.js v4: +With web3.js: ```typescript import { Web3 } from 'web3'; @@ -106,7 +106,7 @@ async function createWallet() { createWallet(); ``` -In web3.js: +With web3.js: ```typescript async function createWallet() { @@ -124,13 +124,13 @@ createWallet(); ### Get unlocked account -In ethers.js: +With ethers.js: ```typescript const signer = await provider.getSigner(); ``` -In web3.js: +With web3.js: ```typescript const account = (await web3.eth.getAccounts())[0]; @@ -155,7 +155,7 @@ async function sendTransaction() { sendTransaction(); ``` -In web3.js v4: +With web3.js: The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. Or, if you are using a local dev node, and you have some accounts already unlocked at the node. Note that it is highly risky and not recommended to unlock an account at a production or even a test node. @@ -191,7 +191,7 @@ Posting a signed transaction to the node with ethers.js: provider.broadcastTransaction(signedTx); ``` -In web3.js v4: +With web3.js: ```typescript async function sendSignedTransaction() { @@ -202,10 +202,13 @@ async function sendSignedTransaction() { gas: 21000, type: 1, }; + + // you might also use below `web3.eth.personal.signMessage`, depending on your use case. const signedTransaction = await web3.eth.accounts.signTransaction( transaction, privateKey, ); + const tx = await web3.eth.sendSignedTransaction( signedTransaction.rawTransaction, ); @@ -213,28 +216,50 @@ async function sendSignedTransaction() { console.log(tx); } -sendTransaction(); +sendSignedTransaction(); ``` ### Signing a string message + with ethers.js: ```typescript -signature = await signer.signMessage('Some data') +async function signMessage() { + const signer = new ethers.Wallet(privateKey); + + const signature = await signer.signMessage('Some data'); + console.log(signature); +} +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +signMessage(); ``` -In web3.js v4: +With web3.js: ```typescript -// web3 (using a private key) -const signature = web3.eth.accounts.sign('Some data', privateKey).signature; +// sign with web3.js, using a private key: +async function signMessageWithPrivateKey() { + const signature = web3.eth.accounts.sign('Some data', privateKey).signature; + console.log(signature); +} +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +signMessageWithPrivateKey(); // Using an unlocked account managed by connected RPC client or a browser-injected provider -const signature = await web3.eth.sign( +async function signMessageByProvider() { + // you might also use below `web3.eth.personal.sign`, depending on your use case. + const signature = await web3.eth.sign( web3.utils.utf8ToHex('Some data'), // data to be signed (4.x only supports Hex Strings) - '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe' // the address that its private key would be used to sign + '0x6E599DA0bfF7A6598AC1224E4985430Bf16458a4', // the address that its private key would be used to sign ); + console.log(signature); +} +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +signMessageByProvider(); ``` @@ -278,4 +303,62 @@ event.on('data', resolve); event.on('error', reject); ``` + +## Utilities + +### Hashing +Here is how to compute `keccak256` hash of a UTF-8 string with web3 and ethers. + + +With ethers.js: + +```typescript +// hash of a string +ethers.utils.id('hello world') +// hash of binary data +ethers.utils.keccak256('0x4242') +``` + +With web3.js: + +```typescript +// computes the Keccak-256 hash of the input and returns a hexstring: +// the `utils.sha3` accepts: string and Uint8Array +web3.utils.sha3('hello world'); +// the `utils.keccak256` accepts: string, Uint8Array, Numbers and ReadonlyArray +web3.utils.keccak256('hello world'); +``` + +### Ethers Conversion + +Here is how to convert from and to ether units. + +With ethers.js: + +```typescript +const fromWieToEther = ethers.formatEther('1000000000000000000'); +// outputs: 1.0 +console.log(fromWieToEther); + +const fromEtherToWie = ethers.parseEther('1.0'); +// outputs: 1000000000000000000n +console.log(fromEtherToWie); +``` + +With web3.js: + +```typescript +// the second parameter is "the unit to convert to" +const fromWieToEther = Web3.utils.fromWei('1000000000000000000', 'ether'); +// outputs: 1 +console.log(fromWieToEther); + +// the second parameter is "the unit of the number passed" +const fromEtherToWie = Web3.utils.toWei('1.0', 'ether'); +// outputs: 1000000000000000000 +console.log(fromEtherToWie); +``` + +## Conclusion + This guide should provide a starting point for migrating from ethers.js to web3.js version 4.x. Remember to adapt the example code to your actual use case and verify the function arguments and setup as you migrate your application. The official documentation of web3.js [documentation](https://docs.web3js.org/) will be your go-to resource for detailed information and updates. From 97e705fc5e8ba2b487220795e42bfaf8cb96d86f Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:44:54 +0100 Subject: [PATCH 04/12] add contracts section at ethers migration guide --- .../sign_and_send_tx/wallet_of_eth_node.md | 1 + .../{ethers/index.md => ethers.md} | 114 ++++++++++++++++-- 2 files changed, 104 insertions(+), 11 deletions(-) rename docs/docs/guides/migration_from_other_libs/{ethers/index.md => ethers.md} (73%) diff --git a/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md b/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md index 7a1905b4bc4..fe1b1c967b6 100644 --- a/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md +++ b/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md @@ -169,6 +169,7 @@ import { Web3 } from 'web3'; const web3 = new Web3(/* PROVIDER*/); // Second step: add an account to the Ethereum node and unlock it +// IMPORTANT: never unlock an account on the mainnet. Use this only with your local dev node. const account = { privateKey: '0xb45b02f408a0dd0996aab2b55a54f4ed7735f82b133c0786a9ff372ffaaf11bd', address: '0xe4beef667408b99053dc147ed19592ada0d77f59', diff --git a/docs/docs/guides/migration_from_other_libs/ethers/index.md b/docs/docs/guides/migration_from_other_libs/ethers.md similarity index 73% rename from docs/docs/guides/migration_from_other_libs/ethers/index.md rename to docs/docs/guides/migration_from_other_libs/ethers.md index 64d8b804506..61678ea05fc 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers/index.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -263,40 +263,132 @@ signMessageByProvider(); ``` -## Interacting with Contracts +## Contracts + +### Contracts Deployment + +To deploy a contract in ethers.js you might have something like: + +```typescript +const signer = provider.getSigner(); +const factory = new ethers.ContractFactory(abi, bytecode, signer); +const contract = await factory.deploy("constructor param"); +console.log('contract address', contract.address); + +// wait for contract creation transaction to be mined +await contract.deployTransaction.wait(); +``` + +In web3.js: + +```typescript +const contractObject = new web3.eth.Contract(abi); +const deployedContract = await contractObject.deploy({ + data: bytecode, + arguments: ["constructor param"] +}).send({ + from: "0x12598d2Fd88B420ED571beFDA8dD112624B5E730", + gas: '1000000', + // other transaction's params +}); + +console.log('contract address', deployedContract.options.address) +``` + +:::tip +📝 To get the smart contract ABI, you are advised to check: [Compile the Solidity code using the Solidity Compiler and get its ABI and Bytecode](/guides/smart_contracts/deploying_and_interacting_with_smart_contracts#step-4-compile-the-solidity-code-using-the-solidity-compiler-and-get-its-abi-and-bytecode) and [Infer Contract Types from JSON Artifact](/guides/smart_contracts/infer_contract_types_guide/) +::: + + +### Calling Contracts' Methods To interact with contracts in ethers.js: ```typescript -const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, wallet); +const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, providerOrSigner); const result = await contract.someFunction(); ``` -In web3.js v4: +In web3.js: ```typescript +const web3 = new Web3(provider); const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS); -const result = await contract.methods.someFunction().call(); + +// If the method was only to read form the Blockchain: +const result = await contract.methods.someFunction().call(); +// Or, if the method would need a transaction to be sent: +const result = await contract.methods.someFunction().send(); +``` + +#### Contracts Overloaded Methods + +In ethers.js: + +```typescript +// ethers +const abi = [ + "function getMessage(string) public view returns (string)", + "function getMessage() public view returns (string)" +] +const contract = new ethers.Contract(address, abi, signer); + +// for ambiguous functions (two functions with the same +// name), the signature must also be specified +message = await contract['getMessage(string)']('nice'); +// and to call the overladed method without a parameter: +message = await contract['getMessage()'](); + +// in ethers.js v6 +contract.foo(Typed.string('nice')) +``` + +In web3.js: + +```typescript +// in web3.js the overloaded method implementation is automatically picked based on the passed datatype +message = await contract.methods.getMessage('nice').call(); +// To call the overladed method without a parameter: +message = await contract.methods.getMessage().call(); ``` +### Gas Estimation + +To interact with contracts in ethers.js: + +```typescript +// Estimate the gas +contract.myMethod.estimateGas(123) +``` + +In web3.js: + +```typescript +// Estimate the gas +const gasAmount = await myContract.methods.myMethod(123).estimateGas( + { gas: 5000000, from: transactionSenderAddress } // optional +); +``` + + ## Handling Events Handling events with ethers.js: ```typescript contract.on('SomeEvent', (arg1, arg2, event) => { - // event handling + // event handling }); ``` -In web3.js v4: +With web3.js: ```typescript const event = contract.events.SomeEvent({ - filter: { - filter: { val: 100 }, + filter: { + filter: { val: 100 }, }, - fromBlock: 0 + fromBlock: 0, }); event.on('data', resolve); @@ -304,7 +396,7 @@ event.on('error', reject); ``` -## Utilities +## Utility methods ### Hashing Here is how to compute `keccak256` hash of a UTF-8 string with web3 and ethers. @@ -361,4 +453,4 @@ console.log(fromEtherToWie); ## Conclusion -This guide should provide a starting point for migrating from ethers.js to web3.js version 4.x. Remember to adapt the example code to your actual use case and verify the function arguments and setup as you migrate your application. The official documentation of web3.js [documentation](https://docs.web3js.org/) will be your go-to resource for detailed information and updates. +This guide should provide a starting point for migrating from ethers.js to web3.js version 4.x. Remember to adapt the example code to your actual use case and verify the function arguments and setup as you migrate your application. And the official documentation of web3.js is your go-to resource for detailed information and updates. From 1191e060cdb3bbee44c1ab659926df87a2d37d55 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:51:25 +0100 Subject: [PATCH 05/12] a title update at docs --- docs/docs/guides/migration_from_other_libs/_category_.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guides/migration_from_other_libs/_category_.yml b/docs/docs/guides/migration_from_other_libs/_category_.yml index 75eb4a3e92c..ee8c672520c 100644 --- a/docs/docs/guides/migration_from_other_libs/_category_.yml +++ b/docs/docs/guides/migration_from_other_libs/_category_.yml @@ -1,4 +1,4 @@ -label: 'Migration from Libraries' +label: 'Migration from Other Libraries' collapsible: true collapsed: false link: null \ No newline at end of file From 1619d8430711535ee92cef974e813b95f1423bef Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 16 Nov 2023 22:22:16 +0100 Subject: [PATCH 06/12] few edits to ethers migration guide --- .../migration_from_other_libs/ethers.md | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index 61678ea05fc..9977dbabedd 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -24,9 +24,12 @@ With ethers.js, you would initialize like: import { ethers } from 'ethers'; async function getBlockNumber() { - const provider = new ethers.JsonRpcProvider( - 'https://mainnet.infura.io/v3/ec907b4a35c64ea1852711ba1cd42415', - ); + // in v5: + const provider = new ethers.providers.JsonRpcProvider(url); + + // in v6: + const provider = new ethers.JsonRpcProvider(url); + const ts = provider.getBlockNumber(); ts.then(console.log); } @@ -40,7 +43,7 @@ With web3.js: import { Web3 } from 'web3'; async function getBlockNumber() { - const web3 = new Web3('https://mainnet.infura.io/v3/ec907b4a35c64ea1852711ba1cd42415'); + const web3 = new Web3(url); const ts = web3.eth.getBlockNumber(); ts.then(console.log); } @@ -53,11 +56,11 @@ getBlockNumber(); With ethers.js: ```typescript -// v5 -provider = new ethers.providers.Web3Provider(window.ethereum); +// in v5 +const provider = new ethers.providers.Web3Provider(window.ethereum); -// v6: -provider = new ethers.BrowserProvider(window.ethereum); +// in v6 +const provider = new ethers.BrowserProvider(window.ethereum); ``` With web3.js: @@ -122,6 +125,15 @@ async function createWallet() { createWallet(); ``` +:::info + In web3.js, if you want to use a private key to later sign and send transactions, you first need to add this private key to the accounts with, for example, one of the methods: + `web3.eth.accounts.create()`, or `web3.eth.accounts.wallet.add(privateKey)`. + + And then whenever you provide the the public address of that private key, web3.js will use that private key to sign. For example, you would pass the public key at `web3.eth.sendTransaction({from: publicAddress,...})` and web3.`eth.signTransaction({from: publicAddress,...})` then the privateKey of that publicAddress will be lookup and used to sign. + + However, it is not advised to use the privatekey directly. And you are advised to use a secret storage or a vault instead. +::: + ### Get unlocked account With ethers.js: @@ -157,7 +169,13 @@ sendTransaction(); With web3.js: -The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. Or, if you are using a local dev node, and you have some accounts already unlocked at the node. Note that it is highly risky and not recommended to unlock an account at a production or even a test node. +:::info +The method `web3.eth.sendTransaction` will use the account that you pass the public address at `from` to sign the transaction. + +So, the `from` needs to be the public address of a private key that you added previously to the web3.eth.accounts. Or, else, it would pass it to the provider where an unlocked account would be used. + +And for the case when you did not add the private key early, and so the `from` was just passed to the provider. Then if the provider was a browser-injected provider like metamask, for example, it will ask the user to sign. And, if you are using a local dev node as a provider, it should be one of the accounts that were already unlocked at the node. However, note that it is highly risky and not recommended to unlock an account at a production or even a test node. +::: ```typescript async function sendTransaction() { @@ -167,6 +185,10 @@ async function sendTransaction() { // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). const account = (await web3.eth.getAccounts())[0]; + + // Alternative to the above, here is how to add wallet to be used as a signer later: + const wallet = web3.eth.accounts.wallet.add(privateKey); + const account = wallet[0].address; const tx = await web3.eth.sendTransaction({ from: account, @@ -184,10 +206,10 @@ sendTransaction(); Posting a signed transaction to the node with ethers.js: ```typescript -// v5 -// provider.sendTransaction(signedTx) +// in v5 +provider.sendTransaction(signedTx) -// v6 +// in v6 provider.broadcastTransaction(signedTx); ``` @@ -339,7 +361,7 @@ message = await contract['getMessage(string)']('nice'); // and to call the overladed method without a parameter: message = await contract['getMessage()'](); -// in ethers.js v6 +// in v6 contract.foo(Typed.string('nice')) ``` From 9b4cc28352246b401850f81721dae6b343259c67 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Fri, 17 Nov 2023 10:30:50 +0100 Subject: [PATCH 07/12] tiny edits --- .../migration_from_other_libs/ethers.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index 9977dbabedd..bcde5ecaa1f 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -33,7 +33,7 @@ async function getBlockNumber() { const ts = provider.getBlockNumber(); ts.then(console.log); } -// outputs something like: 18561956n +// outputs something like: 18561956 getBlockNumber(); ``` @@ -47,7 +47,7 @@ async function getBlockNumber() { const ts = web3.eth.getBlockNumber(); ts.then(console.log); } -// outputs something like: 18561956 +// outputs something like: 18561956n getBlockNumber(); ``` @@ -99,7 +99,7 @@ In ethers.js: async function createWallet() { const wallet = new ethers.Wallet( // A private key that you might had generated with: - // ethers.Wallet.createRandom().privateKey + // ethers.Wallet.createRandom().privateKey privateKey, ); @@ -129,7 +129,7 @@ createWallet(); In web3.js, if you want to use a private key to later sign and send transactions, you first need to add this private key to the accounts with, for example, one of the methods: `web3.eth.accounts.create()`, or `web3.eth.accounts.wallet.add(privateKey)`. - And then whenever you provide the the public address of that private key, web3.js will use that private key to sign. For example, you would pass the public key at `web3.eth.sendTransaction({from: publicAddress,...})` and web3.`eth.signTransaction({from: publicAddress,...})` then the privateKey of that publicAddress will be lookup and used to sign. + And then whenever you provide the public address of that private key, web3.js will use that private key to sign. For example, you would pass the public key at `web3.eth.sendTransaction({from: publicAddress,...})` and web3.`eth.signTransaction({from: publicAddress,...})` then the privateKey of that publicAddress will be lookup and used to sign. However, it is not advised to use the privatekey directly. And you are advised to use a secret storage or a vault instead. ::: @@ -182,8 +182,8 @@ async function sendTransaction() { const web3 = new Web3('http://localhost:8545'); // The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. - // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. - // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). + // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. + // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). const account = (await web3.eth.getAccounts())[0]; // Alternative to the above, here is how to add wallet to be used as a signer later: @@ -253,7 +253,7 @@ async function signMessage() { console.log(signature); } // Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b signMessage(); ``` @@ -267,7 +267,7 @@ async function signMessageWithPrivateKey() { console.log(signature); } // Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b signMessageWithPrivateKey(); // Using an unlocked account managed by connected RPC client or a browser-injected provider @@ -280,7 +280,7 @@ async function signMessageByProvider() { console.log(signature); } // Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b signMessageByProvider(); ``` @@ -306,10 +306,10 @@ In web3.js: ```typescript const contractObject = new web3.eth.Contract(abi); const deployedContract = await contractObject.deploy({ - data: bytecode, - arguments: ["constructor param"] + data: bytecode, + arguments: ["constructor param"] }).send({ - from: "0x12598d2Fd88B420ED571beFDA8dD112624B5E730", + from: "0x12598d2Fd88B420ED571beFDA8dD112624B5E730", gas: '1000000', // other transaction's params }); From 174caf80646e12299acab40671329700849ff15f Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:53:57 +0100 Subject: [PATCH 08/12] tiny enhancement at ethers.md --- docs/docs/guides/migration_from_other_libs/ethers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index bcde5ecaa1f..243b27f6118 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -222,7 +222,7 @@ async function sendSignedTransaction() { to: receiverPublicAddress, value: 1, gas: 21000, - type: 1, + type: 0, }; // you might also use below `web3.eth.personal.signMessage`, depending on your use case. From beae97973c442c9e6771e0e6cfc69328c9c9eecc Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:24:43 +0100 Subject: [PATCH 09/12] tiny edit at ethers.md --- docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md | 1 - docs/docs/guides/migration_from_other_libs/ethers.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md b/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md index fe1b1c967b6..7a1905b4bc4 100644 --- a/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md +++ b/docs/docs/guides/basics/sign_and_send_tx/wallet_of_eth_node.md @@ -169,7 +169,6 @@ import { Web3 } from 'web3'; const web3 = new Web3(/* PROVIDER*/); // Second step: add an account to the Ethereum node and unlock it -// IMPORTANT: never unlock an account on the mainnet. Use this only with your local dev node. const account = { privateKey: '0xb45b02f408a0dd0996aab2b55a54f4ed7735f82b133c0786a9ff372ffaaf11bd', address: '0xe4beef667408b99053dc147ed19592ada0d77f59', diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index 243b27f6118..daa33c58af3 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -4,7 +4,7 @@ sidebar_label: 'Migration from ethers.js' title: 'Migration from ethers.js' --- -Follow this guide, if you're currently using the ethers.js library to interact with the Ethereum blockchain and want to migrate to web3.js. +Follow this guide, if you're currently using the ethers.js library to interact with the Ethereum blockchain and want to migrate to web3.js. This guide is for ethers v5 and v6. And, if there are differences, code for both would be provided. And, if you find something missing, or worth adding, feel free to open a PR, please. However, migrating from a library to another would usually need careful changes. But, ethers.js have lots of similarities with web3.js and migration would usually be easy and straightforward. However, you still need to check your code for possible tweaks as needed. From c1f8a17e7736e8895d724b36df09cc83089152d3 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:31:05 +0100 Subject: [PATCH 10/12] tiny edit at ethers.md --- .../migration_from_other_libs/ethers.md | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index daa33c58af3..acf1b384800 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -28,10 +28,10 @@ async function getBlockNumber() { const provider = new ethers.providers.JsonRpcProvider(url); // in v6: - const provider = new ethers.JsonRpcProvider(url); + const provider = new ethers.JsonRpcProvider(url); - const ts = provider.getBlockNumber(); - ts.then(console.log); + const ts = provider.getBlockNumber(); + ts.then(console.log); } // outputs something like: 18561956 getBlockNumber(); @@ -43,9 +43,9 @@ With web3.js: import { Web3 } from 'web3'; async function getBlockNumber() { - const web3 = new Web3(url); - const ts = web3.eth.getBlockNumber(); - ts.then(console.log); + const web3 = new Web3(url); + const ts = web3.eth.getBlockNumber(); + ts.then(console.log); } // outputs something like: 18561956n getBlockNumber(); @@ -97,13 +97,13 @@ In ethers.js: ```typescript async function createWallet() { - const wallet = new ethers.Wallet( - // A private key that you might had generated with: - // ethers.Wallet.createRandom().privateKey - privateKey, - ); + const wallet = new ethers.Wallet( + // A private key that you might had generated with: + // ethers.Wallet.createRandom().privateKey + privateKey, + ); - console.log(wallet.address); + console.log(wallet.address); } // outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 createWallet(); @@ -113,13 +113,13 @@ With web3.js: ```typescript async function createWallet() { - const web3 = new Web3(); - const wallet = web3.eth.accounts.wallet.add( - // you can generate a private key using web3.eth.accounts.create().privateKey - privateKey, - ); + const web3 = new Web3(); + const wallet = web3.eth.accounts.wallet.add( + // you can generate a private key using web3.eth.accounts.create().privateKey + privateKey, + ); - console.log(wallet[0].address); + console.log(wallet[0].address); } // outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 createWallet(); @@ -179,23 +179,23 @@ And for the case when you did not add the private key early, and so the `from` w ```typescript async function sendTransaction() { - const web3 = new Web3('http://localhost:8545'); + const web3 = new Web3('http://localhost:8545'); - // The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. - // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. - // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). - const account = (await web3.eth.getAccounts())[0]; + // The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. + // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. + // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). + const account = (await web3.eth.getAccounts())[0]; - // Alternative to the above, here is how to add wallet to be used as a signer later: - const wallet = web3.eth.accounts.wallet.add(privateKey); - const account = wallet[0].address; - - const tx = await web3.eth.sendTransaction({ - from: account, - to: '0x92d3267215Ec56542b985473E73C8417403B15ac', - value: web3.utils.toWei('0.00000000001', 'ether'), - }); - console.log(tx); + // Alternative to the above, here is how to add wallet to be used as a signer later: + const wallet = web3.eth.accounts.wallet.add(privateKey); + const account = wallet[0].address; + + const tx = await web3.eth.sendTransaction({ + from: account, + to: '0x92d3267215Ec56542b985473E73C8417403B15ac', + value: web3.utils.toWei('0.00000000001', 'ether'), + }); + console.log(tx); } sendTransaction(); @@ -399,7 +399,7 @@ Handling events with ethers.js: ```typescript contract.on('SomeEvent', (arg1, arg2, event) => { - // event handling + // event handling }); ``` @@ -407,10 +407,10 @@ With web3.js: ```typescript const event = contract.events.SomeEvent({ - filter: { - filter: { val: 100 }, - }, - fromBlock: 0, + filter: { + filter: { val: 100 }, + }, + fromBlock: 0, }); event.on('data', resolve); From 1f3cf0b377d89d35d6ba57dd672bf703548e1222 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:07:46 +0100 Subject: [PATCH 11/12] tiny edits at ethers.md --- .../migration_from_other_libs/ethers.md | 254 ++++++++---------- 1 file changed, 115 insertions(+), 139 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index acf1b384800..10546d8db91 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -16,42 +16,40 @@ First, install the latest version of web3.js: npm install web3 ``` -## Initialization and getting the last block number +## Providers -With ethers.js, you would initialize like: +### Initialization and Calling RPC Methods + +With ethers.js, you would get the last block number from a provider like this: ```typescript import { ethers } from 'ethers'; -async function getBlockNumber() { - // in v5: - const provider = new ethers.providers.JsonRpcProvider(url); +// in v5: +const provider = new ethers.providers.JsonRpcProvider(url); + +// in v6: +const provider = new ethers.JsonRpcProvider(url); - // in v6: - const provider = new ethers.JsonRpcProvider(url); +const ts = provider.getBlockNumber(); - const ts = provider.getBlockNumber(); - ts.then(console.log); -} // outputs something like: 18561956 -getBlockNumber(); +ts.then(console.log); ``` -With web3.js: +With web3.js, you would get the last block number from a provider like this: ```typescript import { Web3 } from 'web3'; -async function getBlockNumber() { - const web3 = new Web3(url); - const ts = web3.eth.getBlockNumber(); - ts.then(console.log); -} +const web3 = new Web3(url); +const ts = web3.eth.getBlockNumber(); + // outputs something like: 18561956n -getBlockNumber(); +ts.then(console.log); ``` -## Use browser-injected provider +### Use browser-injected provider With ethers.js: @@ -69,7 +67,10 @@ With web3.js: const web3 = new Web3(window.ethereum); ``` -## Generate Private Key + +## Wallets and Accounts + +### Generate Private Key With ethers.js: @@ -88,41 +89,32 @@ With web3.js: // (Be sure to store it encrypted in a safe place) const privateKey = web3.eth.accounts.create().privateKey; ``` - -## Wallets and Accounts - ### Create a wallet In ethers.js: ```typescript -async function createWallet() { - const wallet = new ethers.Wallet( - // A private key that you might had generated with: - // ethers.Wallet.createRandom().privateKey - privateKey, - ); - - console.log(wallet.address); -} +const wallet = new ethers.Wallet( + // A private key that you might had generated with: + // ethers.Wallet.createRandom().privateKey + privateKey, +); + // outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 -createWallet(); +console.log(wallet.address); ``` With web3.js: ```typescript -async function createWallet() { - const web3 = new Web3(); - const wallet = web3.eth.accounts.wallet.add( - // you can generate a private key using web3.eth.accounts.create().privateKey - privateKey, - ); - - console.log(wallet[0].address); -} +const web3 = new Web3(); +const wallet = web3.eth.accounts.wallet.add( + // you can generate a private key using web3.eth.accounts.create().privateKey + privateKey, +); + // outputs: 0x6f7D735dFB514AA1778E8D97EaCE72BfECE71865 -createWallet(); +console.log(wallet[0].address); ``` :::info @@ -149,22 +141,56 @@ const account = (await web3.eth.getAccounts())[0]; ``` -## Sending Transactions +### Signing a string message -Sending a transaction with ethers.js: +with ethers.js: ```typescript -async function sendTransaction() { - const signer = new ethers.Wallet(privateKey, provider); +const signer = new ethers.Wallet(privateKey); + +const signature = await signer.signMessage('Some data'); +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +console.log(signature); + +``` + +With web3.js: + +```typescript + +// Sign with web3.js, using a private key: +const signature = web3.eth.accounts.sign('Some data', privateKey).signature; + +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +console.log(signature); + +// Sign using an account managed by the connected provider (for example the RPC client or a browser-injected provider) +const signature = await web3.eth.sign( + web3.utils.utf8ToHex('Some data'), // data to be signed (4.x only supports Hex Strings) + '0x6E599DA0bfF7A6598AC1224E4985430Bf16458a4', // the address that its private key would be used to sign +); + +// Outputs something like: +// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b +console.log(signature); +``` - const tx = await signer.sendTransaction({ - to: '0x92d3267215Ec56542b985473E73C8417403B15ac', - value: ethers.parseUnits('0.001', 'ether'), - }); - console.log(tx); -} +## Signing and Sending Transactions -sendTransaction(); +### Sending Transactions + +Sending a transaction with ethers.js: + +```typescript +const signer = new ethers.Wallet(privateKey, provider); + +const tx = await signer.sendTransaction({ + to: '0x92d3267215Ec56542b985473E73C8417403B15ac', + value: ethers.parseUnits('0.001', 'ether'), +}); +console.log(tx); ``` With web3.js: @@ -178,30 +204,26 @@ And for the case when you did not add the private key early, and so the `from` w ::: ```typescript -async function sendTransaction() { - const web3 = new Web3('http://localhost:8545'); +const web3 = new Web3(url); - // The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. - // Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. - // And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). - const account = (await web3.eth.getAccounts())[0]; - - // Alternative to the above, here is how to add wallet to be used as a signer later: - const wallet = web3.eth.accounts.wallet.add(privateKey); - const account = wallet[0].address; - - const tx = await web3.eth.sendTransaction({ - from: account, - to: '0x92d3267215Ec56542b985473E73C8417403B15ac', - value: web3.utils.toWei('0.00000000001', 'ether'), - }); - console.log(tx); -} - -sendTransaction(); +// The method web3.eth.sendTransaction is helpful if you are using a browser-injected provider like metamask. +// Or, if you are using a local dev node like ganache; and you have some accounts already unlocked at the node. +// And this is how you would get the first unlocked account from a local node (not advised for production or even on test node to use unlock accounts on the node). +const account = (await web3.eth.getAccounts())[0]; + +// Alternative to the above, here is how to add wallet to be used as a signer later: +const wallet = web3.eth.accounts.wallet.add(privateKey); +const account = wallet[0].address; + +const tx = await web3.eth.sendTransaction({ + from: account, + to: '0x92d3267215Ec56542b985473E73C8417403B15ac', + value: web3.utils.toWei('0.00000000001', 'ether'), +}); +console.log(tx); ``` -## Sending a Signed Transactions +### Sending a Signed Transactions Posting a signed transaction to the node with ethers.js: @@ -216,73 +238,27 @@ provider.broadcastTransaction(signedTx); With web3.js: ```typescript -async function sendSignedTransaction() { - const transaction: Transaction = { - from: senderPublicAddress, - to: receiverPublicAddress, - value: 1, - gas: 21000, - type: 0, - }; - - // you might also use below `web3.eth.personal.signMessage`, depending on your use case. - const signedTransaction = await web3.eth.accounts.signTransaction( - transaction, - privateKey, - ); - - const tx = await web3.eth.sendSignedTransaction( - signedTransaction.rawTransaction, - ); - - console.log(tx); -} - -sendSignedTransaction(); -``` - -### Signing a string message - -with ethers.js: +const transaction: Transaction = { + from: senderPublicAddress, + to: receiverPublicAddress, + value: 1, + gas: 21000, + type: 0, +}; + +// you might also use below `web3.eth.personal.signMessage`, depending on your use case. +const signedTransaction = await web3.eth.accounts.signTransaction( + transaction, + privateKey, +); -```typescript -async function signMessage() { - const signer = new ethers.Wallet(privateKey); +const tx = await web3.eth.sendSignedTransaction( + signedTransaction.rawTransaction, +); - const signature = await signer.signMessage('Some data'); - console.log(signature); -} -// Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b -signMessage(); +console.log(tx); ``` -With web3.js: - -```typescript - -// sign with web3.js, using a private key: -async function signMessageWithPrivateKey() { - const signature = web3.eth.accounts.sign('Some data', privateKey).signature; - console.log(signature); -} -// Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b -signMessageWithPrivateKey(); - -// Using an unlocked account managed by connected RPC client or a browser-injected provider -async function signMessageByProvider() { - // you might also use below `web3.eth.personal.sign`, depending on your use case. - const signature = await web3.eth.sign( - web3.utils.utf8ToHex('Some data'), // data to be signed (4.x only supports Hex Strings) - '0x6E599DA0bfF7A6598AC1224E4985430Bf16458a4', // the address that its private key would be used to sign - ); - console.log(signature); -} -// Outputs something like: -// 0xb475e02218d7d6a16f3575de789996d0a57f900f240d73ed792672256d63913840c1da0dd3e7fe2e79485b7a1d81e8cc163f405c3df22d496f28f1dd148faebf1b -signMessageByProvider(); -``` ## Contracts @@ -393,7 +369,7 @@ const gasAmount = await myContract.methods.myMethod(123).estimateGas( ``` -## Handling Events +### Handling Events Handling events with ethers.js: From 1f6f216ff239bd7d1589db692ebc3e3073ea19d7 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:40:25 +0100 Subject: [PATCH 12/12] add a tip for bigint at ethers.md --- .../migration_from_other_libs/ethers.md | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/docs/docs/guides/migration_from_other_libs/ethers.md b/docs/docs/guides/migration_from_other_libs/ethers.md index 10546d8db91..96dfa9e5943 100644 --- a/docs/docs/guides/migration_from_other_libs/ethers.md +++ b/docs/docs/guides/migration_from_other_libs/ethers.md @@ -31,10 +31,10 @@ const provider = new ethers.providers.JsonRpcProvider(url); // in v6: const provider = new ethers.JsonRpcProvider(url); -const ts = provider.getBlockNumber(); +const blockNumber = provider.getBlockNumber(); // outputs something like: 18561956 -ts.then(console.log); +blockNumber.then(console.log); ``` With web3.js, you would get the last block number from a provider like this: @@ -43,12 +43,34 @@ With web3.js, you would get the last block number from a provider like this: import { Web3 } from 'web3'; const web3 = new Web3(url); -const ts = web3.eth.getBlockNumber(); +const blockNumber = web3.eth.getBlockNumber(); // outputs something like: 18561956n -ts.then(console.log); +blockNumber.then(console.log); ``` +:::tip +📝 web3.js uses `bigint` as the default type for all big numbers returned. For, this you see above the blocknumber has the `n` at its end (`18561956n`). However, you can change the returned type by passing an optional parameter like: +```ts +import { Web3, DEFAULT_RETURN_FORMAT, FMT_NUMBER } from 'web3'; + +const blockNumber = web3.eth.getBlockNumber({ + ...DEFAULT_RETURN_FORMAT, + number: FMT_NUMBER.HEX, // to get the block number in hex format +}); +// outputs something like: 0x11B3BA4 +blockNumber.then(console.log); + + +const blockNumber = web3.eth.getBlockNumber({ + ...DEFAULT_RETURN_FORMAT, + number: FMT_NUMBER.STR, // to get the block number as a string +}); +// the value would like: '18561956' +blockNumber.then(console.log); +``` +::: + ### Use browser-injected provider With ethers.js: