一:VS2019配置curl库
1、下载curl安装包并解压
进入https://curl.haxx.se/download.html下载curl库,解压得到文件夹【curl-7.65.3】
2、编译curl
1)双击运行【curl-7.65.3】文件夹下的【buildconf.bat】
2)打开VS2019自带的命令提示符
4)输入命令编译
nmake /f Makefile.vc mode=dll VC=16 MACHINE=x86 DEBUG=yes
[图片上传中...(image.png-9a6b9e-1567388398889-0)]
命令 | 释义 |
---|---|
mode | static表示静态编译,dll表示动态编译(在我的使用中,静态编译后的项目执行报错,所以建议使用动态编译,下文也均是动态编译的属性配置) |
VC | VC后面的数字表示编译的libcurl和VS相对应的版本号,VS2019的VC版本号是VC16 |
MACHINE | x64表示编译64位环境使用的libcurl,x86表示编译32位环境使用的libcurl。我的VS是x86版本。 |
debug | 如果需要debug版,将“DEBUG=no”改为“DEBUG=yes”,DEBUG=no”即release版本 |
3、为你的项目配置curl
1)选择对应的平台和版本 image.png2)选择【你的项目】->【属性】
3)选择【配置属性】->【VC++目录】->【包含目录】->添加curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\include文件夹
4)选择【配置属性】->【VC++目录】->【库目录】->添加curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夹
5)选择【配置属性】->【c/c++】->【代码生成】->【运行库】,选择【MTd/MDd】
6)选择【配置属性】->【链接器】->【常规】->【附加库目录】,添加curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夹
7)选择【配置属性】->【链接器】->【输入】->【附加依赖项】,添加lib文件:libcurl_debug.lib(编译生成的.lib文件,在curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夹下)
8)点击【应用】完成配置
二:JsonRpc与以太坊交互
Json解析可参考文章:
//eth_connect.h文件
#include<curl/curl.h>
#include <string>
#include <json/json.h>
using namespace std;
CURL* curl;
CURLcode cres;
size_t write_data_a(void* buffer, size_t size, size_t nmemb, void* userp) {
char* d = (char*)buffer;
char* u = (char*)userp;
strcpy(u, d);
return nmemb;
}
bool setCurl(char* jm, struct curl_slist* headers, char* r_header, char* r_result) {
curl = curl_easy_init();
headers = curl_slist_append(headers, "Content-Type: application/json");
char* body_str_json = jm;//"{\"jsonrpc\":\"2.0\",\"method\":\"personal_newAccount\",\"params\":[\""+psw+"\"],\"id\":1}";
//响应头
string address = "http://127.0.0.1";
int port = 8545;
string post_url = address + ":" + to_string(port);
if (curl) {
//设置post请求的url地址
curl_easy_setopt(curl, CURLOPT_URL, post_url.c_str());
//设置HTTP头
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
//设置发送超时时间
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(body_str_json));
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body_str_json);
//设置返回头
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &write_data_a);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, r_header);
//设置响应体
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data_a);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, r_result);
return true;
}
return false;
}
char* getEthereumInformation(string request) {
curl_global_init(CURL_GLOBAL_ALL);
cres = CURLE_OK;
char* r_header = new char[256], * r_result = new char[2048];
struct curl_slist* headers = NULL;
//string tmp = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}";
char* body_str_json = new char[strlen(tmp.c_str()) + 1];
strcpy(body_str_json, tmp.c_str());
if (setCurl(body_str_json, headers, r_header, r_result)) {
//执行单条请求
//设置返回头
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &write_data_a);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, r_header);
//设置响应体
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_data_a);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, r_result);
cres = curl_easy_perform(curl);
curl_slist_free_all(headers);
//这个调用用来结束一个会话.与curl_easy_init配合着用
curl_easy_cleanup(curl);
//在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数
curl_global_cleanup();
return r_result;
}
return 0;
}
//test.cpp(主函数)
#include"eth_connect.h"
using namespace std;
int main() {
//获取区块链当前区块高度
string getBlockHeightJson = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}";
char* getBlockHeight_ResultJson = getEthereumInformation(getBlockHeightJson);
//返回的json数据格式:{"id":83,"jsonrpc" : "2.0","result" : "0x4b7" // 1207}
//解析Json数据
string HexBlockHeight = ReadJson(getBlockHeight_ResultJson, "result");
//int height= HexStringToInt(HexBlockHeight);
//HexBlockHeight = "0x" + dec2hex(round, 8);
//根据blockNumber获取block信息(blockHash)
//HexBlockHeight = "0x9" ;
string getBlockByNumberJson = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"params\":[\"" + HexBlockHeight + "\", true],\"id\":1}";
char* getBlockByNumber_ResultJson = getEthereumInformation(getBlockByNumberJson);
string BlockHash = readJson(getBlockByNumber_ResultJson);
//string BlockHashShort = BlockHash.substr(0, 15);
//strcpy(seed, BlockHashShort.c_str());
curl_global_cleanup();
return 0;
}
string ReadJson(string str, string keyOfstr)
{
//示例字符串
/*string result = "{\"id\":83,\"jsonrpc\" : \"2.0\",\"result\" : \"0xc94\" }";*/
Json::Reader reader;
Json::Value root;
//从字符串中读取数据
if (reader.parse(str, root))
{
std::string result = root[keyOfstr].asString();
return result;
}
return "";
}
//读取区块hash值,响应结果为:
//{
//"id":1,
//"jsonrpc" : "2.0",
//"result" : {
// "hash":"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b",
// "nonce" : "0x",
// "blockHash" : "0xbeab0aa2411b7ab17f30a99d3cb9c6ef2fc5426d6ad6fd9e2a26a6aed1d1055b",
// "blockNumber" : "0x15df", // 5599
// "transactionIndex" : "0x1", // 1
// "from" : "0x407d73d8a49eeb85d32cf465507dd71d507100c1",
// "to" : "0x85h43d8a49eeb85d32cf465507dd71d507100c1",
// "value" : "0x7f110", // 520464
// "gas" : "0x7f110", // 520464
// "gasPrice" : "0x09184e72a000",
// "input" : "0x603880600c6000396000f300603880600c6000396000f3603880600c6000396000f360",
//}
//}
string readJson(string str) {
int32_t index = str.find("{");
if (-1 != index) {
string resultJson = str.substr(index, str.size() - index);
Json::Reader reader;
Json::Value value;
if (reader.parse(resultJson, value)) {
if (!value["result"].isNull()) {
Json::Value result = value["result"];
if (!result["hash"].isNull()) {
const char* hash = result["hash"].asCString();
//memcpy(plat_user->nick_name_, name, strlen(name));
return hash;
}
}
return "";
}
}
}
网友评论