Migration: From Web3.js

本迁移指南的重点是将web3.js 1.2.9版本迁移到ethers.js v5。

Providers

在ethers中,Providers为连接到ethers网络提供了一个抽象的概念。 它可以用来发布只读查询,并向ethers网络发送签名的状态变化交易。

连接到ethers

// web3 var Web3 = require('web3'); var web3 = new Web3('http://localhost:8545'); // ethers var ethers = require('ethers'); const url = "http://127.0.0.1:8545"; const provider = new ethers.providers.JsonRpcProvider(url);

连接到ethers: Metamask

// web3 const web3 = new Web3(Web3.givenProvider); // ethers const provider = new ethers.providers.Web3Provider(window.ethereum);

签名者

在ethers中,签名是ethers账户的一个抽象概念。它可以用来签署消息和交易,并将签署的交易发送到ethers网络。

在web3中,一个账户可以用来签署消息和交易。

创建签名

// web3 const account = web3.eth.accounts.create(); // ethers (随机创建新账户) const signer = ethers.Wallet.createRandom(); // ethers (连接到JSON-RPC账户) const signer = provider.getSigner();

签署信息

// web3 (使用私钥) signature = web3.eth.accounts.sign('Some data', privateKey) // web3 (使用JSON-RPC账户) // @TODO // ethers signature = await signer.signMessage('Some data')

合约

一个合约对象是ethers网络上智能合约的一个抽象。它允许与智能合约简单交互。

部署合约

// web3 const contract = new web3.eth.Contract(abi); contract.deploy({ data: bytecode, arguments: ["my string"] }) .send({ from: "0x12598d2Fd88B420ED571beFDA8dD112624B5E730", gas: 150000, gasPrice: "30000000000000" }), function(error, transactionHash){ ... }) .then(function(newContract){ console.log('new contract', newContract.options.address) }); // ethers const signer = provider.getSigner(); const factory = new ethers.ContractFactory(abi, bytecode, signer); const contract = await factory.deploy("hello world"); console.log('contract address', contract.address); // 等待合约创建交易完成 await contract.deployTransaction.wait();

与合约交互

// web3 const contract = new web3.eth.Contract(abi, contractAddress); // 只读查询 contract.methods.getValue().call(); // 状态变化的操作 contract.methods.changeValue(42).send({from: ....}) .on('receipt', function(){ ... }); // ethers // 在初始化只读查询合约的时候传递一个provider const contract = new ethers.Contract(contractAddress, abi, provider); const value = await contract.getValue(); // 传递一个signer,为改变状态的操作创建一个合同实例。 const contract = new ethers.Contract(contractAddress, abi, signer); const tx = await contract.changeValue(33); // 等待交易完成 const receipt = await tx.wait();

重载函数

重载函数是具有相同名称但参数类型不同的函数。

在以太网中,调用一个重载合约函数的语法与非重载函数不同。 本节展示了web3 和ethers在调用重载函数时的区别。

查看issue #407更多详情。

// web3 message = await contract.methods.getMessage('nice').call(); // ethers const abi = [ "function getMessage(string) public view returns (string)", "function getMessage() public view returns (string)" ] const contract = new ethers.Contract(address, abi, signer); // 对于不明确的函数(两个具有相同名称的函数名称) // ,也必须指定签名 message = await contract['getMessage(string)']('nice');

数字

BigNumber

转换为BigNumber类型

// web3 web3.utils.toBN('123456'); // ethers (一个数字;必须是在可靠安全的范围内) ethers.BigNumber.from(123456) // ethers (10进制字符串) ethers.BigNumber.from("123456") // ethers (十六进制字符串) ethers.BigNumber.from("0x1e240")

Utilities

哈希

计算web3和ethers中UTF-8字符串的Keccak256哈希值:

// web3 web3.utils.sha3('hello world'); web3.utils.keccak256('hello world'); // ethers (字符串的哈希值) ethers.utils.id('hello world') // ethers (二进制数据的哈希值) ethers.utils.keccak256('0x4242')