cari
Rumahpembangunan bahagian belakangtutorial phpphp与ethereum客户端交互使用详解

这次给大家带来php与ethereum客户端交互使用详解,php与ethereum客户端交互使用的注意事项有哪些,下面就是实战案例,一起来看一下。

php与ethereum rpc server通信

一、Json RPC

Json RPC就是基于json的远程过程调用,这么解释比较抽象。简单来说,就是post一个json格式的数据调用rpc server中的方法. 而这个json格式是固定的, 总的来说有这么几项:

{
  "method": "",
  "params": [],
  "id": idNumber
}
  • method: 方法名

  • params: 参数列表

  • id: 对过程调用的唯一标识号

二、构建一个Json RPC客户端

<?php
class jsonRPCClient {
  
  /**
   * Debug state
   *
   * @var boolean
   */
  private $debug;
  
  /**
   * The server URL
   *
   * @var string
   */
  private $url;
  /**
   * The request id
   *
   * @var integer
   */
  private $id;
  /**
   * If true, notifications are performed instead of requests
   *
   * @var boolean
   */
  private $notification = false;
  
  /**
   * Takes the connection parameters
   *
   * @param string $url
   * @param boolean $debug
   */
  public function construct($url,$debug = false) {
    // server URL
    $this->url = $url;
    // proxy
    empty($proxy) ? $this->proxy = &#39;&#39; : $this->proxy = $proxy;
    // debug state
    empty($debug) ? $this->debug = false : $this->debug = true;
    // message id
    $this->id = 1;
  }
  
  /**
   * Sets the notification state of the object. In this state, notifications are performed, instead of requests.
   *
   * @param boolean $notification
   */
  public function setRPCNotification($notification) {
    empty($notification) ?
              $this->notification = false
              :
              $this->notification = true;
  }
  
