Ethereum Basics - Transaction

๋ธ”๋ก์ฒด์ธ๊ณผ ์ด๋”๋ฆฌ์›€์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ์ดˆ ๊ฐœ๋…์ธ ํŠธ๋žœ์žญ์…˜์— ๋Œ€ํ•ด ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

Transaction์ด๋ž€?

Blockchain์—์„œ๋Š” Transaction์€ ์ƒํƒœ(State)์˜ ๋ณ€๊ฒฝ์„ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ฒ˜๋ฆฌ ๋‹จ์œ„์ž…๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ Transaction์€ ๋””์ง€ํ„ธ ์ž์‚ฐ์„ ์ „์†กํ•˜๊ฑฐ๋‚˜ ๋ฐ›๋Š” ์ž‘์—…์œผ๋กœ Sender์˜ ์ž์‚ฐ์ด Receiver์˜ ์ฃผ์†Œ๋กœ ์ „์†ก๋˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ๋”์šฑ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Transaction์ด ๋ฐœ์ƒํ•˜๋ฉด์„œ, Sender(User A)๊ฐ€ ๋ณด์œ ํ•˜๊ณ  ์žˆ๋Š” ETH์˜ ์ž”๊ณ (State)์™€ Receiver(User B)๊ฐ€ ๋ณด์œ  ์ค‘์ธ ETH์˜ ์ž”๊ณ (State)๊ฐ€ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. Node๋Š” ์ด๋Ÿฌํ•œ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๋„คํŠธ์›Œํฌ์— ์ „ํŒŒํ•˜๊ฒŒ ๋˜๊ณ  ๋ฒจ๋ฆฌ๋ฐ์ดํ„ฐ(์ฑ„๊ตด์ž)๋“ค์ด ์ „ํŒŒ๋œ Transaction์„ ๋ชจ์•„ Block์„ ์ฑ„๊ตดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. Transaction์˜ ์ข…๋ฅ˜๋Š” ETH๋ฅผ ์ „์†กํ•˜๋Š” Transaction์™ธ์— ๋ธ”๋ก์ฒด์ธ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ธฐ ์œ„ํ•œ Transaction, ์Šค๋งˆํŠธ ์ปจํŠธ๋ž™ํŠธ์˜ Method๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ Transaction ๋“ฑ ๋‹ค์–‘ํ•œ Transaction์ด ์žˆ์Šต๋‹ˆ๋‹ค.


Transaction๊ณผ Gas

