안녕하세요.
쌩광부입니다.
이더소셜 PHP API 서버 만들기 강좌를 시작하도록 하겠습니다.
이번 시간에는 실제 프로그래밍에 앞서 기본적인 구조에 대해서 설명하도록 하겠습니다.
프롤로그에서 얘기한대로 저희는 Apache2와 PHP를 이용할 예정이고요.
이더리움(geth), 이더소셜(gesn) 등등의 노드에 연결하여 블록정보와 계정잔액을 읽어오게 되고요.
그 자료를 계정별로 분리한 트랜젝션 히스토리를 MySQL에 저장합니다.
일반적으로 geth와 같은 노드 데몬에서는 자체적으로 JSON RPC API를 제공하고 있는데요.
그럼 그 API를 이용하면 되지 굳이 왜 별도의 API를 만드는지 궁굼하시죠??
geth의 경우 블록을 생성하고 검증하고 다른 노드와 동기화하는 등등의 기능을 포함하고 있고
계정별로 정보를 가지고 있는 것이 아닌 블록 단위로 저장되므로
계정별 트랜젝션 히스토리를 읽어올 때 상당히 오랜시간이 걸립니다.
또한 그렇게 잦은 호출을 하는 경우 geth에 부하가 증가되어 본연의 노드 기능에 영향을 줄 수 있습니다.
그렇기 때문에 생성되는 블록의 정보를 파악하여 계정별로 별도의 데이터를 저장합니다.
그럼 geth에서 읽을때 보다 훨씬 빠르게 읽을 수 있습니다.
계정별 히스토리 정보 저장 방식
서버에서는 블록타임(대략 13초) 보다 짧은 주기로 geth의 JSON RPC로 최신 블록에 대한 정보를 읽어옵니다.
그리고 블록에 포함된 트랜젝션을 확인하여 계정별 인덱스가 가능하도록 MySQL 테이블에 저장합니다.
이때 MySQL 대신 MongoDB 또는 Redis를 이용하셔도 됩니다.
다만 Redis의 경우 메모리 기반의 캐시 데이터베이스이므로 매우 많은 메인 메모리가 필요할 수 있습니다.MySQL에 저장하지 않는 정보
계정의 잔액과 트랜젝션의 수, 그리고 토큰의 잔액등은 별도로 MySQL DB에 저장하지 않습니다.
geth의 JSON RPC로 호출하여도 성능에 큰 차이가 없기 때문입니다.ERC20 토큰 등록
저희의 API는 ERC20의 토큰에 대한 정보도 표함하고 있는데요.
계정별 히스토리 정보 저장 방식처럼 블록을 읽어와서 그중에 ERC20 토큰 컨트렉트가 생성되었는지 확인합니다.
이더리움의 경우 어떤 트랜젝션이 있을 때 받는 주소가 기록되지 않은 경우 컨트렉트가 생성되는대요.
그때 Input Data값을 확인하여 정상적인 컨트렉트인지 확인합니다.
그후 MySQL에 컨트렉트 주소를 저장해둡니다.
그리고 차후 블록이 생성될때 해당 컨트렉트 주소로 전송한 내역이 있는지 확인하고 그때 ERC20 ABI와 일치하는지 확인합니다.
만약 ERC20 ABI와 일치한다면 그 컨트렉트는 ERC20 토큰이 되는것이겠죠.
이렇게 파악된 ERC20 컨트렉트 주소를 바탕으로 계정별 토큰 히스토리 정보를 저장합니다.트렌젝션의 전송
우리가 만드는 API 서버는 보안을 위해 어떠한 지갑의 Private Key를 가지고 있지 않기 때문에 eth_sendTransaction을 사용할 수 없습니다.
그렇기 때문에 geth의 eth_sendRawTransaction JSON RPC 명령을 그대로 이용합니다.
오늘 강의는 여기까지에요~~!!
관심 있으신 분들은 이더리움 위키의 JSON RPC를 둘러보시는 것도 좋을것 같습니다.
https://github.com/ethereum/wiki/wiki/JSON-RPC
다음 시간에는 서버 세팅방법에 대해서 설명하도록 하겠습니다.
좋아요!! 쾅쾅 부탁드립니다.