您的位置:首頁(yè) > 軟件教程 > 教程 > web3.js:使用eth包

web3.js:使用eth包

來(lái)源:好特整理 | 時(shí)間:2024-05-13 08:49:35 | 閱讀:155 |  標(biāo)簽: T ETH S   | 分享到:

原文在這里 簡(jiǎn)介 web3-eth包提供了一套強(qiáng)大的功能,可以與以太坊區(qū)塊鏈和智能合約進(jìn)行交互。在本教程中,我們將指導(dǎo)您如何使用web3.js版本4的web3-eth包的基礎(chǔ)知識(shí)。我們將在整個(gè)示例中使用TypeScript。 步驟 1:配置環(huán)境 在我們開(kāi)始編寫(xiě)和部署我們的合約之前,我們需要設(shè)置我們的

原文在 這里

簡(jiǎn)介

web3-eth 包提供了一套強(qiáng)大的功能,可以與以太坊區(qū)塊鏈和智能合約進(jìn)行交互。在本教程中,我們將指導(dǎo)您如何使用web3.js版本4的 web3-eth 包的基礎(chǔ)知識(shí)。我們將在整個(gè)示例中使用TypeScript。

步驟 1:配置環(huán)境

在我們開(kāi)始編寫(xiě)和部署我們的合約之前,我們需要設(shè)置我們的環(huán)境。為此,我們需要安裝以下內(nèi)容:

  1. Ganache - Ganache是一個(gè)用于以太坊開(kāi)發(fā)的個(gè)人區(qū)塊鏈,它允許你看到你的智能合約在現(xiàn)實(shí)世界場(chǎng)景中的功能。你可以從 http://truffleframework.com/ganache 下載它
  2. Node.js - Node.js是一個(gè)JavaScript運(yùn)行時(shí)環(huán)境,允許你在服務(wù)器端運(yùn)行JavaScript。你可以從 https://nodejs.org/en/download/ 下載它
  3. npm - Node Package Manager用于發(fā)布和安裝到公共npm注冊(cè)表或私有npm注冊(cè)表的包。這是如何安裝它的方法 https://docs.npmjs.com/downloading-and-installing-node-js-and-npm 。(或者,你可以使用yarn代替npm https://classic.yarnpkg.com/lang/en/docs/getting-started/

步驟 2:創(chuàng)建一個(gè)新的項(xiàng)目目錄并初始化一個(gè)新的Node.js項(xiàng)目

首先,為你的項(xiàng)目創(chuàng)建一個(gè)新的項(xiàng)目目錄,并導(dǎo)航到該目錄:

$ mkdir smart-contract-tutorial
$ cd smart-contract-tutorial

然后使用 npm 初始化項(xiàng)目:

$ npm init -y 

這將在你的項(xiàng)目目錄中創(chuàng)建一個(gè)新的 package.json 文件。

$ npm i typescript @types/node

這將為我們的項(xiàng)目安裝typescript。

步驟3:設(shè)置web3.js并連接到Ganache網(wǎng)絡(luò)

在這一步,我們將設(shè)置web3.js庫(kù)并連接到Ganache網(wǎng)絡(luò)。所以,如果你還沒(méi)有運(yùn)行Ganache,一定要運(yùn)行。

首先,使用npm安裝 web3 包:

$ npm i web3

接下來(lái),在你的項(xiàng)目目錄中創(chuàng)建一個(gè)名為 index.ts 的新文件,并向其中添加以下代碼:

import { Web3 } from 'web3';

// Set up a connection to the Ganache network
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
/* NOTE:
instead of using ganache, you can also interact with a testnet/mainnet using another provider
https://app.infura.io/
https://dashboard.alchemy.com/
or use a public provider https://chainlist.org/
*/

// Log the current block number to the console
const block = await web3.eth.getBlockNumber();

console.log('Last block:', block);
// ? Last block: 4975299n

這段代碼建立了與Ganache網(wǎng)絡(luò)的連接,并將當(dāng)前的區(qū)塊號(hào)記錄到控制臺(tái)。

運(yùn)行以下命令來(lái)測(cè)試連接:

$ npx ts-node index.ts

如果一切正常,你應(yīng)該能在控制臺(tái)看到當(dāng)前的區(qū)塊號(hào)。然而,如果你得到了一個(gè)錯(cuò)誤,原因是 connect ECONNREFUSED 127.0.0.1:7545 ,那么請(qǐng)?jiān)俅螜z查你是否在本地的 7545 端口上運(yùn)行Ganache。

步驟4:使用web3.js將智能合約部署到Ganache網(wǎng)絡(luò)

在這一步,我們將使用web3.js將智能合約部署到Ganache網(wǎng)絡(luò)。

在第一個(gè)例子中,我們將發(fā)送一個(gè)簡(jiǎn)單的交易。創(chuàng)建一個(gè)名為 transaction.ts 的文件,并用以下代碼填充它:

import { Web3 } from 'web3';
import fs from 'fs';
import path from 'path';

// Set up a connection to the Ethereum network
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));
web3.eth.Contract.handleRevert = true;

async function interact() {
  //fetch all the available accounts
  const accounts = await web3.eth.getAccounts();
  console.log(accounts);

  let balance1, balance2;
  //The initial balances of the accounts should be 100 Eth (10^18 wei)
  balance1 = await web3.eth.getBalance(accounts[0]);
  balance2 = await web3.eth.getBalance(accounts[1]);

  console.log(balance1, balance2);

  //create a transaction sending 1 Ether from account 0 to account 1
  const transaction = {
    from: accounts[0],
    to: accounts[1],
    // value should be passed in wei. For easier use and to avoid mistakes,
    //	we utilize the auxiliary `toWei` function:
    value: web3.utils.toWei('1', 'ether'),
  };

  //send the actual transaction
  const transactionHash = await web3.eth.sendTransaction(transaction);
  console.log('transactionHash', transactionHash);

  balance1 = await web3.eth.getBalance(accounts[0]);
  balance2 = await web3.eth.getBalance(accounts[1]);

  // see the updated balances
  console.log(balance1, balance2);

  // irrelevant with the actual transaction, just to know the gasPrice
  const gasPrice = await web3.eth.getGasPrice();
  console.log(gasPrice);
}

(async () => {
  await interact();
})();

重要信息
當(dāng)使用Ganache運(yùn)行本地開(kāi)發(fā)區(qū)塊鏈時(shí),所有賬戶通常默認(rèn)解鎖,允許在開(kāi)發(fā)和測(cè)試期間輕松訪問(wèn)和執(zhí)行交易。這意味著可以在不需要私鑰或密碼短語(yǔ)的情況下訪問(wèn)這些賬戶。這就是為什么我們?cè)谑纠兄挥? from 字段指示賬戶。

運(yùn)行下面的命令:

$ npx ts-node transaction.ts

如果一切正常,你應(yīng)該會(huì)看到如下內(nèi)容:

[
  '0xc68863f36C48ec168AD45A86c96347D520eac1Cf',
  '0x80c05939B307f9833d905A685575b45659d3EA70',
  '0xA260Cf742e03B48ea1A2b76b0d20aaCfe6F85E5E',
  '0xf457b8C0CBE41e2a85b6222A97b7b7bC6Df1C0c0',
  '0x32dF9a0B365b6265Fb21893c551b0766084DDE21',
  '0x8a6A2b8b00C1C8135F1B25DcE54f73Ee18bEF43d',
  '0xAFc526Be4a2656f7E02501bdf660AbbaA8fb3d7A',
  '0xc32618116370fF776Ecd18301c801e146A1746b3',
  '0xDCCD49880dCf9603835B0f522c31Fcf0579b46Ff',
  '0x036006084Cb62b7FAf40B979868c0c03672a59B5'
]
100000000000000000000n 100000000000000000000n

transactionHash {
  transactionHash: '0xf685b64ccf5930d3779a33335ca22195b68901dbdc439f79dfc65d87c7ae88b0',
  transactionIndex: 0n,
  blockHash: '0x5bc044ad949cfd32ea4cbb249f0292e7dded44c3b0f599236c6d20ddaa96cc06',
  blockNumber: 1n,
  from: '0xc68863f36c48ec168ad45a86c96347d520eac1cf',
  to: '0x80c05939b307f9833d905a685575b45659d3ea70',
  gasUsed: 21000n,
  cumulativeGasUsed: 21000n,
  logs: [],
  status: 1n,
  logsBloom: '0x......000'
}

98999580000000000000n 101000000000000000000n

20000000000n

注意事項(xiàng)
為了計(jì)算實(shí)際花費(fèi)的以太幣,我們需要計(jì)算發(fā)送的值加上費(fèi)用。初始余額 = (剩余余額 + 值 + gasUsed*gasPrice)。在我們的情況下:

98999580000000000000 + 1000000000000000000 + (20000000000*21000) = 100 Ether

在下一個(gè)示例中,我們將使用 estimateGas 函數(shù)來(lái)查看合約部署預(yù)期的gas。(關(guān)于合約的更多信息,請(qǐng)參閱相應(yīng)的教程)。創(chuàng)建一個(gè)名為 estimate.ts 的文件,并用以下代碼填充它:

import { Web3, ETH_DATA_FORMAT, DEFAULT_RETURN_FORMAT } from 'web3';

async function estimate() {
  // abi of our contract
  const abi = [
    {
      inputs: [{ internalType: 'uint256', name: '_myNumber', type: 'uint256' }],
      stateMutability: 'nonpayable',
      type: 'constructor',
    },
    {
      inputs: [],
      name: 'myNumber',
      outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
      stateMutability: 'view',
      type: 'function',
    },
    {
      inputs: [{ internalType: 'uint256', name: '_myNumber', type: 'uint256' }],
      name: 'setMyNumber',
      outputs: [],
      stateMutability: 'nonpayable',
      type: 'function',
    },
  ];

  const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));

  //get the available accounts
  const accounts = await web3.eth.getAccounts();
  let acc = await accounts[0];

  let contract = new web3.eth.Contract(abi);

  const deployment = contract.deploy({
    data: '0x608060405234801561001057600080fd5b506040516101d93803806101d983398181016040528101906100329190610054565b806000819055505061009e565b60008151905061004e81610087565b92915050565b60006020828403121561006657600080fd5b60006100748482850161003f565b91505092915050565b6000819050919050565b6100908161007d565b811461009b57600080fd5b50565b61012c806100ad6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806323fd0e401460375780636ffd773c146051575b600080fd5b603d6069565b6040516048919060bf565b60405180910390f35b6067600480360381019060639190608c565b606f565b005b60005481565b8060008190555050565b60008135905060868160e2565b92915050565b600060208284031215609d57600080fd5b600060a9848285016079565b91505092915050565b60b98160d8565b82525050565b600060208201905060d2600083018460b2565b92915050565b6000819050919050565b60e98160d8565b811460f357600080fd5b5056fea2646970667358221220d28cf161457f7936995800eb9896635a02a559a0561bff6a09a40bfb81cd056564736f6c63430008000033',
    // @ts-expect-error
    arguments: [1],
  });

  let estimatedGas = await deployment.estimateGas({ from: acc }, DEFAULT_RETURN_FORMAT);
  // the returned data will be formatted as a bigint

  console.log('Default format:', estimatedGas);

  estimatedGas = await deployment.estimateGas({ from: acc }, ETH_DATA_FORMAT);
  // the returned data will be formatted as a hexstring

  console.log('Eth format:', estimatedGas);
}

(async () => {
  await estimate();
})();

運(yùn)行下面的命令:

$ npx ts-node estimate.ts

如果一切正常,你應(yīng)該會(huì)看到如下內(nèi)容:

Default format: 140648n
Eth format: 0x22568

注意事項(xiàng)
從web3.js返回的數(shù)字默認(rèn)以 BigInt 格式返回。在這個(gè)例子中,我們使用了 ETH_DATA_FORMAT 參數(shù),它可以在web3.js的大多數(shù)方法中傳遞,以便以十六進(jìn)制格式化結(jié)果。

在下一個(gè)示例中,我們將簽署一個(gè)交易,并使用 sendSignedTransaction 來(lái)發(fā)送已簽署的交易。創(chuàng)建一個(gè)名為 sendSigned.ts 的文件,并用以下代碼填充它:

import { Web3 } from 'web3';
const web3 = new Web3('http://localhost:7545');

//make sure to copy the private key from ganache
const privateKey = '0x0fed6f64e01bc9fac9587b6e7245fd9d056c3c004ad546a17d3d029977f0930a';
const value = web3.utils.toWei('1', 'ether');

async function sendSigned() {
  const accounts = await web3.eth.getAccounts();
  const fromAddress = accounts[0];
  const toAddress = accounts[1];
  // Create a new transaction object
  const tx = {
    from: fromAddress,
    to: toAddress,
    value: value,
    gas: 21000,
    gasPrice: web3.utils.toWei('10', 'gwei'),
    nonce: await web3.eth.getTransactionCount(fromAddress),
  };

  // Sign the transaction with the private key
  const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);

  // Send the signed transaction to the network
  const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);

  console.log('Transaction receipt:', receipt);
}
(async () => {
  await sendSigned();
})();

