Skip to content

Commit cefac45

Browse files
committed
finish the tutorial
1 parent 7ee6b53 commit cefac45

File tree

1 file changed

+114
-107
lines changed

1 file changed

+114
-107
lines changed

pages/builders/app-developers/tutorials/sdk-estimate-costs.mdx

Lines changed: 114 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ import { Callout, Steps, Tabs } from 'nextra/components'
88

99
# Estimating Transaction Costs on OP Stack
1010

11-
1211
In this tutorial, you'll learn how to use the [Viem](https://viem.sh/op-stack/) to estimate the cost of a transaction on OP Mainnet.
1312
You'll learn how to estimate the [execution gas fee](/builders/app-developers/transactions/fees#execution-gas-fee) and the [L1 data fee](/builders/app-developers/transactions/fees#l1-data-fee) independently.
1413
You'll also learn how to estimate the total cost of the transaction all at once.
1514

1615
<Callout>
17-
Check out the full explainer on [OP Stack transaction fees](/builders/app-developers/transactions/fees) for more information on how OP Mainnet charges fees under the hood.
16+
Check out the full explainer on [OP Stack transaction fees](/builders/app-developers/transactions/fees) for more information on how OP Mainnet charges fees under the hood.
1817
</Callout>
1918

2019
## Prerequisites
@@ -60,15 +59,14 @@ npm install -g pnpm
6059
```
6160

6261
{<h4>Install dependencies</h4>}
63-
62+
6463
Install `viem`, and `dotenv` for managing environment variables.
6564

6665
```bash
6766
pnpm add viem dotenv
6867
```
6968
</Steps>
7069

71-
7270
{<h3>Configure Environment Variables</h3>}
7371

7472
You need a private key in order to sign transactions.
@@ -80,28 +78,27 @@ npm install -g pnpm
8078
touch .env
8179
```
8280

83-
Add your wallet private key in the `.env` file.
84-
You need a private key in order to sign transactions.
85-
Make sure this private key corresponds to an address that has ETH on OP Sepolia.
81+
Add your wallet private key in the `.env` file.
82+
You need a private key in order to sign transactions.
83+
Make sure this private key corresponds to an address that has ETH on OP Sepolia.
8684

87-
```bash
88-
RPC_URL=https://optimism-mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID
89-
TUTORIAL_PRIVATE_KEY=0x...
90-
```
85+
```bash
86+
RPC_URL=https://optimism-mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID
87+
TUTORIAL_PRIVATE_KEY=0x...
88+
```
9189
</Steps>
9290

9391
<Callout type="warning">
9492
Never share your private key and avoid committing this file to version control.
9593
</Callout>
9694

97-
9895
## Get ETH on OP Sepolia
9996

10097
This tutorial explains how estimate transaction costs on OP Sepolia.
10198
You will need to get some ETH on OP Sepolia in order to run the code in this tutorial.
10299

103100
<Callout type="info">
104-
You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=docs) to get ETH on OP Sepolia.
101+
You can use the [Superchain Faucet](https://console.optimism.io/faucet?utm_source=docs) to get ETH on OP Sepolia.
105102
</Callout>
106103

107104
## Start the Node REPL
@@ -120,23 +117,20 @@ This will bring up a Node REPL prompt that allows you to run javascript code.
120117
You need to import some dependencies into your Node REPL session.
121118
With `viem`, we will create an account using the private key and create the RPC provider
122119

123-
124120
<Steps>
125-
126-
{<h3>Import the Viem</h3>}
127-
128-
```js
129-
130-
// Import required modules
131-
import { createPublicClient, createWalletClient, http, parseEther, parseGwei, formatEther } from 'viem'
132-
import { privateKeyToAccount } from 'viem/accounts'
133-
import { optimismSepolia } from 'viem/chains'
134-
import { publicActionsL2, walletActionsL2 } from 'viem/op-stack'
135-
import * as dotenv from 'dotenv';
136-
// Load environment variables
137-
dotenv.config();
138-
```
139-
121+
{<h3>Import the Viem</h3>}
122+
123+
```js
124+
125+
// Import required modules
126+
import { createPublicClient, createWalletClient, http, parseEther, parseGwei, formatEther } from 'viem'
127+
import { privateKeyToAccount } from 'viem/accounts'
128+
import { optimismSepolia } from 'viem/chains'
129+
import { publicActionsL2, walletActionsL2 } from 'viem/op-stack'
130+
import * as dotenv from 'dotenv';
131+
// Load environment variables
132+
dotenv.config();
133+
```
140134
</Steps>
141135

142136
## Set Session Variables
@@ -153,7 +147,7 @@ Let's set those up now.
153147
```
154148
</Tabs.Tab>
155149

156-
<Tabs.Tab>
150+
<Tabs.Tab>
157151
Set up our Wallet Clients for L2(optimismSepolia)
158152

159153
```js
@@ -162,7 +156,6 @@ Let's set those up now.
162156
transport: http(process.env.L2_RPC_URL),
163157
}).extend(walletActionsL2())
164158
```
165-
166159
</Tabs.Tab>
167160

168161
<Tabs.Tab>
@@ -174,127 +167,141 @@ Let's set those up now.
174167
transport: http(process.env.L2_RPC_URL),
175168
}).extend(publicActionsL2());
176169
```
177-
178170
</Tabs.Tab>
179-
180171
</Tabs>
181172

