以太坊开发工具集使用说明

以太坊开发工具集

一个简单,方便,易用的web在线以太坊开发工具集!在线体验:以太坊开发工具集

为什么要做这些工具

从开始接触以太坊底层C++版本开发,跟底层进行交互的主要工具是truffle。通过truffle,能发布合约,调用合约,以及能使用Web3.js。至于调用底层的JSON-RPC接口,只能在Linux上使用curl工具发送http请求进行调用。这些工具,都有如下缺点:

  • 无法记录调用的历史记录。比如使用curl,调用完了之后如果关闭xshell了,再来调用我又必须重新组包。
  • 返回显示不友好。比如使用curl调用返回的结果没有着色,没有按友好的JSON格式显示,无法快速复制结果等。
  • 使用truffle调用合约麻烦。想要调用一个合约,你需要先用truffle console进入调试模式,找到合约的地址,然后加载合约,经过一系列非常繁琐过程之后,然后才能调用。而且数据输入极其不友好。尤其是在调用我们jueth的内置合约,编译一次内置合约耗费很久。如果你退出truffle想再次调用合约,那么,您再来一次上面繁琐的步骤吧。
  • 切换不方便。如果有多个节点想在一个窗口调试。那你需要不要不断的修改truffle配置或者geth attach来更换IP。
  • 提示不友好。表现在两个方面,假设我用geth attach 的console模式连接后台要用Web3.js获取最新的区块信息。第一个方面是无法使用tab键补全,输入web3.et无法给我补全为web3.eth.getBlock。第二个方面是没有调用说明,比如需要输入几个参数?每个参数的意义是什么?
  • 调用脚本不友好。比如,我需要验证块消耗的gasUsed等于块内所有交易的gasUsed之和。那么我需要一次性发送很多交易使之一个块含多比交易。那么你必须使用接口eth_sendTransaction来发送交易。你去truffle或者geth的console下面写个JavaScript脚本调用试试?
  • 浏览整个区块麻烦。比如:我想要看当前有多少个节点?最近的10个区块信息,每个区块里面的交易的详细信息等等。这些你只能一个一个的发送JSON RPC请求来获取。
  • 工具不通用。我们每个开发人员都有truffle工具(而且我们的truffle还只能用我们自己特定的版本),非底层开发人员不一定有。但是,浏览器每台电脑都会有。

基于上面的缺点,给我的开发带来了诸多不便,对我自己来说,主要是这些繁琐的操作影响心情,进而影响开发效率。 所以从我自己开发以太坊底层开始,利用空余时间给自己做一些工具来解决这些问题。最初只是想用利用Web3.js来简化合约的调用,所以域名叫 http://web3.luchenqun.com/ 。后面将以太坊相关的能提高开发效率的工具都集成进来了,形成了现在的以太坊开发工具集。

使用指导

环境搭建

首先您需要搭建自己的以太坊平台。这个工具目前我只测试过go-ethereumaleth(原以太坊C++版本,含我们的jueth),ganache(一个以太坊开发的可视化全真模拟环境,包括他的ganache-cli)。
如果您没有搭建自己的环境,我用我的云服务器用geth 1.8.19-unstable以develop的模式(所谓develop模式就是不挖矿只有交易进来才出块)搭建了一个开发环境。我的启动命令是:geth --datadir ./ethereum-public/ --networkid 88 --nodiscover --rpccorsdomain "*" --port 41229 --rpc --rpcaddr 0.0.0.0 --rpcport 41230 --rpcapi "db,eth,net,web3,personal,admin" --ws --wsaddr 0.0.0.0 --wsport 41231 --wsorigins "*" --wsapi "db,eth,net,web3,personal,admin" --debug --dev。连接信息如下:

IP:111.231.72.59
http port: 41230
websocket port: 41231

首次进入主页默认链接的是这个环境。请不要滥用此环境,不要用脚本去压测,仅作测试使用。若发现有人滥用环境,我只能关闭测试环境。
接下来对工具的使用做一些简单使用说明。注意:工具可能不断更新,若使用遇到问题,请先查看文档。
还有两个需要特别注意的是:首先浏览器我只测试了谷歌浏览器,版本请至少使用版本 69.0.3497.100(正式版本)。其他浏览器兼容性问题一概不处理!请喝再多咖啡都不会处理。然后一定要启用跨域支持,否则浏览器将无法链接到你后台。以geth为例,启动时候你需要加上跨域的参数--rpccorsdomain "*"。请注意,*号是有双引号引起来的。不要问我为什么,因为我没用双引号就不支持跨域。

导航栏

