search
HomeBackend DevelopmentPHP TutorialDetailed explanation of interaction between php and ethereum client

This article tells you the relevant knowledge points about the interaction between PHP and Ethereum clients. It has certain reference value. Friends in need can follow and learn.

php communicates with ethereum rpc server

1. Json RPC

Json RPC is based on json's remote procedure call, this explanation is relatively abstract. To put it simply, it is to post a json format data and call the method in the rpc server. The json format is fixed. In general, there are the following items:

{
  "method": "",
  "params": [],
  "id": idNumber
}

  • method: method name

  • params: parameter list

  • id: unique identifier for the procedure call No.

##2. Build a Json RPC client

<?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;
    }
  }
}
?>

Relatively simple code , if you are lazy, just take it and use it. You can also go to packagist.org to find an rpc client yourself.

3. Two types of methods for calling RPC

There are two types of methods that need to be called. One type It is the RPC server's own method, and the other type is the contract method.

RPC server method calls json format

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

RPC Server's own method The list

It is relatively simple to call the built-in method. Refer to the above link, most of them have examples.

Contract method call json format


Must be used to call the contract method eth_call in the built-in method. The contract method name and contract method parameter list are reflected using params. For example: If we want to call the balanceOf method in the contract, how should the json data be constructed?

Let’s take a look first Function implementation of getBalanace:

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

Extract the function prototype:

balanceOf(address)

in geth Run the command under the console:

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

Get the function hash "0x70a08231"

Assume that the address to be queried is address _owner = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", then Remove the "0x" in front and add 24 zeros on the left (the general address length is 42 bits, and it is 40 bits after removing the '0x') to form a 64-bit hexadecimal parameter.

Finally obtained The parameter is "0x70a082310000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750"

Assume that our contract address is "0xaeab4084194B2a425096fb583Fbcd67385210ac 3".

Then the final json data will be:

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

Send the above json data to the server in post mode, then you can call the contract method "balanceOf" to query the token balance in the given address.

You must also be new when calling other methods in the contract Following the above method, let's analyze the transfer method again to deepen our impression:

First, look at the function implementation in the code:

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

Secondly, extract the function prototype:

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

Again, run the sha3 function on the console:

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

Get the function hash "0xa9059cbb"

The first parameter assumes address _to = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", then go to "0x" and add zeros to 64 bits.


No. Assuming that uint256 _value = 43776, the two parameters are converted into hexadecimal "0xab00", then "0x" is removed, and zeros are added to 64 bits. 27c5ec5750000000000000000000000000000000000000000000000000000000000ab00"

Construct json data:

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

##from transferor address

    to contract address
  • data The hexadecimal number obtained by the above operation
  • Convert the above steps into code.
  • Build an Ethereum 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]);

  }

}

The code is relatively simple, there are a few points to note:

##transfer function The value unit is very small, 10 ^ -18, so if you want to transfer 1,000 times, you actually need to multiply by 10 to the 18th power, where 18 is decimals.

Because Point 1, bcpow should be used instead of the pow function.
  • You cannot use the dechex function that comes with PHP. Because dechex requires that the integer type cannot be larger than PHP_INT_MAX, and this number is 4294967295 on a 32-bit machine. . Due to point 1, all numbers must be multiplied by 10 to the 18th power, so the resulting number is much larger than PHP_INT_MAX. It is recommended to convert decimal to hexadecimal by yourself. If you don't know how to implement it, refer to the above code.
  • When running certain contract methods, such as transfer, the user must be unlocked first.
  • After sending the transaction, it must be started on the server side Mining, so that the transaction will actually be written into the block. For example, after you call transfer, you find that the other party has not received the account. Don't be surprised, start mining and try. If you want to enable automatic code mining, add --mine at the end of geth --rpc...
  • Test:

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


The above is the detailed content of Detailed explanation of interaction between php and ethereum client. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact 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

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

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%。第一季消费者交

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,才有机会领取全

美国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托管服务。这一举措引发了市场和监管机构之间对数字资产监管的持续关注,尤其

最强加密货币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官网信息未来几个月内将

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment