안녕하세요.
많은 분들이 web3를 이용하여 Ethereum과 통신하고 있습니다. web3는 well-made 프로젝트이기 때문에 우리가 그 안에서 어떻게 돌아가는지 까지 알 필요가 없게 잘 만들어져어있습니다. 하지만 그렇기 때문에 web3에 대해서 의존적일 수 밖에 없으며 커스터마이징 하는것도 힘듭니다. 그래서 이번에 어떻게 Ethereum의 smart-conract와 transaction을 주고 받는지, 그리고 그 내용을 분석해보았습니다.
- Transaction이 발생할 때 보통 본인의 private Key와 Nonce값으로 먼저 Sign을 하는데 이런 부분은 이번 포스트에서는 제외하겠습니다. 궁금하신 분은 아래를 보시면 좋은 참고가 될 것 같습니다.
Transaction Flow
- 기본 Transaction Data를 만들고 Private Key와 Nonce값으로 Sign을 합니다.
- Sign된 Transaction Data를 Cleint -> Ethereum으로 전송합니다.
- 해당 Transactiond에 대한 Hash값을 받습니다.
- Transaction을 받은 Ethereum은 해당 Transaction을 Pending상태로 대기시킨 후 해당 Transaction을 Commit할 수 있을때 까지 기다립니다.(transaction fee를 너무 낮게 설정하면 Pending이 길어지며, Mining이 안되고 있다면 계속 Pending입니다.)
- Pending 상태에서 Receipt를 요청한다면 Ethereum은 null을 반환합니다.
- Ethereum에서 해당 Transaction이 Commit된다면 Receipt를 만들어 냅니다.
- Transaction에 대한 Receipt요청이 Transaction Commit이후에 들어온다면 해당 Receipt를 반환합니다.
mining이 안되고 있거나
이런 Transaction Flow에서 사용하는 json-rpc 프로토콜은 2개가 있습니다.
(nonce값을 구하던지 하는 부가적인 부분은 생략 했습니다.)
- eth_sendRawTransaction
- Ethereum에 Transaction 처리 요청
- eth_getTransactionReceipt
- Block에 write된 Transaction 결과 요청
아래에서 자세한 설명을 보겠습니다.
SendTransaction Hash
eth_sendRawTransaction
Creates new message call transaction or a contract creation for signed transactions.
Parameters
DATA, The signed transaction data.
Example Parameters
params: > ["0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"]Returns
DATA, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available.
Use eth_getTransactionReceipt to get the contract address, after the transaction was mined, when you created a contract.
- block의 데이터를 읽어오기나 쓰는 행위, Sign된 transaction을 보내야합니다.
- Paramter로는 Signed Transaction을 보내면 됩니다. 이 Signed Transaction은 보내는 값에 따라 길이가 천차만별 일 수 있습니다. Smart Contract를 생성한다면 셀수 없이 길 수 있으며, 단순한 getMethod 호출이라면 정말 짧을 수도 있습니다.
- Return되는 값은 32Byte의 Transaction Hash 값입니다. 이 해쉬값으로 Transaction이 Ethereum에 Commit된 후에 Receipt를 가져올 수 있습니다.
getTransactionReceipt
Spec
eth_getTransactionReceipt
Returns the receipt of a transaction by transaction hash.
Note That the receipt is not available for pending transactions.
Parameters
DATA, 32 Bytes - hash of a transaction
Example Parameters
params: [
'0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238'
] Returns
Object - A transaction receipt object, or null when no receipt was found:
transactionHash : DATA, 32 Bytes - hash of the transaction.
transactionIndex: QUANTITY - integer of the transaction's index position in the block.
blockHash: DATA, 32 Bytes - hash of the block where this transaction was in.
blockNumber: QUANTITY - block number where this transaction was in.
from: DATA, 20 Bytes - address of the sender.
to: DATA, 20 Bytes - address of the receiver. null when it's a contract creation transaction.
cumulativeGasUsed : QUANTITY - The total amount of gas used when this transaction was executed in the block.
gasUsed : QUANTITY - The amount of gas used by this specific transaction alone.
contractAddress : DATA, 20 Bytes - The contract address created, if the transaction was a contract creation, otherwise null.
logs: Array - Array of log objects, which this transaction generated.
logsBloom: DATA, 256 Bytes - Bloom filter for light clients to quickly retrieve related logs.
It also returns either :root : DATA 32 bytes of post-transaction stateroot (pre Byzantium)
status: QUANTITY either 1 (success) or 0 (failure)
- Transaction에 대한 Receipt는 Transaction이 Block에 쓰이고 나서 반환 해주는 값으로 상당히 많은 정보를 가지고 있습니다. 몇개만 확인해보겠습니다.
- from : transaction을 보낸 사람
- to : transaction을 받은 사람(Or Contract)
- cumulativeGasUsed : 현재 블럭에서 사용된 Gas
- 일반적으로 1 Block에 사용할 수 있는 Gas의 양은 한정되어 있습니다.
- 시간의 경과 또는 Gas 사용량의 초과로 Block이 새로 생성됩니다.
- gas : 이번 transaction에 사용한 gas
- usedTotal gas = GasPrice * gas 기준 이며, 여기서 gas 기준은 32Byte를 Insert 하는데 20000이라고 알고 있습니다. (Event, Update, Delete는 각각 다릅니다.)
- ContractAddress : smart contract제작도 sendRawTransaction Method를 통해서 할 수 있습니다. 그때 생성된 Contract의 Address입니다.
- 기존 smart-contract와 통신한다면 null 반환입니다.
결론
Client가 Ethereum과 통신은 모든것이 단방향[Client -> Ethereum]으로 이루어집니다. (사실상 Event도 마찬가지 입니다.)
그렇기 때문에 Client에서는 Ethereum과의 통신관련 Thread 관리가 중요할 것으로 보여집니다.
위의 사양을 직접 코딩 해보면서 익혀보고 싶으신 분들은 지금 연재하고 있는 제 포스팅을 참고하시면 될것 같습니다.
제작한 Smart Contract(Lottery 시스템)과 통신해보기 - get
다음번에는 Ethereum에서 RPC 관련하여 거의 모든 Client 라이브러리(web3, web3j 등)가 참조하고 있는 Json-RPC에 관하여 이야기 해보고자 합니다.
감사합니다!
참조
'기타 > 블록체인' 카테고리의 다른 글
[java & ethereum] web3j를 통해 ethereum과 통신해보기 (0) | 2019.09.02 |
---|---|
[ethereum] Smart Contract(Lottery 시스템)과 통신해보기 - event & log (0) | 2019.08.28 |
[ethereum] Smart Contract(Lottery 시스템)과 통신해보기 - basic (2) | 2019.08.21 |
[ethereum]ethereum과 통신해보기 (0) | 2019.08.12 |
Smart Contract(Lottery 시스템) 제작 _ 쉽게 수정 예정 (0) | 2019.08.08 |
댓글