从左至右,依次是 连接信息->搜索框->菜单栏。
链接信息:是你当前连接到的主机信息,点击该信息,可切换主机。
搜索栏:你可以输入字符串latest搜索最新的区块信息,pending搜索将要出块的块信息,genesis搜索创世区块,输入任意区块哈希,交易哈希搜索相关信息。当然,你还可以输入任何块索引,比如0搜索创世区块信息,88第88个区块信息。如果你搜索交易信息,我会连着将该交易的块一同显示。你搜索的关键字我会用红色显示。
菜单栏:菜单栏信息结构以及功能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
菜单栏
├── 首页
├── 区块链
│ ├── 查看所有区块
│ └── 单个区块详情
├── RPC
├── Web3
├── 合约
│ ├── 合约调用
│ └── Solidity开发
├── 以太坊工具
│ └── 编码解码
└── 设置
├── 更换链接
├── 编辑缓存
├── 打赏
└── 帮助

其中有些有二级菜单,点一级菜单会默认响应一个二级菜单。区块链默认响应查看所有区块合约默认响应合约调用以太坊工具默认响应编码节码设置默认响应编辑缓存。下面介绍各个菜单所展示的内容以及操作提示。

首页

主要展示整个区块链的一些相关信息。可以设置间隔时间自动刷新整个页面信息,也可点按钮立即刷新更新内容。当然,如果你后台支持Websocket协议,而且支持Web3.js的订阅模式,最新区块订阅才会自动更新区块。否则只能手动刷新。

查看所有区块

此页面默认展示最新一些区块的简要信息,点分页按钮可切换响应页码的区块。左边的刷新按钮可重新获取最新区块的简要信息。搜索框按钮可以搜索当前页面区块信息。注意:是当前页面,不是整个区块链区块信息。如果区块数目超过300,那么我会在分页的右边启动一个输入框,输入指定的页码,我会自动跳转到该页面。点击该页面的任意区块的简要信息,会跳转到区块的详细信息。

单个区块详情

此页面是区块的所有详细信息,包括该区块的所有详细交易信息。左边的刷新按钮,不管当前页面展示哪个区块,都直接给你获取最新的区块详细信息。右边的两个按钮,表示下一个,上一个区块详细信息。区块详细信息里面有一栏点我可查看块详细JSON信息。会将区块返回的JOSN详细信息展示。为什么要这样呢?因为各个版本可能返回的信息不一致,这里面一定可以查看到全部的没有任何删减原汁原味的JSON返回信息。
第二部分是该区块的交易详细信息。右边的搜索框,注意搜索的是当前展示的交易信息,不是在区块所有交易信息里面搜索。同样,交易数过多,亦会有页码输入框供快速跳转页面。点我可查看交易详细JSON信息,套路跟区块的一样。

RPC

这个页面是JSON-RPC的调用页面。
首先,一个正常的RPC请求格式如下所示:

1
2
3
4
5
6
7
8
9
{
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": [
"0x1b4",
true
],
"id": 1
}

从上至下,依次是:最近调用;调用方法选择或输入,相当于method;请求ID,相当于id;请求参数,相当于params;格式化按钮,确认按钮,调用结果,调用详细说明。
你只要选择调用方法,其中调用方法可以搜索,比如你要调用一个块相关的RPC方法,你只需要输入block,调用方法差不多就过滤出来了。id可以输可以不输,不输的话以当前时间的时分秒作为id。如当前时间是13:20:18那么请求id就是132018。参数输入需要注意的是,字符串只能是双引号,不要用单引号。填完之后你点确定,一个RPC请求就发送出去了。系统自动将你填的参数保存,下次再调用该RPC请求的时候,会自动填好输入参数。而且该RPC请求会作为最近一次请求,下次你再打开这个页面,页面已经默认给你填好这个RPC请求啦。
最近调用展示你最近使用的RPC请求,括号里面的数字是你使用这个RPC请求的次数。因为你常用的RPC请求可能就几个,每次去选择也很麻烦的。你点一下最近调用的,系统就给你直接按照你最近调用的请求参数给你填好了。当然,最近调用我只保留大概浏览器一行的样子。超过一定数目,就会提示你不能保存了,这时候你双击一下它,就从最近调用列表里面删掉了。
格式化按钮(A),是用来格式话你输入的请求参数的,因为有时候你从其他地方复制来的请求参数,乱七八糟的的你想修改,那么你可以先格式化一下让其显示更友好。
调用结果后面还有一个复制的小按钮,你点一下,整个请求的结果就自动复制到你的剪切板里面了。其他地方看到这样的复制小按钮,不再说明。
那么,如果新开发的RPC请求可以调用吗?是可以的,你只需要按照格式 method — RPC说明的格式填好,如eth_getCallPermissions — 返回指定合约的防火墙状态。你就可以请求你新增的RPC方法啦。注意:中间的是中文的破折号的一半,输入法下面shift 加 —(0键与+键之间的按键)再删掉一半。而且左右要空一格。不会你直接选一个系统的,删掉左右两边的按照你的新RPC填好就行了。新加入的RPC请求方法你只要调用一次,系统也会给你保存好,下次你就不要输啦!当然,第一次请求完列表可能没有,你需要按F5刷新一下页面。

