이더리움 계정, 트랜잭션, 가스 그리고 블록 가스 한도

Yeji Park
Yeji Park
Published in
14 min readDec 16, 2017

--

*해당 글은 저자 Hudson Jameson으로부터 작성된 포스트를 한글로 번역한 것입니다. 번역: 박예지 / 교정: atomrigs

이 글은 이더리움의 계정, 트랜잭션, 가스 그리고 블록 사이즈를 세팅하기 위한 채굴자들의 역할과 같은 이더리움의 기초 매카니즘을 이해하는데 도움을 주고자 작성하였습니다. 수정사항이 있다면 언제든지 알려주세요 :)

계정이란 무엇인가?

EOA vs contract accounts

이더리움에는 2가지 타입의 계정이 존재합니다.

  • EOA(Externally Owned Accounts: 외부 소유 계정)
  • CA(Contracts Accounts: 컨트랙트 계정)

이 구분은 다가오는 메트로폴리스 업그레이드 시 추상화될 예정입니다.

외부 소유 계정(EOA)

외부적으로 관리되는 계정으로

  • 이더 잔액을 가지고 있으며,
  • 트랜잭션을 전송할 수 있고(이더 거래 혹은 스마트 코드 작동),
  • 프라이빗키로 관리되며,
  • 관련 코드를 가지고 있지 않습니다.

컨트랙트 계정(CA)

컨트랙트 계정은

  • 이더 잔액을 가지고 있으며,
  • 관련 코드를 가지고 있으며,
  • 코드 실행은 다른 계약에 의해서 받은 메세지(호출) 혹은 트랜잭션을 통해서 작동이 시작됩니다.
  • 컨트랙트는 실행되었을 시 — 임의적 복잡성을 가진 연산들(튜링 완전성)을 수행하게 되는데 — 예들 들면 자체적인 지속적 상태를 가지는 저장공간을 설정하기도 하고 — 다른 컨트랙트를 호출할 수도 있습니다.

이더리움 블록체인에서 일어나는 모든 행위들은 계정으로부터 이뤄지는 트랜잭션에 의해 실행됩니다. 컨트랙트 계정이 트랜잭션을 받을 때 마다 해당 트랜잭션의 일부로서 전송된 입력 파라미터가 지시한대로 코드가 실행됩니다. 컨트랙트 코드는 새로운 블록을 검증하는 과정에서 이더리움 네트워크에 참여하고 있는 각 노드의 가상머신에 의해서 실행됩니다.

트랜잭션 및 메시지란 무엇인가?

트랜잭션

“트랜잭션”이라는 용어는 이더리움에서 블록체인 내에서 EOA(외부 소유 계정)에서 다른 계정으로 보낼 메시지를 저장하는 서명된 데이터 패키지를 의미합니다.

트랜잭션은 다음과 같은 사항을 포함합니다.

  • 메시지의 수신자
  • 송신자를 인증하고, 수신자에게 블록체인을 통해 메시지를 전달할 의사가 있다는 것을 입증할 서명
  • VALUE 필드- 송신자가 수신자에게 전송할 wei 양
  • 컨트랙트로 전송된 메시지에 포함될 수 있는 옵션 데이터 필드.
  • GASLIMIT값, 해당 트랜잭션이 실행될 수 있도록 소모가 허락된 컴퓨터 연산능력의 최대량.
  • GASPRICE값, 가스당 송신자가 지불하고자 하는 수수료. 가스의 한 단위는 한 번의 컴퓨터 연산작업과 같은 하나의 독립적 명령의 실행에 해당합니다.

메시지

컨트랙트는 다른 컨트랙트에 “메시지”를 보낼 수 있는 능력을 가지고 있습니다. 메시지는 외부로 저장되지 않는 가상적인 존재이며 오직 이더리움 실행 환경안에서만 존재합니다. 메시지는 함수 호출로서 생각 할 수 있습니다.

