EthCommon.class.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. <?php
  2. namespace Common\Ext;
  3. class EthCommon
  4. {
  5. protected $host, $port, $version;
  6. protected $id = 0;
  7. public $base = 1000000000000000000;//1e18 wei 基本单位
  8. /**
  9. * 构造函数
  10. * Common constructor.
  11. * @param $host
  12. * @param string $port
  13. * @param string $version
  14. */
  15. function __construct($host, $port = "80", $version = "2.0")
  16. {
  17. $this->host = $host;
  18. $this->port = $port;
  19. $this->version = $version;
  20. }
  21. /**
  22. * 发送请求
  23. * @author qiuphp2
  24. * @since 2017-9-21
  25. * @param $method
  26. * @param array $params
  27. * @return mixed
  28. */
  29. function request($method, $params = array())
  30. {
  31. $data = array();
  32. $data['jsonrpc'] = $this->version;
  33. $data['id'] = $this->id + 1;
  34. $data['method'] = $method;
  35. $data['params'] = $params;
  36. // echo json_encode($data);
  37. $ch = curl_init();
  38. curl_setopt($ch, CURLOPT_URL, $this->host);
  39. curl_setopt($ch, CURLOPT_PORT, $this->port);
  40. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  41. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
  42. curl_setopt($ch, CURLOPT_POST, TRUE);
  43. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  44. $ret = curl_exec($ch);
  45. //返回结果
  46. if ($ret) {
  47. curl_close($ch);
  48. return json_decode($ret, true);
  49. } else {
  50. $error = curl_errno($ch);
  51. curl_close($ch);
  52. return json_decode('ETH钱包服务器连接失败', true);
  53. // throw new Exception("curl出错,错误码:$error");
  54. }
  55. }
  56. /**
  57. * @author qiuphp2
  58. * @since 2017-9-21
  59. * @param $weiNumber 16进制wei单位
  60. * @return float|int 10进制eth单位【正常单位】
  61. */
  62. function fromWei($weiNumber)
  63. {
  64. $ethNumber = hexdec($weiNumber) / $this->base;
  65. return $ethNumber;
  66. }
  67. /**
  68. * @author qiuphp2
  69. * @since 2017-9-21
  70. * @param $ethNumber 10进制eth单位
  71. * @return string 16进制wei单位
  72. */
  73. function toWei($ethNumber)
  74. {
  75. $weiNumber = dechex($ethNumber * $this->base);
  76. // $weiNumber = float($weiNumber);
  77. return $weiNumber;
  78. }
  79. /**
  80. * 判断是否是16进制
  81. * @author qiuphp2
  82. * @since 2017-9-21
  83. * @param $a
  84. * @return int
  85. */
  86. function assertIsHex($a)
  87. {
  88. if (ctype_xdigit($a)) {
  89. return true;
  90. } else {
  91. return false;
  92. }
  93. }
  94. /**
  95. * 获取版本信息,判断是否连接
  96. * @author qiuphp2
  97. * @since 2017-9-19
  98. */
  99. function web3_clientVersion()
  100. {
  101. $params = array();
  102. $data = $this->request(__FUNCTION__, $params);
  103. if ($data['result']) {
  104. return true;
  105. } else {
  106. return false;
  107. }
  108. //return $data['result'];
  109. }
  110. /**
  111. * 获取主账户
  112. * @author qiuphp2
  113. * @since 2017-9-19
  114. */
  115. function eth_coinbase()
  116. {
  117. $params = array();
  118. $data = $this->request(__FUNCTION__, $params);
  119. if ($data['result']) {
  120. return $data['result'];
  121. } else {
  122. return $data['error']['message'];
  123. }
  124. // return $data['result'];
  125. }
  126. /**
  127. * 获取区块数量
  128. * @author qiuphp2
  129. * @since 2017-9-19
  130. */
  131. function eth_blockNumber()
  132. {
  133. $params = array();
  134. $data = $this->request(__FUNCTION__, $params);
  135. if ($data['result']) {
  136. return $data['result'];
  137. } else {
  138. return $data['error']['message'];
  139. }
  140. // return $data['result'];
  141. }
  142. /**
  143. * 新建账号 有点耗时 最好给用户生成的之后,密码保存在数据库里面
  144. * @author qiuphp2
  145. * @since 2017-9-19
  146. */
  147. function personal_newAccount($password='')//一般用账户名作为加密密码
  148. {
  149. // $password = "123";//密码
  150. $params = array($password);
  151. $data = $this->request(__FUNCTION__, $params);
  152. if (empty($data['error']) && !empty($data['result'])) {
  153. return $data['result'];//新生成的账号公钥
  154. } else {
  155. return $data['error']['message'];
  156. }
  157. }
  158. /**
  159. * @author qiuphp2
  160. * @since 2017-9-21
  161. * @return float|int 返回eth数量 10进制
  162. */
  163. function eth_getBalance($account='')
  164. {
  165. // var_dump($account);
  166. // $account = $_REQUEST['account'];//获得账号公钥
  167. if ($account=='') {
  168. echo '请传入账号公钥';
  169. return false;
  170. }
  171. $params = [$account,"latest"];
  172. $data = $this->request(__FUNCTION__, $params);
  173. if (empty($data['error']) && !empty($data['result'])) {
  174. // return $this->fromWei($data['result']);//返回eth数量,自己做四舍五入处理
  175. return $data['result'];//返回eth数量,自己做四舍五入处理
  176. } else {
  177. return $data['error']['message'];
  178. }
  179. }
  180. /**
  181. * @author qiuphp2
  182. * @since 2017-9-21
  183. * @return float|int 返回eth数量 10进制
  184. */
  185. function eth_getBalancehex($account='')
  186. {
  187. // var_dump($account);
  188. // $account = $_REQUEST['account'];//获得账号公钥
  189. if ($account=='') {
  190. // echo '请传入账号公钥';
  191. return false;
  192. }
  193. $params = [$account,"latest"];
  194. $data = $this->request(eth_getBalance, $params);
  195. if (empty($data['error']) && !empty($data['result'])) {
  196. return $data['result'];//返回eth数量,自己做四舍五入处理
  197. } else {
  198. return $data['error']['message'];
  199. }
  200. }
  201. /**
  202. * 转账
  203. * @author qiuphp2
  204. * @since 2017-9-15
  205. */
  206. function eth_sendTransaction($from='',$to='',$password='',$value='')
  207. {
  208. if ($from=='' || $to=='' || $password=='' || $value=='') {
  209. // echo '传入参数缺失';
  210. return false;
  211. }
  212. if (!ctype_xdigit($value)) {
  213. $value = $this->toWei($value);//这里是发送10进制的方法
  214. }
  215. $value = '0x'.$value;//转换成可识别格式
  216. $gas = $this->eth_estimateGas($from, $to, $value);//16进制 消耗的gas 0x5209
  217. $gasPrice = $this->eth_gasPrice();//价格 0x430e23400
  218. $status = $this->personal_unlockAccount($from, $password);//解锁
  219. if (!$status) {
  220. return '解锁失败';
  221. // return false;
  222. }
  223. $params = array(
  224. "from" => $from,
  225. "to" => $to,
  226. "gas" => $gas,//2100
  227. "gasPrice " => $gasPrice,//18000000000
  228. "value" => $value,//2441406250
  229. "data" => "",
  230. );
  231. $data = $this->request(__FUNCTION__, [$params]);
  232. if (empty($data['error']) && !empty($data['result'])) {
  233. return $data['result'];//转账之后,生成HASH
  234. // return true;
  235. } else {
  236. // return $data['error']['message'];
  237. return false;
  238. }
  239. }
  240. function eth_sendTransactionraw($from='',$to='',$password='',$data='')
  241. {
  242. if($from=='' || $to=='' || $password=='' || $data==''){
  243. // return 'lost.';
  244. return false;
  245. }
  246. $status = $this->personal_unlockAccount($from, $password);//解锁
  247. if (!$status) {
  248. // return 'unlock fail';
  249. return false;
  250. }
  251. $params = array(
  252. "from" => $from,
  253. "to" => $to,
  254. "data" => $data,
  255. );
  256. $data = $this->request(eth_sendTransaction, [$params]);
  257. if (empty($data['error']) && !empty($data['result'])) {
  258. return $data['result'];//转账之后,生成HASH
  259. // return true;
  260. } else {
  261. // return $data['error']['message'];
  262. return false;
  263. }
  264. }
  265. /**
  266. * 转账详细信息
  267. * @author qiuphp2
  268. * @since 2017-9-20
  269. */
  270. function eth_getTransactionReceipt($transactionHash='')
  271. {
  272. //$transactionHash = "0x536135ef85aa8015b086e77ab8c47b8d40a3d00a975a5b0cc93b2a6345f538cd";
  273. if($transactionHash==''){
  274. echo '缺少交易hash';
  275. return false;
  276. }
  277. // 交易 hash
  278. $params = array(
  279. $transactionHash,
  280. );
  281. $data = $this->request(__FUNCTION__, $params);
  282. if (empty($data['error'])) {
  283. if (count($data['result']) == 0) {
  284. $result['status'] = 0;
  285. $result['data'] = '等待确认';
  286. // echo '等待确认';
  287. } else {
  288. $result['status'] = 1;
  289. $result['data'] = $data['result']['blockHash'];
  290. // return $data['result']['blockHash'];//返回blockhash值
  291. // return $data['result'];//转账成功了
  292. }
  293. } else {
  294. $result['status'] = 0;
  295. $result['data'] = $data['error']['message'];
  296. // return $data['error']['message'];
  297. }
  298. return $result;
  299. }
  300. /**
  301. * 获得消耗多少 GAS
  302. * @author qiuphp2
  303. * @since 2017-9-15
  304. */
  305. function eth_estimateGas($from, $to, $value)
  306. {
  307. $params = array(
  308. "from" => $from,
  309. "to" => $to,
  310. "value" => $value
  311. );
  312. $data = $this->request(__FUNCTION__, [$params]);
  313. return $data['result'];
  314. }
  315. /**
  316. * 获得当前 GAS 价格
  317. * @author qiuphp2
  318. * @since 2017-9-15
  319. */
  320. function eth_gasPrice()
  321. {
  322. $params = array();
  323. $data = $this->request(__FUNCTION__, $params);
  324. return $data['result'];
  325. }
  326. /**
  327. * 解锁账号 此函数可能比较耗时
  328. * @author qiuphp2
  329. * @since 2017-9-15
  330. */
  331. function personal_unlockAccount($account, $password)
  332. {
  333. $params = array($account,$password,100);
  334. $data = $this->request(__FUNCTION__, $params);
  335. if (!empty($data['error'])) {
  336. return $data['error']['message'];//解锁失败
  337. } else {
  338. return $data['result'];//成功返回true
  339. }
  340. }
  341. function personal_listAccounts(){
  342. $params = array();
  343. $data = $this->request(__FUNCTION__, $params);
  344. if (empty($data)) {
  345. return false;
  346. } else {
  347. return $data['result'];//成功返回true
  348. }
  349. }
  350. }
  351. ?>