체인의정석

web3에서 트랜잭션 정보를 가져오는 방법들과 차이점(getTransactionReceipt, getTransaction, getBlock) 본문

블록체인/퍼블릭 블록체인

web3에서 트랜잭션 정보를 가져오는 방법들과 차이점(getTransactionReceipt, getTransaction, getBlock)

체인의정석 2023. 2. 23. 12:25
728x90
반응형

만약 자체 서비스에서 대량의 데이터를 가져와서 처리해 주는 서비스라면 또는 이더스캔과 같은 서비스를 만든다면 최초의 어느 시점에서는 블록체인 노드에 직접 접근하여 트랜잭션을 가져와야 한다.

 

이 과정에서 여러 함수를 사용할 수 있는데 각 상황에 따라 사용하면 좋은 함수가 갈린다.

getTransaction

web3.eth.getTransaction('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b§234')
.then(console.log);

> {
    "hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
    "nonce": 2,
    "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
    "blockNumber": 3,
    "transactionIndex": 0,
    "from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
    "to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
    "value": '123450000000000000',
    "gas": 314159,
    "gasPrice": '2000000000000',
    "input":
}

이 경우 실제 실행된 트랜잭션 뿐 만 아니라 팬딩 된 트랜잭션도 볼 수 있다.

물론 이건 transactionIndex를 통해서 필터링을 할 수 있다. 그럼 처리된 트랜잭션만 나오게 된다.

 

getTransaction의 장점

일단 getTransaction은 장점이 바로 input을 보여준다는 것이다.

input을 가져올 수 있고 이를 DB에 저장하게 되면 유용한 정보가 될 수 있다.

 

input값은 transactionReceipt 

 

getBlock

getBlock의 경우 특정 블록에 있는 트랜잭션을 모두 가져오게 된다.

web3.eth.getBlock(3150)
.then(console.log);

> {
    "number": 3,
    "hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
    "parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88",
    "nonce": "0xfb6e1a62d119228b",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee",
    "stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb",
    "miner": "0x8888f1f195afa192cfee860698584c030f4c9db1",
    "difficulty": '21345678965432',
    "totalDifficulty": '324567845321',
    "size": 616,
    "extraData": "0x",
    "gasLimit": 3141592,
    "gasUsed": 21662,
    "timestamp": 1429287689,
    "transactions": [
        "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b"
    ],
    "uncles": []
}

여기서 만약 2번째 옵션을 true 로 주면 

getTransaction의 내용까지 한번에 리턴되게 된다.

async function getBlockInfos() {
    getBlockInfo = await web3.eth.getBlock(블록번호,true);
    console.log("getBlock Info >>>", getBlockInfo);
}

getBlockInfos().then(console.log)
    .catch((error) => {
    console.error(error);
    process.exitCode = 1;
  });

요런식으로 쓰면 확인이 가능하다.

 

transactions의 배열 안에 내부적으로 정보들이 표시되게 된다.

(예전에 비트코인 노드에서도 비슷한 형태로 옵션을 주면 상세 내용을 조회할 수 있었던 기억이 있다.)

 

아무튼 이걸 통해서 특정 블록의 모든 트랜잭션들을 가져올 수 있다. (팬딩 내용을 포함하여)

 

getTransactionReceipt

근데 실행된 트랜잭션 중. 트랜잭션의 status 즉 해당 트랜잭션이 실패했는지까지 표시해주어야 한다면 어떻게 해야할까?

그때 쓰는것이 getTransactionReceipt이다.

 

var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b')
.then(console.log);

> {
  "status": true,
  "transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
  "transactionIndex": 0,
  "blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
  "blockNumber": 3,
  "contractAddress": "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe",
  "cumulativeGasUsed": 314159,
  "gasUsed": 30234,
  "logs": [{
         // logs as returned by getPastLogs, etc.
     }, ...]
}

결국 트랜잭션 중 실패한 트랜잭션을 분리해서 기록해야 할 경우 영수증을 받아와야 한다.

최종적으로 getBlock의 2번째 옵션을 true로 두고 getTransactionReceipt를 쓰면 모든 정보가 다 리턴된다.

 

 

다만, 대규모 시스템 + 처리해야 되는 데이터가 한정되어 있는경우

그냥 이벤트를 호출해서 db에 업데이트 시키면 된다.

그치만 전체를 다 기록해두면 모든 데이터를 자유자재로 다 뽑아낼 수있으므로 대규모 시스템을 만든다면 위의 로직이 더 좋다.

이를 고려해서 상황에 맞게 선택을 하거나 2개의 로직을 분리해서 각각 다루는 것을 추천한다.

 

 

 

참고 : web3 공식문서

https://web3js.readthedocs.io/en/v1.2.11/web3-eth.html#getblock

 

web3.eth — web3.js 1.0.0 documentation

The web3-eth package allows you to interact with an Ethereum blockchain and Ethereum smart contracts. Note on checksum addresses All Ethereum addresses returned by functions of this package are returned as checksum addresses. This means some letters are up

web3js.readthedocs.io

 

728x90
반응형
Comments