運(yùn)行下面的命令:

$ npx ts-node sendSigned.ts

如果一切正常,你應(yīng)該會(huì)看到如下內(nèi)容:

Transaction receipt: {
  transactionHash: '0x742df8f1ad4d04f6e5632889109506dbb7cdc8a6a1c80af3dfdfc71a67a04ddc',
  transactionIndex: 0n,
  blockNumber: 1n,
  blockHash: '0xab6678d76499b0ee383f182ab8f848ba27bd787e70e227524255c86b25224ed3',
  from: '0x66ce32a5200aac57b258c4eac26bc1493fefddea',
  to: '0x0afcfc43ac454348d8170c77b1f912b518b4ebe8',
  cumulativeGasUsed: 21000n,
  gasUsed: 21000n,
  logs: [],
  logsBloom: '0x...0000',
  status: 1n,
  effectiveGasPrice: 10000000000n,
  type: 2n
}

步驟5:導(dǎo)入指定的包

為了利用web3-eth包的功能,你可以選擇直接導(dǎo)入這個(gè)包,而不是依賴全局的web3包,這將會(huì)減小構(gòu)建大小。

直接導(dǎo)入web3-eth

例如使用 getBalance 方法:

import { Web3Eth } from 'web3-eth';

const eth = new Web3Eth('http://localhost:7545');

async function test() {
	const accounts = await eth.getAccounts();
	const currentBalance = await eth.getBalance(accounts[0]);
	console.log('Current balance:', currentBalance);
	// 115792089237316195423570985008687907853269984665640564039437613106102441895127n
}

(async () => {
	await test();
})();

直接將配置設(shè)置到web3-eth包中

import { Web3Eth } from 'web3-eth';

const eth = new Web3Eth('http://localhost:8545');

console.log('defaultTransactionType before', eth.config.defaultTransactionType);
// defaultTransactionType before 0x0

eth.setConfig({ defaultTransactionType: '0x1' });

console.log('eth.config.defaultTransactionType after', eth.config.defaultTransactionType);
// defaultTransactionType before 0x1

步驟6:發(fā)送不同類型的交易

傳統(tǒng)交易

在以太坊中,'傳統(tǒng)交易'通常指的是傳統(tǒng)的交易,其中燃?xì)赓M(fèi)由發(fā)送者明確設(shè)定,并且可以根據(jù)網(wǎng)絡(luò)需求波動(dòng)。這些傳統(tǒng)交易在實(shí)施以太坊改進(jìn)提案(EIP) 1559之前在以太坊網(wǎng)絡(luò)上非常普遍。

傳統(tǒng)交易的主要特點(diǎn)包括:

  1. 燃?xì)鈨r(jià)格:在傳統(tǒng)交易中,發(fā)送者指定他們?cè)敢鉃榻灰紫牡拿繂挝蝗細(xì)庵Ц兜娜細(xì)鈨r(jià)格(以Gwei計(jì))。燃?xì)鈨r(jià)格可以由發(fā)送者調(diào)整,它決定了交易被礦工處理的優(yōu)先級(jí)。更高的燃?xì)鈨r(jià)格意味著更快的交易確認(rèn)。
  2. 燃?xì)庀拗疲喊l(fā)送者還設(shè)定了一個(gè)燃?xì)庀拗,這是交易可以消耗的最大燃?xì)饬。燃(xì)馐怯糜谠谝蕴痪W(wǎng)絡(luò)上執(zhí)行交易和智能合約的計(jì)算燃料。主要設(shè)定燃?xì)庀拗剖菫榱舜_保發(fā)送者在處理交易時(shí)不會(huì)耗盡以太幣。它也可能影響交易的成功或失敗。
  3. 費(fèi)用不確定性:傳統(tǒng)交易受到基于網(wǎng)絡(luò)擁堵的燃?xì)鈨r(jià)格波動(dòng)的影響。在需求高的時(shí)期,燃?xì)鈨r(jià)格可能會(huì)飆升,導(dǎo)致用戶為他們的交易被及時(shí)處理而支付更多的費(fèi)用。相反,在網(wǎng)絡(luò)較為安靜的時(shí)期,用戶可以支付較低的費(fèi)用。
  4. 手動(dòng)費(fèi)用估算:用戶負(fù)責(zé)手動(dòng)估算在他們的傳統(tǒng)交易中包含的適當(dāng)?shù)娜細(xì)鈨r(jià)格,以確保及時(shí)處理。這個(gè)過(guò)程可能很具挑戰(zhàn)性,因?yàn)樵O(shè)定的燃?xì)鈨r(jià)格過(guò)低可能導(dǎo)致確認(rèn)慢,而設(shè)定的價(jià)格過(guò)高可能導(dǎo)致過(guò)度支付。
  5. 如下所述的EIP-1559引入了對(duì)以太坊交易費(fèi)用系統(tǒng)的改變,使其更加用戶友好和可預(yù)測(cè)。在EIP-1559中,'基礎(chǔ)費(fèi)用'的概念取代了手動(dòng)設(shè)定燃?xì)鈨r(jià)格,這減少了與傳統(tǒng)交易相關(guān)的一些不確定性。

雖然EIP-1559大大改善了用戶體驗(yàn),但傳統(tǒng)交易仍然在以太坊網(wǎng)絡(luò)上得到支持,用戶如果愿意,可以繼續(xù)發(fā)送帶有手動(dòng)指定的燃?xì)鈨r(jià)格和燃?xì)庀拗频慕灰。然而,EIP-1559機(jī)制現(xiàn)在是大多數(shù)交易的推薦方法,因?yàn)樗?jiǎn)化了過(guò)程,減少了過(guò)度支付費(fèi)用的可能性。

要發(fā)送傳統(tǒng)交易,請(qǐng)使用下面的代碼:

import { Web3 } from 'web3';

const web3 = new Web3('http://localhost:8545');

async function test() {
  const privateKey = 'YOUR PRIVATE KEY HERE';
  // add private key to wallet to have auto-signing transactions feature
  const account = web3.eth.accounts.privateKeyToAccount(privateKey);
  web3.eth.accounts.wallet.add(account);

  // create transaction object
  const tx = {
    from: account.address,
    to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
    value: '0x1',
    gas: BigInt(21000),
    gasPrice: await web3.eth.getGasPrice(),
    type: BigInt(0), // <- specify type
  };

  // send transaction
  const receipt = await web3.eth.sendTransaction(tx);

  console.log('Receipt:', receipt);
  // Receipt: {
  //   blockHash: '0xc0f2fea359233b0843fb53255b8a7f42aa7b1aff53da7cbe78c45b5bac187ad4',
  //   blockNumber: 21n,
  //   cumulativeGasUsed: 21000n,
  //   effectiveGasPrice: 2569891347n,
  //   from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
  //   gasUsed: 21000n,
  //   logs: [],
  //   logsBloom: '0x0...00000',
  //   status: 1n,
  //   to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
  //   transactionHash: '0x0ffe880776f5631e4b64caf521bd01cd816dd2cc29e533bc56f392211856cf9a',
  //   transactionIndex: 0n,
  //   type: 0n
  // }
}
(async () => {
  await test();
})();

EIP-2930交易

以太坊改進(jìn)提案2930是對(duì)以太坊網(wǎng)絡(luò)的一項(xiàng)改變提案,該提案作為柏林硬分叉的一部分實(shí)施,于2021年4月激活。EIP-2930引入了一個(gè)名為“交易類型和訪問(wèn)列表”的功能。這項(xiàng)改進(jìn)提高了某些智能合約交互的燃?xì)庑,并在指定誰(shuí)可以訪問(wèn)智能合約內(nèi)特定資源方面提供了更多的靈活性。以下是EIP-2930的主要組成部分:

  1. 交易類型:EIP-2930引入了一種新的交易類型,稱為“訪問(wèn)列表交易”。這種交易類型旨在通過(guò)允許發(fā)送者指定可能在交易過(guò)程中被訪問(wèn)或修改的地址列表,使與智能合約的某些交互更加高效。
  2. 訪問(wèn)列表:訪問(wèn)列表是與交易一起包含的結(jié)構(gòu)化數(shù)據(jù)格式。它包含了預(yù)期在交易執(zhí)行過(guò)程中被訪問(wèn)或修改的地址和存儲(chǔ)鍵的列表。這有助于減少這些操作所需的燃?xì)饬,因(yàn)榈V工可以檢查訪問(wèn)列表以優(yōu)化執(zhí)行。
  3. 燃?xì)夤?jié)。篍IP-2930旨在顯著降低使用訪問(wèn)列表功能的交易的燃?xì)獬杀尽Mㄟ^(guò)指定與交易相關(guān)的存儲(chǔ)槽和地址,它允許更有效地使用燃?xì),特別是在與具有大狀態(tài)的智能合約的交互中。
  4. 合約交互:這項(xiàng)改進(jìn)在與具有復(fù)雜狀態(tài)結(jié)構(gòu)的合約交互時(shí)特別有用,因?yàn)樗钚』藦奶囟ù鎯?chǔ)槽讀取或?qū)懭胨璧娜細(xì)。這可以為用戶節(jié)省成本,并使某些交互更加實(shí)用。