메시지는 다음과 같은 사항을 포함합니다.

  • 메시지의 송신자 (내재적)
  • 메시지의 수신자
  • VALUE field— 컨트랙트 주소로 메시지와 함께 전송할 wei양
  • 컨트랙트에 실제 입력된 데이터를 포함한 옵션 데이터 필드
  • GASLIMIT값은 메시지에 의해 실행된 코드가 발생시킬 수 있는 가스의 최대량을 제한합니다.

본질적으로 메시지는 외부 행위자가 아닌 컨트렉트에 의해서 생성된다는 점을 제외하면 트랜잭션과 같다고 할 수 있습니다. 메시지는 컨트랙트가 현재 실행되고 있는 코드를 CALL 혹은 DELEGATECALL 명령코드로 작동시키면 메시지가 생성되고 실행됩니다. 메시지는 때때로 “내부 트랜잭션 ”으로도 불립니다. 트랜잭션과 같이 메시지는 수신자 계정이 그들의 코드를 실행할 수 있도록 만듭니다. 따라서 컨트랙트는 외부 행위자가 할 수 있는 정확히 동일한 방식으로 다른 컨트랙트와 상호작용이 가능합니다. 많은 사람들은 메시지를 언급할 때 트랜잭션이라는 용어를 사용합니다. 이에 따라 메시지라는 용어를 커뮤니티의 합의 하에 사용하지 않기로 하여 해당 용어의 사용을 점차 사라지게 할 수 있을 것 입니다.

가스란 무엇인가?

이더리움은 이더리움 가상 머신(EVM:Ethereum Virtual Machine)이라고 불리는 실행 환경을 블록체인에 구현하고 있습니다. 네트워크에 참여하는 모든 노드는 블록 검증 프로토콜의 부분으로서 EVM을 실행합니다. 노드들은 그들이 검증을 하고 있는 블록들에 담겨진 트랜잭션들을 하나싹 처리해가면서 트랜잭션들에 의해 구동된 코드들을 EVM 안에서 실행하게 됩니다. 네트워크의 모든 노드는 동일한 계산을 수행하고 동일한 값을 저장합니다. 컨트랙트 실행이 네트워크의 노드들을 거쳐 중복적으로 복제된다는 사실은 당연히 이 프로세스의 비용을 비싸게 만듭니다. 따라서 오프체인에서 처리할 수 있는 연산은 블록체인을 사용하지 않는 것이 유리합니다. 실행되는 모든 운영작업에는 이에 해당하는 비용이 발생하며 이는 가스 단위 수로 표시합니다. 컨트랙트가 이용할 수 있는 모든 작업은 이에 상응하는 가스 값을 가지고 있습니다. 여기 예전의 각 작업 코드에 따른 가스 비용 리스트를 참고해주십시오.

가스와 트랜잭션 비용

모든 트랜잭션은 가스 한도(또는 startGas라고도 불림)와 각 가스에 대해 지불하고자 하는 수수료를 포함해야 합니다. 채굴자들은 트랜잭션을 포함할지그리고 수수료를 부과할지 안 할지 선택할 수 있습니다. 실제로 현재 모든 트랜잭션은 결국 채굴자들로부터 선택되지만 사용자가 트랙잭션을 전송하기 위해 정한 수수료의 값은 해당 트랜잭션이 채굴될 때까지 걸리는 시간에 영향을 미칩니다. 어떤 트랜잭션의 주메시지와 이것에 의해 발생된 하위메시지들이 구동한 연산 단계들에 사용되는 가스의 총량이 가스한도 이하이면 이 트랜잭션은 처리됩니다. 하지만 만약 총 가스 양이 가스 한도를 초과할 경우, 트랜잭션의 실행 도중 변화된 상태는 전부 원상태로 되돌려 지게 되지만, 이미 사용된 가스 수수료는 반환되지 않고 채굴자가에게 지불됩니다. 블록체인 상에는 해당 트랜잭션의 실행이 시도되었지만, 충분한 가스양이 제공되지 않아, 실행되었던 모든 작업이 되돌려 졌다는 상태를 보여줍니다. 트랜잭션 실행에 이용되지 않은 모든 초과 가스는 이더로 발신자에게 상환됩니다. 가스 비용 추정치는 오직 대략적인 것이기 때문에 많은 사용자들이 그들의 트랜잭션의 실행을 보장하기 위해서 가스 비용을 초과 송금하는 경우가 많습니다.하지만 초과 지불된 가스 비용은 다시 환불되기 때문에 걱정하지 않으셔도 됩니다.

트랜잭션 비용 예측하기

트랜잭션의 총 이더 비용은 다음과 같은 2 요인을 기반으로 합니다.

  • 사용된 가스gasUsed: 트랜잭션으로 소비된 총 가스
  • 가스 가격gasPrice: 트랜잭션에서 지정한 가스 한 단위의 가격(이더로)

총 비용= 사용된 가스 * 가스가격

사용된 가스

이더리움 가상 머신에서의 각 작업에 얼마나 많은 가스의 양이 소비되는냐에 따라 할당됩니다. 사용된 가스는 모든 작업을 실행하기 위해 쓰여진 가스의 합계입니다.

사용된가스를 추정하기 위해서 가스추정 API를 이용할 수 있지만 몇 가지 주의사항이 있습니다.

가스 가격

이용자는 트랜잭션을 만들어 사인해서 보낼 때 0부터 시작하여 그들이 원하는 가스 가격을 지정할 수 있습니다. 하지만 이더리움 프론티어에서 런치된 클라이언트의 기본 가격은 0.05e12 wei부터 였습니다. 만약 대부분의 트랜잭션이 0.05e12 wei의 가스 가격으로 제출된다면 채굴자들은 그들의 수익을 최적화하기 위하여 트랜잭션 처리를 위한 가스 가격을 0.05e12 wei보다 더 낮게 혹은 0으로 지정한 트랜잭션 선택을 꺼려할 것 입니다.

트랜잭션 비용의 예

훌륭한 마이이더월렛 팀으로부터 허가를 받아 다음과 같은 예시를 사용하여 비유하였습니다. 가스에 관련하여 잘 쓰여진 가이드를 여기서 찾으실 수 있습니다. 또한 이더의 양을 하위 단위로 쉽게 전환할 수 있는 페이지도 제공하고 있습니다.

가스 한도는 자동차를 위한 가스의 단위/리터/갤론의 양과 같이 생각할 수 있습니다. 그리고 가스 가격은 가스의 단위/리터/갤론의 비용으로 생각할 수 있습니다.

자동차에 비유하면 각 갤론(단위) 당 $2.5(가격)이며, 이더리움에서는 각 가스(단위) 당 20GWEI(가격)인 것 입니다. 자동차의 연료를 채우기 위해서는 10갤론이 필요하며 이는 즉 10갤론*$2.50=$25에 해당합니다. 이더리움에서는 21000 단위의 가스가 필요함으로써 이는 즉 21000*20GWEI=0.00042이더에 해당합니다.

따라서 총 트랜잭션 수수료는 0.00042이더가 되는 것 입니다.

주로 토큰을 전송할 때 ~50000가스에서 ~100000가스 정도 소요되므로 총 트랜잭션 수수료는 0.001이더에서 0.002이더 정도로 증가합니다.

블록 가스 한도란?

블록 가스 한도는 한 블록에 얼마나 많은 트랜잭션이 들어갈 수 있는지 결정하기 위한 한 블록에 허용되는 최대 가스량입니다. 예를 들어 5개의 트랜잭션이 있고 각 트랜잭션의 가스 한도가 10, 20, 30, 40, 50이라고 가정합시다. 만약 해당 블록의 가스 한도가 100이라면 가스 한도가 10, 20, 30, 40인 처음 4개의 트랜잭션은 해당 블록에 들어갈 수 있습니다. 채굴자는 어느 트랜잭션을 블록에 포함시킬 지 결정합니다. 다른 채굴자가 마지막의 두개의 트랜잭션(50+40)을 포함할 수 있으며 그럼 오직 첫번째 트랜잭션(10)만이 나머지 공간에 포함될 수 있습니다. 만약 당신이 현재 블록 가스 한도보다 더 많은 가스를 사용하게되는 트랜잭션을 포함시키려 한다면 이는 네트워크에서 거절 당할 것 이며 이더리움 클라이언트로부터 “트랜잭션이 블록 가스 한도를 초과하였습니다”라는 메시지를 받게될 것 입니다. 해당 예제에 대한 크래딧은 “ethers”가 작성한 이더리움 StackExchange 포스트에 있습니다.

현재 제가 이 글을 쓰고 있는 시간에 ethstats.net에 따르면 블록 가스 한도는 4,712,357 가스로 나타납니다. 즉 21000의 트랜잭션 가스 한도를 가진 약 224 트랜잭션이 한 블록에 들어갈 수 있음을 나타냅니다.(평균적으로 15–20초 마다 생성됩니다). 해당 프로토콜은 한 블록의 채굴자가 블록 가스 한도를 어느 방향에서든(증가 혹은 감소) 1/1024(0.0976%)만큼 조정이 가능하도록 해줍니다.

블록 가스 한도는 누가 정하나요?

네트워크의 채굴자들이 블록 가스 한도를 정합니다. 조정이 가능한 프로토콜 블록 가스 한도와는 별개로 대부분의 클라이언트들에게는 4,712,388의 최소 블록 가스 한도를 기본값으로 가지고 있습니다. 채굴자들은 해당 값을 변경할 수 있지만 대다수의 채굴자들은 변경을 선택하지 않고 기본값을 유지합니다.

블록 가스 한도는 어떻게 변경되나요?

이더리움의 채굴자들은 Geth 혹은 Parity 이더리움 클라이언트 노드에 연결할 수 있는 Ethminer와 같은마이닝 프로그램을 이용합니다. Geth와 Parity는 채굴자들이 변경할 수 있는 옵션을 가지고 있습니다. Geth의 마이닝을 위한 명령 라인 옵션은 여기서 확인이 가능하며 Parity의 옵션은 여기서 확인하실 수 있습니다.

이더리움 네트워크의 “DoS”란 무엇입니까?

최근 이더리움 네트워크가 느려지거나 마비되거나 사용할 수 없게 되는 상황에 대하여 많은 언급이 있었습니다. 이러한 언급에서 네트워크가 느려지는 현상을 이더리움 네트워크의 “DoS”라고 설명합니다. 이더리움 네트워크의 서비스 거부 공격(DoS)은 지속적으로 블록들이 최고치를 포함하고 많은 미결 트랜잭션이 네트워크에 존재할 때 발생하였습니다. 채굴자들은 함께 첨부된 트랜잭션 수수료에 기반하여 포함할 트랜잭션을 선택할 수 있음을 상기해보세요. 만약 수십만개의 트랜잭션이 처리되기를 대기하고 있다면(혹은 기술적인 용어로 트랜잭션 풀) 이는 몇 시간의 비정상적인 트랜잭션 지연을 야기시킬 수 있습니다. 디도스 공격은 고의적으로도 발생할 수 있지만, 비고의적인 경우도 있습니다.

고의적 DoS

지난 가을 이더리움은 “트랜잭션 스팸 공격”이라 불리는 방법으로 한 사람 혹은 그룹에 의하여 공격을 받았습니다.

해당 공격에 대한 설명이 이 블로그 포스트에 기술되어 있습니다.

공격자는 클라이언트가 처리할 수 있는 컴퓨터 연산능력을 초과하는, 매우 어렵지만 네트워크에 추가하기는 매우 싼, 특정한 작업 코드(명령코드)를 반복적으로 그들의 스마트 컨트렉트에 실행함으로서 Dos공격을 실행하였습니다.

해당 공격이 실행되는 동안, 채굴자들은 블록 가스 한도를 150만으로 낮추라는 요청을 받았으며 다른 경우에는 200만으로 낮추라는 요청을 받았습니다. 네트워크가 공격을 당하는 동안 채굴자들에게 블록 가스 한도를 더 낮출 것을 요구하는 다른 사건들도 있었습니다.

비고의적 DoS