์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์—์„œ๋Š” ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰ํ•  ๋•Œ Gas๋ผ๋Š” ์ด๋ฆ„์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ง€๋ถˆํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์™œ P2P ๋„คํŠธ์›Œํฌ์ธ ์ด๋”๋ฆฌ์›€์—์„œ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ง€๋ถˆํ•˜๊ฒŒ ๊ตฌ์„ฑ์ด ๋˜์–ด ์žˆ์„๊นŒ์š”? ์ด์œ ๋Š” ๋ฐ”๋กœ ์•ˆ์ „ํ•œ ๋„คํŠธ์›Œํฌ ํ™˜๊ฒฝ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ ์ƒ์ƒํ•ด ๋ณผ๊นŒ์š”? ์•…์˜์ ์ธ ๊ณต๊ฒฉ์ž๊ฐ€ Gas๊ฐ€ ์—†๋Š” ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์—์„œ ๋ฌดํ•œ์œผ๋กœ ๋กœ์ง์ด ๋™์ž‘ํ•˜๋Š” Transaction์„ ์‹คํ–‰ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋”๋ฆฌ์›€ ํŠน์„ฑ ์ƒ, ํ•ด๋‹น Transaction์ด ์‹คํ–‰๋  ๋•Œ ๋‹ค๋ฅธ Transaction์€ ์‹คํ–‰ ์ค‘์ธ Transaction์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์•…์˜์ ์ธ Transaction์ด ๋ฌดํ•œ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋‹ค๋ฅธ Transaction๋“ค์ด ์‹คํ–‰๋˜์ง€ ๋ชปํ•ด ๋„คํŠธ์›Œํฌ์— ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ณต๊ฒฉ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ๋Š” Transaction์„ ์‹คํ–‰ํ•  ๋•Œ ๊ฐ ์ž‘์—…๋งˆ๋‹ค Gas๋ผ๋Š” ์ด๋ฆ„์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์†Œ๋น„ํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์•…์˜์ ์ธ ๊ณต๊ฒฉ์ž๊ฐ€ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์—์„œ ๋ฌดํ•œ๋ฃจํ”„ ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰ํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •์„ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž์˜ Transacntion์ด ๋ฌดํ•œ๋ฃจํ”„๋ฅผ ๋Œ ๋•Œ ๋งˆ๋‹ค Gas๊ฐ€ ์†Œ๋ชจ๋˜๋ฉด์„œ ๊ณต๊ฒฉ์ž๊ฐ€ ๋ณด์œ ํ•œ ETH์˜ ์ž”๊ณ ๊ฐ€ ์ค„์–ด๋“ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค ๊ณต๊ฒฉ์ž๊ฐ€ ๋ณด์œ ํ•œ ๋ชจ๋“  ETH๋ฅผ ์†Œ๋ชจํ•˜๋ฉด Transaction์€ ์‹คํŒจํ•˜๊ณ  State๋Š” ์•…์˜์ ์ธ ๊ณต๊ฒฉ์ž์˜ Transaction ์‹คํ–‰ ์ด์ „ State๋กœ ๋Œ์•„๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์•…์˜์ ์ธ ๊ณต๊ฒฉ์ž๋Š” ์ž์‹ ์˜ ETH๋งŒ ์†Œ๋ชจํ•˜๊ณ  ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ๋Š” ์•„๋ฌด๋Ÿฐ ํƒ€๊ฒฉ์„ ๋ฐ›์ง€ ์•Š๊ฒŒ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. (Transaction์ด ์‹คํŒจํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, ์‹คํŒจํ•œ ๋ถ€๋ถ„ ๊นŒ์ง€ ์†Œ๋ชจ๋œ Gas๋Š” ์ง€๋ถˆํ•˜๊ฒŒ ๋˜๊ณ  State๋Š” ์›์ƒ๋ณต๊ตฌ ๋ฉ๋‹ˆ๋‹ค.)

๋˜ํ•œ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์—์„œ๋Š” Transaction์— ๋Œ€ํ•œ ์ตœ๋Œ€ Gas ์†Œ๋ชจ๋Ÿ‰์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์ œํ•œํ•˜๋Š” ์ด์œ ๋Š” ์˜ˆ์ƒ๋˜๋Š” Gas ์†Œ๋ชจ๋Ÿ‰ ์ด์ƒ ์‚ฌ์šฉ๋˜๋Š” ํŠธ๋žœ์žญ์…˜์ด ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, ์ด๋ฅผ ์ฐจ๋‹จํ•˜์—ฌ ์œ ์ €์˜ ์ž์‚ฐ์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค. ์œ ์ €๋Š” Transaction์„ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ตœ๋Œ€ Gas์˜ Limit์„ ์ง€์ •ํ•˜๊ณ  Node๋Š” Transaction์„ ์‹คํ–‰ํ•˜๋‹ค๊ฐ€ ์ง€์ •๋œ Gas์˜ Limit๋ณด๋‹ค ๋งŽ์€ Gas๋ฅผ ์†Œ๋ชจํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, Transaction์„ Fail๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  State๋ฅผ Transaction ์‹คํ–‰ ์ด์ „์œผ๋กœ ๋˜๋Œ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๋“ฏ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ๋Š” Gas์™€ GasLimit์„ ํ†ตํ•ด ๋„คํŠธ์›Œํฌ๋ฅผ ๋ณด๋‹ค ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€ํ•˜๊ณ  ์œ ์ €์˜ ์ž์‚ฐ์„ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Transaction์˜ Structure ๋ฐ ๋ถ„์„

์ด๋”๋ฆฌ์›€ Client์ธ Go-Ethereum(Geth)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” Transaction์˜ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

type Transaction struct {
    data txdata   
    hash common.Hash   
    size int      
    from common.Address  
    nonce uint64      
    gasPrice *big.Int    
    gasLimit uint64   
    to *common.Address 
    value *big.Int  
    // EIP155-specific fields
    chainID *big.Int  
    accessList types.AccessList  
    type uint8 
     
    **// caches**
    fromCache atomic.Value
    encodedCache atomic.Value
    sizeCache atomic.Value
    hashCache atomic.Value
}

์ฐธ์กฐ : https://github.com/ethereum/go-ethereum/blob/master/core/types/transaction.go

Transaction

Transaction์—๋Š” ๊ฑฐ๋ž˜ ๋ฐ์ดํ„ฐ์™€ Transaction ์‹œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์Šค์˜ ์ •๋ณด ๋“ฑ์ด ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. Transaction ํ•„๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • data : Transaction ๊ฑฐ๋ž˜ ๋ฐ์ดํ„ฐ ์ž…๋‹ˆ๋‹ค. txdata๋ผ๋Š” ๊ตฌ์กฐ์ฒด์—์„œ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
  • hash : Transaction์˜ ํ•ด์‹œ ์ž…๋‹ˆ๋‹ค.
  • size : Transaction์˜ ํฌ๊ธฐ ์ž…๋‹ˆ๋‹ค.
  • from : Transaction์„ ์‹คํ–‰ํ•˜๋Š” Sender์˜ ์ฃผ์†Œ ์ž…๋‹ˆ๋‹ค.
  • nonce : from ์ฃผ์†Œ์˜ nonce ์ž…๋‹ˆ๋‹ค. Account์˜ nonce๋Š” ์ผ์ข…์˜ ์นด์šดํ„ฐ๋กœ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ Transaction์„ ๋ฐœ์ƒ์‹œํ‚ฌ ๋•Œ ๋งˆ๋‹ค 1์”ฉ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • gasPrice : Transaction ์‹œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์Šค์˜ ๊ฐ€๊ฒฉ์œผ๋กœ Sender๊ฐ€ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. gasPrice๊ฐ€ ๋†’์„์ˆ˜๋ก ์†Œ๋ชจ๋˜๋Š” gas์˜ ๊ฐ€๊ฒฉ์ด ๋น„์‹ธ์ง€์ง€๋งŒ Transaction์ด ๋นจ๋ฆฌ ์‹คํ–‰๋  ํ™•๋ฅ ์ด ๋†’์•„์ง‘๋‹ˆ๋‹ค.
  • gasLimit : Transaction ์‹คํ–‰์— ํ•„์š”ํ•œ ์ตœ๋Œ€ ๊ฐ€์Šค๋Ÿ‰์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ์‹œ ํ•„์š”ํ•œ ๊ฐ€์Šค์˜ ์–‘์€ ์ปจํŠธ๋ž™ํŠธ์˜ ๋ณต์žก์„ฑ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š”๋ฐ gasLimit์„ ์ง€์ •ํ•˜์—ฌ ์ตœ๋Œ€ ์‚ฌ์šฉ๋  ๊ฐ€์Šค์˜ ์–‘์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ Transaction ์‹คํ–‰์— ํ•„์š”ํ•œ ๊ฐ’๋ณด๋‹ค ๋‚ฎ๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๊ฑฐ๋‚˜ Transaction์ด gasLimit๋ณด๋‹ค ๋งŽ์€ gas๋ฅผ ์†Œ๋ชจํ•˜๊ฒŒ ๋  ๊ฒฝ์šฐ, Transaction์€ ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • to : Transaction์„ ๋ฐ›๋Š” ์ฃผ์†Œ ์ž…๋‹ˆ๋‹ค. EOA๋กœ ์„ค์ •์ด ๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ, ์•„๋ž˜ ์ž…๋ ฅํ•˜๋Š” Value์— ๋”ฐ๋ผ ETH๋ฅผ ์ „์†ก๋ฐ›๊ฒŒ ๋˜๋ฉฐ CA๋กœ ์„ค์ •๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ, data์— ์ž…๋ ฅํ•œ ๊ฐ’์— ๋”ฐ๋ผ Contract์˜ Method๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปจํŠธ๋ž™ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” Transaction์ผ ๊ฒฝ์šฐ, to์˜ ๊ฐ’์€ null ์ž…๋‹ˆ๋‹ค.
  • value : From ์ฃผ์†Œ์—์„œ To ์ฃผ์†Œ๋กœ ์ „์†กํ•  ETH์˜ ์–‘ ์ž…๋‹ˆ๋‹ค.
  • chainID : EIP-155 ๊ทœ๊ฒฉ์—์„œ ์ง€์ •๋œ chain ID ์ž…๋‹ˆ๋‹ค. ์ด๋”๋ฆฌ์›€ ๊ณ„์—ด์˜ ์ฒด์ธ์€ ID๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ์ฒด์ธ์—์„œ ์‹คํ–‰ํ•˜๋Š” Transaction์ž„์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ด๋”๋ฆฌ์›€ ๋ฉ”์ธ๋„ท์˜ chainID๋Š” 1, Sepolia ํ…Œ์ŠคํŠธ๋„ท์˜ chainID๋Š” 11155111 ์ž…๋‹ˆ๋‹ค.
  • accessList : EIP-2930 ๊ทœ๊ฒฉ์—์„œ ์ง€์ •๋œ ๊ฐ’์œผ๋กœ ํŠธ๋žœ์žญ์…˜์—์„œ ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ์Šคํ† ๋ฆฌ์ง€์˜ ์œ„์น˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜๋งŒ ์—…๋ฐ์ดํŠธ, ์กฐํšŒํ•˜๋Š” ๋“ฑ ํ•„์š”ํ•œ ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•˜์—ฌ gas ๋น„์šฉ์„ ์ค„์ด๊ณ  ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. accessList์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ array์ด๋ฉฐ accessList์— ์ž…๋ ฅ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํฌ๋งท์€ address์™€ storageKeys๋ผ๋Š” ์ด๋ฆ„์˜ 32byte ๋ฐฐ์—ด์ž…๋‹ˆ๋‹ค. address์— ๋Œ€ํ•œ ์ ‘๊ทผ ํŒจํ„ด ์ค‘ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์Šคํ† ๋ฆฌ์ง€์˜ ์œ„์น˜๋ฅผ storageKeys๋กœ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

