[강좌] 이더소셜 PHP API 서버 만들기 #5. 블록 내용 살펴보기

in topmining •  6 years ago 

안녕하세요.
쌩광부입니다.

지난 강좌보기
https://steemit.com/@topmining
https://www.ddengle.com/@TopMining

오늘 강좌 내용은 트랜잭션(거래내역)을 MySql DB로 옮기기 위해 필요한 사항을 알아보겠습니다.

그런데 왜 블록이 기록된 트랜잭션을 MySql로 옮겨야 되는것일까요?

일반적으로 하나의 블록에는 다양한 트랜잭션이 기록되어서 체인으로 연결되어 있는데요. 거기서 특정 주소의 트랜잭션만 모아서 뽑으려고 한다면 어느 블록에 기록되어 있는지를 모르기 때문에 첫 블록부터 마지막 블록까지 모두 뒤져서 특정 주소와 연관된 트랜잭션을 찾아야 합니다. 만약 현재 100만 블록이 생성되었다 치면 100만 개의 블록을 확인해야 되기 때문에 사실상 엄청나게 느릴 수밖에 없습니다. 이더리움 계열의 블록체인에서 사용하는 DB는 MySql과 같은 DB처럼 완벽한 검색 기능이 없기 때문에 매우 느립니다.
결론적으로 빠른 속도로 트랜잭션을 검색하기 위해 각각의 트랜잭션을 MySql에 저장하는 것입니다. 물론 MongoDB, Redis 등을 이용해도 되겠죠. ^^

그럼 코인을 전송할 때도 계정의 잔액을 확인하기 위해 블록을 전부 다 체크해야 되는 건가요?

그건 아닙니다.
이더리움 계열 코인은 블록체인을 보조하기 위해 스테이트를 가지고 있는데요.
예를 들어 특정 계정의 현재 잔액, 컨트랙트의 변수값 같은 내용을 저장한 데이터입니다.
이 스테이트 데이터를 따로 저장하고 있기 때문에 코인 전송과 같은 처리를 빠르게 검증할 수 있죠.

그럼 블록체인의 블록에 기록되어 있는 트랜잭션이 어떻게 구성되어있는지 살펴보겠습니다.

우분투 콘솔에서 아래와 같이 호출해봅니다. (JSON RPC)
맨뒤 IP와 포트는 설정된 값을 넣어주시면 되고요.

$ curl -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x16E34", true],"id":1}' "http://127.0.0.1:9545" 

eth_getblockbynumber는 params에 블록번호를 Hex(16진수)값으로 넣어 블록의 정보를 읽어오는 명령입니다.
위 예제는 93748번째(Hex 0x16E34) 블록정보를 읽어오겠죠.
eth_getblockbynumber에 대한 자세한 정보는 아래 링크를 확인하세요.
https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber

결과값은 JSON 형태로 되어 있는데요.