비고의적 DoS 사건은 간단합니다. 네트워크에 미결된 트랜잭션이 많이 존재하게 되면 트랜잭션을 처리하기 위해 비정상적으로 긴 시간이 걸릴 수 있습니다. 최근에 토큰 배부 이벤트가(혹은 ICOs 혹은 토큰세일) 급증하고 인기를 끌면서 이는 네트워크에 트랜젝션의 정체를 야기하였습니다. Infura의 관계자가 이에 관련한 기술적인 세부사항에 대해 블로그에 작성하였습니다.

블록들이 꽉 차더라도 왜 블록 가스 한도는 변경되지 않나요?

주요 원인은 채굴자들이 신축적인 가스 한도 조정 기능을 이용하지 않고 있기 때문입니다.

이더리움 프로토콜에는 채굴자들이 가스 한도에 대해 투표할 수 있는 매커니즘을 가지고 있습니다. 그렇기 때문에 하드포크를 사용하지 않고서도 가스 한도 양을 늘릴 수 있습니다. 본래 이 매커니즘은 채굴자들이 최소 470만의 가스 한도에 투표할 수 있고, 만약 가스 양이 더 높아질 경우 최근의(1024-블록의 기하급수적 이동) 이용된 가스양 평균의 150%를 타켓으로, 안티-스팸 목적을 포함하면서 수요 증가에 따라 조직적으로 용량을 증가시킬 수 있도록 하는 기본 전략과 같이 작동하게 되어 있었습니다.

상기 “고의적인 DoS” 세션에 기술되어 있는 것과 같이 이에 대한 해결책이 개발될 때까지 채굴자들에게 공격을 막기위하여 그들의 세팅을 비기본값(non-default) 세팅으로 바꾸도록 여러번 제안된 바 있습니다. 문제는 몇몇 채굴풀들(mining pools)은 공격이 끝난 이후에 해당 세팅을 다시 되돌리지 않았다는 점입니다. 최근 토큰 세일로 인하여 블록이 빠르게 채워지고 블록체인 트랜잭션 혼잡이 야기되어, 몇 달 전 쯤에 채굴자들에게 신축적인 가스 한도 조정을 재도입하기 위한 가스한도와 가스가격 세팅의 변경 요청이 이루어졌습니다.

ETH 가스 스테이션”는 사람들에게 각 채굴풀들이 어느 블록 가스 한도에 투표하고 있는지 최근 정보를 제공해주는 훌륭한 리소스입니다.

이 상황을 해결하기 위해 채굴자들이 해야하는 것은 무엇입니까?

채굴자들은 신축적인 가스 한도를 활성화시키기 위한 셋팅을 geth 나 parity에서 설정할 수 있습니다. 노트: 하기에 보여지는 값은 Reddit포스트에서 가져왔으며, 이 포스트에서 설명하듯이 실질적으로 더 높은 값으로 세팅이 가능합니다.

Geth

세팅 제안

--gasprice 4000000000 --targetgaslimit 4712388

설명

타켓가스한도targetgaslimit 채굴 할 블록들을 위한 가상 타켓가스한도를 지정합니다.(기본값: “4712388”) — 가스가격gasprice트랜잭션을 채굴하기 위해 수용할 최소 가스가격(기본값:“20000000000”). 노트: 가스가격은 wei로 표기됩니다.

Parity

세팅 제안

--gas-floor-target 4712388 --gas-cap 9000000 --gasprice 4000000000

설명

가스-층-타켓--gas-floor-target 새로운 블록을 봉인할 시, 각 블록 당 타켓으로 하는 가스량(기본값:4700000)

가스 상한선--gas-cap 트랜잭션 양에 따른 각 블록 당 얼마나 가스 한도를 올릴 것인지에 대한 상한선

가스가격 --gasprice트랜잭션이 채굴되기 위해 지불해야 하는 가스 당 wei의 최저액. 노트: 가스가격은 wei로 표기됩니다. 노트2: 가스가격은 “레거시 옵션” 입니다.

다른 마이닝 옵션들

gethParity를 위해 채굴자들이 설정을 최적화할 수 있는 모든 옵션들의 리스트 확인을 위해서는 CLI(Command Line Interface: 명령어 인터페이스) 옵션 페이지를 방문하시기 바랍니다.

추가 참고 자료들

--

--