c++之通過JsonRpc與以太坊交互

一:VS2019配置curl庫

1、下載curl安裝包并解壓

進(jìn)入https://curl.haxx.se/download.html下載curl庫,解壓得到文件夾【curl-7.65.3】

image.png

2、編譯curl

1)雙擊運(yùn)行【curl-7.65.3】文件夾下的【buildconf.bat】
2)打開VS2019自帶的命令提示符

image.png
3)進(jìn)入【curl-7.65.3\winbuild】文件夾下
4)輸入命令編譯
nmake /f Makefile.vc mode=dll VC=16 MACHINE=x86 DEBUG=yes
[圖片上傳中...(image.png-9a6b9e-1567388398889-0)]

命令 釋義
mode static表示靜態(tài)編譯,dll表示動態(tài)編譯(在我的使用中,靜態(tài)編譯后的項(xiàng)目執(zhí)行報錯,所以建議使用動態(tài)編譯,下文也均是動態(tài)編譯的屬性配置)
VC VC后面的數(shù)字表示編譯的libcurl和VS相對應(yīng)的版本號,VS2019的VC版本號是VC16
MACHINE x64表示編譯64位環(huán)境使用的libcurl,x86表示編譯32位環(huán)境使用的libcurl。我的VS是x86版本。
debug 如果需要debug版,將“DEBUG=no”改為“DEBUG=yes”,DEBUG=no”即release版本
image.png

5)編譯完成后,會在【curl-7.65.3\builds】文件夾下生成三個文件夾,使用【libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl】文件夾就可以,另外兩個文件夾的用途暫不知
image.png
3、為你的項(xiàng)目配置curl

1)選擇對應(yīng)的平臺和版本
image.png

2)選擇【你的項(xiàng)目】->【屬性】
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++】->【代碼生成】->【運(yùn)行庫】,選擇【MTd/MDd】
6)選擇【配置屬性】->【鏈接器】->【常規(guī)】->【附加庫目錄】,添加curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夾
7)選擇【配置屬性】->【鏈接器】->【輸入】->【附加依賴項(xiàng)】,添加lib文件:libcurl_debug.lib(編譯生成的.lib文件,在curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夾下)
8)點(diǎn)擊【應(yīng)用】完成配置

二: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}";
    //響應(yīng)頭
    string address = "http://127.0.0.1";
    int port = 8545;
    string post_url = address + ":" + to_string(port);

    if (curl) {
        //設(shè)置post請求的url地址
        curl_easy_setopt(curl, CURLOPT_URL, post_url.c_str());
        //設(shè)置HTTP頭
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        //設(shè)置發(fā)送超時時間
        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);
        //設(shè)置返回頭
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &write_data_a);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, r_header);
        //設(shè)置響應(yīng)體
        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)) {
        //執(zhí)行單條請求
        //設(shè)置返回頭
        curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &write_data_a);
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, r_header);
        //設(shè)置響應(yīng)體
        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);
        //這個調(diào)用用來結(jié)束一個會話.與curl_easy_init配合著用
        curl_easy_cleanup(curl);
        //在結(jié)束libcurl使用的時候,用來對curl_global_init做的工作清理。類似于close的函數(shù)
        curl_global_cleanup();
        return r_result;
    }
    return 0;
}
//test.cpp(主函數(shù))
#include"eth_connect.h"
using namespace std;
int main() {
        //獲取區(qū)塊鏈當(dāng)前區(qū)塊高度
        string getBlockHeightJson = "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}";
        char* getBlockHeight_ResultJson = getEthereumInformation(getBlockHeightJson);
        //返回的json數(shù)據(jù)格式:{"id":83,"jsonrpc" : "2.0","result" : "0x4b7" // 1207}
        //解析Json數(shù)據(jù)
        string HexBlockHeight = ReadJson(getBlockHeight_ResultJson, "result");
        //int height= HexStringToInt(HexBlockHeight);
        //HexBlockHeight = "0x" + dec2hex(round, 8);

        //根據(jù)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;
    //從字符串中讀取數(shù)據(jù)
    if (reader.parse(str, root))
    {
        std::string result = root[keyOfstr].asString();

        return result;
    }
    return "";
}
//讀取區(qū)塊hash值,響應(yīng)結(jié)果為:
//{
//"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 "";
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容