详解php与ethereum客户端 交互
发布时间:2023-02-15 11:12:43 所属栏目:PHP 来源:
导读: php与ethereum rpc server通信
一、Json RPC
Json RPC就是基于json的远程过程调用,这么解释比较抽象。简单来说,就是post一个json格式的数据调用rpc server中的方法. 而这个json格式是固定的,总的来说
一、Json RPC
Json RPC就是基于json的远程过程调用,这么解释比较抽象。简单来说,就是post一个json格式的数据调用rpc server中的方法. 而这个json格式是固定的,总的来说
php与ethereum rpc server通信 一、Json RPC Json RPC就是基于json的远程过程调用,这么解释比较抽象。简单来说,就是post一个json格式的数据调用rpc server中的方法. 而这个json格式是固定的,总的来说有这么几项: method: 方法名 params: 参数列表 id: 对过程调用的唯一标识号 二、构建一个Json RPC客户端 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 = '' : $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('Method name has no scalar value'); } // check if (is_array($params)) { // no keys $params = $params[0]; } else { throw new Exception('Params must be given as array'); } // sets notification or request task if ($this->notification) { $currentId = NULL; } else { $currentId = $this->id; } // prepares the request $request = array( 'method' => $method,'params' => $params,'id' => $currentId ); $request = json_encode($request); $this->debug && $this->debug.='***** Request *****'."\n".$request."\n".'***** End Of request *****'."\n\n"; // performs the HTTP POST $opts = array ('http' => array ( 'method' => 'POST','header' => 'Content-type: application/json','content' => $request )); $context = stream_context_create($opts); if ($fp = fopen($this->url,'r',false,$context)) { $response = ''; while($row = fgets($fp)) { $response.= trim($row)."\n"; } $this->debug && $this->debug.='***** Server response *****'."\n".$response.'***** End of server response *****'."\n"; $response = json_decode($response,true); } else { throw new Exception('Unable to connect to '.$this->url); } // debug output if ($this->debug) { echo nl2br($debug); } // final checks and return if (!$this->notification) { // check if ($response['id'] != $currentId) { throw new Exception('Incorrect response id (request id: '.$currentId.',response id: '.$response['id'].')'); } if (!is_null($response['error'])) { throw new Exception('Request error: '. var_export($response['error'],true)); } return $response['result']; } else { return true; } } } ?> 比较简单的代码,如果比较懒,拿过去用就行了。也可以上packagist.org自己找一个rpc client. 三、调用RPC的两类方法 有两类方法需要调用. 一类是RPC server自带方法,另一类就是合约方法. RPC server方法调用json格式 RPC Server自带方法的列表 调用自带方法比较简单,参考上述链接,大部分都有示例. 合约方法调用json格式 调用合约方法必须使用自带方法中的eth_call. 而合约方法名称和合约方法参数列表则使用params进行体现,比如: 我们要调用合约中的balanceOf方法,则json数据应该如何构造呢? 首先看看getBalanace的函数实现: 提炼出函数原型: 在geth控制台下运行命令: 得到函数hash "0x70a08231" 假设待查询的地址 address _owner = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750",则去掉前面的"0x",并在左边补24个零(一般地址长度为42位,去掉'0x'后为40位),构成64位十六进制参数. 最终得到的参数为 "0x70a0823100000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750" 假设我们的合约地址为 "0xaeab4084194B2a425096fb583Fbcd67385210ac3". 则得到最终的json数据为: 把以上json数据以post方式发送给服务器,就可以调用合约方法"balanceOf",查询给定的地址中的代币余额. 调用合约中的其他方法也要新遵循上面的方式,我们再分析一下transfer方法,加深印象: 首先,看看代码中的函数实现: 其次,提炼出函数原型: 再次,在控制台运行sha3函数: 得到函数hash "0xa9059cbb" 第一个参数假设 address _to = "0x38aabef4cd283ccd5091298dedc88d27c5ec5750",则去"0x",补零到64位. 第二个参数假设 uint256 _value = 43776,则化为十六进制"0xab00"后,去"0x",补零到64位. 连接起来 "0xa9059cbb00000000000000000000000038aabef4cd283ccd5091298dedc88d27c5ec5750000000000000000000000000000000000000000000000000000000000000ab00" 构建json数据: from 转出者地址 to 合约地址 data 上述操作得到的十六进制数 把以上的步骤转化为代码. 构建一个以太坊RPC client require './jsonRPCClient.php'; //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 = '0x38aabef4cd283ccd5091298dedc88d27c5ec5750'; //合约地址 const CONTRACT = '0xaeab4084194B2a425096fb583Fbcd67385210ac3'; (编辑:草根网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