웹소켓 사용하기
이 문서는 웹소켓과 Alchemy를 사용하여 이더리움 블록체인에 요청을 보내는 방법을 다루는 초급 가이드입니다.
(opens in a new tab)웹소켓과 HTTP 비교
HTTP와 달리 웹소켓을 사용하면 특정 정보를 원할 때 지속적으로 요청을 보낼 필요가 없습니다. 웹소켓은 (올바르게 구현된 경우) 네트워크 연결을 유지하며 변경 사항을 수신합니다.
다른 네트워크 연결과 마찬가지로 웹소켓이 중단 없이 영원히 열려 있을 것이라고 가정해서는 안 되지만, 끊어진 연결과 재연결을 수동으로 올바르게 처리하는 것은 까다로울 수 있습니다. 웹소켓의 또 다른 단점은 응답에서 HTTP 상태 코드를 받지 못하고 오류 메시지만 받는다는 것입니다.
Alchemy Web3 (opens in a new tab)는 별도의 구성 없이도 웹소켓 실패 및 재시도 처리를 자동으로 추가합니다.
직접 해보기
웹소켓을 테스트하는 가장 쉬운 방법은 wscat (opens in a new tab)과 같은 웹소켓 요청용 명령줄 도구를 설치하는 것입니다. wscat을 사용하면 다음과 같이 요청을 보낼 수 있습니다.
참고: Alchemy 계정이 있는 경우 demo를 자신의 API 키로 바꿀 수 있습니다. 여기에서 무료 Alchemy 계정에 가입하세요! (opens in a new tab)
wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo
> {"jsonrpc": "2.0", "id": 0, "method": "eth_gasPrice"}
< {"jsonrpc": "2.0", "result": "0xb2d05e00", "id": 0}
웹소켓 사용 방법
시작하려면 앱의 웹소켓 URL을 사용하여 웹소켓을 엽니다. 대시보드 (opens in a new tab)에서 앱 페이지를 열고 "View Key"를 클릭하여 앱의 웹소켓 URL을 찾을 수 있습니다. 앱의 웹소켓 URL은 HTTP 요청용 URL과 다르지만, 두 URL 모두 "View Key"를 클릭하여 찾을 수 있습니다.
Alchemy API 참조 (opens in a new tab)에 나열된 모든 API는 웹소켓을 통해 사용할 수 있습니다. 이렇게 하려면 HTTP POST 요청의 본문으로 보낼 페이로드와 동일한 페이로드를 사용하되, 해당 페이로드를 웹소켓을 통해 보내면 됩니다.
Web3와 함께 사용하기
Web3와 같은 클라이언트 라이브러리를 사용하면서 웹소켓으로 전환하는 것은 간단합니다. Web3 클라이언트를 인스턴스화할 때 HTTP URL 대신 웹소켓 URL을 전달하기만 하면 됩니다. 예:
const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key")
web3.eth.getBlockNumber().then(console.log) // -> 7946893
구독 API
웹소켓을 통해 연결된 경우 eth_subscribe 및 eth_unsubscribe라는 두 가지 추가 메서드를 사용할 수 있습니다. 이 메서드들을 사용하면 특정 이벤트를 수신하고 즉시 알림을 받을 수 있습니다.
eth_subscribe
지정된 이벤트에 대한 새 구독을 생성합니다. eth_subscribe에 대해 자세히 알아보기 (opens in a new tab).
매개변수
- 구독 유형
- 선택적 매개변수
첫 번째 인수는 수신할 이벤트의 유형을 지정합니다. 두 번째 인수는 첫 번째 인수에 따라 달라지는 추가 옵션을 포함합니다. 다양한 구독 유형, 해당 옵션 및 이벤트 페이로드는 아래에 설명되어 있습니다.
반환값
구독 ID: 이 ID는 수신된 모든 이벤트에 첨부되며, eth_unsubscribe를 사용하여 구독을 취소할 때도 사용할 수 있습니다.
구독 이벤트
구독이 활성화되어 있는 동안 다음 필드가 있는 객체인 이벤트를 수신하게 됩니다.
jsonrpc: 항상 "2.0"method: 항상 "eth_subscription"params: 다음 필드가 있는 객체:subscription: 이 구독을 생성한eth_subscribe호출에서 반환된 구독 ID입니다.result: 구독 유형에 따라 내용이 달라지는 객체입니다.
구독 유형
alchemy_newFullPendingTransactions
대기 중(pending) 상태에 추가된 모든 트랜잭션에 대한 트랜잭션 정보를 반환합니다. 이 구독 유형은 표준 Web3 호출인 web3.eth.subscribe("pendingTransactions")와 유사하게 대기 중인 트랜잭션을 구독하지만, 트랜잭션 해시뿐만 아니라 전체 트랜잭션 정보를 내보낸다는 점에서 다릅니다.
예:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["alchemy_newFullPendingTransactions"]}
< {"id":1,"result":"0x9a52eeddc2b289f985c0e23a7d8427c8","jsonrpc":"2.0"}
< {
"jsonrpc":"2.0",
"method":"eth_subscription",
"params":{
"result":{
"blockHash":null,
"blockNumber":null,
"from":"0xa36452fc31f6f482ad823cd1cf5515177d57667f",
"gas":"0x1adb0",
"gasPrice":"0x7735c4d40",
"hash":"0x50bff0736c713458c92dd1848d12f3354149be1363123dae35e94e0f2a9d56bf",
"input":"0xa9059cbb0000000000000000000000000d0707963952f2fba59dd06f2b425ace40b492fe0000000000000000000000000000000000000000000015b1111266cfca100000",
"nonce":"0x0",
"to":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40",
"transactionIndex":null,
"value":"0x0",
"v":"0x26",
"r":"0x195c2c1ed126088e12d290aa93541677d3e3b1d10f137e11f86b1b9227f01e3b",
"s":"0x60fc4edbf1527832a2a36dbc1e63ed6193a6eee654472fbebbf88ef1750b5344"},
"subscription":"0x9a52eeddc2b289f985c0e23a7d8427c8"
}
}
newHeads
체인 재구성 중을 포함하여 체인에 새 헤더가 추가될 때마다 이벤트를 내보냅니다.
체인 재구성이 발생하면 이 구독은 새 체인의 모든 새 헤더가 포함된 이벤트를 내보냅니다. 특히, 이는 동일한 높이에서 여러 헤더가 내보내지는 것을 볼 수 있음을 의미하며, 이 경우 나중에 나온 헤더를 재구성 이후의 올바른 헤더로 간주해야 합니다.
예:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
< {
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"result": {
"extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
"gasLimit": "0x47e7c4",
"gasUsed": "0x38658",
"logsBloom":
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x084149998194cc5f",
"number": "0x1348c9",
"parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
"receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
"timestamp": "0x56ffeff8",
"transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
},
"subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
}
}
logs
지정된 필터 기준과 일치하는 새로 추가된 블록의 일부인 로그를 내보냅니다.
체인 재구성이 발생하면 이전 체인의 블록에 속한 로그가 removed 속성이 true로 설정된 상태로 다시 내보내집니다. 또한 새 체인의 블록에 속한 로그가 내보내지므로, 재구성이 발생할 경우 동일한 트랜잭션에 대한 로그를 여러 번 볼 수 있습니다.
매개변수
- 다음 필드가 있는 객체:
address(선택 사항): 주소를 나타내는 문자열 또는 이러한 문자열의 배열입니다.- 이 주소 중 하나에서 생성된 로그만 내보내집니다.
topics: 주제(topic) 지정자의 배열입니다.- 각 주제 지정자는
null, 주제를 나타내는 문자열 또는 문자열 배열 중 하나입니다. - 배열에서
null이 아닌 각 위치는 내보내지는 로그를 해당 위치에 주어진 주제 중 하나를 가진 로그로만 제한합니다.
- 각 주제 지정자는
주제 지정의 몇 가지 예:
[]: 모든 주제 허용.[A]: 첫 번째 위치에 A (그리고 그 이후에는 무엇이든).[null, B]: 첫 번째 위치에 무엇이든, 두 번째 위치에 B (그리고 그 이후에는 무엇이든).[A, B]: 첫 번째 위치에 A, 두 번째 위치에 B (그리고 그 이후에는 무엇이든).[[A, B], [A, B]]: 첫 번째 위치에 (A 또는 B), 두 번째 위치에 (A 또는 B) (그리고 그 이후에는 무엇이든).
예:
> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}
< {
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"subscription": "0x4a8a4c0517381924f9838102c5a4dcb7",
"result": {
"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
"blockHash": "0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04",
"blockNumber": "0x29e87",
"data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003",
"logIndex":"0x0",
"topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],
"transactionHash": "0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4",
"transactionIndex": "0x0"
}
}
}
eth_unsubscribe
더 이상 이벤트가 전송되지 않도록 기존 구독을 취소합니다.
매개변수
- 이전에
eth_subscribe호출에서 반환된 구독 ID입니다.
반환값
구독이 성공적으로 취소된 경우 true, 주어진 ID의 구독이 존재하지 않는 경우 false를 반환합니다.
예:
요청
curl https://eth-mainnet.alchemyapi.io/v2/your-api-key
-X POST
-H "Content-Type: application/json"
-d '{"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}'
결과
{
"jsonrpc": "2.0",
"id": 1,
"result": true
}
무료로 Alchemy에 가입 (opens in a new tab)하고, 공식 문서 (opens in a new tab)를 확인해 보세요. 최신 소식은 트위터 (opens in a new tab)에서 팔로우할 수 있습니다.