Web3

这个页面很简单,点方法按照提示下面的调用说明填参数再点确定就可以了。如果不需要填参数的,系统自动给你点了确定了。当然,这个页面可能没完善,有些方法是不能用的,哪些不能用,我也不太清楚了。

合约调用

以第一排按钮ContractcallsendupdateSysContrac分别说明。

Contract

这个页面主要是实例化一个合约。从上至下填合约名字,合约地址,合约调用接口描述(就是truffle编译合约生成的abi),以及合约配置对象(参考页面下面的说明options)。from不要填,调用的时候你可以选择调用者。由于该页面目前不支持合约部署,所以data也不要填。你只要填合适的gas与gasPrice就行了,系统也默认给你填了一个。如果你只想调用一次,可以不要填合约名字,如果你以后还想调用此合约,那么请填上合约名字,系统会将合约的信息保存起来。下次再调用的时候,你只要选择合约名字,系统就将你填的合约地址,接口描述,配置选项都给你加载出来了。
填完之后点确定,一个合约实例就出来了,你就可以去调用合约了。当然,以后你再进来,系统会加载一个你最近调用的合约,自动给你实例化好了。你可以在我提供的上述测试环境里面测试合约调用,在下面的JavaScript模块有相应的合约地址与abi。当然,你也可以用Solidity模块自己写个合约部署然后来调用。

call send

两个需要填的参数一样,区别是call调用合约的只读方法,send向合约发送交易来执行指定方法。你需要自己区别到底是调用哪个方法。
第一栏是你想要调用的方法选择,请选择一个你想要调用的方法就可以了。这些方法都是来源于初始化合约时候填的abi,如果你嫌弃方法太多选起来麻烦,那么你填abi的时候可以删掉你不需要调用的方法,这样就不会来烦你了。
第二栏是调用方法的参数输入,假设你智能合约里面写了一个下面的f函数。

1
2
3
function f(address ar, uint n, bytes data, bool flag) public {
// ...
}

那么,该栏参数可以这样填["0x5f169EB2430D2aB55E2EEF07b6838e8E506fc502", 1230, "i love this world", true]。如果一个参数都不需要填的话,那你可以不填任何数据或者填[]
第三栏是选择调用者。你可以选择一个,当然你也可以自己输入一个。填完之后,点确定就行了。
有个小细节需要说明一下:因为send调用其实最终会转化成eth_sendTransaction请求,有时候没有解锁就会调用失败。所以只要调用失败,我都会默认给你的所有的账号解锁一遍。如果你调用过Web3页面的unlockAccount,我会以你输的那个密码解锁,否则,默认以密码12345678解锁。故建议创建账号的时候建议用密码12345678

updateSysContrac

这个主要是针对jueth的,其他的后台这个功能完全无用。主要是将jueth系统的内置合约的abi一次性复制进来,不要在合约实例化页面一个一个地去填。按照系统提示,将里面的文件内容全部复制过来填入输入框按确定即可,系统就会将所有的内置合约的abi保存起来。如果系统合约接口更新了,请将新的内容复制过来即可按确定即可。当然,这只是得到了系统内置合约的abi。你在Contract页面,在清空按钮的左边有个小小的刷新按钮,你只要一点它,系统就自动会调用内置合约RegisterManager的方法getRegisteredContract,将内置合约的名字,地址全部给你缓存好,然后你就啥也不要填,就可以愉快的调用所有内置合约了。

Solidity 开发

这个页面用来测试简单的Solidity语言写的只能合约,默认编译器版本为soljson-v0.4.25+commit.59dbf8f1.js,后期视心情添加可选任何编译器版本的选项。
第一栏是合约文件名字,请以合约名字加后缀.sol命名。系统如果检测到你保存过合约,会自动加载一个你最近写的合约。如果你要新测试一个新合约,重新命名一个合约名字,否则你点保存会覆盖以前写的合约。
第二栏是合约内容。自己编写。注意:只支持单个文件,不要想着什么import啥的,这就是一个简单的测试Solidity开发工具。
第三栏是按钮,保存按钮会将你写的合约内容保存到缓存中。编译按钮编译智能合约,如果你打开了左边的编译自动保存代码,那么你只要编译成功,就会自动缓存一次。最后一个部署按钮,如果你编译成功,这个按钮才生效,再选择下面你想要用来部署合约的账号,点部署,自动将只能合约部署到链上了。而且系统不止做了这些,部署完成之后,自动将你的合约名字,新合约地址,abi什么的缓存起来了,你去合约调用页面直接可以调用啦!
下面的几栏就是编译之后的结果,自己看吧。

JavaScript

这个功能需要会一点点JavaScript脚本语言基础。此功能主要源于我自己在开发过程需要调用脚本才能实现的功能,比如压测查看最大TPS。之前都是调用使用Node.js来实现,但是还是觉得麻烦,所以做了这个页面。
这个页面的实现方式是,当你切换链接的时候,我给你准备好了一个全局的变量clientweb3,前者我已经实现了一个函数dispatch供你来调用RPC请求,后者供你来调用web3.js的函数。废话不多说,直接以示例来说明。
我已经在111.231.72.59:41230上面部署了一个智能合约。内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pragma solidity ^0.4.18;
contract Math {
uint num;

function add(uint x) public {
num = num + x;
}

function sub(uint x) public {
num = num - x;
}

function mul(uint x) public {
num = num * x;
}

function div(uint x) public {
num = num / x;
}
function get() public returns (uint retVal) {
return num;
}
}

部署的合约地址为0x156a9ddded1b57a41c24d4f235d0fe168a28126a(如果重启环境可能会变化,你自己用Solidity开发页面部署一次替换地址,账号就行了),那么我就可以使用client来调用100次add函数,使变量num每次加1。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var data = {
"jsonrpc": "2.0",
"id": 418,
"method": "eth_sendTransaction",
"params": [{
"gas": "0x54c563",
"gasPrice": "0x77359400",
"from": "0x5f169eb2430d2ab55e2eef07b6838e8e506fc502", // 调用者
"data": "0x1003e2d20000000000000000000000000000000000000000000000000000000000000001", // 前面的1002e2d为函数add摘要
"to": "0x156a9ddded1b57a41c24d4f235d0fe168a28126a" // 合约地址
}]
}

let count = 100;
while (count--) {
let reply = await client.dispatch(data); // 看到await了没,dispatch我是用Promise实现的哟
console.log(reply);
}

再来一个web3如何调用上述合约add方法的代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const mathAddress = "0x156a9ddded1b57a41c24d4f235d0fe168a28126a";
const mathAbi = [
{
"constant": false,
"inputs": [{ "name": "x", "type": "uint256" }],
"name": "add",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "name": "x", "type": "uint256" }],
"name": "mul",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "name": "x", "type": "uint256" }],
"name": "sub",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "get",
"outputs": [{ "name": "retVal", "type": "uint256" }],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [{ "name": "x", "type": "uint256" }],
"name": "div",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
]
const from = "0x5f169EB2430D2aB55E2EEF07b6838e8E506fc502";

let contract = new web3.eth.Contract(mathAbi, mathAddress, null); // 实例化一个合约,web3直接用,我已经给你实例化好了。

let funcGet = contract.methods["get"].apply(contract.methods, []);
let beginNum = await funcGet.call({ "from": from });
console.log("beginNum = ", beginNum);

let funcAdd = contract.methods["add"].apply(contract.methods, [1]); // 调用方法add每次+1
let options = {
"gas": 5555555,
"gasPrice": 2000000000,
"from": from
};
let count = 5;
while (count--) {
let reply = await funcAdd.send(options);
console.log(reply);
}

let endNum = await funcGet.call({ "from": from });
console.log("endNum = ", endNum); // 最终结果应该就是 endNum - beginNum === 5

需要提醒的是,这个模块我拦截的是console.log信息,其他的打印都不拦截。如果是对象,我会用console.info再打印到浏览器的console调试页面,方便你查看。页面后面有对web3.js与rpc请求的调用说明。自己按照说明调用吧。web3.js我用的是1.0的版本,所有有些方法后台是不支持的,自己根据后台实际情况选择合适的方法调用。
这个模块就说到这了,若你对JavaScript语言从未学习过,那你用我提供的RPC页面与合约调用页面吧。

编码解码

这里面主要是计算sha3,创建账号,通过账号密码解锁出私钥与公钥,以及RLP编码及解码。没什么可说的。

设置

其他的不说了。里面有个编辑缓存的二级页面,整个系统的缓存的信息都在里面。等哪天得空,详细说一下每个缓存对应的地方。当然你也可以试着编辑,编辑之前备份就行了。

开发计划

  • 引入mocha,可供JavaScript脚本执行测试使用。
您的支持将鼓励我继续创作!
0%