develop custom_top_html:no
default debug random = 1 / type = READ / detected = READ

안녕하세요.

쌩광부입니다.

 

지난 강좌

https://steemit.com/@topmining

https://www.ddengle.com/@TopMining

 

전체 소스

https://github.com/topmining/ethersocial-php-api

 

이번 강좌는 블록을 읽어서 트랜잭션을 데이터베이스에 저장하는 과정입니다.

이더리움의 블록 구조는 지난 시간에 설명을 했으니 참고해주시고요.

 

먼저 MySQL의 아래 2개의 테이블을 생성합니다.

 

CREATE TABLE `block` (

  `blocknumber` bigint(20) NOT NULL,

  `timestamp` bigint(20) DEFAULT NULL,

  `blockhash` varchar(66) DEFAULT NULL,

  `transactions` int(11) DEFAULT NULL,

  PRIMARY KEY (`blocknumber`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

CREATE TABLE `txaccount` (

  `hash` varchar(66) NOT NULL,

  `fromaddr` varchar(42) DEFAULT NULL,

  `toaddr` varchar(42) DEFAULT NULL,

  `timestamp` bigint(20) DEFAULT NULL,

  `blocknumber` bigint(20) DEFAULT NULL,

  `blockhash` varchar(66) DEFAULT NULL,

  `txindex` int(11) DEFAULT NULL,

  `gas` decimal(65,0) DEFAULT NULL,

  `gasprice` decimal(65,0) DEFAULT NULL,

  `value` decimal(65,0) DEFAULT NULL,

  `input` text,

  `v` varchar(22) DEFAULT NULL,

  `r` varchar(82) DEFAULT NULL,

  `s` varchar(82) DEFAULT NULL,

  `nonce` varchar(22) DEFAULT NULL,

  PRIMARY KEY (`hash`),

  KEY `idx_from` (`fromaddr`,`blocknumber`),

  KEY `idx_to` (`toaddr`,`blocknumber`),

  KEY `idx_block` (`blocknumber`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

block 테이블에는 블록에 대한 기본 정보들을 저장합니다.

큰 의미는 없지만 마지막으로 몇 번째 블록을 읽었는지를 확인합니다.

 

txaccount 테이블에는 트랜잭션 내용을 저장합니다.

 

지난 강좌에서 만들었던 api-config.php 파일에 아래 내용을 추가합니다.

 

$mysql_host = "127.0.0.1";

$mysql_user = "esnapi";   // YOUR ID

$mysql_pass = "1234";     // YOUR PASSWORD

$mysql_database = "ethersocial";

 

MySQL 접속을 위한 정보인데요.

이 부분은 알아서 수정하시는 센스! 

 

또 지난 강좌에서 만들었던 json-rpc.php 파일에 아래 내용을 추가합니다.

 

function getEtherRpcMulti($host, $port, $list) {

    $ch = curl_init();

 

    curl_setopt($ch, CURLOPT_URL, $host);

    curl_setopt($ch, CURLOPT_PORT, $port);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));

    curl_setopt($ch, CURLOPT_POST, TRUE);

 

    $data = "[";

    $n = 0;

    foreach($list as $item) {

        if($n > 0) $data .= ",";

        $data .= '{"jsonrpc":"2.0","method":"'.$item['method'].'","params":['.$item['params'].'],"id":'.$item['id'].'}';

        $n++;

    }

    $data .= "]";

    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

 

    $ret = curl_exec($ch);

    curl_close($ch);

 

    return $ret;

}

 

기존에 getEtherRpc 함수를 만들어서 사용했었는데요.

이번에는 getEtherRpcMulti 함수를 추가해서 JSON RPC를 동시에 여러개를 호출할 수 있게합니다.

블록이 많아지는 경우 매우 많은 호출을 해야되기 때문에 1건씩 호출하면 매우 느립니다.

그렇기 때문에 이 함수를 만들어 좀 더 빠르게 호출할 수 있습니다.

 

이제 본격적인 코딩을 위해 read_block.php 파일을 만듭니다.

전체 소스는 아래 링크를 확인해주세요.

 

https://github.com/topmining/ethersocial-php-api/blob/master/read_block.php

 

소스를 한줄 한줄 설명하겠습니다.

 

use Brick\Math\BigInteger;

wei 단위의 매우 큰 이더리움의 숫자를 처리하기 위해 BigInteger를 이용합니다.

 

$json = getEtherRpc($api_host, $api_port, 'eth_blockNumber', '"latest"', $id++);

eth_blockNumber 명령을 호출해서 현재 블록체인의 마지막 블록이 몇 번인지를 확인합니다.

 

$tonumber = hexdec($data['result']);

결과값이 Hex값이기 때문에 10진수로 변경합니다.

 

$conn = new mysqli($mysql_host, $mysql_user, $mysql_pass, $mysql_database);

MySQL에 연결합니다.

 

if($query = $conn->query("select max(blocknumber) from block"))

block 테이블에서 저장된 최종 블록을 읽어옵니다.

저희는 read_block.php 파일을 지속적으로 실행시켜서 저장된 최종 블록 이후에 생성된 블록을 읽어와 저장하게 됩니다.

 

$blocknumber=$fromblock;

while($blocknumber<=$tonumber)

$fromblock은 기존에 block 테이블에 저장된 최종 블록입니다.

$tonumber는 블록체인에 저장된 최종 블록입니다.

즉, $fromblock에서 $tonumber까지 반복해서 블록을 확인하기 위함이죠.

 

$list = [];

for($i=0; $i<100; $i++) {

  if($blocknumber > $tonumber) break;

  $list[] = array(

    "method" => "eth_getBlockByNumber",

    "params" => '"0x'.dechex($blocknumber).'", true',

    "id" => $id++

  );

  $blocknumber++;

}

RPC 명령을 100개씩 배열에 넣습니다.

 

$json = getEtherRpcMulti($api_host, $api_port, $list);

위에 만들어 놓은 getEtherRpcMulti 함수를 이용해 블록 정보를 읽어옵니다.

 

foreach($datas as $data)

결과값을 순차적으로 읽습니다.

RPC를 Multi로 호출하면 배열 형태로 값을 가져올 수 있습니다.

 

foreach($transactions as $tr)

블록에는 여러개의 트랜잭션이 저장되기 때문에 반복해서 읽습니다.

 

$value = BigInteger::parse(str_replace("0x", "", $tr['value']), 16);

이더리움의 숫자 단위는 wei라는 10의 18승 이라는 엄청나게 큰 값이므로 기존 integer로는 처리할 수가 없습니다.

그렇기 때문에 BigInteger를 이용하는 거죠. ^^

 

if(strcasecmp($fromaddr, "0x2f16af67dbd141c53beb03a533de6ab3bd0e69df") == 0) continue;

이 부분은 생략해도 되는 부분입니다만.

이더소셜의 경우 지난번 트랜잭션 공격이 있었는데요.

위 주소에서 의미없는 엄청나게 많은 트랜잭션을 발생시켜 문제가 되었죠.

그렇기 때문에 해당 주소의 경우는 아예 테이블에 저장하지 않는게 좋습니다.

DB 용량을 엄청나게 줄일 수 있죠.

 

$sql = "insert into txaccount ... on duplicate key update ...

테이블에 저장하기 위한 쿼리를 만듭니다.

이때 on duplicate key update 쿼리를 만들어 중복되는 경우 새로 insert되지 않도록 합니다.

 

$sql = "insert into block ... on duplicate key update ...

트랜잭션 저장이 완료되면 블록을 저장합니다.

이때도 마찬가지로 on duplicate key update 쿼리를 만들어 중복 방지는 필수!

 

코딩을 마쳤으면 한번 실행해볼까요.

우분투 콘솔창에서 read_block.php 파일이 있는 곳으로 이동 후 아래와 같이 입력합니다.

물론 MySQL이 실행중이며 위에 설명한 테이블이 만들어져 있어야 하고요.

또한 gesn도 실행중인 상태여야 겠죠.

 

$ php read_block.php

Current block height: 2602588

Block: 100

Block: 200

Block: 300

Block: 400

...

 

위와 같이 나오면 성공!!

100 블록씩 읽어서 DB 테이블에 저장하는 과정입니다.

2602588 블록까지 저장되면 중지되는데요.

아주 많은 시간이 걸립니다.

일단은 최종 블록까지 저장될때까지 기다리셔야 되고요.

그 이후에는 crontab을 이용해 주기적으로 새로 생성된 블록을 기록해야합니다.

 

crontab에 대해서는 아래 링크를 확인하세요.

https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EB%B0%98%EB%B3%B5_%EC%98%88%EC%95%BD%EC%9E%91%EC%97%85_cron,_crond,_crontab

 

오늘 강좌는 끝~~

다음 시간에는 계정별로 저장된 트랜잭션을 읽는 API를 만들겠습니다.

 

그럼 다음 강좌도 많이 기대해주세요~~

 

 

 

-------------------------------------

꼬리말

* 게시글 내용 삭제레벨 강등

* 질문은 각 주제별 게시판에 적어주세요.

 

비트코인 암호화화폐 커뮤니티 땡글~ 땡글~

-------------------------------------

757

쌩광부님의 서명

댓글 2
default debug random = 0 / type = READ / detected = READ

List of Articles
번호 분류 제목 추천 수 조회 수 글쓴이 날짜
261 질문 G MAIL도 못 믿을 듯     코인을 G MAIL에 연동시켜 두신 분 많은 것 같은데 해커놈이 어떻게 흔적도 없이 비번을 바꿔놓고 발자국을 다 지웠을까요? 잘 찾아보면 발자국을 찾을 수 있을까요?   구글봇은 MAC주소를 ... 5 file 1 2232
내가총대멘다
2019.02.20
260 질문 이더리움 동기화모드를 full로 하신분 계신가요? 이더리움 동기화모드를 fast로 하지 않고 full 로 할경우 현시점에 블록데이터 크기가 어떻게 되는지 알수 있을까요? 혹은 알 수있는 방법이 있을까요?                       -----------------... 7 0 1246
나비잠
2019.02.21
259 질문 스마트폰 앱 개발하시는 분께 질문이 있습니다. 구상하는하고 있는게 있는데 현재 아이디어 수준입니다. 제가 앱개발은 전혀 몰라서 질문좀 드릴려구요.   어떤 블루투스 디바이스가 있고 이 디바이스는 스마트폰과 블루투스로 통신하면서 약1... 20 0 1524
꿀맨
2019.02.22
258 개발 삭제한 글입니다 삭제한 글입니다 0 1157
헬로월드
2019.02.24
개발 [강좌] 이더소셜 PHP API 서버 만들기 #6. 트랜잭션 기록하기 안녕하세요. 쌩광부입니다.   지난 강좌 https://steemit.com/@topmining https://www.ddengle.com/@TopMining   전체 소스 https://github.com/topmining/ethersocial-php-api   이번 강좌는 블... 2 7 2002
쌩광부
2019.02.24
256 질문 Blockchain explorer를 만들어 보고 싶습니다. 글쓰기가 가능해져서 처음으로 글 남겨봅니다. Blockchain explorer를 만들고자 합니다만, Insight이외에 추천해주시만할것이 있나요? levelDB를 Postgresql이나 오라클로 이행하는 방법은 난이... 4 0 951
ohworld5
2019.02.26
255 질문 알트코인 빌드하고 테스트넷 돌리는데 코인전송에서 The Transaction was rejected!   the transaction was rejected this might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy bu... 6 file 0 1023
hifivefootball
2019.02.26
254 질문 이더리움 동기화를 하면서 이런 에러 겪어보신분 계신가요? 이더리움 테스트넷(롭스텐)블록을 동기화 하던 중 아래와 같은 에러 때문에 동기화 더이상 진행이 안되는 문제가 발생했는데 해결 방법이나 이 에러가 왜 발생하게 되는건지 원인을 알 수 있을까... 3 0 1043
나비잠
2019.02.27
253 질문 quorum 관련해서 도움 얻을 수 있는 곳이 있을까요?   quorum에 대해서 공부좀 해볼려고 하는데 정보가 너무없네요...   혹시 관련 개발 정보 나와있는곳 아시는 분 계시면 답변 좀 부탁드립니다.(__);;   답변 감사합니다.                     --... 0 407
로텔
2019.02.27
252 개발 [강좌] 이더소셜 PHP API 서버 만들기 #7. 트랜잭션 내역 확인하기 안녕하세요. 쌩광부입니다.   지난 강좌 https://steemit.com/@topmining https://www.ddengle.com/@TopMining   전체 소스 https://github.com/topmining/ethersocial-php-api   이번 강좌는 지... 3 955
쌩광부
2019.02.27
251 질문 채굴은 하지만 블록체인에 대해서는 지식이 전혀 없습니다. 특정 기계에 블록체인을 돌리는것이 가능한지 궁금합니다.    예를 들면 노래방 기기에서 뮤지코인을 사용한다는면 노래방 기기에 블록체인이 사용되는건가요 ? 아니면 블록체인 플랫폼이 주가되... 2 0 1144
휘리릭릭릭릭
2019.02.27
250 개발 bitcoin에서 잔액주소만 표시해주는 명령어가 있을까요?     제목글처럼 비트코인 wallet명령어중에서 잔돈수신용으로 생성된 주소를 검색하는 명령어가 있을까요?   아님 방법이라도 있을까요?                   -----------------------------------... 4 0 997
ohworld5
2019.02.28
249 질문 이더리움 트랜잭션과 관련하여 질문 있습니다. 이더리움 EOA &lt;---&gt; EOA 간의 이더를 주고 받을 때 나오는 트랜잭션 해쉬값으로 해당 트랜잭션 해쉬가 어떤 노드에서 발생되었고 그 노드의  IP 정보를 알 수 있는 방법이 있을까요?            ... 1 0 724
나비잠
2019.02.28
248 개발 [강좌] 이더소셜 PHP API 서버 만들기 #8. 트랜잭션 전송하기 안녕하세요. 쌩광부입니다.   지난 강좌 https://steemit.com/@topmining https://www.ddengle.com/@TopMining   전체 소스 https://github.com/topmining/ethersocial-php-api   이번 강좌는 이... 2 8 2347
쌩광부
2019.03.05
247 개발 NodeRed를 이용한 시각화툴 Grafana 이용하기 비트코인 모니터링 시스템으로 Grafana를 활용하고 있습니다.   본인만의 모니터시스템을 구현하고자 하는 분들은 영상 확인해보시기 바랍니다.   Grafana로 구현중인 내용은 1. 거래소별 비트... 3 file 4 2391
까치섬
2019.03.06
246 질문 이더스켄 궁금한게있는데요.     안녕하세요. 코인 공부하면서 이것저것 만들어보고있는 초보입니다.   메타마스크 연동해서 코인을 만들어서 개인지갑에  저장까지 했습니다.   그렇다면 이더스캔검색(자동완성?)목록에 심... 10 0 1549
심퉁이
2019.03.06
245 질문 알트코인 지갑 오픈소스 어떤게 있을까요? 안드로이드용 알트코인 지갑 오픈소스 많이쓰는게 어떤게 있을까요? (너무 복잡하거나 잡다한거 없는게 좋을꺼같습니다 ㅎㅎ) bitcoin-wallet은 빌드해봤습니다.         ----------------------... 0 985
vosiv
2019.03.06
244 질문 스마트 컨트랙트내에서 비밀번호를 설정할 수 있을까요?   스마트 컨트렉트에서 선언된 변수에 저장된 데이터를   변경해주는 특정 메소드를 컨트랙트 배포자만 호출이 가능하게 설정을 하더라도   컨트랙트 배포자의 키파일이 복사되어 외부에 유출이 ... 3 0 749
나비잠
2019.03.08
243 질문 이더리움 코인 서버 세팅과 관련되어 질문있습니다. 몇 일 전에 키스토어 디렉토리안에 있는 키 파일이 외부에 유출이 됬을 경우를 대비하여   이더리움 스마트 컨트랙트 내에서 데이터를 변경하기 위한 비밀번호를 설정할 수 있는 방법이 없을까?... 2 0 928
나비잠
2019.03.11
242 질문 버전업데이트로 인한 bitcoin-cli 명령어 질문 0.16 버전으로 다운그레이드 한  bitcoin 를 사용하다가 비트코인 git 의 최신버전인 0.18버전으로 업데이트를 예정중입니다! 버전 업데이트가 되면서 account 기능이 label 로 대체되는것 같더... 3 0 1123
이모이모이모
2019.03.12
Board Pagination Prev 1 ... 75 76 77 78 79 80 81 82 83 84 ... 93 Next
/ 93
default debug random = 0 / type = READ / detected = READ