JsonHelper.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file JsonHelper.cpp
  15. * @authors:
  16. * Gav Wood <i@gavwood.com>
  17. * @date 2014
  18. */
  19. #include "JsonHelper.h"
  20. #include <libevmcore/Instruction.h>
  21. #include <libethcore/SealEngine.h>
  22. #include <libethereum/Client.h>
  23. #include <libwebthree/WebThree.h>
  24. #include <libethcore/CommonJS.h>
  25. #include <libethcore/ICAP.h>
  26. #include <libwhisper/Message.h>
  27. #include <libwhisper/WhisperHost.h>
  28. #include <jsonrpccpp/common/exception.h>
  29. using namespace std;
  30. using namespace dev;
  31. using namespace eth;
  32. namespace dev
  33. {
  34. Json::Value toJson(unordered_map<u256, u256> const& _storage)
  35. {
  36. Json::Value res(Json::objectValue);
  37. for (auto i: _storage)
  38. res[toJS(i.first)] = toJS(i.second);
  39. return res;
  40. }
  41. Json::Value toJson(map<u256, u256> const& _storage)
  42. {
  43. Json::Value res(Json::objectValue);
  44. for (auto i: _storage)
  45. res[toJS(i.first)] = toJS(i.second);
  46. return res;
  47. }
  48. Json::Value toJson(Address const& _address)
  49. {
  50. return toJS(_address);
  51. }
  52. // ////////////////////////////////////////////////////////////////////////////////
  53. // p2p
  54. // ////////////////////////////////////////////////////////////////////////////////
  55. namespace p2p
  56. {
  57. Json::Value toJson(p2p::PeerSessionInfo const& _p)
  58. {
  59. //@todo localAddress
  60. //@todo protocols
  61. Json::Value ret;
  62. ret["id"] = _p.id.hex();
  63. ret["name"] = _p.clientVersion;
  64. ret["network"]["remoteAddress"] = _p.host + ":" + toString(_p.port);
  65. ret["lastPing"] = (int)chrono::duration_cast<chrono::milliseconds>(_p.lastPing).count();
  66. for (auto const& i: _p.notes)
  67. ret["notes"][i.first] = i.second;
  68. for (auto const& i: _p.caps)
  69. ret["caps"].append(i.first + "/" + toString((unsigned)i.second));
  70. return ret;
  71. }
  72. }
  73. // ////////////////////////////////////////////////////////////////////////////////
  74. // eth
  75. // ////////////////////////////////////////////////////////////////////////////////
  76. namespace eth
  77. {
  78. Json::Value toJson(dev::eth::BlockHeader const& _bi, SealEngineFace* _sealer)
  79. {
  80. Json::Value res;
  81. if (_bi)
  82. {
  83. DEV_IGNORE_EXCEPTIONS(res["hash"] = toJS(_bi.hash()));
  84. res["parentHash"] = toJS(_bi.parentHash());
  85. res["sha3Uncles"] = toJS(_bi.sha3Uncles());
  86. res["author"] = toJS(_bi.author());
  87. res["stateRoot"] = toJS(_bi.stateRoot());
  88. res["transactionsRoot"] = toJS(_bi.transactionsRoot());
  89. res["receiptsRoot"] = toJS(_bi.receiptsRoot());
  90. res["number"] = toJS(_bi.number());
  91. res["gasUsed"] = toJS(_bi.gasUsed());
  92. res["gasLimit"] = toJS(_bi.gasLimit());
  93. res["extraData"] = toJS(_bi.extraData());
  94. res["logsBloom"] = toJS(_bi.logBloom());
  95. res["timestamp"] = toJS(_bi.timestamp());
  96. // TODO: remove once JSONRPC spec is updated to use "author" over "miner".
  97. res["miner"] = toJS(_bi.author());
  98. if (_sealer)
  99. for (auto const& i: _sealer->jsInfo(_bi))
  100. res[i.first] = i.second;
  101. }
  102. return res;
  103. }
  104. Json::Value toJson(dev::eth::Transaction const& _t, std::pair<h256, unsigned> _location, BlockNumber _blockNumber)
  105. {
  106. Json::Value res;
  107. if (_t)
  108. {
  109. res["hash"] = toJS(_t.sha3());
  110. res["input"] = toJS(_t.data());
  111. res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress());
  112. res["from"] = toJS(_t.safeSender());
  113. res["gas"] = toJS(_t.gas());
  114. res["gasPrice"] = toJS(_t.gasPrice());
  115. res["nonce"] = toJS(_t.nonce());
  116. res["value"] = toJS(_t.value());
  117. res["blockHash"] = toJS(_location.first);
  118. res["transactionIndex"] = toJS(_location.second);
  119. res["blockNumber"] = toJS(_blockNumber);
  120. }
  121. return res;
  122. }
  123. Json::Value toJson(dev::eth::BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts, SealEngineFace* _face)
  124. {
  125. Json::Value res = toJson(_bi, _face);
  126. if (_bi)
  127. {
  128. res["totalDifficulty"] = toJS(_bd.totalDifficulty);
  129. res["uncles"] = Json::Value(Json::arrayValue);
  130. for (h256 h: _us)
  131. res["uncles"].append(toJS(h));
  132. res["transactions"] = Json::Value(Json::arrayValue);
  133. for (unsigned i = 0; i < _ts.size(); i++)
  134. res["transactions"].append(toJson(_ts[i], std::make_pair(_bi.hash(), i), (BlockNumber)_bi.number()));
  135. }
  136. return res;
  137. }
  138. Json::Value toJson(dev::eth::BlockHeader const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts, SealEngineFace* _face)
  139. {
  140. Json::Value res = toJson(_bi, _face);
  141. if (_bi)
  142. {
  143. res["totalDifficulty"] = toJS(_bd.totalDifficulty);
  144. res["uncles"] = Json::Value(Json::arrayValue);
  145. for (h256 h: _us)
  146. res["uncles"].append(toJS(h));
  147. res["transactions"] = Json::Value(Json::arrayValue);
  148. for (h256 const& t: _ts)
  149. res["transactions"].append(toJS(t));
  150. }
  151. return res;
  152. }
  153. Json::Value toJson(dev::eth::TransactionSkeleton const& _t)
  154. {
  155. Json::Value res;
  156. res["to"] = _t.creation ? Json::Value() : toJS(_t.to);
  157. res["from"] = toJS(_t.from);
  158. res["gas"] = toJS(_t.gas);
  159. res["gasPrice"] = toJS(_t.gasPrice);
  160. res["value"] = toJS(_t.value);
  161. res["data"] = toJS(_t.data, 32);
  162. return res;
  163. }
  164. Json::Value toJson(dev::eth::TransactionReceipt const& _t)
  165. {
  166. Json::Value res;
  167. res["stateRoot"] = toJS(_t.stateRoot());
  168. res["gasUsed"] = toJS(_t.gasUsed());
  169. res["bloom"] = toJS(_t.bloom());
  170. res["log"] = dev::toJson(_t.log());
  171. return res;
  172. }
  173. Json::Value toJson(dev::eth::LocalisedTransactionReceipt const& _t)
  174. {
  175. Json::Value res;
  176. res["transactionHash"] = toJS(_t.hash());
  177. res["transactionIndex"] = _t.transactionIndex();
  178. res["blockHash"] = toJS(_t.blockHash());
  179. res["blockNumber"] = _t.blockNumber();
  180. res["cumulativeGasUsed"] = toJS(_t.gasUsed()); // TODO: check if this is fine
  181. res["gasUsed"] = toJS(_t.gasUsed());
  182. res["contractAddress"] = toJS(_t.contractAddress());
  183. res["logs"] = dev::toJson(_t.localisedLogs());
  184. return res;
  185. }
  186. Json::Value toJson(dev::eth::Transaction const& _t)
  187. {
  188. Json::Value res;
  189. res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.to());
  190. res["from"] = toJS(_t.from());
  191. res["gas"] = toJS(_t.gas());
  192. res["gasPrice"] = toJS(_t.gasPrice());
  193. res["value"] = toJS(_t.value());
  194. res["data"] = toJS(_t.data(), 32);
  195. res["nonce"] = toJS(_t.nonce());
  196. res["hash"] = toJS(_t.sha3(WithSignature));
  197. res["sighash"] = toJS(_t.sha3(WithoutSignature));
  198. res["r"] = toJS(_t.signature().r);
  199. res["s"] = toJS(_t.signature().s);
  200. res["v"] = toJS(_t.signature().v);
  201. return res;
  202. }
  203. Json::Value toJson(dev::eth::LocalisedTransaction const& _t)
  204. {
  205. Json::Value res;
  206. if (_t)
  207. {
  208. res["hash"] = toJS(_t.sha3());
  209. res["input"] = toJS(_t.data());
  210. res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress());
  211. res["from"] = toJS(_t.safeSender());
  212. res["gas"] = toJS(_t.gas());
  213. res["gasPrice"] = toJS(_t.gasPrice());
  214. res["nonce"] = toJS(_t.nonce());
  215. res["value"] = toJS(_t.value());
  216. res["blockHash"] = toJS(_t.blockHash());
  217. res["transactionIndex"] = toJS(_t.transactionIndex());
  218. res["blockNumber"] = toJS(_t.blockNumber());
  219. }
  220. return res;
  221. }
  222. Json::Value toJson(dev::eth::LocalisedLogEntry const& _e)
  223. {
  224. Json::Value res;
  225. if (_e.isSpecial)
  226. res = toJS(_e.special);
  227. else
  228. {
  229. res = toJson(static_cast<dev::eth::LogEntry const&>(_e));
  230. res["polarity"] = _e.polarity == BlockPolarity::Live ? true : false;
  231. if (_e.mined)
  232. {
  233. res["type"] = "mined";
  234. res["blockNumber"] = _e.blockNumber;
  235. res["blockHash"] = toJS(_e.blockHash);
  236. res["logIndex"] = _e.logIndex;
  237. res["transactionHash"] = toJS(_e.transactionHash);
  238. res["transactionIndex"] = _e.transactionIndex;
  239. }
  240. else
  241. {
  242. res["type"] = "pending";
  243. res["blockNumber"] = Json::Value(Json::nullValue);
  244. res["blockHash"] = Json::Value(Json::nullValue);
  245. res["logIndex"] = Json::Value(Json::nullValue);
  246. res["transactionHash"] = Json::Value(Json::nullValue);
  247. res["transactionIndex"] = Json::Value(Json::nullValue);
  248. }
  249. }
  250. return res;
  251. }
  252. Json::Value toJson(dev::eth::LogEntry const& _e)
  253. {
  254. Json::Value res;
  255. res["data"] = toJS(_e.data);
  256. res["address"] = toJS(_e.address);
  257. res["topics"] = Json::Value(Json::arrayValue);
  258. for (auto const& t: _e.topics)
  259. res["topics"].append(toJS(t));
  260. return res;
  261. }
  262. Json::Value toJson(std::unordered_map<h256, dev::eth::LocalisedLogEntries> const& _entriesByBlock, vector<h256> const& _order)
  263. {
  264. Json::Value res(Json::arrayValue);
  265. for (auto const& i: _order)
  266. {
  267. auto entries = _entriesByBlock.at(i);
  268. Json::Value currentBlock(Json::objectValue);
  269. LocalisedLogEntry entry = entries[0];
  270. if (entry.mined)
  271. {
  272. currentBlock["blockNumber"] = entry.blockNumber;
  273. currentBlock["blockHash"] = toJS(entry.blockHash);
  274. currentBlock["type"] = "mined";
  275. }
  276. else
  277. currentBlock["type"] = "pending";
  278. currentBlock["polarity"] = entry.polarity == BlockPolarity::Live ? true : false;
  279. currentBlock["logs"] = Json::Value(Json::arrayValue);
  280. for (LocalisedLogEntry const& e: entries)
  281. {
  282. Json::Value log(Json::objectValue);
  283. log["logIndex"] = e.logIndex;
  284. log["transactionIndex"] = e.transactionIndex;
  285. log["transactionHash"] = toJS(e.transactionHash);
  286. log["address"] = toJS(e.address);
  287. log["data"] = toJS(e.data);
  288. log["topics"] = Json::Value(Json::arrayValue);
  289. for (auto const& t: e.topics)
  290. log["topics"].append(toJS(t));
  291. currentBlock["logs"].append(log);
  292. }
  293. res.append(currentBlock);
  294. }
  295. return res;
  296. }
  297. Json::Value toJsonByBlock(LocalisedLogEntries const& _entries)
  298. {
  299. vector<h256> order;
  300. unordered_map <h256, LocalisedLogEntries> entriesByBlock;
  301. for (dev::eth::LocalisedLogEntry const& e: _entries)
  302. {
  303. if (e.isSpecial) // skip special log
  304. continue;
  305. if (entriesByBlock.count(e.blockHash) == 0)
  306. {
  307. entriesByBlock[e.blockHash] = LocalisedLogEntries();
  308. order.push_back(e.blockHash);
  309. }
  310. entriesByBlock[e.blockHash].push_back(e);
  311. }
  312. return toJson(entriesByBlock, order);
  313. }
  314. TransactionSkeleton toTransactionSkeleton(Json::Value const& _json)
  315. {
  316. TransactionSkeleton ret;
  317. if (!_json.isObject() || _json.empty())
  318. return ret;
  319. if (!_json["from"].empty())
  320. ret.from = jsToAddress(_json["from"].asString());
  321. if (!_json["to"].empty() && _json["to"].asString() != "0x")
  322. ret.to = jsToAddress(_json["to"].asString());
  323. else
  324. ret.creation = true;
  325. if (!_json["value"].empty())
  326. ret.value = jsToU256(_json["value"].asString());
  327. if (!_json["gas"].empty())
  328. ret.gas = jsToU256(_json["gas"].asString());
  329. if (!_json["gasPrice"].empty())
  330. ret.gasPrice = jsToU256(_json["gasPrice"].asString());
  331. if (!_json["data"].empty()) // ethereum.js has preconstructed the data array
  332. ret.data = jsToBytes(_json["data"].asString(), OnFailed::Throw);
  333. if (!_json["code"].empty())
  334. ret.data = jsToBytes(_json["code"].asString(), OnFailed::Throw);
  335. if (!_json["nonce"].empty())
  336. ret.nonce = jsToU256(_json["nonce"].asString());
  337. return ret;
  338. }
  339. dev::eth::LogFilter toLogFilter(Json::Value const& _json)
  340. {
  341. dev::eth::LogFilter filter;
  342. if (!_json.isObject() || _json.empty())
  343. return filter;
  344. // check only !empty. it should throw exceptions if input params are incorrect
  345. if (!_json["fromBlock"].empty())
  346. filter.withEarliest(jsToFixed<32>(_json["fromBlock"].asString()));
  347. if (!_json["toBlock"].empty())
  348. filter.withLatest(jsToFixed<32>(_json["toBlock"].asString()));
  349. if (!_json["address"].empty())
  350. {
  351. if (_json["address"].isArray())
  352. for (auto i : _json["address"])
  353. filter.address(jsToAddress(i.asString()));
  354. else
  355. filter.address(jsToAddress(_json["address"].asString()));
  356. }
  357. if (!_json["topics"].empty())
  358. for (unsigned i = 0; i < _json["topics"].size(); i++)
  359. {
  360. if (_json["topics"][i].isArray())
  361. {
  362. for (auto t: _json["topics"][i])
  363. if (!t.isNull())
  364. filter.topic(i, jsToFixed<32>(t.asString()));
  365. }
  366. else if (!_json["topics"][i].isNull()) // if it is anything else then string, it should and will fail
  367. filter.topic(i, jsToFixed<32>(_json["topics"][i].asString()));
  368. }
  369. return filter;
  370. }
  371. // TODO: this should be removed once we decide to remove backward compatibility with old log filters
  372. dev::eth::LogFilter toLogFilter(Json::Value const& _json, Interface const& _client) // commented to avoid warning. Uncomment once in use @ PoC-7.
  373. {
  374. dev::eth::LogFilter filter;
  375. if (!_json.isObject() || _json.empty())
  376. return filter;
  377. // check only !empty. it should throw exceptions if input params are incorrect
  378. if (!_json["fromBlock"].empty())
  379. filter.withEarliest(_client.hashFromNumber(jsToBlockNumber(_json["fromBlock"].asString())));
  380. if (!_json["toBlock"].empty())
  381. filter.withLatest(_client.hashFromNumber(jsToBlockNumber(_json["toBlock"].asString())));
  382. if (!_json["address"].empty())
  383. {
  384. if (_json["address"].isArray())
  385. for (auto i : _json["address"])
  386. filter.address(jsToAddress(i.asString()));
  387. else
  388. filter.address(jsToAddress(_json["address"].asString()));
  389. }
  390. if (!_json["topics"].empty())
  391. for (unsigned i = 0; i < _json["topics"].size(); i++)
  392. {
  393. if (_json["topics"][i].isArray())
  394. {
  395. for (auto t: _json["topics"][i])
  396. if (!t.isNull())
  397. filter.topic(i, jsToFixed<32>(t.asString()));
  398. }
  399. else if (!_json["topics"][i].isNull()) // if it is anything else then string, it should and will fail
  400. filter.topic(i, jsToFixed<32>(_json["topics"][i].asString()));
  401. }
  402. return filter;
  403. }
  404. }
  405. // ////////////////////////////////////////////////////////////////////////////////////
  406. // shh
  407. // ////////////////////////////////////////////////////////////////////////////////////
  408. namespace shh
  409. {
  410. Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message const& _m)
  411. {
  412. Json::Value res;
  413. res["hash"] = toJS(_h);
  414. res["expiry"] = toJS(_e.expiry());
  415. res["sent"] = toJS(_e.sent());
  416. res["ttl"] = toJS(_e.ttl());
  417. res["workProved"] = toJS(_e.workProved());
  418. res["topics"] = Json::Value(Json::arrayValue);
  419. for (auto const& t: _e.topic())
  420. res["topics"].append(toJS(t));
  421. res["payload"] = toJS(_m.payload());
  422. res["from"] = toJS(_m.from());
  423. res["to"] = toJS(_m.to());
  424. return res;
  425. }
  426. shh::Message toMessage(Json::Value const& _json)
  427. {
  428. shh::Message ret;
  429. if (!_json["from"].empty())
  430. ret.setFrom(jsToPublic(_json["from"].asString()));
  431. if (!_json["to"].empty())
  432. ret.setTo(jsToPublic(_json["to"].asString()));
  433. if (!_json["payload"].empty())
  434. ret.setPayload(jsToBytes(_json["payload"].asString()));
  435. return ret;
  436. }
  437. shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret const& _from)
  438. {
  439. unsigned ttl = 50;
  440. unsigned workToProve = 50;
  441. shh::BuildTopic bt;
  442. if (!_json["ttl"].empty())
  443. ttl = jsToInt(_json["ttl"].asString());
  444. if (!_json["workToProve"].empty())
  445. workToProve = jsToInt(_json["workToProve"].asString());
  446. if (!_json["topics"].empty())
  447. for (auto i: _json["topics"])
  448. {
  449. if (i.isArray())
  450. {
  451. for (auto j: i)
  452. if (!j.isNull())
  453. bt.shift(jsToBytes(j.asString()));
  454. }
  455. else if (!i.isNull()) // if it is anything else then string, it should and will fail
  456. bt.shift(jsToBytes(i.asString()));
  457. }
  458. return _m.seal(_from, bt, ttl, workToProve);
  459. }
  460. pair<shh::Topics, Public> toWatch(Json::Value const& _json)
  461. {
  462. shh::BuildTopic bt;
  463. Public to;
  464. if (!_json["to"].empty())
  465. to = jsToPublic(_json["to"].asString());
  466. if (!_json["topics"].empty())
  467. for (auto i: _json["topics"])
  468. bt.shift(jsToBytes(i.asString()));
  469. return make_pair(bt, to);
  470. }
  471. }
  472. // ////////////////////////////////////////////////////////////////////////////////////
  473. // rpc
  474. // ////////////////////////////////////////////////////////////////////////////////////
  475. namespace rpc
  476. {
  477. u256 u256fromHex(string const& _s)
  478. {
  479. try
  480. {
  481. return u256(_s);
  482. }
  483. catch (runtime_error const&)
  484. {
  485. throw jsonrpc::JsonRpcException("Invalid hex-encoded string: " + _s);
  486. }
  487. }
  488. }
  489. }