  /**
   * Performs a jsonRCP request and gets the results as an array
   *
   * @param string $method
   * @param array $params
   * @return array
   */
  public function call($method,$params) {
    
    // check
    if (!is_scalar($method)) {
      throw new Exception(&#39;Method name has no scalar value&#39;);
    }
    
    // check
    if (is_array($params)) {
      // no keys
      $params = $params[0];
    } else {
      throw new Exception(&#39;Params must be given as array&#39;);
    }
    
    // sets notification or request task
    if ($this->notification) {
      $currentId = NULL;
    } else {
      $currentId = $this->id;
    }
    
    // prepares the request
    $request = array(
            &#39;method&#39; => $method,
            &#39;params&#39; => $params,
            &#39;id&#39; => $currentId
            );
    $request = json_encode($request);
    $this->debug && $this->debug.=&#39;***** Request *****&#39;."\n".$request."\n".&#39;***** End Of request *****&#39;."\n\n";
    // performs the HTTP POST
    $opts = array (&#39;http&#39; => array (
              &#39;method&#39; => &#39;POST&#39;,
              &#39;header&#39; => &#39;Content-type: application/json&#39;,
              &#39;content&#39; => $request
              ));
    $context = stream_context_create($opts);
    if ($fp = fopen($this->url, &#39;r&#39;, false, $context)) {
      $response = &#39;&#39;;
      while($row = fgets($fp)) {
        $response.= trim($row)."\n";
      }
      $this->debug && $this->debug.=&#39;***** Server response *****&#39;."\n".$response.&#39;***** End of server response *****&#39;."\n";
      $response = json_decode($response,true);
    } else {
      throw new Exception(&#39;Unable to connect to &#39;.$this->url);
    }
    
    // debug output
    if ($this->debug) {
      echo nl2br($debug);
    }
    
    // final checks and return
    if (!$this->notification) {
      // check
      if ($response[&#39;id&#39;] != $currentId) {
        throw new Exception(&#39;Incorrect response id (request id: &#39;.$currentId.&#39;, response id: &#39;.$response[&#39;id&#39;].&#39;)&#39;);
      }
      if (!is_null($response[&#39;error&#39;])) {
        throw new Exception(&#39;Request error: &#39;. var_export($response[&#39;error&#39;], true));
      }
      
      return $response[&#39;result&#39;];
      
    } else {
      return true;
    }
  }
}
?>

比较简单的代码,如果比较懒,拿过去用就行了。也可以上packagist.org自己找一个rpc client.

三、调用RPC的两类方法

有两类方法需要调用. 一类是RPC server自带方法,另一类就是合约方法.

RPC server方法调用json格式

{
  "method": "eth_accounts",
  "params": [],
  "id": 1
}

RPC Server自带方法的列表

调用自带方法比较简单,参考上述链接,大部分都有示例.

合约方法调用json格式

调用合约方法必须使用自带方法中的eth_call. 而合约方法名称和合约方法参数列表则使用params进行体现, 比如: 我们要调用合约中的balanceOf方法, 则json数据应该如何构造呢?

首先看看getBalanace的函数实现:

function balanceOf(address _owner) public view returns (uint256 balance)

提炼出函数原型:

balanceOf(address)

在geth控制台下运行命令:

web3.sha3("balanceOf(address)").substring(0, 10)

得到函数hash "0x70a08231"

假设待查询的地址 address _owner = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", 则去掉前面的"0x", 并在左边补24个零(一般地址长度为42位, 去掉'0x'后为40位),构成64位十六进制参数.

最终得到的参数为 "0x70a0823100000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750"

假设我们的合约地址为 "0xaeab4084194B2a425096fb583Fbcd67385210ac3".

则得到最终的json数据为:

{
  "method": "eth_call",
  "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0x70a0823100000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750"}, "latest"],
  "id": 1
}

把以上json数据以post方式发送给服务器,就可以调用合约方法"balanceOf", 查询给定的地址中的代币余额.

调用合约中的其他方法也要新遵循上面的方式, 我们再分析一下transfer方法, 加深印象:

首先, 看看代码中的函数实现:

function transfer(address _to, uint256 _value) public returns (bool)

其次, 提炼出函数原型:

transfer(address,uint256) //注意逗号后面不能有空格

再次, 在控制台运行sha3函数:

web3.sha3("transfer(address,uint256)").substring(0, 10)

得到函数hash "0xa9059cbb"

第一个参数假设 address _to = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", 则去"0x", 补零到64位.

第二个参数假设 uint256 _value = 43776, 则化为十六进制"0xab00"后, 去"0x", 补零到64位.

连接起来

"0xa9059cbb00000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000000000000000000000000000000000000000000000000000ab00"

构建json数据:

{
  "method": "eth_call",
  "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0xa9059cbb00000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000000000000000000000000000000000000000000000000000ab00"}, "latest"],
  "id": 1
}
  • from 转出者地址

  • to 合约地址

  • data 上述操作得到的十六进制数

把以上的步骤转化为代码.

构建一个以太坊RPC client

<?php 
require &#39;./jsonRPCClient.php&#39;;
//php自带的dechex无法把大整型转换为十六进制
function bc_dechex($decimal)
{
  $result = [];
  while ($decimal != 0) {
    $mod = $decimal % 16;
    $decimal = floor($decimal / 16);
    array_push($result, dechex($mod));    
  }
  return join(array_reverse($result));
}
class EthereumRPCClient
{
  public static $client = null;
  
  //布署合约的账户地址
  const COINBASE = &#39;0x38aabef4cd283ccd5091298dedc88d27c5ec5750&#39;;
  
  //合约地址
  const CONTRACT = &#39;0xaeab4084194B2a425096fb583Fbcd67385210ac3&#39;;
  public static function callStatic($method, $params)
  {
    $params = count($params) < 1 ? [] : $params[0];
    try {
      if (is_null(self::$client)) {
        self::$client = new jsonRPCClient(&#39;http://127.0.0.1:8545&#39;, true);  
      }
    } catch (\Exception $e) {
      echo $e->getMessage();
    }
    return call_user_func([self::$client, $method], $params);
  }
  public static function getBalance($address)
  {
    $method_hash = &#39;0x70a08231&#39;;
    $method_param1_hex = str_pad(substr($address, 2), 64, &#39;0&#39;, STR_PAD_LEFT);
    $data = $method_hash . $method_param1_hex;
    $params = [&#39;from&#39; => $address, &#39;to&#39; => self::CONTRACT, &#39;data&#39; => $data];
    $total_balance = self::eth_call([$params, "latest"]);
    return hexdec($total_balance) / (pow(10, 18));
  }
  public static function transfer($to, $value)
  {
    self::personal_unlockAccount([self::COINBASE, "123456", 3600]);
    $value = bcpow(10, 18) * $value;
    $method_hash = &#39;0xa9059cbb&#39;;
    $method_param1_hex =str_pad(substr($to, 2), 64, &#39;0&#39;, STR_PAD_LEFT);  
    $method_param2_hex = str_pad(strval(bc_dechex($value)), 64, &#39;0&#39;, STR_PAD_LEFT);
    $data = $method_hash . $method_param1_hex . $method_param2_hex;
    $params = [&#39;from&#39; => self::COINBASE, &#39;to&#39; => self::CONTRACT, &#39;data&#39; => $data];
    return self::eth_sendTransaction([$params]);
  }
}

代码比较简单, 要注意几点:

  • transfer函数的value单位很小, 是 10 ^ -18, 所以如果你想转1000个,其实是要乘于 10的18次方, 这里的18是decimals.

  • 由于第1点, 应该使用bcpow代替pow函数.

  • 不能使用php自带的dechex函数. 因为dechex要求整型不能大于 PHP_INT_MAX, 而这个数在32位机上为4294967295。由于第1 点, 所有的数都要乘于10的18次方, 所以得到的数要远远大于PHP_INT_MAX. 建议自己实现10进制转16进制,如果你不知道如何实现,参考上述代码。

  • 在运行某些合约方法, 比如transfer时, 要先unlock用户.

  • 发送交易之后, 一定要在服务器端启动挖矿, 这样交易才会真的写入到区块, 比如你调用transfer之后,却发现对方没有到账,先别吃惊,启动挖矿试试。如果想启用自动挖码, 在geth --rpc ...最后加上 --mine.

测试:

<?php 
var_dump(EthereumRPCClient::personal_newAccount([&#39;password&#39;]));
var_dump(EthereumRPCClient::personal_unlockAccount([EthereumRPCClient::COINBASE, "password", 3600]);
var_dump(EthereumRPCClient::getBalance("0x...."));

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

PHP使用file_get_contents发送http请求步骤详解

PHP实现随机剔除算法

Atas ialah kandungan terperinci php与ethereum客户端交互使用详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
IQ50模因币免费空投教学!先签署ETH钱包再登记SOL链IQ50模因币免费空投教学!先签署ETH钱包再登记SOL链Mar 10, 2024 am 09:10 AM

一款名为“IQ50”的模因币项目近日引发社群热议,被戏称为“低智商才能暴富”的极具魔性。据悉,该Meme币将于今日北京时间下午5点(UTC9:00AM)在DeFi平台BakerySwap的BakeryLaunchpad上展开免费IDO,引起了投资者的关注。IQ50发行在Solana链上,总供应量505,050,505,050颗,其中80%(404,040,404,040颗)用于本次Launchpad空投,20%用于流动性池。如何参与IQ50的Launchpad?1.前往BakeryLaunchp

孙宇晨从币安撤资6000万美元,ETH占比最高,其次为AAVE、SHIB等孙宇晨从币安撤资6000万美元,ETH占比最高,其次为AAVE、SHIB等Jan 24, 2024 pm 01:39 PM

最近,与波场创始人孙宇晨的加密货币生态系统相关的问题出现了一些骚动。首先,市值排名第五的稳定币TUSD在16日宣布与波场脱钩。然后,火币交易所在19日晚上8点发生了大规模故障。提领6,000万美元等值代币根据Lookonchain数据,从2023年12月18日开始,孙哥开始将资产从币安交易所撤出,并在链上大量囤币,总计提取价值达到6,000万美元等值的加密货币资产。这些资产包括多种加密货币,其中占比最高的是17,433枚ETH,价值高达4,300万美元。除此之外,在这一个月中,他还提取了68,9

Coinbase财报:第一季净利逾11亿美元!持有9千枚BTC、9万枚ETHCoinbase财报:第一季净利逾11亿美元!持有9千枚BTC、9万枚ETHMay 03, 2024 pm 03:40 PM

本站(120bTC.coM):美国合规交易所Coinbase在2024年第一季创造了16亿美元的收入,较上去年同期增长112%。净利逾11亿美元。而Coinbase自身因投资持有的加密资产,在本季增值认列了6.5亿美元的收益,股价持稳在200美元上方。交易收入大增,第一季营收达16亿美元Coinbase在2024年第一季创造了16亿美元的收入,较上去年同期增长112%。其中国际交易所(International)贡献了17%的收入。第一季消费者交易收入为9.35亿美元,季增99%。第一季消费者交

Ethereum (ETH) Open Interest Soars as Spot ETFs Go Live, Signaling Bullish Sentiment and Impending VolatilityEthereum (ETH) Open Interest Soars as Spot ETFs Go Live, Signaling Bullish Sentiment and Impending VolatilityJul 30, 2024 am 01:04 AM

The value of Ether (ETH) has been on the rise lately, and so has Ethereum's open interest. While this signals bullish sentiment from traders, it also indicates

Pirate Nation将发币!免费Mint创世海盗NFT地板价暴涨1.3枚ETHPirate Nation将发币!免费Mint创世海盗NFT地板价暴涨1.3枚ETHJun 13, 2024 pm 01:20 PM

本站(120btC.coM):在去年9月获得知名风投a16z领投3,300万美元种子轮融资的链游开发商ProofofPlay,在2022年4月推出链上RPG游戏PirateNation的beta测试版版本并测试至今,该链游最初在Polygon上线,后来转移至ArbitrumNova上。PirateNation目前仅开放有邀请码或持有PirateNation创世海盗NFT的用户游玩,游戏背景设定在一个海盗国度之中,玩家扮演海盗船长,需要建造船只、招募船员,为领地赚取经验、制作物品、升级装备,与具有

黄立成砸962枚ETH抄底FRIEND:币价上涨至10美元黄立成砸962枚ETH抄底FRIEND:币价上涨至10美元May 07, 2024 pm 01:43 PM

基于Layer2网络Base的去中心化社交平台Friend.tech在去年8月正式上线后,因空投预期、获Paradigm等知名风投加持而迅速爆红,但这波热潮在去年10月就大幅消退,直到上月预告即将推出V2和开放空投申领后,才再度重拾社群关注。而Friend.tech在3日终于正式开放代币FRIEND空投申领,并在4日上线V2版本,不过FRIEND申领却惹出争议,社群抱怨申领网站太卡无法申领、以及无法全部申领,Friend.tech的V2版本引入主要新功能club,只有加入club,才有机会领取全

最强加密货币ETF要来了?BTC、ETH和SOL联合基金将出现申请最强加密货币ETF要来了?BTC、ETH和SOL联合基金将出现申请Jul 23, 2024 am 09:10 AM

本站(120bTC.coM):以太坊现货ETF正式上市的预期在经过多次落空之后,目前看来美东时间本周23日上市正逐渐成为现实。据芝加哥期权交易所(Cboe)显示,该平台已新增VanEck、Invesco、Fidelity、21Shares、FranklinTempleton等5档以太坊现货ETF信息,预计开放交易的时间就在7月23日。“我们很高兴地宣布,一种交易所交易产品(ETP)将于2024年7月23日在Cboe上架并作为新发行产品开始交易,这有待监管的有效性。”Cboe官网信息未来几个月内将

美国48名国会议员联名上书!要SEC主席讲清楚ETH是不是证券美国48名国会议员联名上书!要SEC主席讲清楚ETH是不是证券Mar 27, 2024 pm 09:20 PM

美国国会再度施压美国证券交易委员会(SEC)澄清以太坊(ETH)是否为「证券」。两位具权威影响力的共和党众议员,即众议院金融服务委员会主席PatrickMcHenry和农业委员会主席Glenn“GT”Thompson,今日发表了一封联名信。他们要求SEC主席GaryGensler澄清,作为第一家数字资产证券特殊目的经纪商(SPBD)的Prometheum将如何在以太坊(ETH)尚未被定义为「证券」之前,合法地向客户提供ETH托管服务。这一举措引发了市场和监管机构之间对数字资产监管的持续关注,尤其

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

MantisBT

MantisBT

Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ialah aplikasi web PHP/MySQL yang sangat terdedah. Matlamat utamanya adalah untuk menjadi bantuan bagi profesional keselamatan untuk menguji kemahiran dan alatan mereka dalam persekitaran undang-undang, untuk membantu pembangun web lebih memahami proses mengamankan aplikasi web, dan untuk membantu guru/pelajar mengajar/belajar dalam persekitaran bilik darjah Aplikasi web keselamatan. Matlamat DVWA adalah untuk mempraktikkan beberapa kelemahan web yang paling biasa melalui antara muka yang mudah dan mudah, dengan pelbagai tahap kesukaran. Sila ambil perhatian bahawa perisian ini

SublimeText3 versi Inggeris

SublimeText3 versi Inggeris

Disyorkan: Versi Win, menyokong gesaan kod!

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual