遍历区块数据,获取所有历史交易数据入库
首先要建立数据库 ethereum吧
然后建立数据表 表结构将跟以太坊返回的信息一致
在以太坊控制台下输入一下命令
eth.getBlock(0)
表示获取第0个区块的信息 也就是创世块信息
difficulty: 17179869184,
extraData: "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
gasLimit: 5000,
gasUsed: 0,
hash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000042",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 540,
stateRoot: "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544",
timestamp: 0,
totalDifficulty: 17179869184,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
将这个json格式数据剔除掉 transactions 和 uncles后转换为数据表字段
所以sql语句如下
CREATE TABLE `ethereum_block` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`difficulty` varchar(32) NOT NULL COMMENT '工作难度',
`extraData` varchar(255) NOT NULL COMMENT '外部数据',
`gasLimit` varchar(11) NOT NULL COMMENT '限制的气体数量',
`gasUsed` varchar(30) NOT NULL COMMENT '所使用的气体总量',
`hash` varchar(255) NOT NULL COMMENT 'hash值',
`logsBloom` text NOT NULL,
`miner` varchar(255) NOT NULL COMMENT '旷工',
`mixHash` text NOT NULL COMMENT '最小hash',
`nonce` text NOT NULL COMMENT '随机数',
`number` int(11) NOT NULL COMMENT '第几个区块',
`parentHash` varchar(255) NOT NULL COMMENT '前一区块的hash',
`receiptsRoot` varchar(255) NOT NULL COMMENT '接收根',
`sha3Uncles` varchar(255) NOT NULL,
`size` varchar(255) NOT NULL COMMENT '区块尺寸 即大小',
`stateRoot` varchar(255) NOT NULL COMMENT '星宿 百度翻译的',
`timestamp` int(11) NOT NULL COMMENT '时间戳',
`totalDifficulty` varchar(255) NOT NULL COMMENT '总难度',
`transactionsRoot` varchar(255) NOT NULL COMMENT '交易根',
`create_at` int(11) NOT NULL COMMENT '创建时间 插入数据库时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='以太坊区块表';
然后写一个死循环的程序
思路如下:
先查询本地数据的最后一条数据,
获取number的数字,
然后递增1查下一个区块信息,
一直查询区块信息
这样就可以遍历所有的区块高度信息了
下面是实例
public function getBlockInfo()
{
$db = D('Block');
$number = $db->max('number');
// $this->ajaxReturn($number);
if (!$number) {
$number = 0;
}
$block = '0x'. dechex($number + 1); // 需要转换为16进制数据
$info = $this->eth->eth_getBlockByNumber($block,true); // 查询区块高度所包含的信息
if (!$info) {
$this->ajaxReturn(['code'=>0,'msg'=>'data is empty']);
}
$res = $db->update($info); // 添加高度信息
if ($res) {
$this->ajaxReturn(['code'=>1,'msg'=>'add data ok']);
}else{
$this->ajaxReturn(['code'=>0,'msg'=>'add data fail']);
}
}
需要注意的是 jsonrpc调用api命令与在控制台直接使用是不一样的 需要参考下官网文档
sh执行该php方法 (域名都不需要)
cd /data/wwwroot/www.ethereum.io/
while true
do
php /data/wwwroot/www.ethereum.io/index.php Api/Block/getBlockInfo
done
nohup sh block.sh &
common控制器初始化链接以太坊节点代码
<?php
namespace Api\Controller;
use Think\Controller;
class CommonController extends Controller
{
public function _initialize()
{
vendor('jsonRPC.jsonRPCClient');
$url = 'http://127.0.0.1:8545';
$this->eth = new \jsonRPCClient($url);
}
}
区块数据处理的模型
<?php
namespace Common\Model;
use Think\Model;
class BlockModel extends Model
{
/**
* 自动验证
* @var array
*/
protected $_validate = array(
array('number', 'require', 'number不能为空'),
array('number','','number已经存在!',0,'unique',1), // 在新增的时候验证 number 字段是否唯一
);
protected $_auto = array(
array('create_time', NOW_TIME, 1),
array('number','hexdec',1,'function'), // 对number字段在新增的时候回调hexdec方法
);
/**
* 插入高度记录
* @DateTime 2018-05-02
* @param [type] $info [description]
* @return [type] [description]
*/
public function update($data)
{
$data = $this->create($data);
return $this->add($data);
}
}
一直跑到死为止..........这样肯定是不行的
数据库数据太大了 肯定不行 现在的区块高度是620多万了
可以优化一下该信息的 具体怎么优化留给你们思考吧