专栏首页极客起源区块链与以太坊实战(5):访问以太坊节点的N中方式

区块链与以太坊实战(5):访问以太坊节点的N中方式

---------支持作者请转发本文-----------

本文主要介绍用web3.js访问以太坊节点的几种方式,主要包括HTTP和Web两种访问方式。

1. 什么是Web3.js

Web3.js是一套用JavaScript实现的API,用于与以太坊节点进行通信,并通过以太坊节点操作以太坊网络。Web3.js内部使用JSON-RPC协议与以太坊节点(geth和其他类型的节点)进行通信。

JSON-RPC是一个无状态且轻量级的远程过程调用(RPC)协议。 该协议主要定义了一些数据结构及其相关的处理规则。允许运行在基于Socket、HTTP等诸多不同消息传输环境的同一进程中使用JSON作为数据格式。

Web3.js将所有的JSON-RPC API封装成JavaScript API。Web3.js可以与所有种类的、支持JSON-RPC协议的以太坊节点通信。

2. 安装Web3.js

安装Web3.js之前需要先安装Node.js,读者可以到下面的页面下载Node.js的最新版,下载后直接安装即可,非常简单。Node.js支持Windows、Mac OS X和Linux。

https://nodejs.org

使用下面的命令安装Web3.js的最新版本。

npm install web3

如果想安装Web3.js的特定版本,可以使用下面的命令。

npm install web3@0.20.6

上面的命令安装Web3.js的0.20.6版本。

如果读者觉得npm安装比较慢,可以先执行下面的代码安装cnpm,然后使用cnpm安装web3以及其他模块会非常快。cnpm是taobao做的npm国内镜像。

npm install -g cnpm --registry=https://registry.npm.taobao.org

成功安装cnpm后,可以使用下面的命令安装Web3.js 0.20.6。

cnpm install web3@0.20.6

下面验证一下Web3.js是否安装成功。

安装完Web3.js后,在终端执行node命令,会进入Node.js的交互环境(REPL),然后输入下下的代码。

require('web3')

执行上面的代码后,如果输出如图1所示的内容,表明Web3.js已经安装成功。

图1 测试Web3.js是否安装成功

在Node REPL中输入如下的代码,可以查看Web3.js的版本。

> var Web3 = require('web3')

undefined

> var web3 = new Web3()

undefined

> web3.version.api

'0.20.6'

前面代码的执行效果如图2所示。

图2 查看Web3.js的版本号

从图2的输出结果可以看出,Web3.js最新的版本号是0.20.6。

3连接testrpc节点

Web3.js的核心工作就是连接以太坊节点,在连接正式的节点之前,先用测试节点testrpc试一下Web3.js API是否能成功工作。

使用Web3.js API之前,需要先导入web3模块,代码如下:

var Web3 = require("web3");

Web3是一个类,接下来需要创建Web3类的实例,Web3类的构造方法可以没有参数,也可以指定HttpProvider或IpcProvider对象,这两个对象用于连接以太坊节点,如果不为Web类的构造方法指定参数,那么Web3对象不会连接任何以太坊节点,因此必须依赖以太坊节点的API将无法使用。创建完Web3对象后,并且连接以太坊节点后,就可以通过Web3对象调用Web3.js中的所有API了。

下面的例子创建了两个Web3对象,一个连接了testrpc节点,一个未连接testrpc节点。然后使用web3.eth.accounts属性获取并输出testrpc节点自动生成的10个用于测试的账户的地址,最后使用web3.version.api属性获取并输出当前Web3.js的版本号。

//  导入web3模块
var Web3 = require("web3");
//  创建第1个Web3对象,并通过HttpProvider对象连接testrpc节点
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
//  获取并输出testrpc中所有的测试账号
console.log(web3.eth.accounts);
//  获取并输出当前Web3.js的版本号
console.log(web3.version.api);
//  创建第2个Web3对象,该Web3对象没有连接testrpc节点(没有为Web类的构造方法传递参数值)
var myWeb3 = new Web3();
//  正常输出Web3.js的版本号
console.log(myWeb3.version.api);
// 将抛出异常
// console.log(myWeb3.eth.accounts);

