原文在這里 簡介 web3-eth包提供了一套強大的功能,可以與以太坊區(qū)塊鏈和智能合約進行交互。在本教程中,我們將指導您如何使用web3.js版本4的web3-eth包的基礎知識。我們將在整個示例中使用TypeScript。 步驟 1:配置環(huán)境 在我們開始編寫和部署我們的合約之前,我們需要設置我們的
原文在 這里
web3-eth
包提供了一套強大的功能,可以與以太坊區(qū)塊鏈和智能合約進行交互。在本教程中,我們將指導您如何使用web3.js版本4的
web3-eth
包的基礎知識。我們將在整個示例中使用TypeScript。
在我們開始編寫和部署我們的合約之前,我們需要設置我們的環(huán)境。為此,我們需要安裝以下內(nèi)容:
首先,為你的項目創(chuàng)建一個新的項目目錄,并導航到該目錄:
$ mkdir smart-contract-tutorial
$ cd smart-contract-tutorial
然后使用
npm
初始化項目:
$ npm init -y
這將在你的項目目錄中創(chuàng)建一個新的
package.json
文件。
$ npm i typescript @types/node
這將為我們的項目安裝typescript。
在這一步,我們將設置web3.js庫并連接到Ganache網(wǎng)絡。所以,如果你還沒有運行Ganache,一定要運行。
首先,使用npm安裝
web3
包:
$ npm i web3
接下來,在你的項目目錄中創(chuàng)建一個名為
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)絡的連接,并將當前的區(qū)塊號記錄到控制臺。
運行以下命令來測試連接:
$ npx ts-node index.ts
如果一切正常,你應該能在控制臺看到當前的區(qū)塊號。然而,如果你得到了一個錯誤,原因是
connect ECONNREFUSED 127.0.0.1:7545
,那么請再次檢查你是否在本地的
7545
端口上運行Ganache。
在這一步,我們將使用web3.js將智能合約部署到Ganache網(wǎng)絡。
在第一個例子中,我們將發(fā)送一個簡單的交易。創(chuàng)建一個名為
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();
})();
重要信息
當使用Ganache運行本地開發(fā)區(qū)塊鏈時,所有賬戶通常默認解鎖,允許在開發(fā)和測試期間輕松訪問和執(zhí)行交易。這意味著可以在不需要私鑰或密碼短語的情況下訪問這些賬戶。這就是為什么我們在示例中只用from
字段指示賬戶。
運行下面的命令:
$ npx ts-node transaction.ts
如果一切正常,你應該會看到如下內(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
注意事項
為了計算實際花費的以太幣,我們需要計算發(fā)送的值加上費用。初始余額 = (剩余余額 + 值 + gasUsed*gasPrice)。在我們的情況下:98999580000000000000 + 1000000000000000000 + (20000000000*21000) = 100 Ether
在下一個示例中,我們將使用
estimateGas
函數(shù)來查看合約部署預期的gas。(關于合約的更多信息,請參閱相應的教程)。創(chuàng)建一個名為
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();
})();
運行下面的命令:
$ npx ts-node estimate.ts
如果一切正常,你應該會看到如下內(nèi)容:
Default format: 140648n
Eth format: 0x22568
注意事項
從web3.js返回的數(shù)字默認以BigInt
格式返回。在這個例子中,我們使用了ETH_DATA_FORMAT
參數(shù),它可以在web3.js的大多數(shù)方法中傳遞,以便以十六進制格式化結果。
在下一個示例中,我們將簽署一個交易,并使用
sendSignedTransaction
來發(fā)送已簽署的交易。創(chuàng)建一個名為
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();
})();
運行下面的命令:
$ npx ts-node sendSigned.ts
如果一切正常,你應該會看到如下內(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
}
為了利用web3-eth包的功能,你可以選擇直接導入這個包,而不是依賴全局的web3包,這將會減小構建大小。
例如使用 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();
})();
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
在以太坊中,'傳統(tǒng)交易'通常指的是傳統(tǒng)的交易,其中燃氣費由發(fā)送者明確設定,并且可以根據(jù)網(wǎng)絡需求波動。這些傳統(tǒng)交易在實施以太坊改進提案(EIP) 1559之前在以太坊網(wǎng)絡上非常普遍。
傳統(tǒng)交易的主要特點包括:
雖然EIP-1559大大改善了用戶體驗,但傳統(tǒng)交易仍然在以太坊網(wǎng)絡上得到支持,用戶如果愿意,可以繼續(xù)發(fā)送帶有手動指定的燃氣價格和燃氣限制的交易。然而,EIP-1559機制現(xiàn)在是大多數(shù)交易的推薦方法,因為它簡化了過程,減少了過度支付費用的可能性。
要發(fā)送傳統(tǒ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();
})();
以太坊改進提案2930是對以太坊網(wǎng)絡的一項改變提案,該提案作為柏林硬分叉的一部分實施,于2021年4月激活。EIP-2930引入了一個名為“交易類型和訪問列表”的功能。這項改進提高了某些智能合約交互的燃氣效率,并在指定誰可以訪問智能合約內(nèi)特定資源方面提供了更多的靈活性。以下是EIP-2930的主要組成部分:
EIP-2930是以太坊持續(xù)努力提高網(wǎng)絡效率和降低交易成本的一部分,使其對去中心化應用和用戶更加可接入和可擴展。它對于與依賴特定存儲操作和訪問控制機制的有狀態(tài)合約的交互特別有益。
要發(fā)送EIP-2930交易,請使用下面的代碼:
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();
})();
以下是在交易中使用訪問列表的示例。
注意
你可以在這里找到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();
})();
以太坊改進提案1559是對以太坊網(wǎng)絡費用市場和交易定價機制的重大升級。它作為以太坊倫敦硬分叉的一部分實施,該硬分叉于2021年8月發(fā)生。EIP-1559引入了幾項改變以太坊區(qū)塊鏈上交易費用工作方式的變化,其主要目標是改善用戶體驗和網(wǎng)絡效率。
以下是EIP-1559引入的一些關鍵特性和變化:
EIP-1559因其創(chuàng)建更用戶友好和高效的交易費用系統(tǒng)的潛力而受到好評,使以太坊網(wǎng)絡對用戶更加可接入和可預測。它也被視為過渡到以太坊2.0的重要步驟,以太坊2.0旨在解決網(wǎng)絡上的可擴展性和可持續(xù)性挑戰(zhàn)。
要發(fā)送EIP-1559交易,請使用下面的代碼:
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();
})();
在這個教程中,我們學習了如何使用
web3-eth
包提供的不同方法。
有了這些知識,你可以開始嘗試使用以太坊區(qū)塊鏈。請記住,這只是開始,關于以太坊和web3.js還有很多需要學習的內(nèi)容。所以繼續(xù)探索和建設,玩得開心!
Web3.js 4.x版本為與以太坊網(wǎng)絡交互和構建去中心化應用提供了強大且易于使用的接口。并且它已經(jīng)用TypeScript重寫,但為了簡化這個教程,我們用JavaScript與它交互。
以太坊生態(tài)系統(tǒng)正在不斷發(fā)展,總是有更多的東西可以學習和發(fā)現(xiàn)。當你繼續(xù)發(fā)展你的技能和知識時,繼續(xù)探索和嘗試新的技術和工具,構建創(chuàng)新和去中心化的解決方案。
estimateGas
函數(shù)來估算交易所需的燃氣。
聲明:本作品采用 署名-非商業(yè)性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0) 進行許可,使用時請注明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意
騰訊云開發(fā)者社區(qū): 孟斯特
如何使用 Pytorch 中的 DataSet 和 DataLoader
閱讀國產(chǎn)操作系統(tǒng)上實現(xiàn)RTMP推流攝像頭視頻和麥克風聲音到流媒體服務器
閱讀多租戶系統(tǒng)數(shù)據(jù)權限設計與RuoYi系統(tǒng)的借鑒
閱讀count(*)、count(1)哪個更快?面試必問:通宵整理的十道經(jīng)典MySQL必問面試題
閱讀強化學習筆記之【ACE:Off-PolicyActor-CriticwithCausality-AwareEntropyRegularization】
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權,請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2024 haote.com 好特網(wǎng)