Skip to content

Web3.js JavaScript代码库

Intro diagram

概览

Web3.js是一组代码库,允许开发者使用JavaScript,并通过HTTP、IPC或WebSocker协议与以太坊节点交互。Moonbeam拥有与以太坊相似的API供用户使用,其与以太坊风格的JSON RPC调用完全兼容。因此,开发者可以利用此兼容特性并使用Web3.js库与Moonbeam节点交互,与在以太坊操作相同。

在本教程中,您将学习如何使用Web3.js库在Moonbase Alpha上发送交易和部署合约。本教程也同样适用于MoonbeamMoonriverMoonbeam开发节点

查看先决条件

在开始本教程示例之前,您将需要提前准备以下内容:

  • 具有拥有一定数量资金的账户。 您可以每24小时一次从Moonbase Alpha水龙头上获取DEV代币以在Moonbase Alpha上进行测试
  • 要在Moonbeam或Moonriver网络上测试本指南中的示例,您可以从受支持的网络端点提供商之一获取您自己的端点和API密钥。

注意事项

本教程示例基于Ubuntu 18.04和MacOS的环境,用户需根据其所使用的Windows版本进行微调。

创建Javascript项目

首先,您需要创建一个目录,以存储您在本教程中将要创建的所有文件:

mkdir web3-examples && cd web3-examples

在本教程中,您将需要安装Web3.js代码库和Solidity编译器。您可以通过运行以下命令来安装两者的NPM安装包:

npm install web3 solc@0.8.0

在Moonbeam上设置Web3.js

您可以为任何Moonbeam网络配置web3.js。 要为Moonbeam或Moonriver网络配置您的项目,您可以从受支持的网络端点提供商之一获取您自己的端点和API密钥。

每个网络最简单的设置方式如下所示:

const Web3 = require('web3');

//Create Web3 instance
const web3 = new Web3('RPC-API-ENDPOINT-HERE'); // Insert your RPC URL here
const Web3 = require('web3');

//Create Web3 instance
const web3 = new Web3('RPC-API-ENDPOINT-HERE'); // Insert your RPC URL here
const Web3 = require('web3');

//Create Web3 instance
const web3 = new Web3('https://rpc.api.moonbase.moonbeam.network');
const Web3 = require('web3');

//Create Web3 instance
const web3 = new Web3('http://127.0.0.1:9933');

发送交易

在这一部分,您将需要创建一些脚本。第一个脚本将用于发送交易前查看账户余额。第二个脚本将执行交易。

您也可以使用余额脚本在交易发送后查看账户余额。

查看余额脚本

您仅需要一个文件以查看交易发送前后两个地址的余额。首先,您可以运行以下命令创建一个balances.js文件:

touch balances.js

接下来,您将为此文件创建脚本并完成以下步骤:

  1. 设置Web3提供者

  2. 定义addressFromaddressTo变量

  3. 创建打包了web3.eth.getBalance函数的异步balances函数

  4. 使用web3.eth.getBalance函数获取addressFromaddressTo地址的余额。您也可以使用web3.utils.fromWei函数将余额转换成以ETH为单位的数字便于阅读

  5. 最后,运行balances函数

// 1. Add the Web3 provider logic here:
// {...}

// 2. Create address variables
const addressFrom = 'ADDRESS-FROM-HERE';
const addressTo = 'ADDRESS-TO-HERE';

// 3. Create balances function
const balances = async () => {
  // 4. Fetch balance info
  const balanceFrom = web3.utils.fromWei(await web3.eth.getBalance(addressFrom), 'ether');
  const balanceTo = web3.utils.fromWei(await web3.eth.getBalance(addressTo), 'ether');

  console.log(`The balance of ${addressFrom} is: ${balanceFrom} ETH`);
  console.log(`The balance of ${addressTo} is: ${balanceTo} ETH`);
};

// 5. Call balances function
balances();

您可以查看GitHub上的完整脚本

您可以运行以下命令以运行脚本并获取账户余额:

node balances.js

如果成功,发送地址和接收地址的余额将以ETH为单位显示在终端。

发送交易脚本

您仅需要一个文件即可在账户之间执行交易。在本示例中,您将从拥有私钥的发送地址转移1个DEV Token至另一个地址。首先,您可以运行以下命令创建一个transaction.js文件:

touch transaction.js