在运行本例之前,应在终端中执行testrpc命令启动testrpc节点。然后开启另外一个终端,并执行node connect.js命令运行本例,输出结果如图3所示。

图3 连接testrpc节点

本例在创建第1个Web3对象时使用了HttpProvider类,该类用于指定以太坊节点的IP和端口号(默认是8545)。由于本例是在同一台PC上运行testrpc和connect.js,所以IP使用localhost即可。

accounts和api都是Web3.js中的属性,Web3.js中还有很多属性和方法,细节将在本章后面的部分详细介绍。

由于第2个Web3对象(myWeb3)没有通过HttpProvider对象指定testrpc节点的IP和端口号,所以该Web3对象并没有真正连接testrpc节点,所以有部分Web3.js API是无法调用的。例如,调用第2个Web3对象的myWeb3.eth.accounts属性就会抛出异常。而调用myWeb3.version.api属性没有任何问题,因为获取Web3.js的版本号与以太坊节点无关,所以不需要连接以太坊节点。

4. 连接geth节点

geth是以太坊官方提供的节点,可以使用geth创建私有区块链。本节会利用geth创建一个私有区块链,并通过Web3.js API连接geth节点,然后操作该私有区块链。

为了创建私有区块链,首先需要一个区块配置文件,代码如下:

block.json

{
    "config":
    {
        "chainId":15,
        "homesteadBlock":0
    },
    "difficulty":"20",
    "gasLimit":"2100000",
}

接下来需要使用geth命令初始化区块链。

geth init block.json --datadir private

这行命令的作用是在当前目录创建一个名为private的子目录,在该目录下还有两个子目录:keystore和geth。其中keystore目录用于存储当前节点创建的账户文件,geth目录用于存储当前节点需要的其他数据。

最后需要通过下面的命令启动以太坊节点。

geth --rpc --rpcaddr 0.0.0.0  --rpcport 8545 --datadir private

其中--rpc命令行参数表示允许远程连接geth节点,--rpcaddr命令行参数用于指定可以连接geth节点的IP,这里是0.0.0.0,也就是允许任何IP连接geth节点。--rpcport命令行参数用于指定geth节点的端口号,本例是默认端口号(8545),--datadir命令行参数指定了当前geth节点存储数据的根目录,本例是前面初始化私有链时创建的private目录。

下面编写用于连接geth节点的代码

这个例子通过Web3.js API连接geth节点,并输出geth节点中的账户。

connect_geth.js

var Web3 = require("web3");
var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
console.log(web3.eth.accounts);

前面两段代码完全一样,只是前者连接的是用于测试的testrpc节点,后者连接的是geth节点。由于geth节点默认并没有生成任何账户,所以执行第2端代码不会输出任何的账户。

现在使用下面的命令创建两个新账户(每执行一次命令建立一个账户)。

geth account new --datadir private

要注意,在创建新账户时,必须使用--datadir指定geth节点用于存储数据的根目录,否则geth命令会将账户文件保存到默认的目录中。在创建账户的过程中需要输入和确认密码,创建账户的过程如图4所示。

图4 创建两个新账户

每成功创建一个账户,就会返回该账户的地址。

现在执行第2段代码,会输出刚才创建的两个账户的地址,如图5所示。在private/keystore目录中也会多了两个账户文件。

图5 输出两个新创建的账户地址

也可以在其他的PC上使用IP访问本机的geth节点,假设本机的IP是192.168.31.8,那么可以使用http://192.168.31.8:8545来连接本机的geth节点。

这个例子在另一台机器(Windows)上通过IP连接本机的geth节点,并输出该节点中所有账户的地址。

connect_geth_remote.js

var Web3 = require("web3");
var web3 = new Web3(new Web3.providers.HttpProvider('http://192.168.31.8:8545'));
console.log(web3.eth.accounts);

