ether请求demo—–php
php通过ether访问以太坊提供的转账,新建用户等服务。
<?php class Ethereum { private $host = '172.31.186.212'; //IP地址 private $port = '8899'; //启动eth 的端口 private $version = '2.0'; //版本 private $debug = false; //开发者模式 private $coinbase = '0x95140bf555c71xxxxxxxxxxxxxxxxxdabce'; //主钱包地址 private $coinbasePwd = 'lixxxxxxxxxx21'; //主钱包密码 public $shouxu = 0; //转入手续费倍数,如 1%,则值为 0.01 public $transferGas = '0.0005'; //手续费金额 //public $contractAddress = '0x6e6D8d87906e7354905838258cFc204eaDd92185'; private $rpcId = 0; private $contractAddress = "0x6e6D8d87906e7354905838258cFc204eaDd92185"; public function __construct() { } private function checkRpcResult($data) { $result = null; if (empty($data['error']) && !empty($data['result'])) { $result = $data['result']; } else { if ($this->debug) { $result = $data; } else { $result = $data; } } return $result; } private function request($method, $params = array()) { $data = array(); $data['jsonrpc'] = $this->version; $data['id'] = 999999; // $data['id'] = $this->rpcId + 1; $data['method'] = $method; $data['params'] = $params; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->host); curl_setopt($ch, CURLOPT_PORT, $this->port); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); $ret = curl_exec($ch); curl_close($ch); //返回结果 if ($ret) { // dump(json_decode($ret, true));exit(); //return $ret; return $this->checkRpcResult(json_decode($ret, true)); } else { return 123; } } private function eth_gasPrice() { return $this->request(__FUNCTION__); } private function eth_getBalance($address) { return $this->request(__FUNCTION__, array($address, 'latest')); } private function eth_getTransactionByHash($txHash) { return $this->request(__FUNCTION__, array($txHash)); } private function eth_sendTransaction($from, $to, $gas, $gasPrice, $value, $data) { $transVue = array(); $transVue['from'] = $from; $transVue['to'] = $to; $transVue['gas'] = $gas; $transVue['gasPrice'] = $gasPrice; $transVue['value'] = $value; $transVue['data'] = $data; return $this->request(__FUNCTION__, array($transVue)); } private function eth_call($from, $to, $gas, $gasPrice, $value, $data) { $callVue = array(); $callVue['from'] = $from; $callVue['to'] = $to; $callVue['gas'] = $gas; $callVue['gasPrice'] = $gasPrice; $callVue['value'] = $value; $callVue['data'] = $data; return $this->request(__FUNCTION__, array($callVue, 'latest')); } private function eth_estimateGas($from, $to, $gas, $gasPrice, $value, $data) { $callVue = array(); $callVue['from'] = $from; $callVue['to'] = $to; $callVue['gas'] = $gas; $callVue['gasPrice'] = $gasPrice; $callVue['value'] = $value; $callVue['data'] = $data; return $this->request(__FUNCTION__, array($callVue)); } private function personal_unlockAccount($account, $password, $duration = 20) { $params = array( $account, $password, $duration ); return $this->request(__FUNCTION__, $params); } private function personal_newAccount($password) { return $this->rand_str(); exit; /* 原区块链的账号注册 $result = false; if (is_string($password) && strlen($password) > 0) { return $this->request(__FUNCTION__, array($password)); }*/ } /** *获取随机字符串 * @param int $randLength 长度 * @param int $addtime 是否加入当前时间戳 * @param int $includenumber 是否包含数字 * @return string */ private function rand_str($randLength = 40, $addtime = 0, $includenumber = 1) { if ($includenumber) { $chars = 'abcdefghijklmnopqrstuvwxyz123456789'; } else { $chars = 'abcdefghijklmnopqrstuvwxyz'; } $len = strlen($chars); $randStr = ''; for ($i = 0; $i < $randLength; $i++) { $randStr .= $chars[mt_rand(0, $len - 1)]; } $tokenvalue = $randStr; if ($addtime) { $tokenvalue = $randStr . time(); } return '0x' . $tokenvalue; } private function createPassword() { $str = md5(rand(0, 999) . rand(0, 999) . time() . rand(0, 999) . rand(0, 999)); $strArr = str_split($str); for ($i = 0; $i < (count($strArr) - 1) / 2; $i++) { $temp = $strArr[$i]; $strArr[$i] = $str[count($strArr) - 1 - $i]; $strArr[count($strArr) - 1 - $i] = $temp; } $str = ''; foreach ($strArr as $v) { $str = $str . $v; } return $str; } public function checkTransactioning($txHash) { $result = false; $transaction = $this->eth_getTransactionByHash($txHash); if ($transaction && isset($transaction['blockNumber'])) { $result = $transaction['blockNumber'] ? true : false; } return $result; } public function checkAmount($amount) { return is_numeric($amount); } public function checkAddress($address) { $result = false; if (ctype_alnum($address)) { if (strlen($address) == 42 && substr($address, 0, 2) == '0x') { $result = true; } } return $result; } //新建账号 public function createWallet() { $result = false; $wallet = null; $wallet['password'] = 'false'/*$this->createPassword()*/; $wallet['address'] = $this->personal_newAccount($wallet['password']); if ($wallet['address'] && is_string($wallet['address'])) { if (strlen($wallet['address']) == 42) { $result = $wallet; } } return $result; } public function balanceOfHLIANtoCoinBase() { return $this->balanceOfHLIAN($this->coinbase); } public function balanceOfCoinBase() { return $this->balanceOf($this->coinbase); } public function balanceOfHLIAN($address, $contractAddress = "") { $result = 0; if ($this->checkAddress($address)) { $data = null; $dataCode = '0x70a08231000000000000000000000000' . substr($address, 2, 40); $data = $this->eth_call($address, !$contractAddress ? $this->contractAddress : $contractAddress, '0x0', '0x0', '0x0', $dataCode); if ($data && !is_array($data)) { $result = bcdiv(number_format(hexdec($data), 0, '.', ''), number_format(1000000000000000000, 0, '.', ''), 18); } } return $result; } public function balanceOf($address) { $result = 0; if ($this->checkAddress($address)) { $data = $this->eth_getBalance($address); if ($data && !is_array($data)) { $result = bcdiv(number_format(hexdec($data), 0, '.', ''), number_format(1000000000000000000, 0, '.', ''), 18); } } return $result; } public function numToStr($num) { $result = ""; if (stripos($num, 'e') === false) { return $num; } while ($num > 0) { $v = $num - floor($num / 10) * 10; $num = floor($num / 10); $result = $v . $result; } return $result; } public function transferHLIAN($toAddress, $value, $contractAddress = "") { $result = false; if ($this->checkAddress($toAddress) && is_numeric($value)) { $ethBalance = $this->balanceOf($this->coinbase); $gasPriceHex = $this->eth_gasPrice(); $tokenEnough = false; $data = array(); $tokenBalance = $this->balanceOfHLIAN($this->coinbase); $tokenEnough = bcsub($tokenBalance, $value, 2) >= 0; if ($tokenEnough) { $data['to'] = !$contractAddress ? $this->contractAddress : $contractAddress; $data['value'] = '0x0'; $data['data'] = '0xa9059cbb000000000000000000000000' . substr($toAddress, 2, 40); $valueHex = base_convert(bcmul($value, number_format(100, 0, '.', ''), 0), 10, 16); $zeroStr = ''; for ($i = 1; $i <= (64 - strlen($valueHex)); $i++) { $zeroStr .= '0'; } $data['data'] = $data['data'] . $zeroStr . $valueHex; $gasLimitHex = $this->eth_estimateGas($this->coinbase, $data['to'], '0x0', '0x0', $data['value'], $data['data']); if (bcsub($ethBalance, bcdiv(bcmul(hexdec($gasPriceHex), hexdec($gasLimitHex)), number_format(1000000000000000000, 0, '.', ''), 18), 18) >= 0) { $unlockStatus = $this->personal_unlockAccount($this->coinbase, $this->coinbasePwd); if ($unlockStatus) { $result = $this->eth_sendTransaction($this->coinbase, $data['to'], $gasLimitHex, $gasPriceHex, $data['value'], $data['data']); //echo json_encode($gasPriceHex);exit; } } } } return $result; } public function transferHLIANtoCoinbase($fromAddress, $value, $password) { $result = false; if ($this->checkAddress($fromAddress) && is_numeric($value)) { $ethBalance = $this->balanceOf($fromAddress); $gasPriceHex = $this->eth_gasPrice(); $tokenEnough = false; $data = array(); $tokenBalance = $this->balanceOfHLIAN($fromAddress); $tokenEnough = bcsub($tokenBalance, $value, 2) >= 0; if ($tokenEnough) { $data['to'] = $this->contractAddress; $data['value'] = '0x0'; $data['data'] = '0xa9059cbb000000000000000000000000' . substr($this->coinbase, 2, 40); $valueHex = base_convert(bcmul($value, number_format(1000000000000000000, 0, '.', ''), 0), 10, 16); $zeroStr = ''; for ($i = 1; $i <= (64 - strlen($valueHex)); $i++) { $zeroStr .= '0'; } $data['data'] = $data['data'] . $zeroStr . $valueHex; $gasLimitHex = $this->eth_estimateGas($fromAddress, $data['to'], '0x0', $gasPriceHex, $data['value'], $data['data']); if (bcsub($ethBalance, bcdiv(bcmul(hexdec($gasPriceHex), hexdec($gasLimitHex)), number_format(1000000000000000000, 0, '.', ''), 18), 18) >= 0) { $unlockStatus = $this->personal_unlockAccount($fromAddress, $password); if ($unlockStatus) { $result = $this->eth_sendTransaction($fromAddress, $data['to'], $gasLimitHex, $gasPriceHex, $data['value'], $data['data']); } } } } return $result; } public function transferGas($toAddress) { $result = false; if ($this->checkAddress($toAddress)) { $ethBalance = $this->balanceOf($this->coinbase); $gasPriceHex = $this->eth_gasPrice(); $tokenEnough = false; $data = array(); $ethBalance = bcsub($ethBalance, $this->transferGas, 18); $tokenEnough = $ethBalance >= 0; if ($tokenEnough) { $data['to'] = $toAddress; $data['value'] = '0x' . base_convert(bcmul($this->transferGas, number_format(1000000000000000000, 0, '.', ''), 0), 10, 16); $data['data'] = '0x'; $gasLimitHex = $this->eth_estimateGas($this->coinbase, $data['to'], '0x0', $gasPriceHex, $data['value'], $data['data']); if (bcsub($ethBalance, bcdiv(bcmul(hexdec($gasPriceHex), hexdec($gasLimitHex)), number_format(1000000000000000000, 0, '.', ''), 18), 18) >= 0) { $unlockStatus = $this->personal_unlockAccount($this->coinbase, $this->coinbasePwd); if ($unlockStatus) { $result = $this->eth_sendTransaction($this->coinbase, $data['to'], $gasLimitHex, $gasPriceHex, $data['value'], $data['data']); } } } } return $result; } public function transferFromCoinbase($toAddress, $amount) { $result = false; if ($this->checkAddress($toAddress) && is_numeric($amount)) { $ethBalance = $this->balanceOf($this->coinbase); $gasPriceHex = $this->eth_gasPrice(); $tokenEnough = false; $data = array(); $ethBalance = bcsub($ethBalance, $amount, 18); $tokenEnough = $ethBalance >= 0; if ($tokenEnough) { $data['to'] = $toAddress; $data['value'] = '0x' . base_convert(bcmul($amount, number_format(1000000000000000000, 0, '.', ''), 0), 10, 16); $data['data'] = '0x'; $gasLimitHex = $this->eth_estimateGas($this->coinbase, $data['to'], '0x0', $gasPriceHex, $data['value'], $data['data']); if (bcsub($ethBalance, bcdiv(bcmul(hexdec($gasPriceHex), hexdec($gasLimitHex)), number_format(1000000000000000000, 0, '.', ''), 18), 18) >= 0) { $unlockStatus = $this->personal_unlockAccount($this->coinbase, $this->coinbasePwd); if ($unlockStatus) { $result = $this->eth_sendTransaction($this->coinbase, $data['to'], $gasLimitHex, $gasPriceHex, $data['value'], $data['data']); } } } } return $result; } }