随着互联网遭遇区块链的冲击,各种依傍ETH发布各种货币的操作频繁出现,在这里我们不得不说一下我们程序员比如我们PHP是怎么介入的,获取里面的数据以及地址等等信息。在这里首先我们要了解,我们PHP要通过哪些方式去获取数据?然后怎么获取数据?
PHP获取链上数据的方式大概有Web3.0与RPC两种,比如利用第三方还有爬虫写脚本等方式咱们就另说了。PHP安装Web3.0的扩展利用里面封装的方法也可用,这次我们重点说一下RPC是怎么获取数据的。
先版署一下所封装的数组模板:
/**
* 数组模板
* @param $method
* @param array $params
* @return array
*/
public static function Template($method,$params = array()){
$opts = [
'jsonrpc' => '2.0',
'method' => $method,
'params' => $params,
'id' => time()
];
$data = json_encode($opts);
// POST请求 各位可以自行封装
$res = Curl::post(self::$url, $data, 10, array('Content-Type:application/json;charset=UTF-8'));
$res_arr = json_decode($res, true);
return $res_arr;
}
// 节点url
public static $url = 'XXXXX';
1.获取所有账户地址:
// 获取钱包地址
public function getAccountSList(){
$list = Eth::Template('eth_accounts');
if(!empty($list['result'])){
foreach($list['result'] as $key => $val){
echo "<br/>";
print_r($val);
}
}else{
die("error");
}
}
2.获取指定地址账户的余额:
// 获取指定地址账户的余额
public function getBalance(){
$send_arr = array("检查余额的地址","latest");
$list = Eth::Template('eth_getBalance', $send_arr);
if(!empty($list['result'])){
echo "<br/>";
print_r($list['result']);
}else{
die("error");
}
}
3.转账:
// 转账
public function sendTransaction(){
// 转为16进制
$value = number_format(12 * pow(10,18), 0, '', '');
$amout_value = base_convert($value, 10, 16);
$send_arr = array(
array(
'from' => "发送交易的源地址",
'to' => "交易的目标地址",
'value' => '0x'.$amout_value,
'gas' => '0xf4240',
'gasPrice' => '0xe8d4a51000'
)
);
$res_arr = Eth::Template('eth_sendTransaction', $send_arr);
if(empty($res_arr['result'])){
echo "转账失败"."\n";
die;
}
echo "转账成功"."\n";
}
4.解锁账户:
/**
* 解锁账户
* @param array $params
*/
private static function Unlocking(array $params){
$address = $params['address'];
$res_arr = Eth::Template('personal_unlockAccount',array($address,'Gex_15+Etv123456'));
if(empty($res_arr['result'])){
return 'No';
}
return 'Ok';
}
上面大概简单的列出几个例子,其他的操作可以依次类推。如果说我们想本地存储指定链上的指定钱包地址所有交易数据,大家可以参考我一下我的思路和代码,献丑了。
1.写脚本利用Redis存储最新的区块高度:
<?php
/**
* 获取最新区块高度,1分钟执行一次
*/
class GetFilterContent{
// 读取
public static function read(){
$date = date('Y-m-d H:i:s');
$redis = Cache::Redis();
//根据区块高度获取交易记录
$ini_block_height = 262943;
$redis_key = 'new_block_height';
$block_height = $redis->get($redis_key);
if(empty($block_height)){
$redis->set($redis_key, $ini_block_height, 86400*30);
$block_height = $ini_block_height;
}
$new_block_height = Eth::Template('eth_blockNumber');
if(empty($new_block_height) || (int)$new_block_height < 1){
echo $date."获取最新区块高度失败".json_encode($new_block_height)."\n";die;
}
$new_block_height = hexdec($new_block_height['result']);
for ($i=$block_height; $i<$new_block_height;$i++){
$this_block_height = dechex($i);
$block_hash = Eth::Template('eth_getBlockByNumber', array('0x'.$this_block_height, true));
if(empty($block_hash) || !isset($block_hash['result']['hash'])){
echo $date."获取区块hash失败-区块高度:".$i."-".json_encode($block_hash)."\n";
continue;
}
echo $date."获取区块hash成功-区块高度:".$i."-hash:".$block_hash['result']['hash']."\n";
$redis->rpush('block_hash_list',$block_hash['result']['hash']);
}
$redis->set($redis_key, $new_block_height, 86400*30);
echo $date."解析区块高度成功\n";
}
}
GetFilterContent::read();
2.同样写脚本利用解析最新的区块里面的交易记录:
<?php
/**
* 获取交易记录
*/
class GetTransactionRecords{
// 读取
public static function read(){
while (true){
$date = date('Y-m-d H:i:s');
$redis = Cache::Redis();
$value = $redis->lpop('block_hash_list');
print_R($value);echo "\n";
if(empty($value)){
echo $date."没有交易记录\n";
sleep(30);
continue;
}
$res_arr = Eth::Template('eth_getBlockByHash',array($value,true));
$arr = $res_arr['result']['transactions'];
if(!empty($arr)){
$block_time = $res_arr['result']['timestamp'];
foreach($arr as $key => $val){
// 获取区块中的交易记录 依据需求可自行处理
}
}
}
}
GetTransactionRecords::read();
有些写得不对的或者有更好的方法欢迎大家指出。[作揖]
Wow! This blog looks exactly like my old one! It’s on a completely different subject but
it has pretty much the same page layout and design. Outstanding choice of colors!
I’d like to find out more? I’d like to find out more details.