TxData

Transaction ๊ตฌ์กฐ์ฒด์˜ data ํ•„๋“œ๋Š” TxData๋ผ๋Š” ๊ตฌ์กฐ์ฒด์—์„œ ๊ฐ’์„ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค. TxData์— ๊ธฐ๋ก๋˜๋Š” ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

type txdata struct {
    AccountNonce uint64          `json:"nonce"       gencodec:"required"`
    Price        *big.Int        `json:"gasPrice"    gencodec:"required"`
    GasLimit     uint64          `json:"gas"         gencodec:"required"`
    Recipient    *common.Address `json:"to"          rlp:"nil"`
    Amount       *big.Int        `json:"value"       gencodec:"required"`
    Payload      []byte          `json:"input"       gencodec:"required"`
    V            *big.Int        `json:"v"           gencodec:"required"`
    R            *big.Int        `json:"r"           gencodec:"required"`
    S            *big.Int        `json:"s"           gencodec:"required"`
    Type         uint8           `json:"type"        gencodec:"required"`
}
  • AccountNonce : Transaction ์†ก์‹ ์ž์˜ nonce ๊ฐ’ ์ž…๋‹ˆ๋‹ค. nonce๋Š” ๊ฐ ํŠธ๋žœ์žญ์…˜์ด ํ•œ ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌ๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ์นด์šดํ„ฐ ์ž…๋‹ˆ๋‹ค. Transaction์„ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ด ๊ฐ’์„ 1์”ฉ ์ฆ๊ฐ€์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • Price : Transaction ์‹œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์Šค์˜ ๊ฐ€๊ฒฉ์œผ๋กœ Sender๊ฐ€ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • GasLimit : Transaction ์‹คํ–‰์— ํ•„์š”ํ•œ ์ตœ๋Œ€ ๊ฐ€์Šค๋Ÿ‰์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ์‹œ ํ•„์š”ํ•œ ๊ฐ€์Šค์˜ ์–‘์€ ์ปจํŠธ๋ž™ํŠธ์˜ ๋ณต์žก์„ฑ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š”๋ฐ gasLimit์„ ์ง€์ •ํ•˜์—ฌ ์ตœ๋Œ€ ์‚ฌ์šฉ๋  ๊ฐ€์Šค์˜ ์–‘์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ Transaction ์‹คํ–‰์— ํ•„์š”ํ•œ ๊ฐ’๋ณด๋‹ค ๋‚ฎ๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น Transaction์€ ์‹คํŒจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • Recipient : Transaction์˜ ๋ฐœ์‹ ์ž๋กœ To์— ํ•ด๋‹นํ•˜๋Š” Account Address ์ž…๋‹ˆ๋‹ค.
  • Amount :From ์ฃผ์†Œ์—์„œ To ์ฃผ์†Œ๋กœ ์ „์†กํ•  ETH์˜ ์–‘ ์ž…๋‹ˆ๋‹ค.
  • Payload : Transaction ์‹œ ํ•จ๊ป˜ ์ „์†กํ•  ๋ฐ์ดํ„ฐ ์ž…๋‹ˆ๋‹ค. ์ปจํŠธ๋ž™ํŠธ์˜ Method ์‹คํ–‰ ์‹œ Payload์— ์ž‘์„ฑ๋œ ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ ์ปจํŠธ๋ž™ํŠธ์˜ Method๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • V, R, S : ์„œ๋ช… ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ’์œผ๋กœ ์„œ๋ช…์„ ๊ฒ€์ฆํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ’ ์ž…๋‹ˆ๋‹ค.
  • Type : ๊ฑฐ๋ž˜ ์œ ํ˜•์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ 0์€ Legacy, 1์€ AccessList, 2๋Š” EIP-1559์— ๋Œ€ํ•œ Transaction ์œ ํ˜•์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

