ethers.js链上交互指南 / 学习智能合约#65
这些天想升级Dapp的时候却发现web3.js包用不了!web3.js一直以来是又大又难装,这下彻底完犊了,用不了了。这时只能启用备用方案:ethers.js
ethers.js更新的挺快,这就6.8的版本啰!
简单对比了下,ethers.js大约是18M, web3.js却有近57M!ethers.js很是小巧灵活。测试了一些写法,感觉还是很丝滑的。而且功能也很全面,爱了!
下载与资源
ethers |
ethers-github |
中文文档 |
安装
npm install ethers --save
// "ethers": "^6.8.0" 18.3M
// cnpm install ethers --save
// yarn add ethers
Gas
一经创建,每笔交易都收取一定数量的 gas ,目的是限制执行交易所需要的工作量和为交易支付手续费。EVM 执行交易时,gas 将按特定规则逐渐耗尽。
gas price 是交易发送者设置的一个值,发送者账户需要预付的手续费= gasPrice * gas 。如果交易执行后还有剩余, gas 会原路返还。
创建providers
ethers是一套和以太坊节点进行通信的API,是对JSON-RPC的封装。如果我们需要基于以太坊来开发去中心化应用,就需要通过ethers来获取节点状态,获取账号信息,调用合约、监听合约事件等等。
智能合约是运行在节点提供的虚拟机上,因此调用智能合约也需要像节点发送请求。
import { ethers } from 'ethers'
// const ethers = require('ethers')
//使用本地节点或是远程节点
const url = "http://127.0.0.1:8545"
//"http://localhost:8545" 会报错
// const url = "https://rpc-mumbai.maticvigil.com"
// const url = "https://rpc.ftm.tools/"
const provider = new ethers.JsonRpcProvider(url)
//交易签名
const signer = await provider.getSigner() //默认地址,一般是第一个
//const signer = await provider.getSigner("0x025C4AB61A50Ce391E9F3cd88a858E5C5ADABaF1") //可以这样指定
//metamask中获取
provider = new ethers.BrowserProvider(window.ethereum)
基本使用
// Look up the current block number
await provider.getBlockNumber()
// 16383845
//获取一个地址或ENS的余额
let addr = "0xf9eFdD67e2C46a8086aed666ea8e294986AB285C"
let balance = await provider.getBalance(addr)
// 100000000000000000000n
//eth转成wei
ethers.parseEther("1.2")
//1200000000000000000n
//wei转成 eth
ethers.formatEther('23')
// 0.000000000000000023
//发送交易
const option = {
to:toAccount,
value: 1500000000, //wei
gas: gas,
gasPrice: gasPrice
}
eg:
const tx = await signer.sendTransaction({
to: "0xf33B812142b8a008cD98ED889605869B31393849",
value: ethers.parseEther("1.0")
})
const receipt = await tx.wait()
console.log(899, receipt)
/*
TransactionReceipt {
provider: JsonRpcProvider {},
to: '0xf33B812142b8a008cD98ED889605869B31393849',
from: '0xf9eFdD67e2C46a8086aed666ea8e294986AB285C',
contractAddress: null,
hash: '0xafac68a6a871424bf2aa4da66b7aed38c379bd335e56f8bfecdea680febac5ed',
index: 0,
blockHash: '0xb5e876eae0264cdfbbb7e8d0e3676ed31abc6121d78fc9080498fea3bdafa3d2',
blockNumber: 1,
logsBloom: '0x0000000....00',
gasUsed: 21000n,
cumulativeGasUsed: 21000n,
gasPrice: 20000000000n,
type: 0,
status: 1,
root: undefined
}
*/
常用方法
1. 单位换算
//eth转成wei
ethers.parseEther("1.2")
//1200000000000000000n
//wei转成 eth
ethers.formatEther('23')
// 0.000000000000000023
//另外一种转换方法
ethers.parseUnits("1.3", 18) // 乘以10**18
//1300000000000000000n
ethers.formatUnits("1300000000000000000", 18) // 除以10**18
//1.3
2. gasLimit
signer.estimateGas(tx)
通过执行一个消息调用来得到交易的 gas 用量, 在此基础上加30000gas
3. GasPrice
await provider.getFeeData() //获取当前gas价格
/*
FeeData {
gasPrice: 20000000000n,
maxFeePerGas: null,
maxPriorityFeePerGas: null
}*/
4. 查找最新区块号
await provider.getBlockNumber()
//2655567
钱包功能
import { ethers } from 'ethers'
import fs from 'fs'
//直接生成私钥和地址
let lbcWallet = ethers.Wallet.createRandom()
lbcWallet.address
// "0x863e27dbD608649d08c69F83ccA51b045721f318"
lbcWallet.privateKey
// "0x8bc29xxxxxxx"
//随机数生成钱包
let random = ethers.randomBytes(32)
console.log(563, random)
let privateKey = Buffer.from(random).toString('hex') //转成16进制
console.log(112, privateKey)
let wallet = new ethers.Wallet(privateKey)
console.log("账号地址: " + wallet.address, wallet)
//生成随机助记词并创建钱包
let mnemonic = ethers.Mnemonic.fromEntropy(ethers.randomBytes(16))
// let mnemonic = ethers.Mnemonic.fromEntropy(ethers.randomBytes(16), "jxxxx") 第二个参数是密码
console.log(1323, mnemonic)
var path = "m/44'/60'/0'/0/0"
// 通过助记词创建钱包
let wallet = ethers.HDNodeWallet.fromMnemonic(mnemonic, path)
console.log("账号地址: " + wallet.address, wallet)
//根据助记词找回钱包信息
let monic = "dinosaur tape orbit chronic private ....."
let mnemonic = ethers.Wallet.fromPhrase(monic)
console.log(566, mnemonic)
let privateKey = mnemonic.privateKey
console.log("钱包私钥:",privateKey)
//根据私钥找回钱包地址
let wallet = new ethers.Wallet(privateKey)
//钱包地址
let address = wallet.address
console.log(156, address)
//生成json钱包文件
let main = async function (){
let random = ethers.randomBytes(32)
let privateKey = Buffer.from(random).toString('hex') //转成16进制
let wallet = new ethers.Wallet(privateKey)
let password = "xxxxx"
let res = await wallet.encrypt(password)
console.log(156, res)
let d = new Date()
let time = d.getTime()
let path = './keystore/' + time + '-' + wallet.address
fs.writeFileSync(path, res)
}
//json文件找回钱包信息
let main2 = async function (){
let res = fs.readFileSync('./keystore/16983xxxxxxxxxxxB2c6', "utf8")
let password = "xxxxxx"
let wallet = await ethers.Wallet.fromEncryptedJson(res, password)
console.log("Address: " + wallet.address, wallet,"privateKey:", wallet.privateKey)
}
与合约交互
//只读方法 (like view and pure)
import { ethers } from 'ethers'
const url = "http://127.0.0.1:8545"
const provider = new ethers.JsonRpcProvider(url)
let abi = [
"function str() view returns (string)",
"function set(uint x)",
"function get()view returns (uint)"
]
//这里的abi相当于接口
// 也可以使用合约的编译abi: import Storage from '@/static/Storage.json' -> Storage.abi
let contractAddr = "0x600a00aE84b896edd9F2732565cf2195d032315E"
let contract = new ethers.Contract(contractAddr, abi, provider)
let str = await contract.get()
console.log(256, str)
//合约的所有方法, signer签名
const url = "http://127.0.0.1:8545"
const contractAddr = "0x600a00aE84b896edd9F2732565cf2195d032315E"
const provider = new ethers.JsonRpcProvider(url)
const signer = await provider.getSigner()
const contract = new ethers.Contract( contractAddr, Storage.abi, signer)
console.log(56, "signer:", signer)
const option = {
}
const tx = await contract.set(996, option)
await tx.wait()
console.log(669, "singen res:", tx)
//合约的所有方法, 也可以连上钱包来实现
import Storage from '@/static/Storage.json'
const url = "http://127.0.0.1:8545"
const contractAddr = "0x600a00aE84b896edd9F2732565cf2195d032315E"
const provider = new ethers.JsonRpcProvider(url)
const contract = new ethers.Contract(contractAddr, Storage.abi, provider)
const PRIVATE_KEY = "0x182xxxxxxxxx"
const wallet = new ethers.Wallet(PRIVATE_KEY, provider)
console.log(56, "wallet:", wallet)
const nonce = await provider.getTransactionCount(wallet.address)
console.log(58, "nonce:", nonce)
const StorageConnected = contract.connect(wallet)
const option = {
nonce
}
const tx = await StorageConnected.set(86394, option)
await tx.wait()
console.log(669, "res:", tx)
ethers的体验相当不错,功能齐全,它的转正也是情理之中啰。
Leave ethers.js链上交互指南 / 学习智能合约#65 to:
Read more #smartcontract posts
Best Posts From lemooljiang
We have not curated any of lemooljiang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From lemooljiang
- DeepTutor:AI个性化辅导平台 / ai #57
- ComfyUI:可编程和自动化的PS / ai #56
- 将Neo4j封装进Agent / ai #55
- 闲鱼省钱大法:极限0.5折!
- 对Neo4j批量导入结构化数据 / ai #54
- langchain对neo4j进行交互,写入和查询数据 / ai #53
- 知识图谱和图数据库Neo4j的作用和使用场景 / ai #52
- SpaceX、美股和比特币
- 又是币圈血洗日!
- 链股合流,当币安也开始卖股票啰
- 天涯社区重启,爷青回?
- 诺基亚在AI时代重新杀回来啦
- 《2049:未来10000天的可能》书中的镜像世界为什么不叫元宇宙
- 今天适合吃披萨
- 开通即被封,别再给Claude送人头了!
- 两根内存条引发的“官司”
- AI·Joe V12更新, 更新GPT-5.5和DeepSeek V4 等
- 中医进校园活动反响热烈
- 猪价低伤农,猪价贵伤民
- Solidity开发指南