From db8b14ddbf45e58f24060edd45d9c020aa64b67c Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Thu, 25 Apr 2024 16:04:00 +0300 Subject: [PATCH 1/9] edited the raw transaction --- docs/docs/guides/wallet/transactions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 5129c5057a4..1f6af44ff7d 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -51,8 +51,8 @@ const rawTransaction = { from: account.address, to: '0x5875da5854c2adadbc1a7a448b5b2a09b26baff8', //random wallet or contract address value: 1, //optional - value in wei - maxFeePerGas: (await web3.eth.getBlock()).baseFeePerGas * 2n, //updated depending on the network - maxPriorityFeePerGas: 100000, //high + maxFeePerGas: Number((await web3.eth.calculateFeeData()).maxFeePerGas), + maxPriorityFeePerGas: Number((await web3.eth.calculateFeeData()).maxPriorityFeePerGas), gasLimit: 2000000 nonce: await web3.eth.getTransactionCount(account.address), //optional - get the current nonce of the account data: "0x0" //optional - encoded function signature and arguments From 5053513cd267597b6faab64a6af9a8cac1371f93 Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Thu, 25 Apr 2024 16:54:19 +0300 Subject: [PATCH 2/9] added examples tx 0, 1 and 2 --- docs/docs/guides/wallet/transactions.md | 120 ++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 1f6af44ff7d..49d0a2d25a7 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -7,6 +7,126 @@ sidebar_label: 'Tutorial: Sending Transactions' This guide provides insights into sending transactions using web3.js, covering various scenarios from utilizing a local wallet to sending raw transactions. +## Transaction Type 0 (Legacy) + +A Legacy Transaction refers to a transaction that was created using an older version of Ethereum's transaction format, also known as "transaction type 0". This transaction format was used before the EIP-1559 upgrade, which was implemented in August 2021. + +```ts +import { Web3 } from"web3"; + +const web3 = new Web3("https://rpc2.sepolia.org"); + +async function txLegacy() { + const wallet = web3.eth.wallet.add("YOUR_PRIVATE_KEY"); //make sure you have funds + + const sender = wallet[0].address; + const recipient = "0x807BFe4940016B5a7FdA19482042917B02e68359"; + const value = 1; //wei + const nonce = await web3.eth.getTransactionCount(sender); + const gas = 21000; + const gasPrice = await web3.eth.getGasPrice(); + + const tx = { + from: sender, + to: recipient, + value, + nonce, + gas, + gasPrice, + }; + + const result = await web3.eth.sendTransaction(tx); + console.log("Tx hash", result.transactionHash); +} + +txLegacy(); +``` + +## Transaction Type 1 (EIP-2930) + +This EIP was introduced in April 2021, it introduces a feature called 'Transaction Type and Access List.' This improvement allows saving gas on cross-contract calls by declaring in advance which contract and storage slots will be accessed. + +```ts +import { Web3 } from"web3"; + +const web3 = new Web3("https://rpc2.sepolia.org"); + +async function txEIP2930() { + const wallet = web3.eth.wallet.add("YOUR_PRIVATE_KEY"); + + const sender = wallet[0].address; + const contractAddress1 = "0x..."; + const contractAddress2 = "0x..." + const nonce = await web3.eth.getTransactionCount(sender); + const gas = 500000; //could be higher + const gasPrice = await web3.eth.getGasPrice(); + + const tx = { + from: sender, + to: contractAddress1, //the contract we are calling + data: "0x...", + gas, + gasPrice, + type: 1, + accessList: [ + { + address: contractAddress2, //contract1 is calling contract2 + storageKeys: [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001", + ], + }, + ], + }; + + + const result = await web3.eth.sendTransaction(tx); + console.log("Tx hash", result.transactionHash); +} + +txEIP2930() +``` + +## Transaction Type 2 (EIP-1559) + +When a user creates an EIP-1559 transaction, they specify the maximum fee they are willing to pay `maxFeePerGas` as well as a tip `maxPriorityFeePerGas` to incentivize the miner. The actual fee paid by the user is then determined by the network based on the current demand for block space and the priority of the transaction. + +```ts +import { Web3 } from"web3"; + +const web3 = new Web3("https://rpc2.sepolia.org"); + +async function txEIP1559() { + const wallet = web3.eth.wallet.add("YOUR_PRIVATE_KEY"); //make sure you have funds + + const sender = wallet[0].address; + const recipient = "0x807BFe4940016B5a7FdA19482042917B02e68359"; + const value = 1; //wei + const nonce = await web3.eth.getTransactionCount(sender); + const gasLimit = 21000; + const maxFeePerGas = Number((await web3.eth.calculateFeeData()).maxFeePerGas); + const maxPriorityFeePerGas = Number((await web3.eth.calculateFeeData()).maxPriorityFeePerGas); + + const tx = { + from: sender, + to: recipient, + value, + nonce, + gasLimit, + maxFeePerGas, + maxPriorityFeePerGas, + }; + + const result = await web3.eth.sendTransaction(tx); + console.log("Tx hash", result.transactionHash); +} + +txEIP1559(); + +//=> Tx hash 0xa00eb8b1a3f881a416d5d49cb472860f77863d4f4d17998e8d5d7545f51656ec +``` + + ## Sending transactions with a local wallet The simplest way to sign and send transactions is using a local wallet: From 7f8f8dc75d874dce6f8e4efa0cf9e00c7656362c Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Thu, 25 Apr 2024 16:58:34 +0300 Subject: [PATCH 3/9] renamed response for txReceipt --- docs/docs/guides/wallet/transactions.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 49d0a2d25a7..3d7841c9ee4 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -35,8 +35,8 @@ async function txLegacy() { gasPrice, }; - const result = await web3.eth.sendTransaction(tx); - console.log("Tx hash", result.transactionHash); + const txReceipt = await web3.eth.sendTransaction(tx); + console.log("Tx hash", txReceipt.transactionHash); } txLegacy(); @@ -80,8 +80,8 @@ async function txEIP2930() { }; - const result = await web3.eth.sendTransaction(tx); - console.log("Tx hash", result.transactionHash); + const txReceipt = await web3.eth.sendTransaction(tx); + console.log("Tx hash", txReceipt.transactionHash); } txEIP2930() @@ -117,13 +117,11 @@ async function txEIP1559() { maxPriorityFeePerGas, }; - const result = await web3.eth.sendTransaction(tx); - console.log("Tx hash", result.transactionHash); + const txReceipt = await web3.eth.sendTransaction(tx); + console.log("Tx hash", txReceipt.transactionHash); } txEIP1559(); - -//=> Tx hash 0xa00eb8b1a3f881a416d5d49cb472860f77863d4f4d17998e8d5d7545f51656ec ``` From 71ed054e4ac0c43a764e69e0799f88d536b64de1 Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Fri, 26 Apr 2024 18:38:40 +0300 Subject: [PATCH 4/9] added erc20 transfer example --- docs/docs/guides/wallet/transactions.md | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 3d7841c9ee4..937dd9f0564 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -9,6 +9,8 @@ This guide provides insights into sending transactions using web3.js, covering v ## Transaction Type 0 (Legacy) +### Raw Transaction + A Legacy Transaction refers to a transaction that was created using an older version of Ethereum's transaction format, also known as "transaction type 0". This transaction format was used before the EIP-1559 upgrade, which was implemented in August 2021. ```ts @@ -33,6 +35,8 @@ async function txLegacy() { nonce, gas, gasPrice, + // highlight-next-line + type: 0, }; const txReceipt = await web3.eth.sendTransaction(tx); @@ -42,10 +46,39 @@ async function txLegacy() { txLegacy(); ``` +### ERC20 Interaction + +```ts +import { Web3 } from "web3"; + +const web3 = new Web3("https://rpc2.sepolia.org"); + +async function transfer() { + //initialize wallet + const wallet = web3.eth.wallet.add("PRIVATE_KEY"); + + //initialize contract + const myERC20 = new web3.eth.Contract(ABI, ADDRESS); + + //send transfer and specify the type + const txReceipt = await myERC20.methods.transfer(TO, VALUE).send({ + from: wallet[0].address, + // highlight-next-line + type: 0, + }); + + console.log(txReceipt.transactionHash); +} + +transfer(); +``` + ## Transaction Type 1 (EIP-2930) This EIP was introduced in April 2021, it introduces a feature called 'Transaction Type and Access List.' This improvement allows saving gas on cross-contract calls by declaring in advance which contract and storage slots will be accessed. +### Raw Transaction + ```ts import { Web3 } from"web3"; @@ -67,6 +100,7 @@ async function txEIP2930() { data: "0x...", gas, gasPrice, + // highlight-next-line type: 1, accessList: [ { @@ -91,6 +125,8 @@ txEIP2930() When a user creates an EIP-1559 transaction, they specify the maximum fee they are willing to pay `maxFeePerGas` as well as a tip `maxPriorityFeePerGas` to incentivize the miner. The actual fee paid by the user is then determined by the network based on the current demand for block space and the priority of the transaction. +### Raw Transaction + ```ts import { Web3 } from"web3"; @@ -115,6 +151,8 @@ async function txEIP1559() { gasLimit, maxFeePerGas, maxPriorityFeePerGas, + // highlight-next-line + type: 2, }; const txReceipt = await web3.eth.sendTransaction(tx); @@ -124,6 +162,33 @@ async function txEIP1559() { txEIP1559(); ``` +### ERC20 Interaction + +```ts +import { Web3 } from "web3"; + +const web3 = new Web3("https://rpc2.sepolia.org"); + +async function transfer() { + //initialize wallet + const wallet = web3.eth.wallet.add("PRIVATE_KEY"); + + //initialize contract + const myERC20 = new web3.eth.Contract(ABI, ADDRESS); + + //send transfer and specify the type + const txReceipt = await myERC20.methods.transfer(TO, VALUE).send({ + from: wallet[0].address, + // highlight-next-line + type: 2, + }); + + console.log(txReceipt.transactionHash); +} + +transfer(); +``` + ## Sending transactions with a local wallet From a16586619cbe43ba05bdab1ae6450d944f0932b9 Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Fri, 26 Apr 2024 18:40:18 +0300 Subject: [PATCH 5/9] added note --- docs/docs/guides/wallet/transactions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 937dd9f0564..da8e5a3214a 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -7,6 +7,10 @@ sidebar_label: 'Tutorial: Sending Transactions' This guide provides insights into sending transactions using web3.js, covering various scenarios from utilizing a local wallet to sending raw transactions. +:::note +Web3.js uses transactions type 2 by default +::: + ## Transaction Type 0 (Legacy) ### Raw Transaction From 6b62790932d95651969ea137bbc926c8e083ce71 Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Tue, 30 Apr 2024 11:23:02 +0300 Subject: [PATCH 6/9] rewrote eip2930 text --- docs/docs/guides/wallet/transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index da8e5a3214a..6f64e37e677 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -79,7 +79,7 @@ transfer(); ## Transaction Type 1 (EIP-2930) -This EIP was introduced in April 2021, it introduces a feature called 'Transaction Type and Access List.' This improvement allows saving gas on cross-contract calls by declaring in advance which contract and storage slots will be accessed. +This EIP was introduced in April 2021, it introduces a feature called 'Access List.' This improvement allows saving gas on cross-contract calls by declaring in advance which contract and storage slots will be accessed. ### Raw Transaction From 4731902ae86a4f4a8755d370a25e63e41fa731db Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Tue, 30 Apr 2024 12:06:00 +0300 Subject: [PATCH 7/9] added web3.eth.createAccessList to the example --- docs/docs/guides/wallet/transactions.md | 42 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index 6f64e37e677..daeb28ebfa7 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -93,11 +93,36 @@ async function txEIP2930() { const sender = wallet[0].address; const contractAddress1 = "0x..."; - const contractAddress2 = "0x..." - const nonce = await web3.eth.getTransactionCount(sender); const gas = 500000; //could be higher const gasPrice = await web3.eth.getGasPrice(); + // highlight-start + //create access list using web3.eth + const accessListData = await web3.eth.createAccessList({ + from: sender, + to: contractAddress1, + data: "0x9a67c8b100000000000000000000000000000000000000000000000000000000000004d0", + }); + // highlight-end + + console.log(accessListData) + /* + => + { + // highlight-start + "accessList": [ + { + "address": "0x15859bdf5aff2080a9968f6a410361e9598df62f", + "storageKeys": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ] + } + ], + // highlight-end + "gasUsed": "0x7671" + } + */ + const tx = { from: sender, to: contractAddress1, //the contract we are calling @@ -106,19 +131,12 @@ async function txEIP2930() { gasPrice, // highlight-next-line type: 1, - accessList: [ - { - address: contractAddress2, //contract1 is calling contract2 - storageKeys: [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001", - ], - }, - ], + // highlight-next-line + accessList: accessListData.accessList //access the object `accessList` }; - const txReceipt = await web3.eth.sendTransaction(tx); + console.log("Tx hash", txReceipt.transactionHash); } From a9858d59d337d9dd57d02d8ed6c79decaf76c72a Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Tue, 30 Apr 2024 12:07:47 +0300 Subject: [PATCH 8/9] added data value --- docs/docs/guides/wallet/transactions.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index daeb28ebfa7..a89c1db30af 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -95,13 +95,15 @@ async function txEIP2930() { const contractAddress1 = "0x..."; const gas = 500000; //could be higher const gasPrice = await web3.eth.getGasPrice(); + const data = "0x9a67c8b100000000000000000000000000000000000000000000000000000000000004d0" + // highlight-start //create access list using web3.eth const accessListData = await web3.eth.createAccessList({ from: sender, to: contractAddress1, - data: "0x9a67c8b100000000000000000000000000000000000000000000000000000000000004d0", + data, }); // highlight-end @@ -126,7 +128,7 @@ async function txEIP2930() { const tx = { from: sender, to: contractAddress1, //the contract we are calling - data: "0x...", + data, gas, gasPrice, // highlight-next-line From 1b0e82e5b7cb1f7b70d42b9736312dd16e608f99 Mon Sep 17 00:00:00 2001 From: santiagodevrel Date: Sat, 4 May 2024 13:06:55 +0300 Subject: [PATCH 9/9] added tested code in sepolia network interacting with WETH --- docs/docs/guides/wallet/transactions.md | 78 +++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/docs/docs/guides/wallet/transactions.md b/docs/docs/guides/wallet/transactions.md index a89c1db30af..34a856ec4db 100644 --- a/docs/docs/guides/wallet/transactions.md +++ b/docs/docs/guides/wallet/transactions.md @@ -57,12 +57,44 @@ import { Web3 } from "web3"; const web3 = new Web3("https://rpc2.sepolia.org"); +//WETH token in Sepolia https://sepolia.etherscan.io/address/0xfff9976782d46cc05630d1f6ebab18b2324d6b14#code +const ADDRESS_WETH_SEPOLIA = "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"; +const ABI = [ + { + constant: false, + inputs: [ + { + name: "dst", + type: "address", + }, + { + name: "wad", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, +]; + async function transfer() { //initialize wallet - const wallet = web3.eth.wallet.add("PRIVATE_KEY"); + const wallet = web3.eth.accounts.wallet.add("YOUR_PRIVATE_KEY"); //make sure you have WETH tokens in the Sepolia network + //you can swap Sepolia tokens for WETH here https://app.uniswap.org/swap?chain=sepolia + + //initialize WETH contract in sepolia + const myERC20 = new web3.eth.Contract(ABI, ADDRESS_WETH_SEPOLIA); - //initialize contract - const myERC20 = new web3.eth.Contract(ABI, ADDRESS); + const TO = "0xEA9eEca67682Cd9c6Ce3DdD1681049D7A897289F"; //address to send the tokens to + const VALUE = 1; //wei value, dont forget to multiply by decimals //send transfer and specify the type const txReceipt = await myERC20.methods.transfer(TO, VALUE).send({ @@ -72,6 +104,7 @@ async function transfer() { }); console.log(txReceipt.transactionHash); + //=> 0x5f2087c22166f3a1909c40ce537dd564dc3d4c70c5be02f35c6406a628123b16 } transfer(); @@ -193,12 +226,44 @@ import { Web3 } from "web3"; const web3 = new Web3("https://rpc2.sepolia.org"); +//WETH token in Sepolia https://sepolia.etherscan.io/address/0xfff9976782d46cc05630d1f6ebab18b2324d6b14#code +const ADDRESS_WETH_SEPOLIA = "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14"; +const ABI = [ + { + constant: false, + inputs: [ + { + name: "dst", + type: "address", + }, + { + name: "wad", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, +]; + async function transfer() { //initialize wallet - const wallet = web3.eth.wallet.add("PRIVATE_KEY"); + const wallet = web3.eth.accounts.wallet.add("YOUR_PRIVATE_KEY"); //make sure you have WETH tokens in the Sepolia network + //you can swap Sepolia tokens for WETH here https://app.uniswap.org/swap?chain=sepolia + + //initialize WETH contract in sepolia + const myERC20 = new web3.eth.Contract(ABI, ADDRESS_WETH_SEPOLIA); - //initialize contract - const myERC20 = new web3.eth.Contract(ABI, ADDRESS); + const TO = "0xEA9eEca67682Cd9c6Ce3DdD1681049D7A897289F"; //address to send the tokens to + const VALUE = 1; //wei value, dont forget to multiply by decimals //send transfer and specify the type const txReceipt = await myERC20.methods.transfer(TO, VALUE).send({ @@ -208,6 +273,7 @@ async function transfer() { }); console.log(txReceipt.transactionHash); + //=> 0x174bc88023be4af431fad1693a59f7a41135238510cdcd00f15f6409b5471d77 } transfer();