接下来,您将为此文件创建脚本并完成以下步骤:

  1. 设置Web3提供者

  2. 定义addressFrom,包括privateKeyaddressTo变量。此处需要私钥以创建一个钱包实例。请注意:此处操作仅用于演示目的,请勿将您的私钥存储在JavaScript文件中

  3. 创建打包了交易标的以及签署和发送函数的异步send函数

  4. 使用web3.eth.accounts.signTransaction函数创建和签署交易,传入交易的gasaddressTovalue以及发送者的privateKey

  5. 使用web3.eth.sendSignedTransaction函数发送已签署的交易,然后使用await等待交易处理完毕并返回交易回执

  6. 最后,运行send函数

// 1. Add the Web3 provider logic here:
// {...}

// 2. Create account variables
const accountFrom = {
  privateKey: 'YOUR-PRIVATE-KEY-HERE',
  address: 'PUBLIC-ADDRESS-OF-PK-HERE',
};
const addressTo = 'ADDRESS-TO-HERE'; // Change addressTo

// 3. Create send function
const send = async () => {
  console.log(`Attempting to send transaction from ${accountFrom.address} to ${addressTo}`);

  // 4. Sign tx with PK
  const createTransaction = await web3.eth.accounts.signTransaction(
    {
      gas: 21000,
      to: addressTo,
      value: web3.utils.toWei('1', 'ether'),
    },
    accountFrom.privateKey
  );

  // 5. Send tx and wait for receipt
  const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
  console.log(`Transaction successful with hash: ${createReceipt.transactionHash}`);
};

// 6. Call send function
send();

您可以查看GitHub上的完整脚本

您可以在终端运行以下命令以运行脚本:

node transaction.js

如果交易成功,您将在终端看到显示的交易哈希。

您也可以使用balances.js脚本为发送地址和接收地址查看余额是否变化。整体操作流程如下所示:

Send Tx Web3js

部署合约

在下几个部分中您将要编译和部署的合约是一个简单的增量合约,命名为Incrementer.sol。您可以先为合约创建一个文件:

touch Incrementer.sol

接下来,您可以添加Solidity代码至文件:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

contract Incrementer {
    uint256 public number;

    constructor(uint256 _initialNumber) {
        number = _initialNumber;
    }

    function increment(uint256 _value) public {
        number = number + _value;
    }

    function reset() public {
        number = 0;
    }
}

constructor函数将在合约部署时运行,设置存储在链上的数字变量的初始值(默认值为0)。increment函数将提供的_value添加至当前数字,但是需要发送一个交易以修改存储的数据。最后,reset函数将存储的数值重置为零。

注意事项

此合约为简单示例,仅供演示使用,其数值无实际意义。

编译合约脚本

在这一部分,您将创建一个脚本,该脚本使用Solidity编译器为Incrementer.sol合约输出字节码和接口(ABI)。首先,您可以通过运行以下命令创建一个compile.js文件:

touch compile.js

接下来,您将为此文件创建脚本,并执行以下步骤:

  1. 导入fssolc安装包

  2. 使用fs.readFileSync函数,您将读取Incrementer.sol的文件内容并保存至source

  3. 通过指定要使用的languagesourcessettings为Solidity编译器构建input对象

  4. 通过input对象,您可以使用solc.compile编译合约

  5. 提取已编译的合约文件并导出以在部署脚本中使用

// 1. Import packages
const fs = require('fs');
const solc = require('solc');

// 2. Get path and load contract
const source = fs.readFileSync('Incrementer.sol', 'utf8');

// 3. Create input object
const input = {
   language: 'Solidity',
   sources: {
      'Incrementer.sol': {
         content: source,
      },
   },
   settings: {
      outputSelection: {
         '*': {
            '*': ['*'],
         },
      },
   },
};
// 4. Compile the contract
const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));
const contractFile = tempFile.contracts['Incrementer.sol']['Incrementer'];

// 5. Export contract data
module.exports = contractFile;

部署合约脚本

有了用于编译Incrementer.sol合约的脚本,您就可以使用这些结果发送部署的签名交易。首先,您可以为部署的脚本创建一个名为deploy.js的文件:

touch deploy.js

接下来,您将为此文件创建脚本并完成以下步骤:

  1. compile.js导入合约文件

  2. 设置Web3提供者

  3. 定义addressFrom,包括privateKeyaddressTo变量。此私钥将用于创建一个钱包实例。请注意:此处操作仅用于演示目的,请勿将您的私钥存储在JavaScript文件中

  4. 为已编译的合约保存bytecodeabi

  5. 创建将用于部署合约的异步deploy函数

  6. 使用web3.eth.Contract函数创建合约实例

  7. 创建构造函数并为增量器传入bytecode和初始值。在本示例中,您可以将初始值设置为5

  8. 使用web3.eth.accounts.signTransaction函数创建和签署交易,传入交易的datagas以及发送者的privateKey

  9. 使用web3.eth.sendSignedTransaction发送已签署的交易并传入原始交易,然后使用await等待交易处理完毕并返回交易回执

  10. 最后,运行deploy函数

