[Ethereum] - ch 6. Transaction

‍허진·2023년 3월 20일
0

Blockchain

목록 보기
19/19
post-thumbnail

본 글은 'Mastering Ethereum(Andreas M.Antonopoulos, Gavin Wood 저)'을 바탕으로 작성되었습니다.

트랜잭션은 외부 소유 계정(EOA)에 의해 서명된 메세지로, EVM에서 상태 변경을 유발하거나 컨트랙트를 실행할 수 있다. 이더리움은 글로벌 싱글톤 상태 머신이며, 트랜잭션은 이 상태 머신을 움직여서 상태를 변경할 수 있도록 만든다.

> 트랜잭션 구조

각 이더리움 클라이언트와 어플리케이션은 자체 내부 데이터 구조를 사용하여 트랜잭션을 메모리에 저장한다. 트랜잭션은 다음의 데이터를 포함하는 시리얼라이즈된 바이너리 메세지이다.

  • 논스(nonce)
    : 발신 EOA에 의해 발행되어 메세지 재사용을 방지하는 데 사용되는 일련번호
  • 가스 가격(gas price)
    : 발신자가 지급하는 가스의 가격(웨이)
  • 가스 한도(gas limit)
    : 이 트랜잭션을 위해 구입할 가스의 최대량
  • 수신자(recipient)
    : 목적지 이더리움 주소
  • 값(value)
    : 목적지에 보낼 이더의 양
  • 데이터(data)
    : 가변 길이 바이너리 데이터 페이로드
  • v, r, s
    : EOA의 ECDSA 디지털 서명의 세 가지 구성 요소

> 트랜잭션 논스

이더리움 황서에서는 트랜잭션 논스에 대해 다음과 같이 정의한다.

논스(nonce) : 해당 주소에서 보낸 트랜잭션 건수 또는 연결된 코드가 있는 계정의 경우 이 계정에서 만든 컨트랙트 생성 건수와 동일한 스칼라 값

트랜잭션에서 논스는 두 가지의 중요한 기능을 맡는다.
1. 사용성상의 기능(usability feature) : 트랜잭션 생성 순서대로 포함된다.
2. 트랜잭션 복제 방지

위의 기능의 예시로는 다음과 같은 경우가 있다.

1번 기능에 관한 예시
: 만약 6개의 이더를 지급하는 트랜잭션과 8개의 이더를 지급하는 트랜잭션이 전파되었는데 계정에는 이더가 10개밖에 없다고 해보자. 이런 상황에서 논스가 없다면 어느 것이 받아들여지고 어떤 것이 거부될지 알 수 없다. 그러나 논스가 포함된 상태에서 보낸 첫 번째 트랜잭션의 논스 값이 3이라고 하고, 8이더 트랜잭션이 다음 논스 값인 4를 가진다고 하자. 그러면 0부터 3까지의 논스가 있는 트랜잭션이 처리될 때까지 해당 트랜잭션은 수신된 순서와 상관없이 무시된다.

2번 기능에 관한 예시
: 이더리움 네트워크에서 트랜잭션을 보는 사람(수신자를 포함한 모든 사람)은 원래 트랜잭션을 복사하여 붙여넣고 네트워크로 다시 보내는 방식으로 계속 트랜잭션을 반복해서 '재실행'할 수 있다. 그러나 트랜잭션 데이터에 포함된 논스 값을 사용하면 동일한 수신자 주소에 동일한 양의 이더를 여러 번 보내는 경우에도 각각의 개별 트랜잭션은 고유하다. 따라서 트랜잭션의 일부로 논스를 증가시킴으로써 지급된 급액을 복제하는 행위를 막을 수 있다.

> 논스의 간격, 중복 논스 및 확인

트랜잭션을 프로그램을 통해서 생성하는 경우, 특히 여러 독립 프로세스에서 동시에 트랜잭션을 생성하는 경우에는 논스를 추적하는 것이 중요하다.

이더리움 네트워크에서는 누락된 논스가 있다면 해당 논스가 나타날 때까지 다음 트랜잭션은 멤풀에 저장한다. 누락된 논스가 전송되면 그제서야 다음 논스를 가진(그러나 먼저 수신된) 트랜잭션까지 블록에 포함한다. 이러한 특성 때문에 유효하지 않거나 가스가 모자란 트랜잭션은 논스 시퀀스에 의도치 않게 '갭'을 만들 수 있다.(처리 되지 않아서 생긴)

또한, 논스가 같지만 수신자나 값이 다른 2개의 트랜잭션을 전송하는 것과 같이 논스의 중복이 일어나면, 그중 하나가 확정되고 하나는 거부된다. 어떤 트랜잭션이 확정되는지는 무작위적이다.

> 트랜잭션 가스

가스는 이더리움의 연료다. 가스는 이더가 아니라 이더에 대한 자체 환율을 가진 별도의 가상화폐다. 이더리움은 가스를 사용하여 트랜잭션이 사용할 수 있는 자원의 양을 제어한다. 이는 전 세계 수천 대의 컴퓨터에서 처리되기 때문이다. 개방형(튜링 완전) 계산 모델은 DoS(Denial-of-Service) 공격이나 실수로 막대한 자원을 소모하는 트랜잭션을 피하기 위해 특정한 형태의 미터링(metering)이 필요하다.

가스는 이더 가치의 급격한 변화와 함께 발생할 수 있는 변동성으로부터 시스템을 보호하고, 가스가 지급하는 다양한 자원의 비용 사이의 중요하고 민감한 비율을 관리하기 위해 가스를 이더와 분리한다.

> EOA 및 컨트랙트에 값 전달

값을 포함하는 이더리움 트랜잭션을 구성하면 지급(payment)과 동일하다. 이러한 트랜잭션은 대상 주소가 컨트랙트인지 여부에 따라 다르게 작동한다.

EOA 주소의 경우 이더리움은 상태 변경을 기록하여 주소 잔액에 보낸 값을 추가한다.

컨트랙트 주소의 경우 EVM은 컨트랙트를 실행하고 트랜잭션의 데이터 페이로드에 지정된 함수를 호출하려고 시도한다. 트랜잭션에 데이터가 없으면 EVM은 폴백(fallback) 함수를 호출하고, 해당 함수가 지급 가능하다면 다음에 수행할 작업을 결정하기 위해 함수를 실행한다. 폴백 함수가 없다면 트랜잭션의 효과는 지갑에 지급하는 것과 마찬가지로 트랜잭션의 잔액을 늘린다.

> EOA 또는 컨트랙트에 데이터 페이로드 전달

트랜잭션이 컨트랙트 주소로 데이터를 전달한다고 가정해 보자. 이 경우 데이터는 EVM에 의해 컨트랙트 호출(contract invocation)로서 해석된다. 대부분의 컨트랙트에서는 이 데이터를 함수 호출로 사용하며, 명명된 함수를 호출하고 인코딩된 인수를 함수에 전달한다.

만약 트랜잭션이 데이터 페이로드를 EOA에 전달한다면, 대부분의 트랜잭션은 이더리움 프로토콜에 의해 무시된다. 미래에는 지갑이 컨트랙트 방식대로 데이터를 해석할 수 있도로 하는 표준이 등장할 수 있지만, 중요한 차이점은 EOA에 의한 데이터 페이로드의 해석은 컨트랙트 실행과 달리 이더리움의 합의 규칙의 적용을 받지 않는다.

> 특별 트랜잭션 : 컨트랙트 생성

트랜잭션에는 새로운 컨트랙트를 만들어 향후 사용을 위해 배포하는 트랜잭션도 존재한다. 컨트랜트 생성 트랜잭션은 제로 어드레스라고 하는 특수 대상 주소로 전송된다. 이 주소는 EOA나 컨트랙트를 나타내지 않는다. 이 필드는 목적지로만 사용되며, '컨트랙트 작성'이라는 특별한 의미로 사용된다.

디지털 서명

이더리움 트랜잭션에서 디지털 서명은 세 가지 용도로 사용된다.
1. 인증(authentication) : 이더리움 계정과 개인키의 소유자가 이더 지출 또는 컨트랙트 이행을 승인했음을 증명한다.
2. 부인 방지(non-repudiation) : 보낸 사람이 메시지를 보냈다는 사실을 부인할 수 없다.
3. 무결성(integrity) : 트랜잭션이 서명된 후에는 트랜잭션 데이터가 수정되지 않았고 어느 누구도 트랜잭션 데이터를 수정할 수 없음이 증명됨.

구체적인 서명 원리는 다음을 참고하도록 하자.
타원곡선 디지털 서명(ECDSA)

> 서명 및 전송 분리(오프라인 서명)

트랜잭션이 서명되면 트랜잭션은 이더리움 네트워크로 전송할 준비가 된다. 트랜잭션 생성, 서명, 브로드캐스트의 세 단계는 일반적으로 단일 작업에 의해 처리된다. 그러나 두 단계로 나누어서 트랜잭션을 생성하고 서명할 수 있다. 서명된 트랜잭션이 있으면 web3.eth.sendSignedTransaction을 사용하여 트랜잭션을 16진수로 인코딩하고 서명해서 이더리움 네트워크에서 전송할 수 있다.

