您的位置:首页 > Web前端 > JavaScript

使用JSONRPC与以太坊智能合约交互

2018-03-15 11:16 549 查看
以太坊提供JSONRPC和web3.js俩种方式与区块链节点进行交互,详细接口说明文档可看官方用户文档

这里得先了解下JSONRPC的调用。

对JSONRPC协议不熟悉的朋友可以看这俩个博客1博客2

启动测试节点

geth --datadir "D:\blockchain\devchain" --dev   --rpc  --rpcaddr 172.30.34.102 --rpcapi 'db,eth,net,web3,personal,admin,miner' --rpccorsdomain * console


–rpc,标志启动HTTP JSON-RPC

–rpcaddr –rpcport ,更改默认端口(8545)和列表地址(本地主机)

–rpcapi来设置节点开放哪些方法

–rpccorsdomain ,如果从浏览器访问RPC,CORS将需要启用相应的域集。否则,JavaScript调用受到同源策略的限制,请求将失败,‘’表示所有域名可访问

JSON RPC也可以使用该命令从geth控制台启动admin.startRPC(addr, port)。

测试访问节点

节点启动后,可以测试下是否可已正常访问节点,这里我用Postman做了个测试。

调用web3_clientVersion方法,来获取节点客户端的版本信息。

根据接口说明发送POST请求,请求内容为JSON格式。



这里解释下请求参数

jsonrpc:标识协议的版本,建议都填2.0

method:需要调用的接口名

params:方法的请求参数,不同方法的参数要去不一样,可看接口文档

id:请求标识,发起接口方设置,来标记请求。比如有可能同时发送多个接口请求,可以用这个di来识别每个请求的响应

成功返回



这里可以多测试几个接口,来熟悉下用法,

部署智能合约

节点已经可以访问了,现在我们可以部署个智能合约,来看看与自能合约的交互。

这里我用remix solidity来部署智能合约。

写合约

pragma solidity ^0.4.20;//当前solidity版本
contract hello {
string greeting;

//构造函数
function hello(string _greeting) public {
greeting = _greeting;
}
//获取greeting,无需gas
function getGreeting() constant public returns (string) {
return greeting;
}
//设置改变greeting,需要gas
function setGreeting(string _greeting)  public payable{
greeting = _greeting;
}
}


链接测试节点



弹出提示,选择ok,

注意这里需要节点已经开通了的RPC协议,否则无法链接



输入节点rpc的访问地址http://172.30.34.102:8545



输入构造函数的入参,点击creat创建合约



可以看到节点控制台的输出,说明已经部署成功。



交易哈希值=0x47adcb93847acce2c02b680b96447aacd5ebd83b9f2436e7b496038824439771

合约的地址=0xcF9b0ea3D6Cd99C17531eaC74D9B8C845520D688

在At Address上输入合约地址,调用合约方法



与智能合约进行交互

调用getGreeting需要使用接口eth.call

图片描述](//img-blog.csdn.net/20180315111059639?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L3UwMTIxMTc2NTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

这里说明下请求参数params和响应参数result

{“jsonrpc”:”2.0”,”method”:”eth_call”,”params”:[{“to”:”0xcF9b0ea3D6Cd99C17531eaC74D9B8C845520D688”,”data”:”0xfe50cc72”},”latest”],”id”:67}

to:合约地址

data:根据ABI二进制编码规则得到的字符串,用来描述请求方法和入参,详情可看ABI文档博客

latest:是说明从最新的区块开始查找合约,可以根据需要填不同的参数,节省查询时间

result:放回的是经过ABI二进制编码规则编码过得数据,需要根据规则再进行解码,这里解码后得到‘你好’

这里贴个代码

JAVA使用JSONPRC与以太坊节点进行交互-用例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.http.util.TextUtils;

public class EthereumController {

public static void main(String[] args)  {
String url="http://172.30.34.102:8545";
String paramJson="{\"jsonrpc\":\"2.0\",\"method\":\"web3_clientVersion\",\"params\":[{\"to\":\"0x3b37B585D69720a10241b0690310daED9FBD521E\",\"data\":\"0xfe50cc72\"},\"latest\"],\"id\":67}";
System.out.println( doJsonPost(url,paramJson)) ;

}
//发送JSON字符串 如果成功则返回成功标识。
public static String doJsonPost(String urlPath, String Json) {
// HttpClient 6.0被抛弃了
String result = "";
BufferedReader reader = null;
try {
URL url = new URL(urlPath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
// 设置文件类型:
conn.setRequestProperty("Content-Type","application/json; charset=UTF-8");
// 设置接收类型否则返回415错误
//conn.setRequestProperty("accept","*/*")此处为暴力方法设置接受所有类型,以此来防范返回415;
conn.setRequestProperty("accept","application/json");
// 往服务器里面发送数据
if (Json != null && !TextUtils.isEmpty(Json)) {
byte[] writebytes = Json.getBytes();
// 设置文件长度
conn.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
OutputStream outwritestream = conn.getOutputStream();
outwritestream.write(Json.getBytes());
outwritestream.flush();
outwritestream.close();
System.out.println( "doJsonPost: conn"+conn.getResponseCode());
}
if (conn.getResponseCode() == 200) {
reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
result = reader.readLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}


从这里就可以了解到用JSONRPC调用接口,需要手动对数据进行编码和解码,不易理解且非常麻烦。建议使用web3.js或web3J与节点进行交互。它底层也是用JSONRPC进行交互,屏蔽了复杂的编码解码过程,提供更易用的接口。不过用JSONRPC最自由,不限定语言。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  以太坊 智能合约