182173
## Estimate Transaction Costs
183174

184175
You're now going to estimate the cost of a transaction on OP Mainnet.
185-
<Steps>
186176

187-
{<h3>Creating a Transaction in Viem</h3>}
188-
189-
Viem makes it easy to prepare a transactions so you can estimate the cost of a transaction before you sign it.
190-
Here you'll define an object with the required transaction fields and send a small amount of ETH from your address to the address `0x1000000000000000000000000000000000000000`.
191-
192-
```js
193-
const transaction = {
194-
account,
195-
to: '0x1000000000000000000000000000000000000000',
196-
value: parseEther('0.1'),
197-
gasPrice: parseGwei('20')
198-
};
199-
```
200-
{<h3>Estimate the execution gas fee</h3>}
177+
<Steps>
178+
{<h3>Creating a Transaction in Viem</h3>}
179+
180+
Viem makes it easy to prepare a transactions so you can estimate the cost of a transaction before you sign it.
181+
Here you'll define an object with the required transaction fields and send a small amount of ETH from your address to the address `0x1000000000000000000000000000000000000000`.
182+
183+
```js
184+
const transaction = {
185+
account,
186+
to: '0x1000000000000000000000000000000000000000',
187+
value: parseEther('0.1'),
188+
gasPrice: parseGwei('20')
189+
};
190+
```
201191

192+
{<h3>Estimate the execution gas fee</h3>}
202193

203-
Now that you have prepared a transaction that sends a small amount of ETH, we can estimate the gas for that transaction by using the `estimateGas` method from viem.
194+
Now that you have prepared a transaction that sends a small amount of ETH, we can estimate the gas for that transaction by using the `estimateGas` method from viem.
204195

205-
```js
206-
const gasLimit = await publicClient.estimateGas(transaction);
207-
console.log(`Estimated Gas Limit: ${gasLimit}`);
208-
```
209-
<Steps>
196+
```js
197+
const gasLimit = await publicClient.estimateGas(transaction);
198+
console.log(`Estimated Gas Limit: ${gasLimit}`);
199+
```
210200

211-
{<h3>Retrieve the current gas price</h3>}
201+
<Steps>
202+
{<h3>Retrieve the current gas price</h3>}
212203

213-
Retrieve the current gas price (effective gas price), Alternatively, given that you already set the gas price manually, you can use the `getGasPrice` method from viem.
204+
Retrieve the current gas price (effective gas price), Alternatively, given that you already set the gas price manually, you can use the `getGasPrice` method from viem.
214205

215206
```js
216207
const effectiveGasPrice = await publicClient.getGasPrice();
208+
console.log(`effective Gas Price, ${effectiveGasPrice}`);
217209
```
218-
{<h3>Calculate the execution gas fee</h3>}
219210

220-
To calculate the execution gas fee simply multiply the gas limit by the effective gas price.
211+
{<h3>Calculate the execution gas fee</h3>}
212+
213+
To calculate the execution gas fee simply multiply the gas limit by the effective gas price.
221214

222215
```js
223216
const l2CostEstimate = gasLimit * effectiveGasPrice;
224-
console.log(`Estimated Execution Gas Fee: ${formatEther(l2CostEstimate)} wei`);
217+
console.log(`Estimated Execution Gas Fee: ${formatEther(l2CostEstimate)}`);
225218
```
219+
</Steps>
226220

227-
</Steps>
228-
229-
{<h3>Estimate the L1 data fee</h3>}
230-
231-
You can estimate the L1 data fee with the [estimateL1GasCost](https://viem.sh/op-stack/actions/estimateL1Gas) function.
232-
Under the hood, this function is estimating the amount of Ethereum gas required to publish this transaction on Ethereum and multiplying it by the current Ethereum gas price (as tracked by the L2).
233-
This function returns the current cost estimate in wei.
234-
235-
```js
236-
const l1CostEstimate = await publicClient.estimateL1Gas(transaction)
237-
console.log(`Estimated L1 data Fee: ${formatEther(l1CostEstimate)}`);
238-
```
221+
{<h3>Estimate the L1 data fee</h3>}
239222

223+
You can estimate the L1 data fee with the [estimateL1GasCost](https://viem.sh/op-stack/actions/estimateL1Gas) function.
224+
Under the hood, this function is estimating the amount of Ethereum gas required to publish this transaction on Ethereum and multiplying it by the current Ethereum gas price (as tracked by the L2).
225+
This function returns the current cost estimate in wei.
240226

227+
```js
228+
const l1CostEstimate = await publicClient.estimateL1Gas(transaction)
229+
console.log(`Estimated L1 data Fee: ${formatEther(l1CostEstimate)}`);
230+
```
241231

242-
{<h3>Estimate the total cost</h3>}
232+
{<h3>Estimate the total cost</h3>}
243233

244-
Once you've individually estimated the execution gas fee and the L1 data fee, you can sum these two values together to get the total cost of the transaction.
234+
Once you've individually estimated the execution gas fee and the L1 data fee, you can sum these two values together to get the total cost of the transaction.
245235

246-
```js
236+
```js
247237
const totalSum = l2CostEstimate + l1CostEstimate;
248238
console.log(`Estimated Total Cost: ${formatEther(totalSum)} `);
249239
```
250240

251-
{<h3>Send the transaction</h3>}
252-
253-
Now that you've estimated the total cost of the transaction, go ahead and send it to the network.
254-
This will make it possible to see the actual cost of the transaction to compare to your estimate.
241+
{<h3>Send the transaction</h3>}
255242

256-
```js
257-
const txHash = await walletClient.sendTransaction(transaction)
258-
```
243+
Now that you've estimated the total cost of the transaction, go ahead and send it to the network.
244+
This will make it possible to see the actual cost of the transaction to compare to your estimate.
259245

260-
{<h3>Check the actual execution gas fee</h3>}
246+
```js
247+
const txHash = await walletClient.sendTransaction(transaction)
248+
console.log(`Transaction Hash: ${tx}`);
249+
```
261250

262-
Once you get back the transaction receipt, check the actual execution gas fee.
251+
{<h3>Check the actual execution gas fee</h3>}
263252

264-
```js
265-
const l2CostActual = await publicClient.estimateL2Fee(txHash)
266-
console.log(`l2CostActual gas fee: ${formatEther(l2CostActual)}`);
267-
```
253+
Once you get back the transaction receipt, check the actual execution gas fee.
254+
You can do so by accessing the `gasUsed` and `effectiveGasPrice` from the transaction receipt.
255+
You can then multiply these values to get the actual L2 cost of the transaction
268256

269-
{<h3>Check the actual L1 data fee</h3>}
257+
```js
258+
const receipt = await publicClient.getTransactionReceipt({ hash: txHash });
259+
console.log('Transaction receipt:', receipt);
270260

271-
You can also check the actual L1 data fee.
261+
const l2CostActual = receipt.gasUsed * receipt.effectiveGasPrice;
262+
console.log(`L2 Actual Cost: ${formatEther(l2CostActual)}`);
263+
```
272264

273-
```js
274-
const l1CostActual = await publicClient.estimateL1Fee(txHash)
275-
console.log(`l1CostActual gas fee: ${formatEther(l1CostActual)}`);
265+
{<h3>Check the actual L1 data fee</h3>}
276266

277-
```
267+
You can also check the actual L1 data fee.
278268

279-
{<h3>Check the actual total cost</h3>}
269+
```js
270+
const l1CostActual = await publicClient.estimateL1Fee(txHash)
271+
console.log(`l1CostActual gas fee: ${formatEther(l1CostActual)}`);
280272

281-
Sum these two together to get the actual total cost of the transaction.
273+
```
282274

283-
```js
284-
const totalActual = l2CostActual + l1CostActual;
285-
console.log(`Total Actual Cost: ${formatEther(totalActual)}`);
286-
```
275+
{<h3>Check the actual total cost</h3>}
287276

288-
{<h3>Check the difference</h3>}
277+
Sum these two together to get the actual total cost of the transaction.
289278

290-
Finally, check the difference between the estimated total cost and the actual total cost.
291-
This will give you a sense of how accurate your estimate was.
292-
Estimates will never be entirely accurate, but they should be close!
279+
```js
280+
const totalActual = l2CostActual + l1CostActual;
281+
console.log(`Total Actual Cost: ${formatEther(totalActual)}`);
282+
```
293283

294-
```js
295-
const difference = totalSum - totalActual
296-
console.log(`The difference - ${formatEther(difference)}`)
284+
{<h3>Check the difference</h3>}
297285

298-
```
286+
Finally, check the difference between the estimated total cost and the actual total cost.
287+
This will give you a sense of how accurate your estimate was.
288+
Estimates will never be entirely accurate, but they should be close!
299289

290+
```js
291+
const difference = totalSum - totalActual
292+
console.log(`The difference - ${formatEther(difference)}`)
293+
```
300294
</Steps>
295+
296+
<Callout type="info">
297+
Estimates will never be entirely accurate due to network conditions and gas price fluctuations, but they should be close to the actual costs.
298+
</Callout>
299+
300+
## Next Steps
301+
302+
* Always estimate before sending: Estimating costs before sending a transaction helps prevent unexpected fees and failed transactions.
303+
* Account for gas price volatility: Gas prices can change rapidly. Consider adding a buffer to your estimates or implementing a gas price oracle for more accurate pricing.
304+
* Optimize transaction data: Minimize the amount of data in your transactions to reduce L1 data fees.
305+
* Monitor network conditions: Keep an eye on network congestion and adjust your estimates accordingly.
306+
* Use appropriate gas limits: Setting too low a gas limit can cause transactions to fail, while setting it too high can result in unnecessary costs.
307+
* Implement retry mechanisms: If a transaction fails due to underestimated gas, implement a retry mechanism with adjusted gas parameters.

0 commit comments

Comments
 (0)