2023. 6. 22. 11:30ㆍBlockchain/Cosmos
Cosmos SDK 기반 체인은 query를 위한 여러가지 방식을 제공한다. HTTP REST(LCD: Light Client Daemon), gRPC, Tendermint RPC로 제공된다. Account의 balance 확인하는 방법을 예로 들어 query하는 방식을 정리한다.
HTTP REST
Cosmos SDK 기반 체인에서 home directory의 app.toml
에서 API configuration
에서 설정이 정의되며, 기본적으로 1317 port를 사용한다. Cosmos의 module들은 gRPC gateway를 통해 HTTP request도 수신하여 gRPC로 요청한 결과값과 동일한 결과를 return하는 방식으로 HTTP query를 지원한다. /cosmos/[module명]/[version]/[query]의 API가 모두 그것이며 이를 통해 module keeper 및 kv store가 관장하는 state 저장값을 확인할 수 있다. 체인을 동작하면 실행되는 function startInProcess
에서 app.toml
- API configuration
의 enable
값이 true로 설정되어 있다면 config.API.Enable
변수를 통해서 HTTP 서버가 실행되며, RegisterAPIRoutes
를 통해 module에서 정의된 URL routing으로 client의 요청을 server 단에서 처리한다.
대부분의 cosmos 체인들이 API는 동일할 것이며 XPLA를 예로 테스트를 해볼것이다. XPLA testnet cube_47-5
를 사용하여 테스트 한다. account balance에 대한 request API는 아래와 같다. XPLA testnet의 LCD endpoint는 cube-lcd.xpla.dev
가 존재하여 이 URL로 테스트 해본다.
https://cube-lcd.xpla.dev/cosmos/bank/v1beta1/balances/xpla1tknd6230p6fcza5549myhjflhslx425fzxkxfm
조회는 GET 방식으로 사용하며, module명은 bank
, protobuf version은 v1beta1
(현재 cosmos SDK는 v0.47.3 버전이 release 됐으며 protobuf version은 buf.work.yaml
상에서 v1으로 확인할 수 있다. XPLA는 현재 이전 버전인 v0.45.9 버전을 사용한다.), query는 사용자 balance확인을 위한 balances
가 입력되며, 마지막으로 조회를 위한 account 주소를 입력하면 해당 주소의 현재 latest block 기준 balance를 확인 가능하다.
{
"balances": [
{
"denom": "axpla",
"amount": "10225408035287499830671"
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
gRPC
gRPC는 HTTP REST와 마찬가지로 app.toml
에서 gRPC configuration
에서 설정이 정의되며, 기본적으로 9090 port를 사용한다. Proto 파일에서 정의된 메시지 형식에 따라 query를 할수 있다. proto gen을 통하여 proto 파일에 정의된 메시지가 각 모듈 내에 pb.go
를 생성하며, query를 위해서는 query.pb.go
에 정의된 request message 형식에 따라 gRPC 요청을 진행하면 된다. gRPC 서버도 HTTP 서버와 마찬가지로 startInProcess
내의 config.GRPC.Enable
값이 true이면 StartGRPCServer()
를 통해 실행이 되며, baseapp
내의 RegisterGRPCServer()
에서 routing과 정의된 interceptor를 등록한다.
gRPC를 통한 account balance에 대한 request 방법은 아래와 같다.
grpcurl --plaintext -d "{\"address\":\"xpla1tknd6230p6fcza5549myhjflhslx425fzxkxfm\"}" cube-grpc.xpla.dev:9090 cosmos.bank.v1beta1.Query/AllBalances
grpcurl
을 사용하여, balance 조회를 위한 method인 cosmos.bank.v1beta1.Query/AllBalances
를 이용하면 아래와 같은 response를 확인할 수 있다. LCD를 이용한 HTTP가 앞서 언급했던 것처럼 gRPC gateway를 이용하기 때문에 HTTP 요청이나 gRPC 요청 모두 같은 값이 반환된다.
{
"balances": [
{
"denom": "axpla",
"amount": "10225408035287499830671"
}
],
"pagination": {
"next_key": null,
"total": "1"
}
}
Tendermint RPC
Tendermint에서 제공되는 RPC는 위 두 방식과는 다르게 config.toml
에서 RPC server configuration options
에서 설정이 정의되며, 기본적으로 26657 port를 사용한다. 체인 시작 시 같이 시작되는 tendermint node에서 RPC 서버가 구동된다. Tendermint RPC 서버는 다른 query 요청을 진행하지 않아도 html을 제공하여 사용할 수 있는 API의 예시를 들어주고 또한 지원 가능한 API 목록이 나오기 때문에 상대적으로 API 찾기 편하다. 참고적으로 cosmos SDK API swagger와 tendermint RPC swagger를 첨부한다.
Tendermint RPC는 abci_query
를 통해 state를 조회할 수 있다. Tendermint RPC를 통한 account balance에 대한 request 방법은 아래와 같다.
https://cube-rpc.xpla.dev/abci_query?path=%22/cosmos.bank.v1beta1.Query/AllBalances%22&data=%22\n%2Bxpla1tknd6230p6fcza5549myhjflhslx425fzxkxfm%22&height=0&prove=false
path
는 ABCI query시에도 gRPC와 동일한 method를 사용하며 data에는 조회 대상의 account가 필요하다. Data의 %2B
는 URL escape로 "+"이며 즉 code 내에서 data가 확인되는 것은 "\n+xpla1tknd6230p6fcza5549myhjflhslx425fzxkxfm"
값이 입력된다. Height를 0으로 설정하면 latest block을 기준으로 조회하고 특정 블록을 기준으로 보고 싶으면 블록 height를 기입하면 된다. Response 값은 JSON RPC response 형식으로 확인 할 수 있다.
{
"jsonrpc": "2.0",
"id": -1,
"result": {
"response": {
"code": 0,
"log": "",
"info": "",
"index": "0",
"key": null,
"value": "CiAKBWF4cGxhEhcxMDIyNTQwODAzNTI4NzQ5OTgzMDY3MRICEAE=",
"proofOps": null,
"height": "4330497",
"codespace": ""
}
}
}
여기서 value값이 account의 balance가 encoding된 값이다. Cosmos SDK의 codec으로 인코딩된 값이며, decoding은 SDK에 제공되는 function으로 할 수 있다. Encoding/Decoding 방법은 다음에 기회가 있을때 공유하면 좋을것 같다. Base64 decoding으로 내부 몇몇 값은 확인할 수 있으나, 일반적으로 raw tx등의 codec encoding 결과들은 base64 decoding해도 전체 본문이 제대로 출력되지 않는다. 위 value의 encoding 값을 단순 base64 decoding한 결과는 아래와 같다.
axpla 10225408035287499830671
HTTP REST, gRPC, RPC 모두 같은 결과를 출력하는 것을 확인할 수 있다.
Conclusion
Cosmos SDK 기반 체인의 여러 조회 방법을 확인해 보았다. 각 API가 오픈이 되지 않은 경우도 종종 있기 때문에 필요에 따라 선택해서 query를 진행해야 한다. 또한 각 호출 방식 마다 장단점이 존재하기 때문에 현재 개발 상황에 맞는 방식을 취사 선택할 필요도 존재한다. 아래 표는 Cosmos docs에서 제공하는 장단점을 구분한 표이다.
따라서 한가지만 사용하기 보다는 여러 케이스의 사용 방법을 알고 있으면 cosmos chain 개발에 도움이 될 것 같다.
참고
https://docs.cosmos.network/main/core/grpc_rest#comparison-table
https://github.com/cosmos/cosmos-sdk
'Blockchain > Cosmos' 카테고리의 다른 글
Cosmos에서의 gRPC (0) | 2023.09.15 |
---|---|
Inter-Blockchain Communication 구조와 Relayer (0) | 2023.07.07 |
Cosmos SDK 기반 체인 다중 validator 환경 구성 (0) | 2023.06.15 |
Ethereum과 Cosmos의 genesis (0) | 2023.06.15 |
Cosmos chain module 및 components (0) | 2023.06.14 |