TxData์€ User๊ฐ€ ์‹คํ–‰ํ•˜๊ณ ์ž ์ž…๋ ฅํ•œ Transaction์˜ ์ •๋ณด์™€ ์„œ๋ช…๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๊ตฌ์กฐ์ฒด์ด๊ณ  Transaction์€ ํ•ด๋‹น ๊ฑฐ๋ž˜์— ๋Œ€ํ•œ ์ „์ฒด์ ์ธ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด ๊ฑฐ๋ž˜์˜ ๊ฒ€์ฆ ๋ฐ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ํ•˜๋Š” ๊ตฌ์กฐ์ฒด ์ž…๋‹ˆ๋‹ค.

ethers.js๋ฅผ ์ด์šฉํ•˜์—ฌ Transaction ์‹คํ–‰

ether.js๋Š” Ethereum ํ™˜๊ฒฝ์—์„œ ๊ฐœ๋ฐœ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ Ethereum ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ค€์ˆ˜ํ•˜์—ฌ ๋‹ค๋ฅธ ์ด๋”๋ฆฌ์›€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ƒํ˜ธ ์šด์šฉ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋„ท ํ™˜๊ฒฝ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด Transaction์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const { ethers } = require('ethers');

const nodeId = "{Your Node}"
const rpcEndpoint = 'https://ethereum-sepolia.nodit.io/{nodeId}';
const provider = new ethers.providers.JsonRpcProvider(rpcEndpoint);
const privateKey = "{Your Private Key}";
const wallet = new ethers.Wallet(privateKey, provider);
const myNonce = await wallet.getTransactionCount('latest');
const gasPrice = await provider.getGasPrice();

// Raw transaction data
const txData = {
  to: "0x6063B58BED10C5b4d40660bD68b1a0317C3E883c",
  value: ethers.utils.parseEther("0.1"),
  gasLimit : 21000,
  gasPrice : gasPrice._hex,
  nonce: myNonce,
  chainId : 11155111
};

// Sign raw Transaction data
const signedTx = await wallet.signTransaction(txData);
console.log("signed Transcation Data :", signedTx);

// send signed raw transaction data
const txResponse = await provider.sendTransaction(signedTx);
console.log("Transaction Hash : ", txResponse);

Provider ์ธ์Šคํ„ด์Šค์™€ PrivateKey๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด wallet ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ํ•ด๋‹น wallet์˜ nonce๋ฅผ ๊ตฌํ•˜๊ณ  ํ˜„์žฌ ์ด๋”๋ฆฌ์›€ ๋„คํŠธ์›Œํฌ์˜ ํ‰๊ท ์ ์ธ gasPrice๋ฅผ ๊ตฌํ•œ ๋’ค, ์ „์†กํ•  ํŠธ๋žœ์žญ์…˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ, ์„œ๋ช… ํ›„, ํŠธ๋žœ์žญ์…˜์„ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค.