在执行本例之前,需要将192.168.31.8修改成自己的geth节点所在机器的IP地址。程序的运行结果如图6所示。

图6 远程连接geth节点

5. HttpProvider与IpcProvider

Web3.js不仅可以通过HTTP与以太坊节点连接,还可以通过ICP(Inter-Process Communication,进程间通信)方式与以太坊节点连接。HTTP连接方式通过HttpProvider对象指定连接信息,这一点在前面已经讲过,IPC方式需要通过IpcProvider对象指定连接信息。

IpcProvider类的构造方法需要一个ipc文件,在启动geth节点后,从日志输出信息中可以找到这个ipc文件,本例是geth.ipc,如图7所示。

图7 geth.ipc文件的路径

从图7所示的日志信息看出,geth.ipc文件的路径是/chapter4/private/geth.ipc。所以需要使用下面的代码创建IpcProvider对象。

var net = require('net');
new Web3.providers.IpcProvider("/chapter4/private/geth.ipc",net)

下面的例子同时使用HTTP和IPC的方式与geth节点连接,并调用getAccounts函数用异步的方式获取geth节点的账户。

connect_http_ipc.js

var Web3 = require("web3");
var net = require('net');
//  通过HTTP方式连接geth节点
var web3 = new Web3(new Web3.providers.HttpProvider('http://192.168.31.8:8545'));
//  通过getAccounts函数用异步的方式获取并输出geth节点账户的地址
web3.eth.getAccounts(
      function(error, response)
{
         console.log(response)
    }
)
//  通过IPC方式连接geth节点
web3 = new Web3(new Web3.providers.IpcProvider('/chapter4/private/geth.ipc',net));
//  通过getAccounts函数用异步的方式获取并输出geth节点账户的地址
web3.eth.getAccounts(
      function(error, response)
{
         console.log(response)
      }
)

首先启动geth节点。然后使用下面的命令运行本例。

node connect_http_ipc.js

运行本例后,会在终端输出geth节点的账户地址,如图8所示。

图8 用两种方式输出的geth节点账户地址

本文分享自微信公众号 - 极客起源(geekculture),作者:geekori

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python编程思想(26):成员变量

    李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法。读者可以在「极客...

    蒙娜丽宁
  • 你听说过Go语言的TryCatch吗?

    有的同学看到Go和TryCatch一起出现,心里可能会说,难道Go语言升级了,加入了try...catch语句。哈哈,其实Go语言从创建之初就没打算加入try....

    蒙娜丽宁
  • 它抢不走程序员的饭碗,但是会让一部分人瑟瑟发抖

    头部区域的文字是“Mood Tracker”, 然后是按钮“Happy”,“Sad',“Sleepy”,当我按其中一个按钮的时候,显示文本 “right row...

    蒙娜丽宁
  • 二叉树

    爱撒谎的男孩
  • 数据结构(八)--平衡二叉树

    出现背景 前文已经研究过普通的二叉树, 为什么要用二叉树呢?因为二叉树的结构可以实现二分法查找的效果。

    fanfan
  • DFS最难也就这样了

    之前我们已经已经把DFS的核心思想讲清楚了,也就这么回事儿,也再次向大家宣扬了一种循序渐进的思想,从基本解法向外去击破。

    写代码的阿宗
  • BinaryTree二叉树

    二叉树(binary tree),是每个结点最多有2个的有序树(tree) 。 简单的理解,就是一种类似于我们生活中树的结构,只不过每个结点上都最多只能有两个...

    羊羽shine
  • 二叉树非递归版的后序遍历算法

    本公众号主要推送关于对算法的思考以及应用的消息。算法思想说来有,分而治之,搜索,动态规划,回溯,贪心等,结合这些思想再去思考如今很火的大数据,云计算和机器学习,...

    double
  • DNSPOD自动更新公网IP脚本 By HKL, Wedn

    hiplon
  • python过滤 Kubernetes api数据

    其中 pod_name 对应 items-->subsets-->addresses-->targetRef-->name

    py3study

扫码关注云+社区

领取腾讯云代金券