EOS

eos配置keosd的RPC接口遇到的坑

EOS笔记

Posted by Liu Ke on October 29, 2018

Contents

  1. keosd配置文件重要参数
  2. 本地调用rpc接口
  3. 从服务器调用rpc接口遇到的坑
    1. 未开放端口
    2. http-validate-host参数
    3. getman和postman测试
    4. nodeos的rpc接口调用

eos v1.2.4

在1.2版本之后,eos在nodeos服务中取消了wallet钱包相关的插件。所以如果在网上一些教程中,启动nodeos服务时,如果启动了如下插件,就会报找不到插件的错误:

plugin = eosio::wallet_plugin
plugin = eosio::wallet_api_plugin

nodeos钱包插件取消后,与wallet钱包相关的所有服务都由keosd提供。之前文章《EOS钱包和账户》介绍了通过命令行来进行钱包相关的操作,我们还可以通过rpc的方式来进行交互。keosd和nodeos为两个独立的服务,皆可独立启动运行。

将eos从github上clone并且build成功之后,进入~/eos/build/programs/keosd目录下,通过./keosd命令,可启动keosd,同时会在~/eosio-wallet目录下生成keosd的配置文件config.ini。如果配置了环境变量,可以直接通过keosd命令启动;之前如果通过eos命令行进行了cleos wallet相关的操作,则同样会生成钱包的配置文件。

keosd配置文件重要参数

对于钱包的配置文件,几个需要关注的默认参数如下:

# The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin)
# 本地http-server配置的地址和端口
http-server-address = 127.0.0.1:8888

# Append the error log to HTTP responses (eosio::http_plugin)
# 可以在HTTP responses中增加错误日志,便于发现各种错误。
verbose-http-errors = false

# If set to false, then any incoming "Host" header is considered valid (eosio::http_plugin)
http-validate-host = 1

# Timeout for unlocked wallet in seconds (default 900 (15 minutes)). Wallets will automatically lock after specified number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. (eosio::wallet_plugin)
# 钱包锁定的时间,默认是15分钟(900秒)。为了方便开发,可以改为较长的时间。
unlock-timeout = 900

本地调用rpc接口

本地调用keosd的rpc接口比较简单,默认的http-server-address配置即可正常使用,可根据实际情况更改端口,keosd和nodeosd的配置文件初始默认本地http服务端口都为8888

开启keosd服务后,按照eos官方文档,本地调用wallet钱包rpc接口:

create

创建一个指定名称的钱包。POST:http://127.0.0.1:8888/v1/wallet/create.

curl --request POST --url http://127.0.0.1:8888/v1/wallet/create --header 'content-type: application/x-www-form-urlencoded; charset=UTF-8' --data '"WALLET_NAME"'

WALLET_NAME为自定义钱包名

body传入指定钱包名,例如--data '"zhangsan"',keosd服务端会log显示saving wallet to file /~/eosio-wallet/./zhangsan.wallet,将生成的钱包文件存放在eosio-wallet目录下。同时客户端会返回显示首两位字母为PW的钱包密码,为如下形式"PW5HrSo3Hs7rrhcou9Eai5bzHmKeComj5ypia3JuEgdgeZkDBBnXr"

经过测试,去掉--header 'content-type: application/x-www-form-urlencoded; charset=UTF-8',同样可以正常调用返回钱包PassWord。

wopen

打开指定名称的钱包。POST:http://127.0.0.1:8888/v1/wallet/open.

lock

锁定指定名称的钱包。POST:http://127.0.0.1:8888/v1/wallet/lock.

lock_all

锁定所有存在的钱包。POST:http://127.0.0.1:8888/v1/wallet/lock_all.

unlock

解锁给定钱包名称和密码的钱包。POST:http://127.0.0.1:8888/v1/wallet/unlock.

更多接口请参考官方API文档

从服务器调用rpc接口遇到的坑

然后,我尝试在阿里云服务器部署单节点后,启动keosd服务,然后在本地测试远程rpc接口调用情况。这里的坑有很多,前前后后我一共折腾了一个星期。

想要外网访问rpc接口,需要在服务器端修改http-server-address为服务器本机IP,并根据情况设置端口。可通过ifconfig命令可查看IP地址。一般将127.0.0.1设置为服务器本机IP后,启动keosd服务,就能在客户端通过公网调用rpc接口。需要注意的是调用接口时,URL地址需为公网IP,可能与设置的服务器本机IP不同。

然后你就有可能会遇到如下一些问题导致无法正常访问:

未开放端口

阿里云默认未开放某些特定的端口,比如对于8888这种端口一般是没开放的,所以需要在阿里云服务器添加安全组规则来允许自己配置的端口的访问。

http-validate-host参数

我在服务器配置文件中修改了IP之后,无法远程访问rpc接口。然后我从社区论坛里看到,如果是阿里云服务器,还需要开放端口。然后我在阿里云服务器上设置了安全组规则开放了端口。还是不行。关闭防火墙什么的,还是不行。折腾了好几天。然后就在想,官方的发行版可能定是没有问题的,那问题一定是出在了自己的配置文件上。然后我就打开keosd的config.ini配置文件,一个一个参数看。

最后发现了http-validate-host这个参数,默认为1。

# If set to false, then any incoming "Host" header is considered valid (eosio::http_plugin)
http-validate-host = false

注释信息说,如果将这个参数设置为false,则所有进来的Host头部信息都认为是可用的。我就尝试修改了这个参数,将1改为了false,终于调通了!

getman和postman测试

在客户端终端中,我通过命令行curl成功调用了接口后,使用getman和postman进一步测试。然后还发现了问题。

对于getman,在Request请求中,body为”WALLET_NAME”(需要有双引号),然后Header按官方文档填入content-type: application/x-www-form-urlencoded; charset=UTF-8,测试成功。

但是对于postman,就会报500错误。 然后尝试Content-Type为:raw和Text(text/plain)这两个选项,正常调用。而且postman改了Content-Type之后,即使http-validate-host参数设为1,同样可以正常调用接口。

nodeos的rpc接口调用

对于nodeos服务,在服务器端~/.local/share/eos/nodeos/config修改配置文件,将http-server-address改为服务器IP之后,配置好端口。需要注意的是,如果nodeos和keosd服务同时启动,端口需要保证不同,他们默认都为8888。同时需要在config文件末尾启动一系列插件:

plugin = cubetrain::producer_plugin
plugin = cubetrain::chain_api_plugin
plugin = cubetrain::http_plugin
plugin = cubetrain::net_api_plugin
plugin = cubetrain::net_plugin
plugin = cubetrain::http_client_plugin
plugin = cubetrain::bnet_plugin

启动服务后,我发现在客户端远程调用nodeos的rpc接口,同样不能正常使用。然后打开配置文件研究,又发现了http-validate-host这个参数。将默认的1改为false,然后测试,正常!


Fork me on GitHub