EIP-2930是以太坊持續(xù)努力提高網(wǎng)絡(luò)效率和降低交易成本的一部分,使其對(duì)去中心化應(yīng)用和用戶更加可接入和可擴(kuò)展。它對(duì)于與依賴特定存儲(chǔ)操作和訪問(wèn)控制機(jī)制的有狀態(tài)合約的交互特別有益。

要發(fā)送EIP-2930交易,請(qǐng)使用下面的代碼:

import {Web3} from 'web3';

const web3 = new Web3('http://localhost:8545');

async function test() {
  const privateKey = 'YOUR PRIVATE KEY HERE';
  // add private key to wallet to have auto-signing transactions feature
  const account = web3.eth.accounts.privateKeyToAccount(privateKey);
  web3.eth.accounts.wallet.add(account);

  // create transaction object
  const tx = {
    from: account.address,
    to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
    value: '0x1',
    gasLimit: BigInt(21000),
    type: BigInt(1), // <- specify type
    // gasPrice - you can specify this property directly or web3js will fill this field automatically
  };

  // send transaction
  const receipt = await web3.eth.sendTransaction(tx);

  console.log('Receipt:', receipt);
  // Receipt: {
  //   blockHash: '0xd8f6a3638112d17b476fd1b7c4369d473bc1a484408b6f39dbf64410df44adf6',
  //   blockNumber: 24n,
  //   cumulativeGasUsed: 21000n,
  //   effectiveGasPrice: 2546893579n,
  //   from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
  //   gasUsed: 21000n,
  //   logs: [],
  //   logsBloom: '0x...0000',
  //   status: 1n,
  //   to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
  //   transactionHash: '0xd1d682b6f6467897db5b8f0a99a6be2fb788d32fbc1329b568b8f6b2c15e809a',
  //   transactionIndex: 0n,
  //   type: 1n
  // }
}
(async () => {
  await test();
})();

以下是在交易中使用訪問(wèn)列表的示例。

注意
你可以在這里找到 Greeter 合約的代碼

import {Web3} from 'web3';

import { GreeterAbi, GreeterBytecode } from './fixture/Greeter';

const web3 = new Web3('http://localhost:8545');

async function test() {
  const privateKey = 'YOUR PRIVATE KEY HERE';
  // add private key to wallet to have auto-signing transactions feature
  const account = web3.eth.accounts.privateKeyToAccount(privateKey);
  web3.eth.accounts.wallet.add(account);

  // deploy contract
  const contract = new web3.eth.Contract(GreeterAbi);
  const deployedContract = await contract
    .deploy({
      data: GreeterBytecode,
      arguments: ['My Greeting'],
    })
    .send({ from: account.address });
  deployedContract.defaultAccount = account.address;

  const transaction = {
    from: account.address,
    to: deployedContract.options.address,
    data: '0xcfae3217', // greet function call data encoded
  };
  const { accessList } = await web3.eth.createAccessList(transaction, 'latest');

  console.log('AccessList:', accessList);
  // AccessList: [
  //   {
  //     address: '0xce1f86f87bd3b8f32f0fb432f88e848f3a957ed7',
  //     storageKeys: [
  //       '0x0000000000000000000000000000000000000000000000000000000000000001'
  //     ]
  //   }
  // ]

  // create transaction object with accessList
  const tx = {
    from: account.address,
    to: deployedContract.options.address,
    gasLimit: BigInt(46000),
    type: BigInt(1), // <- specify type
    accessList,
    data: '0xcfae3217',
    // gasPrice - you can specify this property directly or web3js will fill this field automatically
  };

  // send transaction
  const receipt = await web3.eth.sendTransaction(tx);

  console.log('Receipt:', receipt);
  // Receipt: {
  //   blockHash: '0xc7b9561100c8ff6f1cde7a05916e86b7d037b2fdba86b0870e842d1814046e4b',
  //   blockNumber: 43n,
  //   cumulativeGasUsed: 26795n,
  //   effectiveGasPrice: 2504325716n,
  //   from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
  //   gasUsed: 26795n,
  //   logs: [],
  //   logsBloom: '0x...00000000000',
  //   status: 1n,
  //   to: '0xce1f86f87bd3b8f32f0fb432f88e848f3a957ed7',
  //   transactionHash: '0xa49753be1e2bd22c2a8e2530726614c808838bb0ebbed72809bbcb34f178799a',
  //   transactionIndex: 0n,
  //   type: 1n
  // }
}
(async () => {
  await test();
})();

EIP-1559交易

以太坊改進(jìn)提案1559是對(duì)以太坊網(wǎng)絡(luò)費(fèi)用市場(chǎng)和交易定價(jià)機(jī)制的重大升級(jí)。它作為以太坊倫敦硬分叉的一部分實(shí)施,該硬分叉于2021年8月發(fā)生。EIP-1559引入了幾項(xiàng)改變以太坊區(qū)塊鏈上交易費(fèi)用工作方式的變化,其主要目標(biāo)是改善用戶體驗(yàn)和網(wǎng)絡(luò)效率。

以下是EIP-1559引入的一些關(guān)鍵特性和變化:

  1. 基礎(chǔ)費(fèi)用:EIP-1559引入了一個(gè)名為“基礎(chǔ)費(fèi)用”的概念;A(chǔ)費(fèi)用是交易被包含在區(qū)塊中所需的最低費(fèi)用。它由網(wǎng)絡(luò)通過(guò)算法確定,并根據(jù)網(wǎng)絡(luò)擁堵動(dòng)態(tài)調(diào)整。當(dāng)網(wǎng)絡(luò)繁忙時(shí),基礎(chǔ)費(fèi)用增加,當(dāng)網(wǎng)絡(luò)擁堵較少時(shí),基礎(chǔ)費(fèi)用減少。
  2. 包含費(fèi)用:除基礎(chǔ)費(fèi)用外,用戶可以自愿包含一個(gè)“小費(fèi)”或“包含費(fèi)用”以激勵(lì)礦工將他們的交易包含在下一個(gè)區(qū)塊中。這允許用戶通過(guò)向礦工提供小費(fèi)來(lái)加快他們的交易。
  3. 可預(yù)測(cè)的費(fèi)用:有了EIP-1559,用戶有更可預(yù)測(cè)的方式來(lái)估算交易費(fèi)用。他們可以設(shè)定他們?cè)敢庵Ц兜淖罡哔M(fèi)用,包括基礎(chǔ)費(fèi)用和小費(fèi)。這消除了用戶需要猜測(cè)適當(dāng)?shù)娜細(xì)鈨r(jià)格的需要。
  4. 銷毀機(jī)制:EIP-1559引入了一種機(jī)制,通過(guò)該機(jī)制,基礎(chǔ)費(fèi)用從流通中“銷毀”,減少了以太幣(ETH)的總供應(yīng)量。這種通縮機(jī)制可以幫助解決一些與ETH供應(yīng)量增加相關(guān)的問(wèn)題,并可能使其成為更好的價(jià)值儲(chǔ)存。
  5. 改進(jìn)的費(fèi)用拍賣:在EIP-1559下,費(fèi)用拍賣更有效。用戶指定他們?cè)敢庵Ц兜淖罡哔M(fèi)用,協(xié)議自動(dòng)調(diào)整小費(fèi),以確保交易得到及時(shí)處理,而不會(huì)過(guò)度支付。
  6. 更簡(jiǎn)單的交易過(guò)程:用戶體驗(yàn)到一個(gè)簡(jiǎn)化的交易過(guò)程,因?yàn)樗麄儾槐厥謩?dòng)設(shè)定燃?xì)鈨r(jià)格。相反,他們指定他們?cè)敢庵Ц兜淖罡哔M(fèi)用,錢(qián)包軟件處理其余的事情。

EIP-1559因其創(chuàng)建更用戶友好和高效的交易費(fèi)用系統(tǒng)的潛力而受到好評(píng),使以太坊網(wǎng)絡(luò)對(duì)用戶更加可接入和可預(yù)測(cè)。它也被視為過(guò)渡到以太坊2.0的重要步驟,以太坊2.0旨在解決網(wǎng)絡(luò)上的可擴(kuò)展性和可持續(xù)性挑戰(zhàn)。

要發(fā)送EIP-1559交易,請(qǐng)使用下面的代碼:

import { Web3 } from 'web3';

const web3 = new Web3('http://localhost:8545');

