Web.js 和 Ether.js

米霖

2024-10-27

web3.js

简介

入门

web3.js 库是一个模块集合,包含以太坊生态系统的功能。

  • web3-eth:用于以太坊区块链和智能合约。
  • web3-shh:用于 Whisper 协议,支持点对点通信和广播。
  • web3-bzz:用于 Swarm 协议,提供去中心化文件存储。
  • web3-utils:包含对 DApp 开发者有用的辅助函数。

添加 web3.js

首先,需要将 web3.js 引入到的项目中。可以通过以下方法实现:

  • npmnpm install web3
  • yarnyarn add web3
  • 纯 JavaScript:链接 dist/web3.min.js

然后,需要创建一个 web3 实例并设置一个提供者。

大多数支持以太坊的浏览器(如 MetaMask)在 window.ethereum 上有一个符合 EIP-1193 的提供者。

对于 web3.js,请检查 Web3.givenProvider

如果该属性为 null,则应连接到远程或本地节点。

// 在 Node.js 中使用:
const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");

就这样!现在可以使用 web3 对象了。

初始化 web3 对象方法总结

初始化 Web3 对象可以通过几种不同的方法,具体取决于您的需求和环境。以下是几种常见的方法:

  1. 使用现有提供者

    const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");

    这种方法会检查是否有可用的提供者(如 MetaMask),如果没有则连接到本地节点。

  2. 使用自定义提供者

    const provider = new Web3.providers.HttpProvider("http://localhost:8545");
    const web3 = new Web3(provider);

    这种方式允许您使用自定义的 HTTP 提供者,适用于连接远程或本地以太坊节点。

  3. 使用 WebSocket 提供者

    const provider = new Web3.providers.WebsocketProvider("ws://localhost:8546");
    const web3 = new Web3(provider);

    这种方法适合需要实时更新(如监听事件)的应用。

  4. 在 Node.js 环境中

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

    这种方式在 Node.js 环境中直接创建 Web3 实例,通常与本地或远程节点一起使用。

  5. 使用 MetaMask 的提供者

    if (typeof window.ethereum !== 'undefined') {
        const web3 = new Web3(window.ethereum);
        // 请求用户授权
        await window.ethereum.request({ method: 'eth_requestAccounts' });
    } else {
        console.log("请安装 MetaMask!");
    }

    这种方法专门用于与 MetaMask 交互,要求用户授权访问其以太坊账户。

provider

在 Web3.js 中,provider 是一个重要的概念,用于连接您的应用程序与以太坊网络。它充当了应用程序与区块链之间的桥梁,允许它们进行通信。以下是对 provider 的一些理解要点:

  1. 定义
    • Provider 是一个对象,负责处理与以太坊节点的所有交互,包括发送交易、查询区块链状态、获取智能合约数据等。
  2. 类型
    • HTTP Provider:通过 HTTP 协议与以太坊节点进行通信。适用于一般的请求和响应模式,但不支持实时事件。

      const provider = new Web3.providers.HttpProvider("http://localhost:8545");
    • WebSocket Provider:通过 WebSocket 协议连接,可以实现实时通信,适用于需要监听事件的应用。

      const provider = new Web3.providers.WebsocketProvider("ws://localhost:8546");
    • IPC Provider:用于本地连接,通常在开发时使用。通过进程间通信(IPC)直接与以太坊节点进行连接。

      const provider = new Web3.providers.IpcProvider("/path/to/geth.ipc", net);
  3. 使用场景
    • 当您需要与以太坊区块链进行交互时,您需要提供一个合适的 provider。
    • 如果您的应用需要实时数据(例如监听区块或事件),WebSocket provider 是一个更好的选择。
  4. 与钱包的关系
    • 在浏览器中使用钱包(如 MetaMask)时,钱包提供的 provider 会自动连接到以太坊网络,并允许您的应用程序访问用户的账户和签名交易。
  5. 选择合适的 provider
    • 选择哪种 provider 取决于您的需求,例如是需要实时更新还是只进行简单的请求。

通过理解 provider,您可以更有效地管理与以太坊区块链的交互,从而构建出更强大和高效的 DApp。

常用方法和属性

web3 对象是与以太坊区块链进行交互的核心工具,提供了多种方法和属性来实现不同的功能。以下是一些常用的方法和属性:

