最近需要搭建以太坊全节点,刚开始用的是geth,同步了1整天发现最新的70~80个块总是同步不下来,网上一查很多人遇到过这个问题,据说跟SSD的读写速度有关,无奈之下只能放弃,改用parity。
parity是一个和geth类似的以太坊客户端程序,由以太坊黄皮书作者Gavin Woods领导,采用Rust语言编写。试用了一下体验还是挺棒的,同步Ropsten的数据只需要几个小时的时间。但是,parity毕竟和geth还是有很大区别的,首先一点数据的目录结构和存储方式是不同的,另外某些RPC的调用方式也有些差异,踩了一些坑,记录下来希望对后来人有点帮助。
parity中所有可用的链参考下面的链接:
https://wiki.parity.io/Chain-specification
在使用geth的时候同步主网跟Ropsten测试网一般用下面的命令:
geth --datadir ./gethData
geth --testnet --datadir ./gethData
对应的parity命令如下:
parity --base-path=./parityData
parity --chain ropsten --base-path=./parityData
我们来看一下生成的parityData的目录结构:
├── cache
├── chains
│ ├── ropsten
│ │ ├── db
│ └── ver.lock
├── jsonrpc.ipc
├── keys
│ └── ropsten
│ └── address_book.json
└── network
└── key
可以发现,原先geth里的keystore变成了keys/,geth.ipc变成了jsonrpc.ipc,另外数据库也已动到了chains//db中。因此为了保证以前使用geth的程序能正常工作,最简单的办法就是创建2个软链接:
cd parityData
ln -s jsonrpc.ipc geth.ipc
ln -s keys/ropsten keystore
我们在开发测试过程中最常用的是dev网络,是一种预先定义好的私网:
parity --config dev
对应的配置文件在下面的链接中:
https://github.com/paritytech/parity-ethereum/blob/master/ethcore/res/instant_seal.json
dev网络预先包含一个持有很多ETH的账户0x00a329c0648769a73afac7f9381e08fb43dbea72,密码为空。
如果想要定制私网,把上面的配置文件拷贝一份,修改好后用下面的命令启动:
parity --chain genesis.json
在使用geth的时候,一般会attach到geth.ipc上,或者通过JSON RPC进行账户解锁。在parity中也是类似,只是geth.ipc变成了jsonrpc.ipc。需要注意的是,启动parity需要增加下面的选项以开启该功能(偷懒的写法,all代表所有类别):
parity --chain genesis.json --base-path=./parityData --ipc-apis="all" --jsonrpc-apis="all"
好,我们先用geth attach的方式试一下:
geth attach ./parityData/jsonrpc.ipc
> personal.unlockAccount(eth.accounts[0], '123', 3600)
Error: Invalid params: invalid type: integer `3600`, expected a 0x-prefixed hex string with length between (0; 32].
> personal.unlockAccount(eth.accounts[0], '123', 0xe10)
Error: Invalid params: invalid type: integer `3600`, expected a 0x-prefixed hex string with length between (0; 32].
> personal.unlockAccount(eth.accounts[0], '123', '0xe10')
unlock duration must be a number
你会发现,不管你怎么写,都无法将账户解锁3600秒。。。只有下面这种能成功:
> personal.unlockAccount(eth.accounts[0], '123', null)
true
但是,这样只是临时解锁,账户只能发起一次交易,然后就必须重新解锁。如果你使用Truffle,就会遇上麻烦了,因为我们都知道,Truffle会先部署1个Migration合约,然后部署我们自己的合约的时候就会永远卡在那里。。。(吐槽一下,竟然没有错误提示)
实际上,github上有人讨论过这个bug,实际上是由于geth跟parity定义的参数类型不一致导致的。web3只处理geth的情况,但是没法兼顾parity。
看来此路不通,让我们再用JSON RPC试一下:
curl --data '{"method":"personal_unlockAccount","params":["0x33baea29cced0097685449fbd8dea161d3ad0a4d","123","0x100"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
很遗憾,没有成功,返回下面的错误:
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Time-unlocking is not supported when permanent unlock is disabled.","data":"Use personal_sendTransaction or enable permanent unlocking, instead."},"id":1}
错误信息说的很清楚:不支持Time-unlocking,替代方案是使用personl_sendTransaction代替eth_sendTransaction。关于如何“enable permanent unlocking”,网上没有查到任何资料,估计是要改parity代码,暂时不考虑。
也就是说,调用personal_sendTransaction是可以的(需要提供keystore密码):
curl -X POST -H "Content-Type: application/json" --data '{"method":"personal_sendTransaction", "params":[{"from": "0x33baea29cced0097685449fbd8dea161d3ad0a4d", "to":"0x146aed09cd9dea7a64de689c5d3ef73d2ee5ca00", "value": "0x10000" }, "123"], "id": 1, "jsonrpc":"2.0"}' localhost:8545
但是调用eth_sendTransaction的时候会卡住:
curl -X POST -H "Content-Type: application/json" --data '{"method":"eth_sendTransaction", "params":[{"from": "0x33baea29cced0097685449fbd8dea161d3ad0a4d", "to":"0x146aed09cd9dea7a64de689c5d3ef73d2ee5ca00", "value": "0x10000" }, "123"], "id": 1, "jsonrpc":"2.0"}' localhost:8545
但是,我们已有的应用肯定都是基于eth_sendTransaction的,另外在网络中传输密码看起来也相当不安全。经多方查找,终于找到了账户永久解锁的优雅解决方案。
首先把要导入的keystore文件放到一个目录中(比如keystore目录),然后通过“account import”命令把keystore导入到parity中。
接下来把该账户的密码写到一个文件中,比如password.txt。
最后,启动parity时加上“–unlock”和"–password"选项就可以永久解锁了:
parity account import ./keystore --chain genesis.json --base-path=./parityData
parity --chain genesis.json --base-path=./parityData --ipc-apis="all" --jsonrpc-apis="all" --unlock="33baea29cced0097685449fbd8dea161d3ad0a4d" --password="password.txt"
更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
或关注飞久微信公众号: