스크립토 6기 하진원입니다.
스크립토 방학 스터디로 마스터링 이더리움 공부하고 있습니다.
트랜잭션은 EOA가 생성하여 이더리움 블록체인으로 보낸 서명된 메시지이다. 트랜잭션은 상태의 변화와 EVM에서의 컨트랙트를 실행하게 해준다. 즉, 이더리움이라는 블록체인의 상태를 변화시키는 것이 트랜잭션이다.
트랜잭션은 Nonce, Gas price, Gas limit, Recipient, value, (v,r,s)로 이루어져 있다.
Nonce는 해당 계좌가 온체인에 올린 트랜잭션의 숫자이다. Nonce는 트랜잭션의 생성 순서를 알 수 있게 하고 트랜잭션 중복 방지 기능도 수행한다(Make every transaction unique).
새로운 트랜잭션을 생성할 때 다음 nonce를 구하여 포함해야 하는데 해당 계정에서 체인에 올린 트랜잭션을 통해 구한다.
가스는 ether와 독립된 화폐로 이더리움의 연료이다. 가스는 트랜잭션이 사용할 수 있는 자원의 양을 정하고 자원을 소모하게 하는 DDOS와 같은 악의적인 공격을 막기 위해 도입된 시스템이다.
가스가 독립되어 있는 이유는 ether 값의 변동성에서부터 시스템을 보호하고 자원과 가스를 통해 지불하는 메모리, 저장공간 등의 균형을 맞추기 위해서이다.
gasPrice는 트랜잭션 생성자가 설정한 가스 값이다. 일반적으로 값이 높으면 트랜잭션이 빨리 처리되고 낮으면 늦게 처리된다.
gasLimit은 트랜잭션 생성자가 지불할 가스의 최대치로 지정해 놓은 가격이다. EOA에서 EOA로 보내는 거래에서는 21000으로 고정되어 있지만 컨트랙트로 보내는 트랜잭션에서는 필요한 가스량을 정확히 계산할 수 없다. 만일 컨트랙트 실행을 하다 gasLimit가 필요한 가스보다 적어 실행되지 못하면 트랜잭션 생성자는 가스 비용을 손해보기 때문에 gasLimit을 보통 크게 설정한다. gasLimit 보다 더 적게 사용하면 남은 만큼 돌려준다.
트랜잭션 수신인에는 20바이트 이더리움 주소를 입력하는데 이더리움은 해당 주소가 실존하는 주소인지 검증하지 않기 때문에 주소를 잘못 입력하면 사라진다.
트랜잭션의 주요 내용으로 value와 data로 이루어져 있다. Value와 data는 모두 있을 수도, 없을 수도 있다. Value만 있는 트랜잭션은 지불, data만 있으면 컨트랙트 호출, 두가지 모두 있으면 둘 다이다. 그리고 두가지 모두 없으면 아무 의미없는, 낭비된 트랜잭션이다.
그 외에도 특별한 경우로 새로운 컨트랙트를 생성하는 트랜잭션이 있다. Zero address가 보내지는 주소로 설정되는데 해당 주소는 EOA도 컨트랙트도 아닌 컨트랙트를 생성한다는 특별한 의미를 가지는 주소이다. 해당 트랜잭션은 컨트랙트를 만들어 주는 역할만 하기 때문에 컨트랙트를 생성할 data는 필요하지만 value는 필수적이지 않다.
이더리움에서는 타원곡선을 사용한 ECDSA가 사용된다. 전자 서명은 이더리움에서 개인키의 소유주, 즉 계정의 소유주가 트랜잭션을 실행했다는 것을 공인하고 트랜잭션이 사인된 후에는 변경되지 않았다는 것을 검증한다.
전자 서명은 개인키를 바탕으로 서명을 만드는 알고리즘과 메시지(트랜잭션)와 공개키 만으로 서명을 검증 가능하게 해주는 알고리즘으로 이루어진다.
Sig=Fsig(Fkeccak256(m),k)
K는 서명하는 개인키, m은 RLP로 인코딩된 트랜잭션, Fkeccak256 은 keccak256, Fsig 은 서명 알고리즘, Sig 는 생성된 전자서명이다. 이로 생성된 Sig 는 r, s 두가지 값으로 이루어진다.
서명 검증 알고리즘은 메시지, 서명자의 공개키, 전자서명을 input으로 받고 참 거짓 여부를 반환한다.
서명하기 전 트랜잭션 데이터에 chain identifier(네트워크에 따라 ID 부여. 예를 들면 메인넷은 1, Ropsten은 3)를 포함한다. 이를 통해 한 블록체인 네트워크에서 생성된 트랜잭션을 다른 블록체인 네트워크에 올릴 수 없게 하여 반복 공격을 막는다. Chain identifier와 0, 0 총 3가지 필드를 추가하는데 이들은 인코딩 전에 트랜잭션 데이터에 포함되어 트랜잭션 데이터의 해시값이 변한다.
보통은 트랜잭션의 생성, 서명, 전송은 한 과정으로 이루어진다. 하지만 서명과 전송은 분리할 수 있는데 분리하는 이유는 보통 보안 때문이다. 서명을 할 때 컴퓨터는 개인키를 메모리에 가지고 있는데 그 상태에서 트랜잭션을 전송하면 개인키를 가진 상태로 온라인이 되고 이러면 개인키의 유출 가능성이 있다. 이를 방지하기 위해 서명과 트랜잭션을 분리하여 하는 오프라인 서명을 한다.
이더리움에서 트랜잭션 전파는 시작 노드에서 다른 노드들로 P2P 방식으로 전파된다.
전파과정은 다음과 같다.
트랜잭션이 생성되면 생성한 노드로부터 직접적으로 연결되어 있는 노드들로 (평균 13개 정도) 전파된다. 해당 노드들이 검증한 후에 복사본을 만들어 저장하고 그들의 이웃으로 전파한다. 그 결과 네트워크 전체로 파도처럼 퍼지게 된다. 수초 만에 전세계의 노드들로 트랜잭션은 퍼지게 되고 공격자는 상당한 양의 노드를 소유하고 있지 않은 이상 트랜잭션의 발원지를 찾을 수 없다.
검증된 트랜잭션은 블록에 담겨 이더리움 블록체인 위에 기록되게 된다. 기록되게 되면 트랜잭션이 이더리움의 계좌, 컨트랙트등에 반영되고 영수증처럼 트랜잭션과 함께 기록된다.