Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit f2abd6a

Browse files
authoredMay 29, 2023
Eth turorial (#6120)
* First draft * Fix typos and mistakes * Update conclusions * Move index.js to index.ts * Add example with DEFAULT_RETURN_FORMAT
1 parent 210455a commit f2abd6a

File tree

1 file changed

+375
-0
lines changed

1 file changed

+375
-0
lines changed
 

‎docs/docs/tutorials/eth.md

+375
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
---
2+
sidebar_position: 3
3+
sidebar_label: 'Using web3-eth package'
4+
---
5+
6+
# Getting Started with `eth` Package
7+
8+
## Introduction
9+
10+
The `web3-eth` package provides a set of powerful functionalities to interact with the Ethereum blockchain and smart contracts. In this tutorial, we will guide you through the basics of using the `web3-eth` package of web3.js version 4. We will be using TypeScript throughout the examples.
11+
12+
## Overview
13+
14+
Here is a high-level overview of the steps we will be taking in this tutorial:
15+
16+
1. Setting up the Environment
17+
2. Create a new project directory and initialize a new Node.js project.
18+
3. Set up web3.js and connect to the Ganache network
19+
4. Interact with the Ethereum blockchain using web3.js.
20+
21+
## Step 1: Setting up the Environment
22+
23+
Before we start writing and deploying our contract, we need to set up our environment. For that, we need to install the following:
24+
25+
1. Ganache - Ganache is a personal blockchain for Ethereum development that allows you to see how your smart contracts function in real-world scenarios. You can download it from http://truffleframework.com/ganache
26+
2. Node.js - Node.js is a JavaScript runtime environment that allows you to run JavaScript on the server-side. You can download it from https://nodejs.org/en/download/
27+
3. npm - Node Package Manager is used to publish and install packages to and from the public npm registry or a private npm registry. Here is how to install it https://docs.npmjs.com/downloading-and-installing-node-js-and-npm. (Alternatively, you can use yarn instead of npm https://classic.yarnpkg.com/lang/en/docs/getting-started/)
28+
29+
## Step 2: Create a new project directory and initialize a new Node.js project
30+
31+
First, create a new project directory for your project and navigate into it:
32+
33+
```
34+
mkdir web3-eth-tutorial
35+
cd web3-eth-tutorial
36+
```
37+
38+
Next, initialize a new Node.js project using npm:
39+
40+
```
41+
npm init -y
42+
```
43+
44+
This will create a new `package.json` file in your project directory.
45+
46+
```
47+
npm install typescript
48+
npm install --save @types/node
49+
```
50+
51+
This will install typescript for our project and install the types for node.
52+
53+
## Step 3: Set up web3.js and connect to the Ganache network
54+
55+
In this step, we will set up the web3.js library and connect to the Ganache network. So, be sure to run Ganache if you did not already did.
56+
57+
First, install the `web3` package using npm:
58+
59+
```
60+
npm install web3@4.0.1-rc.1
61+
```
62+
63+
Note that we are installing the latest version of 4.x, at the time of this tutorial writing. You can check the latest version at https://www.npmjs.com/package/web3?activeTab=versions
64+
65+
Next, create a new file called `index.ts` in your project directory and add the following code to it:
66+
67+
```javascript
68+
const { Web3 } = require('web3'); // web3.js has native ESM builds and (`import Web3 from 'web3'`)
69+
70+
// Set up a connection to the Ganache network
71+
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
72+
73+
// Log the current block number to the console
74+
web3.eth
75+
.getBlockNumber()
76+
.then(result => {
77+
console.log('Current block number: ' + result);
78+
})
79+
.catch(error => {
80+
console.error(error);
81+
});
82+
```
83+
84+
This code sets up a connection to the Ganache network and logs the current block number to the console.
85+
86+
Run the following command to test the connection:
87+
88+
```
89+
npx ts-node index.ts
90+
```
91+
92+
If everything is working correctly, you should see the current block number logged to the console. However, if you got an error with the reason `connect ECONNREFUSED 127.0.0.1:7545` then double check that you are running Ganache locally on port `7545`.
93+
94+
## Step 3: Interact with the Ethereum blockchain using web3.js
95+
96+
In this step, we will use web3.js to interact with the Ganache network.
97+
98+
In the first example, we are going to send a simple value transaction.
99+
Create a file named `transaction.ts` and fill it with the following code:
100+
101+
```typescript
102+
const { Web3 } = require('web3'); // web3.js has native ESM builds and (`import Web3 from 'web3'`)
103+
const fs = require('fs');
104+
const path = require('path');
105+
106+
// Set up a connection to the Ethereum network
107+
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
108+
web3.eth.Contract.handleRevert = true;
109+
110+
async function interact() {
111+
//fetch all the available accounts
112+
const accounts = await web3.eth.getAccounts();
113+
console.log(accounts);
114+
115+
let balance1, balance2;
116+
//The initial balances of the accounts should be 100 Eth (10^18 wei)
117+
balance1 = await web3.eth.getBalance(accounts[0]);
118+
balance2 = await web3.eth.getBalance(accounts[1]);
119+
120+
console.log(balance1, balance2);
121+
122+
//create a transaction sending 1 Ether from account 0 to account 1
123+
const transaction = {
124+
from: accounts[0],
125+
to: accounts[1],
126+
value: web3.utils.toWei('1', 'ether'), // value should be passed in wei. For easier use and to avoid mistakes we utilize the auxiliary `toWei` function.
127+
};
128+
129+
//send the actual transaction
130+
const transactionHash = await web3.eth.sendTransaction(transaction);
131+
console.log('transactionHash', transactionHash);
132+
133+
balance1 = await web3.eth.getBalance(accounts[0]);
134+
balance2 = await web3.eth.getBalance(accounts[1]);
135+
136+
// see the updated balances
137+
console.log(balance1, balance2);
138+
139+
// irrelevant with the actual transaction, just to know the gasPrice
140+
const gasPrice = await web3.eth.getGasPrice();
141+
console.log(gasPrice);
142+
}
143+
144+
(async () => {
145+
await interact();
146+
})();
147+
```
148+
149+
:::note
150+
📝 When running a local development blockchain using Ganache, all accounts are typically unlocked by default, allowing easy access and transaction execution during development and testing. This means that the accounts are accessible without requiring a private key or passphrase. That's why we just indicate the accounts in the examples with the `from` field.
151+
:::
152+
153+
Run the following:
154+
155+
```
156+
npx ts-node transaction.ts
157+
```
158+
159+
If everything is working correctly, you should see something like the following:
160+
161+
```typescript
162+
[
163+
'0xc68863f36C48ec168AD45A86c96347D520eac1Cf',
164+
'0x80c05939B307f9833d905A685575b45659d3EA70',
165+
'0xA260Cf742e03B48ea1A2b76b0d20aaCfe6F85E5E',
166+
'0xf457b8C0CBE41e2a85b6222A97b7b7bC6Df1C0c0',
167+
'0x32dF9a0B365b6265Fb21893c551b0766084DDE21',
168+
'0x8a6A2b8b00C1C8135F1B25DcE54f73Ee18bEF43d',
169+
'0xAFc526Be4a2656f7E02501bdf660AbbaA8fb3d7A',
170+
'0xc32618116370fF776Ecd18301c801e146A1746b3',
171+
'0xDCCD49880dCf9603835B0f522c31Fcf0579b46Ff',
172+
'0x036006084Cb62b7FAf40B979868c0c03672a59B5'
173+
]
174+
100000000000000000000n 100000000000000000000n
175+
176+
transactionHash {
177+
transactionHash: '0xf685b64ccf5930d3779a33335ca22195b68901dbdc439f79dfc65d87c7ae88b0',
178+
transactionIndex: 0n,
179+
blockHash: '0x5bc044ad949cfd32ea4cbb249f0292e7dded44c3b0f599236c6d20ddaa96cc06',
180+
blockNumber: 1n,
181+
from: '0xc68863f36c48ec168ad45a86c96347d520eac1cf',
182+
to: '0x80c05939b307f9833d905a685575b45659d3ea70',
183+
gasUsed: 21000n,
184+
cumulativeGasUsed: 21000n,
185+
logs: [],
186+
status: 1n,
187+
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
188+
}
189+
190+
98999580000000000000n 101000000000000000000n
191+
192+
20000000000n
193+
194+
```
195+
196+
:::note
197+
📝 In order to calculate the actual ether spent, we have to calculate the value sent plus the fees. Initial_balance = (Remaining_balance + value + gasUsed\*gasPrice). In our case:
198+
199+
98999580000000000000 + 1000000000000000000 + (20000000000\*21000) = 100 Ether
200+
:::
201+
202+
In the next example, we are going to use `estimateGas` function to see the expected gas for contract deployment. (For more on contracts, please see the corresponding tutotial). Create a file named `estimate.ts` and fill it with the following code:
203+
204+
```typescript
205+
import Web3, { ETH_DATA_FORMAT, DEFAULT_RETURN_FORMAT } from 'web3';
206+
207+
async function estimate() {
208+
// abi of our contract
209+
const abi = [
210+
{
211+
inputs: [{ internalType: 'uint256', name: '_myNumber', type: 'uint256' }],
212+
stateMutability: 'nonpayable',
213+
type: 'constructor',
214+
},
215+
{
216+
inputs: [],
217+
name: 'myNumber',
218+
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
219+
stateMutability: 'view',
220+
type: 'function',
221+
},
222+
{
223+
inputs: [{ internalType: 'uint256', name: '_myNumber', type: 'uint256' }],
224+
name: 'setMyNumber',
225+
outputs: [],
226+
stateMutability: 'nonpayable',
227+
type: 'function',
228+
},
229+
];
230+
231+
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
232+
233+
//get the available accounts
234+
const accounts = await web3.eth.getAccounts();
235+
let acc = await accounts[0];
236+
237+
let contract = new web3.eth.Contract(abi, undefined);
238+
239+
const deployment = contract.deploy({
240+
data: '0x608060405234801561001057600080fd5b506040516101d93803806101d983398181016040528101906100329190610054565b806000819055505061009e565b60008151905061004e81610087565b92915050565b60006020828403121561006657600080fd5b60006100748482850161003f565b91505092915050565b6000819050919050565b6100908161007d565b811461009b57600080fd5b50565b61012c806100ad6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806323fd0e401460375780636ffd773c146051575b600080fd5b603d6069565b6040516048919060bf565b60405180910390f35b6067600480360381019060639190608c565b606f565b005b60005481565b8060008190555050565b60008135905060868160e2565b92915050565b600060208284031215609d57600080fd5b600060a9848285016079565b91505092915050565b60b98160d8565b82525050565b600060208201905060d2600083018460b2565b92915050565b6000819050919050565b60e98160d8565b811460f357600080fd5b5056fea2646970667358221220d28cf161457f7936995800eb9896635a02a559a0561bff6a09a40bfb81cd056564736f6c63430008000033',
241+
// @ts-expect-error
242+
arguments: [1],
243+
});
244+
estimatedGas = await deployment.estimateGas(
245+
{
246+
from: acc,
247+
},
248+
DEFAULT_RETURN_FORMAT, // the returned data will be formatted as a bigint
249+
);
250+
251+
console.log(estimatedGas);
252+
253+
let estimatedGas = await deployment.estimateGas(
254+
{
255+
from: acc,
256+
},
257+
ETH_DATA_FORMAT, // the returned data will be formatted as a hexstring
258+
);
259+
260+
console.log(estimatedGas);
261+
}
262+
263+
(async () => {
264+
await estimate();
265+
})();
266+
```
267+
268+
Run the following:
269+
270+
```
271+
npx ts-node estimate.ts
272+
```
273+
274+
If everything is working correctly, you should see something like the following:
275+
276+
```typescript
277+
0x22568;
278+
```
279+
280+
:::note
281+
📝 Note that numbers returned from web3.js are returned by default in the `BigInt` format. In this example we used `ETH_DATA_FORMAT` parameter, which, can be passed in most methods in web3.js in order to format the result in `hex`.
282+
:::
283+
284+
In the next example we are going to sign a transaction and use `sendSignedTransaction` to send the signed transaction. Create a file named `sendSigned.ts` and fill it with the following code:
285+
286+
```typescript
287+
import Web3 from 'web3';
288+
const web3 = new Web3('http://localhost:7545');
289+
290+
//make sure to copy the private key from ganache
291+
const privateKey = '0x0fed6f64e01bc9fac9587b6e7245fd9d056c3c004ad546a17d3d029977f0930a';
292+
const value = web3.utils.toWei('1', 'ether');
293+
294+
async function sendSigned() {
295+
const accounts = await web3.eth.getAccounts();
296+
const fromAddress = accounts[0];
297+
const toAddress = accounts[1];
298+
// Create a new transaction object
299+
const tx = {
300+
from: fromAddress,
301+
to: toAddress,
302+
value: value,
303+
gas: 21000,
304+
gasPrice: web3.utils.toWei('10', 'gwei'),
305+
nonce: await web3.eth.getTransactionCount(fromAddress),
306+
};
307+
308+
// Sign the transaction with the private key
309+
const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
310+
311+
// Send the signed transaction to the network
312+
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
313+
314+
console.log('Transaction receipt:', receipt);
315+
}
316+
(async () => {
317+
await sendSigned();
318+
})();
319+
```
320+
321+
Run the following:
322+
323+
```
324+
npx ts-node sendSigned.ts
325+
```
326+
327+
If everything is working correctly, you should see something like the following:
328+
329+
```ts
330+
Transaction receipt: {
331+
transactionHash: '0x742df8f1ad4d04f6e5632889109506dbb7cdc8a6a1c80af3dfdfc71a67a04ddc',
332+
transactionIndex: 0n,
333+
blockNumber: 1n,
334+
blockHash: '0xab6678d76499b0ee383f182ab8f848ba27bd787e70e227524255c86b25224ed3',
335+
from: '0x66ce32a5200aac57b258c4eac26bc1493fefddea',
336+
to: '0x0afcfc43ac454348d8170c77b1f912b518b4ebe8',
337+
cumulativeGasUsed: 21000n,
338+
gasUsed: 21000n,
339+
logs: [],
340+
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
341+
status: 1n,
342+
effectiveGasPrice: 10000000000n,
343+
type: 2n
344+
}
345+
```
346+
347+
## Conclusion
348+
349+
In this tutorial, we learned how to use different methods provied by the `web3-eth` package.
350+
351+
With this knowledge, you can start experimenting with the Ethereum blockchain. Keep in mind that this is just the beginning, and there is a lot more to learn about Ethereum and web3.js. So keep exploring and building, and have fun!
352+
353+
## Additional Resources
354+
355+
- [Official web3.js Documentation](https://docs.web3js.org/)
356+
- [Solidity Documentation](https://solidity.readthedocs.io/)
357+
- [Ganache](https://www.trufflesuite.com/ganache)
358+
- [Truffle](https://trufflesuite.com/)
359+
- [Remix IDE](https://remix.ethereum.org/)
360+
361+
## Tips and Best Practices
362+
363+
- Always test your smart contracts on a local network like Ganache before deploying them to the mainnet.
364+
- Use the latest version of web3.js and Solidity to take advantage of the latest features and security patches.
365+
- Keep your private keys secure and never share them with anyone.
366+
- Use the gas limit and gas price parameters carefully to avoid spending too much on transaction fees.
367+
- Use the `estimateGas` function in web3.js to estimate the gas required for a transaction before sending it to the network.
368+
- Use events to notify the client application about state changes in the smart contract.
369+
- Use a linter like Solhint to check for common Solidity coding errors.
370+
371+
## Final Thoughts
372+
373+
Web3.js version 4.x provides a powerful and easy-to-use interface for interacting with the Ethereum network and building decentralized applications. And it has been rewritten in TypeScript but for simplicity of this tutorial we interacted with it in JavaScript.
374+
375+
The Ethereum ecosystem is constantly evolving, and there is always more to learn and discover. As you continue to develop your skills and knowledge, keep exploring and experimenting with new technologies and tools to build innovative and decentralized solutions.

0 commit comments

Comments
 (0)
This repository has been archived.