이더리움 트랜잭션

이한길·2023년 9월 17일
0

이더리움

목록 보기
2/6

1. 이더리움 트랜잭션

이더리움 트랜잭션(Transaction): 이더리움에 트랜잭션은 역할을 한다.

기본 정보

발신자(from): 거래에 서명할 발신자의 주소.

  • 계약 계정은 거래를 보낼 수 없으므로 이는 외부 소유 계정이 됩니다.

수신자(to): 수신 주소.

  • (외부 소유 계정인 경우 거래는 가치를 전송합니다. 계약 계정인 경우 거래는 계약 코드를 실행합니다)

수량(value): 발신자에서 수신자로 전송할 ETH 양(wei)

입력 데이터(input data): 임의의 데이터를 포함하는 선택 필드.

가스

가스 가격(Price):

가스 한도(GasLimit): 거래에서 소비할 수 있는 최대 가스 단위량.

  • EVM 은 각 계산 단계에 필요한 가스 단위를 지정합니다.

논스

계정 논스(Account Nonce): 계정의 거래 번호를 나타내는 순차적으로 증가하는 카운터

서명

서명(signature): 발신자 식별자. 이것은 발신자의 개인 키가 거래에 서명하고 발신자가 이 거래를 승인했음을 확인할 때 생성됩니다.

트랜잭션 해시(Transaction Hash):
transactionHash = Keccak256(RLP(transactionData))

서명 데이터(Signature Data):
(v,r,s) = secp2561.Sign(transactionHash,privateKey)

v값(v):

r값(r):

s값(s):

2. 트랜잭션 데이터구조

레거시 트랜잭션

class TransactionLegacy:
	signer_nonce: int = 0
	gas_price: int = 0
	gas_limit: int = 0
	destination: int = 0
	amount: int = 0
	payload: bytes = bytes()
	v: int = 0
	r: int = 0
	s: int = 0

2930 트랜잭션

체인ID(chain_id):

y패리티(signature_y_parity):

class Transaction2930Payload:
	chain_id: int = 0
	signer_nonce: int = 0
	gas_price: int = 0
	gas_limit: int = 0
	destination: int = 0
	amount: int = 0
	payload: bytes = bytes()
	access_list: List[Tuple[int, List[int]]] = field(default_factory=list)
	signature_y_parity: bool = False
	signature_r: int = 0
	signature_s: int = 0
    
class Transaction2930Envelope:
	type: Literal[1] = 1
	payload: Transaction2930Payload = Transaction2930Payload()

1559 트랜잭션

가스당 최대 팁(maxPriorityFeePerGas): 검증자에게 팁으로 포함될 소비 가스의 최대 가격.

가스당 최대 수수료(maxFeePerGas): 거래에 대해 지불할 의향이 있는 가스 단위당 최대 수수료(기본 수수료 및 최대 팁 포함).

class Transaction1559Payload:
	chain_id: int = 0
	signer_nonce: int = 0
	max_priority_fee_per_gas: int = 0
	max_fee_per_gas: int = 0
	gas_limit: int = 0
	destination: int = 0
	amount: int = 0
	payload: bytes = bytes()
	access_list: List[Tuple[int, List[int]]] = field(default_factory=list)
	signature_y_parity: bool = False
	signature_r: int = 0
	signature_s: int = 0

class Transaction1559Envelope:
	type: Literal[2] = 2
	payload: Transaction1559Payload = Transaction1559Payload()

4844 트랜잭션

블롭가스당 최대 수수료(max_fee_per_blob_gas):

블롭버전해시(blob_versioned_hashes):

class Transaction1559Payload:
	chain_id: int = 0
	signer_nonce: int = 0
	max_priority_fee_per_gas: int = 0
	max_fee_per_gas: int = 0
	gas_limit: int = 0
	destination: int = 0
	amount: int = 0
	payload: bytes = bytes()
	access_list: List[Tuple[int, List[int]]] = field(default_factory=list)
    max_fee_per_blob_gas: U256
    blob_versioned_hashes: Tuple[VersionedHash, ...]
	signature_y_parity: bool = False
	signature_r: int = 0
	signature_s: int = 0

class Transaction1559Envelope:
	type: Literal[2] = 2
	payload: Transaction1559Payload = Transaction1559Payload()

3. 트랜잭션 생애주기

다음은 이더리움 지분증명에서 트랜잭션이 어떻게 실행되는지에 대한 종합적인 설명이다.

트랜잭션 생성: 사용자는 개인키로 트랜잭션을 생성하고 서명한다. 일반적으로 지갑이나 web3.js와 같은 라이브러리에서 처리하지만, 내부적으로는 사용자가 이더리움 JSON-RPC API를 사용하여 노드에 요청을 한다. 사용자는 트랜잭션을 블록에 포함하도록 유도하기 위해 검증자에게 수수료로 지불할 가스 양을 정한다.

트랜잭션 검증: 노드가 어떤 트랜잭션을 전파받았을 때, 트랜잭션은 노드의 실행 클라이언트에 제출되어 트랜잭션의 유효성을 검증받는다. 이 때 디지털 서명을 사용해서 해당 트랜잭션이 진짜 그 사람이 보낸 것인지 혹은 다른 사람이 조작한 것인지를 확인해야 한다. 트랜잭션이 다음 조건을 만족하면 유효하다고 검증된다.

  • 발신자의 개인키로 서명된 메세지를 공개키로 복호화한 것과 원본 메세지가 일치함.
  • 발신자가 트랜잭션을 이행하기에 충분한 이더를 보유하고 있음.

트랜잭션 전파: 트랜잭션의 유효성이 검증되면, 실행 클라이언트는 로컬 멤풀(보류 중인 트랜잭션 목록)에 트랜잭션을 추가하고 실행 레이어 가십 네트워크를 통해 다른 노드에 전파한다. 다른 노드가 트랜잭션을 전파받으면 동일한 작업을 해 자신의 로컬 멤풀에도 추가한다.

  • 고급 사용자는 트랜잭션 전파를 하는 대신 플래시봇 경매와 같은 전문 블록 빌더에 전달할 수 있다. 이렇게 하면 다음 블록에서 트랜잭션을 구성하여 최대 수익(MEV)을 얻을 수 있다.

트랜잭션의 완결성(Finality): 트랜잭션이 두 체크포인트 사이에 "과반수 링크"가 있는 체인의 일부가 되면 트랜잭션이 "최종 완료"된 것으로 간주할 수 있다.

4. 트랜잭션의 종류

메세지(Message): 컨트랙트가 생성한 메세지를 통해 다른 컨트랙트를 호출할 수 있고, EOA로 이더를 송금할 수 있다.

이더리움에서 트랜잭션은 EOA만이 개인키로 서명해서 발생시킬 수 있으며 상태를 변화시킨다. from과 to에 따라 크게 3가지로 분류된다.

송금(Transfer, EOA → EOA): 개인계정과 개인계정이 이더를 주고받는 트랜잭션. input empty.

컨트랙트 생성 트랜잭션(Contract Creation Transaction, EOA → Empty): 컨트랙트를 새로이 생성, 즉 배포하는 트랜잭션. input으로 컨트랙트의 바이트코드를 넣어줌.

트랜잭션 콜(Transaction Call, EOA → CA) : 컨트랙트의 함수를 호출하는 트랜잭션. input으로 함수의 해시값의 첫 4자리와 인자를 넣어줌.

메세지 콜(Message Call, CA → CA): (EOA → CA → CA → CA)의 형태에서 EOA가 CA로 발생시킨 트랜잭션의 결과로 발생한 연쇄적인 부수 트랜잭션을 메세지 콜 또는 내부 트랜잭션(Internal Transaction)이라고 한다. 인터널 트랜잭션은 온체인 상에서는 확인할 수 없기에 geth와 같은 이더리움 클라이언트로 확인 가능하다.

  • 연속적인 호출을 위한 충분한 가스비가 첫 트랜잭션에 포함되어 있어야 하며 최대 1024 Depth 까지 호출될 수 있다.

  • 델리게이트 콜(Delegate Call): 메세지 콜의 특별한 형태로, 호출된 컨트랙트의 코드가 호출한 컨트랙트의 context에서 수행되는 것(msg.sender와 msg.value가 변하지 않음).
    호출된 컨트랙트에서 코드만 가져오고 스토리지, 주소, 잔액은 여전히 호출한 컨트랙트의 것을 참조한다. 라이브러리와 업그레이드 가능한 스마트 컨트랙트의 기본 개념.

?. 트랜잭션 요청

{
  from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",
  to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",
  gasLimit: "21000",
  maxFeePerGas: "300",
  maxPriorityFeePerGas: "10",
  nonce: "0",
  value: "10000000000"
}

서명요청 트랜잭션

{
  "id": 2,
  "jsonrpc": "2.0",
  "method": "account_signTransaction",
  "params": [
    {
      "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db",
      "gas": "0x55555",
      "maxFeePerGas": "0x1234",
      "maxPriorityFeePerGas": "0x1234",
      "input": "0xabcd",
      "nonce": "0x0",
      "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
      "value": "0x1234"
    }
  ]
}

서명된 트랜잭션

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
    "tx": {
      "nonce": "0x0",
      "maxFeePerGas": "0x1234",
      "maxPriorityFeePerGas": "0x1234",
      "gas": "0x55555",
      "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0",
      "value": "0x1234",
      "input": "0xabcd",
      "v": "0x26",
      "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e",
      "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663",
      "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"
    }
  }
}

raw: 서명된 트랜잭션의 RLP 변환
tx: 서명된 트랜잭션의 JSON 버전

profile
블록체인, 통계학, 수학, 인공지능 공부하고 있습니다

0개의 댓글