// 1. Import the contract file
const contractFile = require('./compile');

// 2. Add the Web3 provider logic here:
// {...}

// 3. Create address variables
const accountFrom = {
  privateKey: 'YOUR-PRIVATE-KEY-HERE',
  address: 'PUBLIC-ADDRESS-OF-PK-HERE',
};

// 4. Get the bytecode and API
const bytecode = contractFile.evm.bytecode.object;
const abi = contractFile.abi;

// 5. Create deploy function
const deploy = async () => {
  console.log(`Attempting to deploy from account ${accountFrom.address}`);

  // 6. Create contract instance
  const incrementer = new web3.eth.Contract(abi);

  // 7. Create constructor tx
  const incrementerTx = incrementer.deploy({
    data: bytecode,
    arguments: [5],
  });

  // 8. Sign transacation and send
  const createTransaction = await web3.eth.accounts.signTransaction(
    {
      data: incrementerTx.encodeABI(),
      gas: await incrementerTx.estimateGas(),
    },
    accountFrom.privateKey
  );

  // 9. Send tx and wait for receipt
  const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
  console.log(`Contract deployed at address: ${createReceipt.contractAddress}`);
};

// 10. Call deploy function
deploy();

您可以查看GitHub上的完整脚本

您可以在终端运行以下命令以运行脚本:

node deploy.js

如果成功,合约地址将显示在终端。

Deploy Contract Web3js