常用属性

  1. web3.eth:用于与以太坊网络交互的模块,提供与区块、交易和账户相关的方法。

    • web3.eth.accounts:获取账户相关信息。
    • web3.eth.blockNumber:获取最新区块的编号。
    • web3.eth.getBlock(blockNumber):获取特定区块的信息。
    • web3.eth.sendTransaction(transaction):发送交易。
  2. web3.shh:用于与 Whisper 协议交互的模块,支持点对点通信。

  3. web3.bzz:用于与 Swarm 网络交互的模块,支持去中心化文件存储。

  4. web3.utils:包含一系列实用工具函数,比如格式转换、加密和解密。

    • web3.utils.toWei(value, unit):将以太转换为 wei。
    • web3.utils.fromWei(value, unit):将 wei 转换为以太。
    • web3.utils.isAddress(address):检查一个字符串是否为有效的以太坊地址。
  5. web3.version:获取当前的 web3.js 版本。

常用方法

  1. web3.eth.getAccounts():获取用户的以太坊账户列表。

  2. web3.eth.getBalance(address):获取指定地址的以太余额。

  3. web3.eth.call(callObject):执行一个调用,不会修改区块链状态,类似于智能合约的查询。

  4. web3.eth.getTransaction(transactionHash):根据交易哈希获取交易信息。

  5. web3.eth.getTransactionReceipt(transactionHash):根据交易哈希获取交易收据。

  6. web3.eth.subscribe(eventName, options, callback):订阅特定事件,例如区块、交易等。

示例代码

// 获取账户列表
web3.eth.getAccounts().then(console.log);

// 获取账户余额
web3.eth.getBalance('0x123...').then(balance => {
    console.log(web3.utils.fromWei(balance, 'ether'));
});

// 发送交易
web3.eth.sendTransaction({ from: '0x123...', to: '0x456...', value: web3.utils.toWei('0.1', 'ether') })
    .then(console.log);

通过这些方法和属性,web3 对象为开发者提供了丰富的功能,便于构建与以太坊网络交互的 DApp。

与合约进行交互

与以太坊合约进行交互主要通过 web3.eth.Contract 对象实现。以下是与合约交互的一般步骤和常用方法:

1. 获取合约的 ABI 和地址

合约的 ABI(应用二进制接口)定义了合约的结构和可调用的方法。合约地址是部署在以太坊网络上的地址。

2. 实例化合约对象

使用 web3.eth.Contract 创建合约实例:

const contractABI = [...]; // 合约的 ABI
const contractAddress = '0xYourContractAddress'; // 合约地址

const contract = new web3.eth.Contract(contractABI, contractAddress);

3. 调用合约的方法

合约的方法通常分为“状态改变函数”和“只读函数”。

只读函数(调用不会改变区块链状态)

这些函数可以使用 call() 方法调用,不会消耗 gas:

contract.methods.methodName(param1, param2).call()
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error(error);
    });

状态改变函数(会改变区块链状态)

这些函数需要使用 send() 方法调用,会消耗 gas:

const fromAddress = '0xYourAddress'; // 发起交易的地址

contract.methods.methodName(param1, param2).send({ from: fromAddress })
    .on('transactionHash', function(hash) {
        console.log('Transaction hash:', hash);
    })
    .on('receipt', function(receipt) {
        console.log('Transaction receipt:', receipt);
    })
    .on('error', function(error) {
        console.error(error);
    });

4. 监听事件

如果合约定义了事件,可以使用 events 属性来监听:

contract.events.EventName({
    filter: { /* optional filter options */ },
    fromBlock: 0
}, function(error, event) {
    if (error) {
        console.error(error);
    } else {
        console.log(event);
    }
});

示例代码

const contractABI = [...];
const contractAddress = '0xYourContractAddress';
const contract = new web3.eth.Contract(contractABI, contractAddress);

// 调用只读函数
contract.methods.getValue().call()
    .then(value => {
        console.log('Value:', value);
    });

// 调用状态改变函数
const fromAddress = '0xYourAddress';
contract.methods.setValue(42).send({ from: fromAddress })
    .on('transactionHash', function(hash) {
        console.log('Transaction hash:', hash);
    })
    .on('receipt', function(receipt) {
        console.log('Transaction receipt:', receipt);
    })
    .on('error', function(error) {
        console.error(error);
    });

// 监听事件
contract.events.ValueChanged()
    .on('data', function(event) {
        console.log('Event data:', event);
    });

通过这些步骤,您可以轻松与以太坊合约进行交互,执行方法和监听事件。

Web.js 的cheatsheet

以下是一个 Web3.js 的重要内容 Cheatsheet,涵盖了基本用法和常用功能。

Web3.js Cheatsheet

安装

npm install web3

导入

Node.js

const Web3 = require('web3');

浏览器

<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

连接以太坊网络

MetaMask

const web3 = new Web3(window.ethereum);
await window.ethereum.request({ method: 'eth_requestAccounts' });

JSON-RPC

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

获取账户

const accounts = await web3.eth.getAccounts();
console.log(accounts);

合约交互

合约实例化

const contractABI = [...]; // 合约 ABI
const contractAddress = '0xYourContractAddress';
const contract = new web3.eth.Contract(contractABI, contractAddress);

调用只读方法

const value = await contract.methods.methodName(param1, param2).call();
console.log(value);

发送交易(状态改变方法)

const accounts = await web3.eth.getAccounts();
const tx = await contract.methods.methodName(param1, param2).send({ from: accounts[0] });
console.log(tx);

监听事件

contract.events.EventName({
    filter: {param1: value}, // 可选参数
}, (error, event) => {
    console.log(event);
});

发送以太币

const tx = await web3.eth.sendTransaction({
    from: '0xYourAddress',
    to: '0xRecipientAddress',
    value: web3.utils.toWei('0.1', 'ether') // 发送 0.1 ETH
});
console.log(tx);

工具函数

转换单位

const wei = web3.utils.toWei('1', 'ether'); // 转换为 wei
const ether = web3.utils.fromWei(wei, 'ether'); // 转换为 ether

生成随机地址(仅用于测试)

const randomAccount = web3.eth.accounts.create();
console.log(randomAccount.address, randomAccount.privateKey);

钱包与私钥

从私钥创建账户

const account = web3.eth.accounts.privateKeyToAccount('your-private-key');
web3.eth.accounts.wallet.add(account);

注意事项

  • 使用 async/await 处理异步操作。
  • 确保与以太坊节点的连接稳定。

常用方法概览

  • web3.eth.getAccounts()
  • web3.eth.sendTransaction({})
  • web3.eth.Contract(ABI, address)
  • contract.methods.methodName().call()
  • contract.methods.methodName().send({ from: 'address' })
  • web3.utils.toWei()
  • web3.utils.fromWei()

这个 Cheatsheet 汇总了 Web3.js 的核心功能,帮助你快速上手和参考常用命令。

ethers

简介

开始使用

安装

Ethers 的各种类和函数可以从 @ethersproject 组织下的子包手动导入,但对于大多数项目,使用总包是最简单的开始方式。

npm install --save ethers

导入

Node.js

// 使用 Node.js 的 require
const { ethers } = require("ethers");

ES6 或 TypeScript

import { ethers } from "ethers";

Web 浏览器 出于安全原因,通常建议将 Ethers 库复制到自己的 web 服务器并自行提供服务。然而,对于快速演示或原型开发,您可以从我们的 CDN 加载它。

在浏览器中使用 ES6

<script type="module">
    import { ethers } from "https://cdn.ethers.io/lib/ethers-5.2.esm.min.js";
    // 在这里编写您的代码...
</script>

在浏览器中使用 ES3(UMD)

<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>

常用术语

  • Provider:在 Ethers 中,Provider 是一个类,提供与以太坊网络连接的抽象。它提供对区块链及其状态的只读访问。

  • Signer:Signer 是一个类,通常以某种方式直接或间接访问私钥,能够签署消息和交易,从而授权网络向您的账户收取以太以执行操作。

  • Contract:Contract 是一个抽象,表示与以太坊网络上特定合约的连接,使得应用可以像使用普通 JavaScript 对象一样使用它。

连接以太坊:MetaMask

实验和开始在以太坊上开发的最快最简单方法是使用 MetaMask,这是一个浏览器扩展,提供:

  • 连接到以太坊网络(Provider)
  • 存储您的私钥并可以进行签名(Signer)

连接到 MetaMask

// Web3Provider 包装一个标准的 Web3 提供者,
// 这是 MetaMask 注入到每个页面的 window.ethereum
const provider = new ethers.providers.Web3Provider(window.ethereum);

// MetaMask 需要请求用户账户的连接权限
await provider.send("eth_requestAccounts", []);

// MetaMask 插件还允许签署交易
// 以发送以太和支付以在区块链中更改状态。
// 为此,您需要账户的 signer...
const signer = provider.getSigner();

连接以太坊:RPC

JSON-RPC API 是另一种与以太坊交互的流行方法。交易以发送以太并更改区块链中的状态。为此,您需要账户的签名者:

const signer = provider.getSigner();

连接以太坊:RPC

JSON-RPC API 是与以太坊互动的另一种流行方法,它允许开发者通过标准的 JSON-RPC 协议发送请求。使用 RPC 连接可以提供更灵活和直接的控制。

示例代码

使用 JSON-RPC 进行连接的示例代码如下:

const { ethers } = require("ethers");

// 创建一个 JSON-RPC Provider
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");

// 获取账户
provider.listAccounts().then(console.log);

总结

  • Ethers.js 提供了易于使用的接口来与以太坊网络交互,支持多种连接方式(如 MetaMask 和 JSON-RPC)。
  • ProviderSigner 类提供了与以太坊区块链的连接和交易签名功能。
  • Contract 类简化了与智能合约的交互,使得开发者可以像使用普通 JavaScript 对象一样使用合约。

这种结构使得开发者能够方便地构建与以太坊相关的应用程序,并通过 Ethers.js 提供的强大工具简化开发流程。

ether.js cheatsheet

以下是一个 Ethers.js 的重要内容 Cheatsheet,涵盖了基本用法和常用功能。

Ethers.js Cheatsheet

安装

npm install --save ethers

导入

Node.js

const { ethers } = require("ethers");

浏览器

<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js" type="application/javascript"></script>

连接以太坊网络

MetaMask

const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);

JSON-RPC

const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");

创建 Signer

const signer = provider.getSigner();

获取账户

const accounts = await provider.listAccounts();
console.log(accounts);

合约交互

合约实例化

const contractABI = [...]; // 合约 ABI
const contractAddress = '0xYourContractAddress';
const contract = new ethers.Contract(contractAddress, contractABI, signer);

调用只读方法

const value = await contract.methodName(param1, param2);
console.log(value);

发送交易(状态改变方法)

const tx = await contract.methodName(param1, param2);
await tx.wait(); // 等待交易被确认

监听事件

contract.on("EventName", (param1, param2) => {
    console.log(param1, param2);
});

发送以太币

const tx = await signer.sendTransaction({
    to: "0xRecipientAddress",
    value: ethers.utils.parseEther("0.1") // 发送 0.1 ETH
});
await tx.wait(); // 等待交易确认

工具函数

转换单位

const wei = ethers.utils.parseEther("1.0"); // 转换为 wei
const ether = ethers.utils.formatEther(wei); // 转换为 ether

生成随机钱包

const randomWallet = ethers.Wallet.createRandom();
console.log(randomWallet.address, randomWallet.privateKey);

钱包与私钥

从私钥创建钱包

const wallet = new ethers.Wallet("your-private-key", provider);

签名消息

const message = "Hello, world!";
const signedMessage = await wallet.signMessage(message);
console.log(signedMessage);

重要概念

  • Provider:用于与以太坊网络交互的类。
  • Signer:用于管理私钥和签名交易的类。
  • Contract:用于与特定智能合约进行交互的类。

总结

Ethers.js 提供了一个简单且安全的方式来与以太坊区块链进行交互,适合快速开发和构建 DApp。以上是一些常用的方法和概念,便于快速参考。

几个例子

web3 js 中以太币数量


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Check Wallet Balance</title>
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
</head>
<body>
    <h1>Check Wallet Balance</h1>
    <button id="connectButton">Connect to MetaMask</button>
    <div id="balanceDisplay"></div>

    <script>
        let web3;

        // 连接到 MetaMask
        document.getElementById('connectButton').addEventListener('click', async () => {
            if (window.ethereum) {
                web3 = new Web3(window.ethereum);
                await window.ethereum.request({ method: 'eth_requestAccounts' });
                console.log("Connected to MetaMask");

                // 获取账户
                const accounts = await web3.eth.getAccounts();
                const account = accounts[0]; // 使用第一个账户

                // 获取余额
                const balance = await web3.eth.getBalance(account);
                const etherBalance = web3.utils.fromWei(balance, 'ether');

                // 显示余额
                document.getElementById('balanceDisplay').innerText = `Balance: ${etherBalance} ETH`;
                console.log("Balance:", etherBalance, "ETH");
            } else {
                alert('MetaMask is not installed. Please install it to use this app.');
            }
        });
    </script>
</body>
</html>