关于PHP 操作eth钱包私链的工具类少之又少,这是本人利用EthCommon.class这个工具类 写的eth钱包私链操作方法
<?php
require("EthCommon.class.php");
//token合约地址
$tbos_ctadr='0xe5fc11fae0a453b56f708288acc46320e12cc0b7';
$candy_ctadr="0x45555629AAbfEA138EAd1C1E5f2AC3Cce2aDd830";//CANDY
$usdt_ctadr="0xdac17f958d2ee523a2206206994597c13d831ec7";
query_trading_record("0x9DBC9be51a4ffe4D0905e4406b87bF6A2F105C8C",$usdt_ctadr);
/**
* 查询交易记录(在线接口)
* 如果$contractAddress为空则默认查询eth,不为空则根据代币合约地址查询代币
*
*/
function query_trading_record($address,$contractAddress){//
$action="txlist";
if($contractAddress){
$contractAddress="&contractAddress=".$contractAddress;
$action="tokentx";
}
date_default_timezone_set("Asia/Shanghai");
$url1='http://api-cn.etherscan.com/api?module=account&action='.$action.'&sort=desc&address='.$address.$contractAddress; //交易记录
print_r($url1);
$url2="http://api-cn.etherscan.com/v4/latest/USD";//货币 汇率兑换
$url3="http://api-cn.etherscan.com/api?module=stats&action=ethprice";//ETH最新价格
$rsobj1 = file_get_contents($url1);
$rsobj2 = file_get_contents($url2);
$rsobj3 = file_get_contents($url3);
echo "\n";
$trading_record=json_decode($rsobj1);
$exchange_rate=json_decode($rsobj2);
$eth_money=json_decode($rsobj3);
echo "\n";
print_r("USD($)".$exchange_rate->rates->USD." = "."RMB(¥)".$exchange_rate->rates->CNY." 校准时间:".date('Y-m-d H:i:s',$exchange_rate->time_last_updated));
echo "\n";
print_r("ETH $".$eth_money->result->ethusd);
echo " ";
print_r("ETH ¥".$exchange_rate->rates->CNY*$eth_money->result->ethusd);
echo " ";
$times=$eth_money->result->ethusd_timestamp;
print_r(" 校准时间:".date('Y-m-d H:i:s',$times));
if($contractAddress){
$nums= pow(10,intval($trading_record->result[0]->tokenDecimal));// wei 基本单位
}else{
$nums= pow(10,18);
}
$trsize=count($trading_record->result);
for($indexs=0;$indexs<$trsize;$indexs++){
$blockNumber=$trading_record->result[$indexs]->blockNumber;
$timeStamp=date('Y-m-d H:i:s',$trading_record->result[$indexs]->timeStamp);
$hash=$trading_record->result[$indexs]->hash;
$nonce=$trading_record->result[$indexs]->nonce;
$blockHash=$trading_record->result[$indexs]->blockHash;
$transactionIndex=$trading_record->result[$indexs]->transactionIndex;
$from=$trading_record->result[$indexs]->from;
$to=$trading_record->result[$indexs]->to;
$money_eth=number_format($trading_record->result[$indexs]->value / $nums,10)." ether";
$gas=$trading_record->result[$indexs]->gas;
$gasPrice=number_format($trading_record->result[$indexs]->gasPrice / $nums,10);
$gasUsed=$trading_record->result[$indexs]->gasUsed;
$cumulativeGasUsed=$trading_record->result[$indexs]->cumulativeGasUsed;
$miner_servicecharge=number_format($gasPrice * $gasUsed,10)." ether";
$money_usd=number_format($money_eth*$eth_money->result->ethusd,10);
$money_cny=number_format($money_eth*$exchange_rate->rates->CNY*$eth_money->result->ethusd,10);
echo "\n";
print_r("区块:".$blockNumber);
echo "\n";
print_r("时间:".$timeStamp);
echo "\n";
print_r("交易号:".$hash);
echo "\n";
print_r("随机数:".$nonce);
echo "\n";
print_r("区块哈希:".$blockHash);
echo "\n";
print_r("区块索引位置:".$transactionIndex);
echo "\n";
print_r("付款地址:".$from);
echo "\n";
print_r("收款地址:".$to);
echo "\n";
print_r("金额:".$money_eth." $:".$money_usd." ¥:".$money_cny);//
echo "\n";
print_r("燃料限制:".$gas);
echo "\n";
print_r("燃料价格:".$gasPrice);
echo "\n";
print_r("交易燃料费用:".$gasUsed);
echo "\n";
print_r("累计使用燃料:".$cumulativeGasUsed);
echo "\n";
print_r("矿工费用:".$miner_servicecharge);
echo "\n";
echo " ";
}
}
/**
* eth转账(geth)
*/
function eth_tr($from,$to,$pwd,$value){
$eth = new EthCommon('192.168.1.1','37564');
$wei=pow(10,18);;// wei 基本单位
$b=$value*$wei;
$b = number_format($b, 0, '', '');
$amounthex=base_convert($b, 10, 16);
$hash= $eth->eth_sendTransaction($from,$to,$pwd,$amounthex);
echo $hash;
}
/**
* 代币转账(geth)
* 如果合约地址是usdt,$exp的值则为6,$exp的为wei单位,自行去eth浏览器查看
* $value:欲转出的数量
* $exp:代币的wei单位
*/
function token_transfer_accounts($from,$pwd,$to,$contractAddress,$value,$exp){
$ethc = new EthCommon('192.168.1.1','37564');
$methodid="0xa9059cbb";//data头部
$wei = pow(10,$exp);
$v=$value/$wei;
$num = pow(10,18);
$nums=$v*$num;
$sbstr=substr($to,2);
$nums = number_format($nums, 0, '', '');
$amounthex=base_convert($nums, 10, 16);
$amounthex = sprintf("%064s", $amounthex); //转换为64位
$dataraw=$methodid.'000000000000000000000000'.$sbstr.$amounthex;//拼接data
$hash= $ethc->eth_sendTransactionraw($from,$contractAddress,$pwd,$dataraw);
echo ' 交易执行返回结果:'.$hash;
}
这个EthCommon.class.php类不是本人写的,是从网上找的
<?php
class EthCommon
{
protected $host, $port, $version;
protected $id = 0;
public $base = 1000000000000000000;//1e18 wei 基本单位
/**
* 构造函数
* Common constructor.
* @param $host
* @param string $port
* @param string $version
*/
function __construct($host, $port = "80", $version = "2.0")
{
$this->host = $host;
$this->port = $port;
$this->version = $version;
}
/**
* 发送请求
* @author qiuphp2
* @since 2017-9-21
* @param $method
* @param array $params
* @return mixed
*/
function request($method, $params = array())
{
$data = array();
$data['jsonrpc'] = $this->version;
$data['id'] = $this->id + 1;
$data['method'] = $method;
$data['params'] = $params;
// echo json_encode($data);
$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);
//返回结果
if ($ret) {
curl_close($ch);
return json_decode($ret, true);
} else {
$error = curl_errno($ch);
curl_close($ch);
return json_decode('ETH钱包服务器连接失败', true);
// throw new Exception("curl出错,错误码:$error");
}
}
/**
* @author qiuphp2
* @since 2017-9-21
* @param $weiNumber 16进制wei单位
* @return float|int 10进制eth单位【正常单位】
*/
function fromWei($weiNumber)
{
$ethNumber = hexdec($weiNumber) / $this->base;
return $ethNumber;
}
/**
* @author qiuphp2
* @since 2017-9-21
* @param $ethNumber 10进制eth单位
* @return string 16进制wei单位
*/
function toWei($ethNumber)
{
$weiNumber = dechex($ethNumber * $this->base);
// $weiNumber = float($weiNumber);
return $weiNumber;
}
/**
* 判断是否是16进制
* @author qiuphp2
* @since 2017-9-21
* @param $a
* @return int
*/
function assertIsHex($a)
{
if (ctype_xdigit($a)) {
return true;
} else {
return false;
}
}
/**
* 获取版本信息,判断是否连接
* @author qiuphp2
* @since 2017-9-19
*/
function web3_clientVersion()
{
$params = array();
$data = $this->request(__FUNCTION__, $params);
if ($data['result']) {
return true;
} else {
return false;
}
//return $data['result'];
}
/**
* 获取主账户
* @author qiuphp2
* @since 2017-9-19
*/
function eth_coinbase()
{
$params = array();
$data = $this->request(__FUNCTION__, $params);
if ($data['result']) {
return $data['result'];
} else {
return $data['error']['message'];
}
// return $data['result'];
}
/**
* 获取区块数量
* @author qiuphp2
* @since 2017-9-19
*/
function eth_blockNumber()
{
$params = array();
$data = $this->request(__FUNCTION__, $params);
if ($data['result']) {
return $data['result'];
} else {
return $data['error']['message'];
}
// return $data['result'];
}
/**
* 新建账号 有点耗时 最好给用户生成的之后,密码保存在数据库里面
* @author qiuphp2
* @since 2017-9-19
*/
function personal_newAccount($password='')//一般用账户名作为加密密码
{
// $password = "123";//密码
$params = array($password);
$data = $this->request(__FUNCTION__, $params);
if (empty($data['error']) && !empty($data['result'])) {
return $data['result'];//新生成的账号公钥
} else {
return $data['error']['message'];
}
}
/**
* @author qiuphp2
* @since 2017-9-21
* @return float|int 返回eth数量 10进制
*/
function eth_getBalance($account='')
{
// var_dump($account);
// $account = $_REQUEST['account'];//获得账号公钥
if ($account=='') {
echo '请传入账号公钥';
return false;
}
$params = [$account,"latest"];
$data = $this->request(__FUNCTION__, $params);
if (empty($data['error']) && !empty($data['result'])) {
// return $this->fromWei($data['result']);//返回eth数量,自己做四舍五入处理
return $data['result'];//返回eth数量,自己做四舍五入处理
} else {
return $data['error']['message'];
}
}
/**
* @author qiuphp2
* @since 2017-9-21
* @return float|int 返回eth数量 10进制
*/
function eth_getBalancehex($account='')
{
// var_dump($account);
// $account = $_REQUEST['account'];//获得账号公钥
if ($account=='') {
// echo '请传入账号公钥';
return false;
}
$params = [$account,"latest"];
$data = $this->request(eth_getBalance, $params);
if (empty($data['error']) && !empty($data['result'])) {
return $data['result'];//返回eth数量,自己做四舍五入处理
} else {
return $data['error']['message'];
}
}
/**
* 转账
* @author qiuphp2
* @since 2017-9-15
*/
function eth_sendTransaction($from='',$to='',$password='',$value='',$data='')
{
if ($from=='' || $to=='' || $password=='' || $value=='') {
// echo '传入参数缺失';
return false;
}
// if (!ctype_xdigit($value)) {
// $value = $this->toWei($value);//这里是发送10进制的方法
// }
$value = '0x'.$value;//转换成可识别格式
$gas = $this->eth_estimateGas($from, $to, $value);//16进制 消耗的gas 0x5209
$gasPrice = $this->eth_gasPrice();//价格 0x430e23400
$status = $this->personal_unlockAccount($from, $password);//解锁
if (!$status) {
return '解锁失败';
// return false;
}
$params = array(
"from" => $from,
"to" => $to,
"gas" => $gas,//'0x5208',//$gas,//21000
"gasPrice " => '0xC350',//$gasPrice,//18000000000//100000
"value" => $value,//2441406250
"data" => $data,
);
$data = $this->request(__FUNCTION__, [$params]);
if (empty($data['error']) && !empty($data['result'])) {
return $data['result'];//转账之后,生成HASH
// return true;
} else {
return $data['error']['message'];
// return false;
}
}
function eth_sendTransactionraw($from='',$to='',$password='',$data='')
{
if($from=='' || $to=='' || $password=='' || $data==''){
// return 'lost.';
return false;
}
$status = $this->personal_unlockAccount($from, $password);//解锁
if (!$status) {
// return 'unlock fail';
return false;
}
//"gas":"60000","gasPrice":"10000000000","gasUsed":"51522"
$params = array(
"from" => $from,
"to" => $to,
// "gas"=> "0x".dechex(2000),
// "gasPrice"=> "0x".dechex(1000000000),
// "gasUsed"=> "0X".dechex(51522),
// "gasLimit"=>"0x".dechex(10000000000),
"data" => $data,
);
$data = $this->request(eth_sendTransaction, [$params]);
if (empty($data['error']) && !empty($data['result'])) {
return $data['result'];//转账之后,生成HASH
// return true;
} else {
return $data['error']['message'];
// return false;
}
}
/**
* 转账详细信息
* @author qiuphp2
* @since 2017-9-20
*/
function eth_getTransactionReceipt($transactionHash='')
{
//$transactionHash = "0x536135ef85aa8015b086e77ab8c47b8d40a3d00a975a5b0cc93b2a6345f538cd";
if($transactionHash==''){
echo '缺少交易hash';
return false;
}
// 交易 hash
$params = array(
$transactionHash,
);
$data = $this->request(__FUNCTION__, $params);
if (empty($data['error'])) {
if (count($data['result']) == 0) {
$result['status'] = 0;
$result['data'] = '等待确认';
// echo '等待确认';
} else {
$result['status'] = 1;
$result['data'] = $data['result']['blockHash'];
// return $data['result']['blockHash'];//返回blockhash值
// return $data['result'];//转账成功了
}
} else {
$result['status'] = 0;
$result['data'] = $data['error']['message'];
// return $data['error']['message'];
}
return $result;
}
/**
* 获得消耗多少 GAS
* @author qiuphp2
* @since 2017-9-15
*/
function eth_estimateGas($from, $to, $value)
{
$params = array(
"from" => $from,
"to" => $to,
"value" => $value
);
$data = $this->request(__FUNCTION__, [$params]);
return $data['result'];
}
/**
* 获得当前 GAS 价格
* @author qiuphp2
* @since 2017-9-15
*/
function eth_gasPrice()
{
$params = array();
$data = $this->request(__FUNCTION__, $params);
return $data['result'];
}
/**
* 解锁账号 此函数可能比较耗时
* @author qiuphp2
* @since 2017-9-15
*/
function personal_unlockAccount($account, $password)
{
$params = array($account,$password,100);
$data = $this->request(__FUNCTION__, $params);
if (!empty($data['error'])) {
return $data['error']['message'];//解锁失败
} else {
return $data['result'];//成功返回true
}
}
function personal_listAccounts(){
$params = array();
$data = $this->request(__FUNCTION__, $params);
if (empty($data)) {
return false;
} else {
return $data['result'];//成功返回true
}
}
}
?>