eth_sendTransaction์˜ ์‘๋‹ต์œผ๋กœ ๋ฐ˜ํ™˜๋ฐ›๋Š” ๊ฐ’์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. Transaction์„ ๋…ธ๋“œ์— ์ „์†กํ•œ ํ›„, ๋ธ”๋ก์— ํฌํ•จ๋˜๋Š” ๊ฒƒ์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ์— ์ „์†กํ•œ Transaction์˜ ๋ฐ์ดํ„ฐ์™€ Transaction Hash๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›์Šต๋‹ˆ๋‹ค.

๐Ÿ‘

Response eth_sendTransaction

{
nonce: 0,
  gasPrice: BigNumber { _hex: '0x59682f07', _isBigNumber: true },
  gasLimit: BigNumber { _hex: '0x5208', _isBigNumber: true },
  to: '0x6063B58BED10C5b4d40660bD68b1a0317C3E883c',
  value: BigNumber { _hex: '0x016345785d8a0000', _isBigNumber: true },
  data: '0x',
  chainId: 11155111,
  v: 22310257,
  r: '0x850df3a3d8c6231bd7a07bc2f54bfff803dbe09a88ded4e21a40be19a1bcca0a',
  s: '0x09a88296814a63733043aa13281e6a0bf241b66e9b9436a2f209e65f4af7fe97',
  from: '{Sender Address}',
  hash: '0x605133d8dfe07579bfa28fffd72cd766e29ba15204ec5bbc48f121f639cda730',
  type: null,
  confirmations: 0,
  wait: [Function (anonymous)]
}

์ดํ›„ Transaction์ด ๋ธ”๋ก์— ํฌํ•จ๋˜์—ˆ๋‹ค๋ฉด getTransactionReceipt Method๋ฅผ ์ด์šฉํ•˜์—ฌ Transaction์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Transaction ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ํฌํ•จํ•œ Receipt๊ฐ€ ๋ฐ˜ํ™˜๋˜๋ฉฐ ์•ž์„œ ์‹คํ–‰ํ•œ Transaction์— ๋Œ€ํ•œ getTransactionReceipt Method์˜ Response๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
  to: '0x6063B58BED10C5b4d40660bD68b1a0317C3E883c',
  from: '0x78D3D552841415FE367F08ACD869d0f0AA93e815',
  contractAddress: null,
  transactionIndex: 6,
  gasUsed: BigNumber { _hex: '0x5208', _isBigNumber: true },
  logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
  blockHash: '0x645ed5b68379bfce8827c6797e5ae430d73370080454914eb739f44d6f5e0091',
  transactionHash: '0x605133d8dfe07579bfa28fffd72cd766e29ba15204ec5bbc48f121f639cda730',
  logs: [],
  blockNumber: 3317977,
  confirmations: 22,
  cumulativeGasUsed: BigNumber { _hex: '0x1d37ef', _isBigNumber: true },
  effectiveGasPrice: BigNumber { _hex: '0x59682f07', _isBigNumber: true },
  status: 1,
  type: 0,
  byzantium: true
}

์‹ค์ œ ํŠธ๋žœ์žญ์…˜ ์‹คํ–‰ ์‹œ ์‚ฌ์šฉ๋œ gas์˜ ์–‘๊ณผ Transaction์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š” block์˜ Hash์™€ number, ๊ทธ๋ฆฌ๊ณ  Confirm๋œ Block์˜ ์ˆ˜ ๋“ฑ, ํ•ด๋‹น Transaction ์‹คํ–‰ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Nodit Web3 Data API๋ฅผ ์ด์šฉํ•œ Transaction ์ •๋ณด ์กฐํšŒ

์•„๋ž˜ Nodit Web3 Data API ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ API๋ฅผ ํ˜ธ์ถœํ•ด๋ณด๊ณ  ์‘๋‹ต์— ํฌํ•จ๋œ Transaction ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”๋กœ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.