{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0xfb51d13207","extraData":"0xd682020084....

https://codebeautify.org/jsonviewer 등의 도구를 이용하면 아래 처럼 이쁘게 볼 수 있겠죠.

{  
    "jsonrpc":"2.0",
    "id":1,
    "result":{  
        "difficulty":"0xfb51d13207",
        "extraData":"0xd6820200846765746887676f312e392e32856c696e7578",
        "gasLimit":"0x47e7c4",
        "gasUsed":"0xa410",
        "hash":"0xc8a29230fec30c0da7556fd4df3d79188576fb4db6ceab7d690440d247ecb3c9",        "logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "miner":"0x6e869c68511c1458f4fbed9a4c5296fe961eb47e",
        "mixHash":"0xf49553a261d5076fb22c0b6242cb6b6d465f9c1e95fbba4de3fbf6b456743a6b",
        "nonce":"0x91b62cb0079eb884",
        "number":"0x16e34",
        "parentHash":"0x23d8f2c14a2214fab4dcb0db8a8f3676187a5e76a9b10cb84197f6c85924fa86",
        "receiptsRoot":"0x153e6bb470fffe949f0965348033f17df6b6323d00a9950ee4d09141dfdedd46",
        "sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "size":"0x300",
        "stateRoot":"0x5ee14af9355d6d35bdad5ceac3e45f4eedba8da5eae3511d0a0cfd170dc79ec5",
        "timestamp":"0x5a76cbef",
        "totalDifficulty":"0x113c171495d1459",
        "transactions":[  
            {  
                "blockHash":"0xc8a29230fec30c0da7556fd4df3d79188576fb4db6ceab7d690440d247ecb3c9",
                "blockNumber":"0x16e34",
                "from":"0x0514c1151f356070ace281435f25c86b58280715",
                "gas":"0x15f90",
                "gasPrice":"0x430e23400",
                "hash":"0x104ff8fe7357acd6621140071630fd6508772d535ca3771a215e56875b5c594b",
                "input":"0x",
                "nonce":"0x65f1",
                "to":"0xfbc9a3c3c429990cc306710b3dd44174dcc72ad4",
                "transactionIndex":"0x0",
                "value":"0xe4ce0abfa0a2800",
                "v":"0x1b",
                "r":"0xc2c8c09023d42921c3756116c15623bb36f275b7c58b8e6904da31ee9aff268e",
                "s":"0x339da00a32cffe0baf68a278d27718114d2b3dc3dc86d93ac9647e716847157b"
            },
            {  
                "blockHash":"0xc8a29230fec30c0da7556fd4df3d79188576fb4db6ceab7d690440d247ecb3c9",
                "blockNumber":"0x16e34",
                "from":"0x2eb64b8ab13f0d7823158217d15ba310ed3d0e58",
                "gas":"0x15f90",
                "gasPrice":"0x430e23400",
                "hash":"0xe7a8298b63efd2bc965c5b91fddff9c37e78cd03cc096bf7af7249f43fef1075",
                "input":"0x",
                "nonce":"0x337e",
                "to":"0xadda124baed2e1fdc1acc7b4a048eab0cd249212",
                "transactionIndex":"0x1",
                "value":"0x420945f974a84e00",
                "v":"0x1b",
                "r":"0x73a5333a3e2fd12bfa9eca16d1df7cc2d2f42294f1ac8a3d4d9c71fc0d44ff6d",
                "s":"0x22348ebdd83d1a75a0270b9b26fec393093dcb974b955b62979c0a9060a9ebb2"
            }
        ],
        "transactionsRoot":"0x2600aa4902f36dd672e61c55656b12d94ba8c4cd61e2f597d02882c3bc597908",
        "uncles":[  

        ]
    }
}

중요한 정보 몇 가지만 설명하면요.

[블록 정보]
number: 블록 번호
hash: 블록 해시
difficulty: 난이도
miner: 채굴자 주소와
gasLimit: gas 한도
gasUsed: 사용된 gas의 양
transactions: 트랜잭션 내역

[트랜잭션 정보]
from: 보낸 주소
to: 받은 주소
gas: gas 수량
gasPrice: gas 가격
hash: 트랜잭션 해시
input: 추가 정보
nonce: 보낸 사람의 트랜잭션 순서
transactionIndex: 트랜잭션 배열의 순서
value: 전송 수량
v, r, s: 디지털 서명을 위한 값

우리가 중요하게 봐야 하는것은 from, to, value, gas, gasPrice 인데요.
누가(from) 누구(to)에게 몇개(value)의 코인을 수수료 몇개(gas * gasPrice)를 지불하여 전송하였느냐를 알수 있겠죠. ^^
모든 수치들은 Hex(16진수)값으로 되어 있으며 수량과 gas에 관련된 것들은 모두 gwei(10의 18승 gwei = 1이더)단위라고 보시면 됩니다.

우리는 위와 같은 정보를 첫 블록부터 현재 블록까지 검색하여 MySql에 저장하고
그 이후는 주기적으로 대략 14초마다 추가된 블록을 검색하여 저장하면 됩니다.

오늘 강좌는 여기서 마무리하겠고요.
다음 시간에는 다시 PHP 코딩으로 들어가겠습니다.

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

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

✅ Enjoy the vote! For more amazing content, please follow @themadcurator for a chance to receive more free votes!