트랜잭션의 서명과 전송을 분리하려는 이유는 보안이다. 트랜잭션에 서명하는 컴퓨터에는 잠금 해제된 개인키가 메모리에 로드되어 있어야 한다. 전송을 수행하는 컴퓨터는 인터넷에 연결되어 있어야 하며, 이더리움 클라이언트를 실행해야 한다. 이 두 기능이 하나의 컴퓨터에 있으면 온라인 시스템에 개인키가 있게 되며, 이는 매우 위험한 상황이 된다. 서명 및 전송 기능을 분리하여 각기 다른 시스템에서 수행하는 것을 오프라인 서명(offline signing)이라고 하며, 이는 일반적인 보안 방법이다.


[그림 - 이더리움 트랜잭션의 오프라인 서명]

  1. 현재의 논스 및 사용 가능한 자금을 검색할 수 있는 계정에서 서명되지 않은 트랜잭션을 온라인 컴퓨터에 만든다.
  2. 서명되지 않은 트랜잭션을 QR 코드 또는 USB 플래시 드라이브를 통해 트랜잭션 서명을 위한 '에어 갭(air-gapped)' 오프라인 장치로 전송한다.
  3. 이더리움 블록체인에 브로드캐스트하기 위해, 서명된 트랜잭션을 QR 코드 또는 USB 플래시 드라이브를 통해 온라인 장치로 전송한다.

필요한 보안 수준에 따라, '오프라인 서명' 컴퓨터는 격리되고 방화벽이 있는 서브넷(온라인이지만 분리되어 있음)에서 에어 갭 시스템으로 알려진 완전히 오프라인인 시스템에 이르기까지 온라인 컴퓨터와 분리 정도를 다르게 할 수 있다. 에어 갭 시스템에서는 네트워크 연결이 전혀 없다.

많은 경우에 완전 에어 갭 시스템을 활용할 수는 없지만, 약간의 격리로도 상당한 보안 이점을 얻을 수 있다. 예를 들어, 메시지 대기열 프로토콜만 허용하는 방화벽이 있는 격리된 서브넷은 온라인 시스템에 서명하는 것보다 공격할 부분을 줄어들게 하고 훨씬 높은 보안을 제공할 수 있다.

> 트랜잭션 전파

이더리움 네트워크는 '플러드 라우팅(flood routing)' 프로토콜을 사용한다. 각 이더리움 클라이언트는 메시(mesh 네트워크를 형성하는 피어투피어(P2P) 네트워크에서 노드(node) 역할을 한다.

트랜잭션 전파는 서명된 트랜잭션을 생성한 이더리움 노드에서 시작한다. 트랜잭션은 검증된 후에 트랜잭션을 생성한 '직접' 연결된 다른 모든 이더리움 노드로 전송된다. 평균적으로 각 이더리움 노드는 이웃(neighbor)이라고 불리는, 적어도 13개의 다른 노드에 대한 연결을 유지한다. 각 이웃 노드는 트랜잭션을 수신하자마자 즉시 유효성을 검사한다. 그들이 그것이 타당하다는 데 동의하면, 그들은 사본을 저장하고 모든 이웃에서 전파한다(출처는 제외). 결과적으로 트랜잭션은 모든 노드가 트랜잭션 사본을 가질 때까지 원래 노드에서 바깥쪽으로 퍼진다.

몇 초 내에 이더리움 트랜잭션이 전 세계의 모든 이러디움 노드로 전파된다. 각 노드의 관점에서 보면 트랜잭션의 출처를 식별할 수 없다. 노드로 전송한 이웃 노드는 트랜잭션의 생성자이거나 인접 노드 중 하나로부터 트랜잭션을 수신했을 수 있다. 트랜잭션의 출처를 추적하거나 전파를 방해하기 위해 공격자는 모든 노드 중 상당 부분을 제어해야 한다. 이것은 P2P 네트워크의 보안 및 개인 정보 보호 설계의 일부이며, 특히 블록체인 네트워크에 적용된다.

> 블록체인에 기록하기

채굴 노드에 의해 후보 블록이 유효하게 만들어진다. 유효한 트랜잭션은 트랜잭션 블록에 포함되어 이더리움 블록체인에 기록된다. 트랜잭션이 블록으로 채워지면 계정의 잔액을 수정하거나 내부 상태를 변경하는 컨트랙트를 호출하여 트랜잭션은 이더리움 싱글톤 상태를 수정한다. 이러한 변경사항은 이벤트가 포함될 수 있는 트랜잭션 영수중 형식으로 트랜잭션과 함께 기록된다.

생성에서 EOA에 의한 서명, 전파, 그리고 마지막으로 채굴까지 완료된 트랜잭션은 싱글톤의 상태를 변경하고 블록체인에서 지울 수 없는 기록을 남긴다.

profile
매일 공부하기 목표 👨‍💻 

0개의 댓글