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

一:VS2019配置curl庫(kù)

1、下載curl安裝包并解壓

進(jìn)入https://curl.haxx.se/download.html下載curl庫(kù),解壓得到文件夾【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表示動(dòng)態(tài)編譯(在我的使用中赊锚,靜態(tài)編譯后的項(xiàng)目執(zhí)行報(bào)錯(cuò)盗忱,所以建議使用動(dòng)態(tài)編譯酱床,下文也均是動(dòng)態(tài)編譯的屬性配置)
VC VC后面的數(shù)字表示編譯的libcurl和VS相對(duì)應(yīng)的版本號(hào),VS2019的VC版本號(hào)是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)編譯完成后料身,會(huì)在【curl-7.65.3\builds】文件夾下生成三個(gè)文件夾汤纸,使用【libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl】文件夾就可以,另外兩個(gè)文件夾的用途暫不知
image.png
3芹血、為你的項(xiàng)目配置curl

1)選擇對(duì)應(yīng)的平臺(tái)和版本
image.png

2)選擇【你的項(xiàng)目】->【屬性】
3)選擇【配置屬性】->【VC++目錄】->【包含目錄】->添加curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\include文件夾
4)選擇【配置屬性】->【VC++目錄】->【庫(kù)目錄】->添加curl-7.65.3\curl-7.65.3\builds\libcurl-vc16-x86-debug-dll-ipv6-sspi-winssl\lib文件夾
5)選擇【配置屬性】->【c/c++】->【代碼生成】->【運(yùn)行庫(kù)】贮泞,選擇【MTd/MDd】
6)選擇【配置屬性】->【鏈接器】->【常規(guī)】->【附加庫(kù)目錄】,添加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請(qǐng)求的url地址
        curl_easy_setopt(curl, CURLOPT_URL, post_url.c_str());
        //設(shè)置HTTP頭
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        //設(shè)置發(fā)送超時(shí)時(shí)間
        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í)行單條請(qǐng)求
        //設(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);
        //這個(gè)調(diào)用用來結(jié)束一個(gè)會(huì)話.與curl_easy_init配合著用
        curl_easy_cleanup(curl);
        //在結(jié)束libcurl使用的時(shí)候,用來對(duì)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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子珠叔,更是在濱河造成了極大的恐慌蝎宇,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祷安,死亡現(xiàn)場(chǎng)離奇詭異姥芥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)汇鞭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門凉唐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虱咧,你說我怎么就攤上這事熊榛。” “怎么了腕巡?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玄坦,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我绘沉,道長(zhǎng)煎楣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任车伞,我火速辦了婚禮择懂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘另玖。我一直安慰自己困曙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布谦去。 她就那樣靜靜地躺著慷丽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳄哭。 梳的紋絲不亂的頭發(fā)上要糊,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音妆丘,去河邊找鬼锄俄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛勺拣,可吹牛的內(nèi)容都是我干的奶赠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼药有,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼车柠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤竹祷,失蹤者是張志新(化名)和其女友劉穎谈跛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塑陵,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡感憾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了令花。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阻桅。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖兼都,靈堂內(nèi)的尸體忽然破棺而出嫂沉,到底是詐尸還是另有隱情,我是刑警寧澤扮碧,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布趟章,位于F島的核電站,受9級(jí)特大地震影響慎王,放射性物質(zhì)發(fā)生泄漏蚓土。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一赖淤、第九天 我趴在偏房一處隱蔽的房頂上張望蜀漆。 院中可真熱鬧,春花似錦咱旱、人聲如沸确丢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲜侥。三九已至,卻和暖如春毯盈,著一層夾襖步出監(jiān)牢的瞬間剃毒,已是汗流浹背病袄。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工搂赋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人益缠。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓脑奠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親幅慌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宋欺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容