async function test() {
  const privateKey = 'YOUR PRIVATE KEY HERE';
  // add private key to wallet to have auto-signing transactions feature
  const account = web3.eth.accounts.privateKeyToAccount(privateKey);
  web3.eth.accounts.wallet.add(account);

  // create transaction object
  const tx = {
    from: account.address,
    to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
    value: '0x1',
    gasLimit: BigInt(21000),
    type: BigInt(2), // <- specify type
    // maxFeePerGas - you can specify this property directly or web3js will fill this field automatically
    // maxPriorityFeePerGas - you can specify this property directly or web3js will fill this field automatically
  };

  // send transaction
  const receipt = await web3.eth.sendTransaction(tx);

  console.log('Receipt:', receipt);
  // Receipt: {
  //   blockHash: '0xfe472084d1471720b6887071d32a793f7c4576a489098e7d2a89aef205c977fb',
  //   blockNumber: 23n,
  //   cumulativeGasUsed: 21000n,
  //   effectiveGasPrice: 2546893579n,
  //   from: '0xe2597eb05cf9a87eb1309e86750c903ec38e527e',
  //   gasUsed: 21000n,
  //   logs: [],
  //   logsBloom: '0x0000...00000000000',
  //   status: 1n,
  //   to: '0x27aa427c1d668ddefd7bc93f8857e7599ffd16ab',
  //   transactionHash: '0x5c7a3d2965b426a5776e55f049ee379add44652322fb0b9fc2f7f57b38fafa2a',
  //   transactionIndex: 0n,
  //   type: 2n
  // }
}
(async () => {
  await test();
})();

結(jié)論

在這個(gè)教程中,我們學(xué)習(xí)了如何使用 web3-eth 包提供的不同方法。

有了這些知識(shí),你可以開(kāi)始嘗試使用以太坊區(qū)塊鏈。請(qǐng)記住,這只是開(kāi)始,關(guān)于以太坊和web3.js還有很多需要學(xué)習(xí)的內(nèi)容。所以繼續(xù)探索和建設(shè),玩得開(kāi)心!

Web3.js 4.x版本為與以太坊網(wǎng)絡(luò)交互和構(gòu)建去中心化應(yīng)用提供了強(qiáng)大且易于使用的接口。并且它已經(jīng)用TypeScript重寫(xiě),但為了簡(jiǎn)化這個(gè)教程,我們用JavaScript與它交互。

以太坊生態(tài)系統(tǒng)正在不斷發(fā)展,總是有更多的東西可以學(xué)習(xí)和發(fā)現(xiàn)。當(dāng)你繼續(xù)發(fā)展你的技能和知識(shí)時(shí),繼續(xù)探索和嘗試新的技術(shù)和工具,構(gòu)建創(chuàng)新和去中心化的解決方案。

提示和最佳實(shí)踐

  • 在將智能合約部署到主網(wǎng)之前,始終在本地網(wǎng)絡(luò)(如Ganache或Hardhat)上測(cè)試你的智能合約。
  • 使用最新版本的web3.js和Solidity,以利用最新的功能和安全補(bǔ)丁。
  • 保護(hù)好你的私鑰,切勿與任何人分享。
  • 謹(jǐn)慎使用燃?xì)庀拗坪腿細(xì)鈨r(jià)格參數(shù),以避免在交易費(fèi)用上花費(fèi)過(guò)多。
  • 在將交易發(fā)送到網(wǎng)絡(luò)之前,使用web3.js中的 estimateGas 函數(shù)來(lái)估算交易所需的燃?xì)狻?
  • 使用事件來(lái)通知客戶端應(yīng)用程序關(guān)于智能合約狀態(tài)的更改。
  • 使用像Solhint這樣的linter來(lái)檢查常見(jiàn)的Solidity編碼錯(cuò)誤。

聲明:本作品采用 署名-非商業(yè)性使用-相同方式共享 4.0 國(guó)際 (CC BY-NC-SA 4.0) 進(jìn)行許可,使用時(shí)請(qǐng)注明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無(wú)意
騰訊云開(kāi)發(fā)者社區(qū): 孟斯特


小編推薦閱讀

好特網(wǎng)發(fā)布此文僅為傳遞信息,不代表好特網(wǎng)認(rèn)同期限觀點(diǎn)或證實(shí)其描述。

相關(guān)視頻攻略

更多

掃二維碼進(jìn)入好特網(wǎng)手機(jī)版本!

掃二維碼進(jìn)入好特網(wǎng)微信公眾號(hào)!

本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]

湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2024 haote.com 好特網(wǎng)