ホームページ バックエンド開発 PHPチュートリアル phpとイーサリアムクライアント間のやり取りの詳しい説明

phpとイーサリアムクライアント間のやり取りの詳しい説明

Apr 28, 2018 am 10:28 AM
ethereum php クライアント

この記事は、PHP と Ethereum クライアントの間の相互作用に関する関連知識のポイントを示しており、必要な友人がフォローして学ぶことができます。

phpはイーサリアムrpcサーバーと通信します

1. Json RPC

Json RPCはjsonに基づくリモートプロシージャコールです。 この説明は比較的抽象的です。簡単に言うと、rpcサーバーにメソッドを呼び出すためにjson形式でデータを投稿することですが、このjson形式は大まかにいくつかの項目があります:

method:メソッド名。
  • params: パラメータリスト
  • id: プロシージャ呼び出しの一意の識別番号
  • 2. Json RPC クライアントを構築します

{
  "method": "",
  "params": [],
  "id": idNumber
}
ログイン後にコピー

怠け者であれば、比較的単純なコードtake 過去に使用するだけです。また、packagist.org にアクセスして、RPC クライアントを自分で見つけることもできます

3. RPC を呼び出すための 2 種類のメソッド

呼び出す必要があるメソッドは 2 種類あります。1 つは RPC サーバー独自のメソッドです。 、もう 1 つはコントラクト メソッドです。

RPC サーバー メソッドは json 形式を呼び出します

<?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;
    }
  }
}
?>
ログイン後にコピー

RPC サーバーの組み込みメソッドのリスト

組み込みメソッドの呼び出しは、上記のリンクを参照してください。

コントラクト メソッドは json 形式を呼び出します

コントラクト メソッドを呼び出すには、組み込みメソッドで eth_call を使用する必要があります。コントラクト メソッド名とコントラクト メソッドのパラメーター リストは、params を使用して反映されます。コントラクト内で BalanceOf メソッドを呼び出したい場合、JSON データはどのように構築されるべきでしょうか?

まず、getBalanace:

{
  "method": "eth_accounts",
  "params": [],
  "id": 1
}
ログイン後にコピー

関数のプロトタイプを抽出します。
function balanceOf(address _owner) public view returns (uint256 balance)
ログイン後にコピー

geth コンソールでコマンドを実行します:

balanceOf(address)
ログイン後にコピー

関数ハッシュ "0x70a08231" を取得します

仮定 クエリされるアドレスは address _owner = "0x38aabef4cd283ccd5091298dedc8" です8d27c5ec5750" を選択し、先頭の "0x" を削除します。左側に 24 個のゼロを追加し (一般的なアドレスの長さは 42 ビットで、「0x」を削除すると 40 ビットになります)、64 ビットの 16 進数を形成します。 パラメーターをカスタマイズします。

最後のパラメーターは、「0x70a082310000000000000000000000038aabef4cd283ccd5091298ded」です。 c88d27c5ec5750"

コントラクト アドレスが "0xaeab4084194B2a425096 fb583Fbcd67385210ac3" であるとします。

その場合、最終的な JSON データは次のようになります:

web3.sha3("balanceOf(address)").substring(0, 10)
ログイン後にコピー

上記の JSON データをポスト モードでサーバーに送信し、コントラクト メソッド "balanceOf" を呼び出してクエリを実行できます。指定されたアドレスのトークン残高。

コントラクト内の他のメソッドを呼び出す場合も、上記のメソッドに従う必要があります。印象を深めるために、転送メソッドを再度分析してみましょう:

まず、コード内の関数の実装を見てください:

{
  "method": "eth_call",
  "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0x70a0823100000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750"}, "latest"],
  "id": 1
}
ログイン後にコピー

次に、関数プロトタイプを抽出します:

function transfer(address _to, uint256 _value) public returns (bool)
ログイン後にコピー

第三に、コンソールで sha3 関数を実行します:

transfer(address,uint256) //注意逗号后面不能有空格
ログイン後にコピー

関数ハッシュ「0xa9059cbb」を取得します

最初のパラメータはアドレスを想定しています_へ= "0x38aabef4cd283ccd5091298dedc88d27c5ec5750"、次に "0x" に移動し、64 ビットにゼロを追加します。

2 番目のパラメーターは uint256 _value = 43776 を想定しており、その後 16 進数に変換されます "0xab00" の後、"0x" に移動し、 64 ビットにゼロを追加します

それらを接続します


"0xa9059cbb000000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000 00000000000 00000000000000000000000000000000ab00"

json データを構築:

web3.sha3("transfer(address,uint256)").substring(0, 10)
ログイン後にコピー

転送者アドレス

    から契約アドレス
  • データ 16進数上記の操作で取得したもの
  • 上記の手順をコードに変換します
  • Ethereum RPCクライアントを構築します

{
  "method": "eth_call",
  "params": [{"from": "0x38aabef4cd283ccd5091298dedc88d27c5ec5750", "to": "0xaeab4084194B2a425096fb583Fbcd67385210ac3", "data": "0xa9059cbb00000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000000000000000000000000000000000000000000000000000ab00"}, "latest"],
  "id": 1
}
ログイン後にコピー

コードは比較的単純ですが、注意すべき点がいくつかあります ポイント: 値の単位

伝達関数の は 10 ^ -18 と非常に小さいため、1000 回転送したい場合は、実際には 10 の 18 乗を掛ける必要があります (18 は小数です)。

    ポイント 1 では、pow 関数の代わりに bcpow を使用する必要があります。PHP に付属の dechex 関数は使用できません。これは、dechex では整数型が PHP_INT_MAX より大きくてはならず、この数値は 32 で 4294967295 であるためです。 -ビットマシン。ポイント 1 により、すべての数値に 10 の 18 乗を掛ける必要があるため、結果の数値は PHP_INT_MAX よりも大幅に大きくなります。実装方法がわからない場合は、自分で 10 進数を 16 進数に変換することをお勧めします。上記のコードに。
  • 転送などの特定のコントラクトメソッドを実行する場合は、まずユーザーのロックを解除する必要があります
  • トランザクションが実際にブロックに書き込まれるように、サーバー側でマイニングを開始する必要があります。 、転送を呼び出した後、相手がアカウントを受け取っていないことがわかりました。驚かないでください。自動コードマイニングを有効にしたい場合は、geth --rpc の最後に --mine を追加します... テスト:
  • <?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]);
    
      }
    
    }
    ログイン後にコピー


  • 以上がphpとイーサリアムクライアント間のやり取りの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles