ZBLOG

以太坊API接口编写实验报告

本实验报告详细记录了基于以太坊区块链的API接口编写过程,实验旨在通过使用Web3.js库与以太坊节点(如Infura或本地Geth节点)进行交互,实现账户信息查询、余额获取、交易发送以及智能合约调用等核心功能,通过本次实验,深入理解了以太坊JSON-RPC API的原理,掌握了使用JavaScript进行以太坊应用开发的基本方法,并体验了去中心化应用(DApp)后端接口的设计与实现。

以太坊;API接口;Web3.js;JSON-RPC;智能合约;DApp

实验目的

  1. 理解以太坊区块链及其JSON-RPC API的基本概念和工作原理。
  2. 掌握使用Web3.js库与以太坊节点进行通信的方法。
  3. 学习编写能够查询账户信息、获取代币余额、发送交易以及调用智能合约函数的API接口。
  4. 熟悉以太坊开发环境(如MetaMask、节点客户端)的配置与使用。
  5. 提升区块链应用后端接口设计与实现的能力。

实验环境与工具

  1. 操作系统: Windows 11 / macOS / Linux (Ubuntu 20.04 LTS)
  2. 编程语言: JavaScript (ES6+)
  3. 开发框架: Node.js (v14.x 或更高版本)
  4. 核心库: Web3.js (v1.x 或更高版本)
  5. 以太坊节点:
    • 远程节点服务:Infura (https://infura.io/)
    • 本地节点客户端(可选):Geth 或 Parity
  6. 浏览器插件钱包: MetaMask (用于测试账户管理和交易签名)
  7. 代码编辑器: Visual Studio Code
  8. 其他工具: npm (Node包管理器), Git

实验原理

以太坊作为一个开放的区块链平台,提供了JSON-RPC API作为与区块链网络进行交互的标准接口,应用程序通过向以太坊节点发送JSON-RPC请求(通常通过HTTP或WebSocket协议),可以查询区块链状态(如账户余额、区块信息、交易详情)或发起状态改变的操作(如发送交易、调用智能合约)。

Web3.js是一个JavaScript库,它封装了以太坊JSON-RPC API的复杂性,提供了简洁易用的JavaScript接口,使得开发者可以在前端浏览器或Node.js后端应用中与以太坊网络进行交互,其核心功能包括:

  • 连接到以太坊节点(Provider)。
  • 账户管理(获取账户、签名交易等)。
  • 读取区块链数据(区块、交易、日志、智能合约状态)。
  • 发送交易(转账、部署合约、调用合约函数)。
  • 事件监听。

实验步骤与过程

环境搭建与项目初始化

  • 安装Node.js和npm:从Node.js官网下载并安装适合操作系统的Node.js版本。
  • 安装MetaMask:在浏览器(如Chrome, Firefox)中安装MetaMask扩展,并创建/导入测试账户。
  • 创建项目目录:在终端中创建一个新的项目文件夹,例如ethereum-api-experiment
  • 初始化npm项目:进入项目目录,运行npm init -y,生成package.json文件。
  • 安装Web3.js:运行npm install web3安装Web3.js库。

连接以太坊节点

在项目中创建一个JavaScript文件(如app.js),首先引入Web3.js库,并创建一个Web3实例,连接到以太坊节点可以通过Infura提供的节点URL,或本地运行的节点。

const Web3 = require('web3');
// 使用Infura节点URL (需要替换为你的Infura项目ID)
const INFURA_URL = 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID';
// 或者连接到本地Geth节点 (默认端口8545)
// const LOCAL_NODE_URL = 'http://localhost:8545';
// 创建Web3实例
const web3 = new Web3(INFURA_URL); // 或 new Web3(LOCAL_NODE_URL);
// 测试连接
web3.eth.getBlockNumber()
    .then(console.log)
    .catch(err => console.error('连接失败:', err));

运行node app.js,若成功输出当前区块号,则表示连接成功。

API接口编写示例

以下为几个核心API接口的编写示例:

1 查询账户余额

编写一个函数,根据以太坊地址查询其ETH余额。

// 查询账户ETH余额
async function getBalance(address) {
    try {
        const balance = await web3.eth.getBalance(address);
        // 将余额从Wei转换为ETH
        const balanceInETH = web3.utils.fromWei(balance, 'ether');
        console.log(`地址 ${address} 的余额: ${balanceInETH} ETH`);
        return balanceInETH;
    } catch (error) {
        console.error('查询余额失败:', error);
        return null;
    }
}
// 示例:查询MetaMask中第一个账户的余额
// (注意:实际API中,地址通常来自请求参数)
// metaMaskAccounts[0] 可以通过 MetaMask API 获取,但后端API通常接收前端传来的地址
// const accounts = await web3.eth.getAccounts(); // 如果节点开启了账户管理
// if (accounts.length > 0) {
//     getBalance(accounts[0]);
// }

2 发送ETH交易

编写一个函数,用于发送ETH交易,这需要发送者的私钥(在实际应用中需妥善保管,通常使用钱包软件签名交易,后端只负责广播或提供签名服务)。

// 发送ETH交易
async function sendTransaction(privateKey, fromAddress, toAddress, amountInETH) {
    try {
        // 将ETH转换为Wei
        const amountInWei = web3.utils.toWei(amountInETH.toString(), 'ether');
        // 获取当前nonce
        const nonce = await web3.eth.getTransactionCount(fromAddress, 'latest');
        // 构建交易对象
        const transaction = {
            to: toAddress,
            value: amountInWei,
            gas: 21000, // 转账ETH的固定gas限制
            gasPrice: await web3.eth.getGasPrice(), // 获取当前gas价格
            nonce: nonce,
            chainId: 1 // 主网chainId,测试网为3 (Ropsten), 4 (Rinkeby)等
        };
        // 签名交易
        const signedTx = await web3.eth.accounts.signTransaction(transaction, privateKey);
        // 发送交易
        const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
        console.log('交易成功! 交易哈希:', receipt.transactionHash);
        return receipt.transactionHash;
    } catch (error) {
        console.error('发送交易失败:', error);
        return null;
    }
}
// 示例 (注意:私钥极度敏感,切勿硬编码在实际生产环境中!)
// const senderPrivateKey = 'YOUR_PRIVATE_KEY';
// const senderAddress = '0xSenderAddress';
// const receiverAddress = '0xReceiverAddress';
// const amountToSend = 0.01;
// sendTransaction(senderPrivateKey, senderAddress, receiverAddress, amountToSend);

3 智能合约交互

假设我们有一个已部署的简单智能合约(例如一个ERC20代币合约),我们需要编写接口来调用其读/写函数。

  • 获取合约ABI和地址: 智能合约的ABI(Application Binary Interface)是合约与交互的接口描述,地址是合约部署在区块链上的位置,这些通常可以从以太坊浏览器(如Etherscan)或合约部署文档中获取。
  • 创建合约实例:
// 假设的ERC20代币合约ABI (简化版,实际需完整ABI)
const tokenABI = [
    {
        "constant": true,
        "inputs": [{"name": "_owner", "type": "address"}],
        "name": "balanceOf",
        "outputs": [{"name": "balance", "type": "uint256"}],
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            {"name": "_to", "type": "address"},
            {"name": "_value", "type": "uint256"}
        ],
        "name": "transfer",
        "outputs": [{"name": "success", "type": "bool"}],
        "type": "function"
    }
    // 其他函数...
];
// 代币合约地址 (示例,需替换为实际地址)
const tokenAddress = '0xYourTokenContractAddress';
// 创建合约实例
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
  • 调用合约读函数(不修改状态,无需gas):
// 查询代
分享:
扫描分享到社交APP