搜尋
首頁後端開發php教程php與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 = "0x38aabef4cd283ccd5091298dededc88d27c5,ec570"5, ecdc78 0x", 並在左邊補24個零(一般位址長度為42位元, 去掉'0x'後為40位元),構成64位元十六進位參數.

最後得到的參數為"0x70a08231000000000000000000000000000000003852 0 "

假設我們的合約位址為"0xaeab4084194B2a425096fb583Fbcd67385210ac3".

則得到最終的json資料為:

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

#

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

json資料以post方式發送給伺服器,就把以上給伺服器可以呼叫合約方法"balanceOf", 查詢給定的地址中的代幣餘額.

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

首先, 看看程式碼中的函數實作:

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

其次, 提煉出函數原型:

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

再次, 在控制台運行sha3函數:

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

得到函數hash "0xa9059cbb"

第一個參數假設address _to = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", 則去"0x", 補零到dc88d27c5ec5750", 則去"0x", 補零到dc88d27c5ec5750", 則去"0x", 補零到dc88d27c5ec5750", 則去"0x", 補零到64位元。 _value = 43776, 則化為十六進位"0xab00"後, 去"0x", 補零到64位.

連接起來

#"0xa9059c000000000000000000000000038 0000000000000000000000000000000000000000000000000000000000ab00"

建構json資料:

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

  • from 轉出者位址

  • to 合約位址

  • data上述運算得到的十六進位數

把以上的步驟轉換成程式碼.

建構一個以太坊RPC client

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

程式碼比較簡單, 要注意幾點:

  • 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实现随机剔除算法

以上是php與ethereum客戶端互動使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!