读取合约数据(调用函数){: #read-contract-data }

调用函数是无需修改合约存储(更改变量)的交互类型,这意味着无需发送交易,只需读取已部署合约的各种存储变量。

首先,您需要创建一个文件并命名为get.js

touch get.js

接下来,您可以遵循以下步骤创建脚本:

  1. compile.js文件导入abi

  2. 设置Web3提供者

  3. 使用已部署合约的地址创建contractAddress变量

  4. 使用web3.eth.Contract函数并传入abicontractAddress以创建合约实例

  5. 创建异步get函数

  6. 使用合约实例以调用其中一个合约函数并输入任何需要的信息。在本示例中,您将调用number函数(此函数无需任何输入)。您可以使用await,这将在请求解决后返回请求的数值

  7. 最后,调用get函数

// 1. Import the contract abi
const { abi } = require('./compile');

// 2. Add the Web3 provider logic here:
// {...}

// 3. Create address variables
const contractAddress = 'CONTRACT-ADDRESS-HERE';

// 4. Create contract instance
const incrementer = new web3.eth.Contract(abi, contractAddress);

// 5. Create get function
const get = async () => {
  console.log(`Making a call to contract at address: ${contractAddress}`);

  // 6. Call contract
  const data = await incrementer.methods.number().call();

  console.log(`The current number stored is: ${data}`);
};

// 7. Call get function
get();

您可以查看GitHub上的完整脚本

您可以在终端运行以下命令以运行脚本:

node get.js

如果成功,数值将显示在终端。

交互合约(发送函数){: #interact-with-contract }

发送函数是修改合约存储(更改变量)的交互类型,这意味着需要签署和发送交易。在这一部分,您将创建两个脚本:一个是增量,另一个是重置增量器。首先,您可以为每个脚本创建一个文件,并分别命名为increment.jsreset.js

touch increment.js reset.js

接下来,打开increment.js文件并执行以下步骤以创建脚本:

  1. compile.js文件导入abi

  2. 设置Web3提供者

  3. 定义初始账户的privateKey、已部署合约的contractAddress以及要增量的_value。此私钥将用于创建一个钱包实例。请注意:此处操作仅用于演示目的,请勿将您的私钥存储在JavaScript文件中

  4. 使用web3.eth.Contract函数并传入abicontractAddress创建合约实例

  5. 通过合约实例使用methods.increment函数并传入_value作为输入值来构建增量交易

  6. 创建异步increment函数

  7. 使用您之前创建的合约实例和增量交易,使用发送者的私钥对交易进行签名。您将使用web3.eth.accounts.signTransaction函数并指定交易的to地址、datagas

  8. 使用web3.eth.sendSignedTransaction发送已签署的交易并传入原始交易,然后使用await等待交易处理完毕并返回交易回执

  9. 最后,调用increment函数

// 1. Import the contract abi
const { abi } = require('./compile');

// 2. Add the Web3 provider logic here:
// {...}

// 3. Create variables
const accountFrom = {
  privateKey: 'YOUR-PRIVATE-KEY-HERE',
};
const contractAddress = 'CONTRACT-ADDRESS-HERE';
const _value = 3;

// 4. Create contract instance
const incrementer = new web3.eth.Contract(abi, contractAddress);

// 5. Build increment tx
const incrementTx = incrementer.methods.increment(_value);

// 6. Create increment function
const increment = async () => {
  console.log(
    `Calling the increment by ${_value} function in contract at address: ${contractAddress}`
  );

  // Sign Tx with PK
  const createTransaction = await web3.eth.accounts.signTransaction(
    {
      to: contractAddress,
      data: incrementTx.encodeABI(),
      gas: await incrementTx.estimateGas(),
    },
    accountFrom.privateKey
  );

  // Send Tx and Wait for Receipt
  const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
  console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};

// 9. Call increment function
increment();

您可以查看GitHub上的完整脚本

您可以在终端运行以下命令以运行脚本:

node increment.js

如果成功,交易哈希将显示在终端。您可以在increment.js脚本旁边使用get.js脚本以确保数值如预期变化:

Increment Contract Web3js

接下来,您可以打开reset.js文件并执行以下步骤以创建脚本:

  1. compile.js文件导入abi

  2. 设置Web3提供者

  3. 定义初始账户的privateKey、已部署合约的contractAddress。此私钥将用于创建一个钱包实例。请注意:此处操作仅用于演示目的,请勿将您的私钥存储在JavaScript文件中

  4. 使用web3.eth.Contract函数并传入abicontractAddress以创建合约实例

  5. 使用methods.reset函数通过合约实例构建重置交易

  6. 创建异步reset函数

  7. 使用您之前创建的合约实例和增量交易,使用发送者的私钥对交易进行签名。您将使用web3.eth.accounts.signTransaction函数并指定交易的to地址、datagas

  8. 使用web3.eth.sendSignedTransaction发送已签署的交易,然后使用await等待交易处理完毕并返回交易回执

  9. 最后,调用reset函数

// 1. Import the contract abi
const { abi } = require('./compile');

// 2. Add the Web3 provider logic here:
// {...}

// 3. Create variables
const accountFrom = {
  privateKey: 'YOUR-PRIVATE-KEY-HERE',
};
const contractAddress = 'CONTRACT-ADDRESS-HERE';

// 4. Create Contract Instance
const incrementer = new web3.eth.Contract(abi, contractAddress);

// 5. Build reset tx
const resetTx = incrementer.methods.reset();

// 6. Create reset function
const reset = async () => {
  console.log(`Calling the reset function in contract at address: ${contractAddress}`);

  // 7. Sign tx with PK
  const createTransaction = await web3.eth.accounts.signTransaction(
    {
      to: contractAddress,
      data: resetTx.encodeABI(),
      gas: await resetTx.estimateGas(),
    },
    accountFrom.privateKey
  );

  // 8. Send tx and wait for receipt
  const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
  console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};

// 9. Call reset function
reset();

您可以查看GitHub上的完整脚本

您可以在终端运行以下命令以运行脚本:

node reset.js

如果成功,交易哈希将显示在终端。您可以在reset.js脚本旁边使用get.js脚本以确保数值如预期变化:

Reset Contract Web3js

本网站的所有信息由第三方提供,仅供参考之用。Moonbeam文档网站(https://docs.moonbeam.network/)上列出和描述的任何项目与Moonbeam立场无关。Moonbeam Foundation不保证网站信息的准确性、完整性或真实性。如使用或依赖本网站信息,需自行承担相关风险,Moonbeam Foundation不承担任何责任和义务。这些材料的所有陈述和/或意见由提供方个人或实体负责,与Moonbeam Foundation立场无关,概不构成任何投资建议。对于任何特定事项或情况,应寻求专业权威人士的建议。此处的信息可能会包含或链接至第三方提供的信息与/或第三方服务(包括任何第三方网站等)。这类链接网站不受Moonbeam Foundation控制。Moonbeam Foundation对此类链接网站的内容(包括此类链接网站上包含的任何信息或资料)概不负责也不认可。这些链接内容仅为方便访客而提供,Moonbeam Foundation对因您使用此信息或任何第三方网站或服务提供的信息而产生的所有责任概不负责。