Kevin Jeong(정순형, 철학자)(kevin.j@onther.io, Onther Inc.)
Thomas Shin(신건우)(thomas.s@onther.io, Onther Inc.)
Jason Hwang(황재승)(jason.k@onther.io, Onther Inc.)
Carl Park(박주형, 4000D)(carl.p@onther.io, Onther Inc.)
PoC1은 유저/개발 친화적인 이더리움 가상 머신(Ethereum Virtual Machine)의 실행 모델로써 이더리움에서 사용된 서비스 거부 공격(DoS Attack)을 막기 위한 가스 수수료 시스템(Gas)을 그대로 유지하면서도, 실행 과정에서 이에 대한 부담을 블록체인에 정의된 제3의 자율 에이전트(Autonomous Agent)인 스마트 컨트랙트를 통해 지정된 어카운트에게 위임할 수 있는 거래처리 공정(procedure)을 제시하는 것을 목표로 한다.
PoC1은 기존의 이더리움 가상 머신을 이용한 트랜잭션 실행 모델에서 지불된 가스 수수료와 value(ETH)를 계정 잔액(State Balance)에서만 차감하는 단선적 구조에서, i)tx.value는 계정 잔액에서 ii)가스 수수료는 스테미나(stamina)라고 불리는 별도로 정의된 컨트랙트의 잔액상태에서 차감하는 복선적인 구조로의 개선을 이뤄냈다.
또한 이렇게 위임된 수수료 소모량을 지속적으로 추적-관리하고, 일정한 기간이 지나면 다시 이를 재생해 줌으로써 수수료 부담 정책은 마치 예치된 정액제(Staked-and-Fixed Charge)의 형태를 띄게 된다.
이를 통해 유저들은 단 한번만 비용을 예치하면, 일정한 사용량 내에서는 어플리케이션 이용간 불필요한 잔액 유지 행위를 지속 할 필요가 없도록 만든다. 또한 서비스 제공자들에게는 더욱 유저/개발 친화적인 탈중앙화 어플리케이션(DApp)을 만들 수 있는 환경을 제공함으로써 블록체인에 익숙하지 않은 사용자들을 끌어들일 수 있는 킬러앱(Killer App)의 등장을 가속시켜 탈중앙화된 생태계가 확장해 나가는데 도움을 줄 것으로 판단된다.
튜링 완전한 블록체인의 목표를 달성 하면서도 네트워크의 부정한 사용을 방지하기 위해 이더리움은 모든 컴퓨팅 연산에 수수료를 부과한다. 이러한 수수료는 가스라는 특별한 단위로 계산되며, 이더리움 블록체인에서 이뤄지는 모든 연산은 “가스”라는 시-공간 비용을 지불하게 되어 있다.
이더리움의 모든 트랜잭션은 가스 제한(Gas Limit)과 가스 가격(Gas Price) 필드를 가지고 있다. 여기서의 가스 제한은 해당 트랜잭션이 얼마나 많고 복잡한 연산을 수행하느냐에 대한 예산(budget)으로서의 특징을 지니고 있으며, 가스 가격(Gas Price)은 이러한 연산을 블록에 포함하기 위해 마이너들에게 지불하는 입찰가로서의 성격을 가지고 있다.
그렇기 때문에 만약 트랜잭션이 수행되는 과정에서 소모한 가스 사용량(Gas Used)이 설정된 가스 제한(Gas Limit)보다 높을 경우, 이 트랜잭션은 유효하지 않은(invalid) 트랜잭션이 된다. 더해서 가스 가격(Gas Price)이 충분히 (블록에 포함되기를 대기하는 다른 트랜잭션에 비하여 상대적으로)높지 않을 경우 마이너들은 해당 트랜잭션을 블록에 포함시키지 않을 가능성이 높아진다.
이더리움 블록체인은 이러한 형태의 수수료 모델을 통해서 서비스 거부공격(DoS Attack)을 방지하고 블록체인의 상태변화에 대한 권리(right of state transition)
라는 한정된 자원에 대한 분배문제를 해결했지만, 각 실행자(Transactor)가 트랜잭션을 전송할 때마다 이러한 비용을 부담해야 한다. 중요한 점은 트랜잭션을 생성하는 계정(Transactor)이 가스 사용량(gas used) * 가스 가격(gas price) 이상의 이더를 트랜잭션 생성간 매번 지불해야 하고, 이를 위해 일정량의 잔액수준(level of balance)
을 상시 유지해야 한다는 점이다. 이는 이더리움 블록체인을 통해 만들어지는 탈중앙화 어플리케이션(DApp)들의 사용성을 현저히 떨어뜨렸다.
PoC1에서는 트랜잭션 수수료의 부담에 관한 문제로 인한 사용성 저하에 대한 문제를 개선한 트랜잭션 실행 레벨에서 처리하는 모델(Execution Model)을 설계하고자 한다. 이를 통해 유저 친화적인(접근성/사용성 관점에서) 어플리케이션 개발을 위한 토양이 마련되기를 기대한다.
페이퍼는 PoC1 구현을 위한 주요 명세를 정의하고, 이에 대한 구체적인 구현을 코드레벨에서 서술하는데 중점을 두고 있다. 구현 코드의 경우 이더리움의 고-언어(golang) 구현체인 go-ethereum과 파이썬(python) 구현체인 py-evm을 분기(Forking)하여 가스비를 위임한 실행 아키텍처에 대해 논의하는 방식으로 진행한다.
약칭은 이더리움 옐로우 페이퍼의 약칭을 필요한 부분을 발췌해서 사용하고, 필요시 재정의 하도록 한다. 또한 PoC1에서 정의된 단어들은 다음과 같다.
value + gasLimit * gasPrice
로 계산된다.(Expenses that are charged before executing EVM.)tx.gasLimit * tx.gasPrice
로 계산된다.tx.value
와 같다.이 장에서 설계하는 시스템은 크게 i)위임된 가스비에 대한 제반사항을 다루는 컨트랙트
와 ii)트랜잭션이 처리되는 과정
에 대한 부분으로 나뉘어 기술된다.
스테미나(Stamina)
는 위임계정(delegator)이 본 트랜잭션 실행 모델을 구동시킬 때 필요한 가스비를 수임계정(delegatee)에게 청구할 때 사용된다. 즉 위임계정(delegator)의 가스비를 수임계정(delegatee)이 스테미나(Stamina)의 형태로 구매하여 위임계정의 가스비 부담을 대신하게 된다. 스테미나는 스테미나 컨트랙트(Stamina contract)에 계정 잔액(state balance)을 예치(deposit)함으로써 얻을 수 있는데, 수임계정의 스테미나를 예치(deposit)한 계정을 예치 계정(depositor account)
이라 부른다.
수임계정의 스테미나는 위임계정의 가스비를 구매하면서 차감된다. 차감된 스테미나는 영원히 사라지는 것이 아니라 일정 기간이 지나면 회복(recover)되는데, 이를 PoC1에서는 스테미나 회복(stamina recover)
이라 부른다. 스테미나가 회복 되기 위해서는 일정 기간이 필요한데, 이 기간을 회복 기간(RECOVER EPOCH LENGTH)
이라 부르고, 다음 기간(EPOCH)에서 수임계정에 총 예치된 양만큼의 스테미나가 새롭게 충전된다.
이렇게 충전된 스테미나 잔액은 다음과 같이 표현할 수 있다.(는 어카운트)
위임계정은 로, 수임계정은 로 표기하고, <위임계정>을 인자로 <수임계정>꺼내는 변환(transformation)을 라 정의하면, 둘의 관계는 다음으로 표기될 수 있다.
스테미나 컨트랙트는 수수료 위임 모델에 있어서 중요한 컨트랙트다. 스테미나 컨트랙트는 다음 기능을 제공한다.
수임 계정(delegatee)은 위임 계정(delegator)을 지정할 수 있다. 오직 수임 계정(delegatee)만 위임 계정(delegator)을 지정할 수 있으며, 이 반대로 위임계정(delegator)은 수임 계정(delegatee)을 지정할 수 없다. 더해서 수임 계정(delegatee)은 여럿의 위임 계정(delegator)을 지정할 수 있다.
수임계정이 위임계정을 지정하게 되면 쌍(pair)이 형성되는데 이를 스테미나 쌍(stamina pair)
또는 수수료 위임 쌍(fee-delegate pair)
이라 부른다. 수임계정(delegatee)는 위임계정(delegator)을 지정하기 위해서 스테미나 컨트랙트의 setDelegator()
함수를 호출한다.
수임계정은 위임계정의 가스비를 구매하기 위해서 스테미나가 필요하다. 수임계정은 가지고 있는 스테미나의 양만큼 위임계정의 가스비를 대신 부담할 수 있다. 수임계정의 스테미나 소모량은 위임계정의 수 또는 트랜잭션 가스비와 비례할 가능성이 높다. 따라서 예치계정은 위임계정의 수와 트랜잭션 가스비에 맞게 수임계정의 스테미나를 늘리거나 줄일 것이다.
스테미나를 늘리기 위해서 예치계정(depositor)은 스테미나 컨트랙트의 deposit()
함수를 호출해야 한다. 예치계정은 예치(deposit)할 만큼의 계정잔액을 예치하고 수임계정은 예치한 만큼의 계정 잔액(state balance)을 추가적인 스테미나로 보유하게 된다.
이와 반대로 수임계정의 스테미나를 출금(withdraw) 받기 위해서는 스테미나 컨트랙트의 withdraw()
함수(더 정확하게는 requestWithdrawl()
, withdraw()
함수)를 사용한다. 이 때 스테미나는 줄어들고 줄어든 스테미나만큼 수임계정에게 계정 잔액이 출금(withdraw)된다.
수임계정이 스테미나를 출금(withdraw)하기 위해서 두 단계(Favor pull over push payments)를 거친다.
requestWithdrawl()
함수 호출requestWithdrawal()
함수를 호출한다. 이를 호출하게 되면 수임 계정의 스테미나는 요청한 양만큼 차감되고 이에 대한 기록은 스테미나 컨트랙트에 남게 된다.withdraw()
함수 호출withdraw()
함수를 호출하여 requestWithdrawl()
함수를 통해 기록된 정보를 이용해 차감한 스테미나만큼 계정 잔액을 채운다.이더리움에서는 트랜잭션을 처리하기 위해서 거래 생성자(transactor)의 잔액(Balance)으로 트랜잭션의 가스비를 구매하고 구매한 가스비로 트랜잭션을 처리 후에 남은 가스비는 다시 거래 생성자(transactor)에게 계정 잔액(ETH)을 되돌려준다. 이와 마찬가지로 PoC1 에서도 위임계정의 가스비를 구매하기 위해서 수임계정의 스테미나를 차감하고 트랜잭션 실행 이후에 남은 스테미나를 수임계정에게 되돌려 준다.
위임계정이 수임계정의 가스비를 구매할 때 수임계정의 스테미나는 차감된다. 더 정확하게 말하면 위임계정이 생성한 트랜잭션의 가스 예산(gas-upfront cost)만큼 스테미나를 차감한 후에 수행 후 남은 스테미나를 환불(refund)해준다.(수식참고번호). 스테미나의 차감은 PoC1이 직접 스테미나 컨트랙트의 subtractStamina()
함수를 호출함으로써 이루어진다.
subtractStamina()
함수는 onlyChain modifier를 가진다. 이 onlyChain modifier를 가지는 함수는 NULL_ADDRESS만이 직접 호출할 수 있고 다른 계정에서는 직접 호출할 수 없다.
스테미나로 가스비를 구매하여 트랜잭션을 처리한 후 남은 가스비는 수임계정에게 환불(refund)된다. 이 또한 널-계정(NULL_ADDRESS)이 스테미나 컨트랙트 함수를 호출함으로써 이루어지는데 addStamina()
함수를 호출하게 된다. addStamina()
함수 안에는 회복량(recoverery amount)을 확인하는 로직도 포함되어 있다.
수임계정(delegatee)의 스테미나는 위임계정(delegator)의 가스비를 구매하면서 결국 고갈될 것이다. 하지만 고갈된 스테미나는 다음 회복 기간(EPOCH)에 새로 충전된다. 즉 수임계정은 가지고 있는 스테미나를 다 사용해도 다음 회복기간(EPOCH)에서 새로 스테미나가 충전되기 때문에 스테미나를 재사용할 수 있다. 스테미나 회복은 스테미나가 환불될 때 자동으로 수행된다. 스테미나를 환불하는 과정에서 회복 기간이 도래했는지(RECOVER EPOCH LENGTH) 체크한 후 해당될 경우 스테미나를 다시 회복해준다. 회복되는 스테미나의 양은 수임자가 예치한 계정잔액의 총량과 같다.
Gav Wood는 ETHEREUM: A SECURE DECENTRALISED GENERALISED TRANSACTION LEDGER[1]에서 트랜잭션의 내재적 유효성(intrisic validity)을 테스트 하기 위한 5가지의 조건을 정의했다.
PoC1은 5번 조건을 다음으로 수정한다.
트랜잭션 생성자(transactor)의 잔액(balance)은 금액 예산(value-upfront cost), , 이상이어야 한다.
<트랜잭션 생성자(transactor)의 잔액> 혹은 <스테미나 쌍에 정의된 트랜잭션 생성자와 대응하는 수임계정의 스테미나 잔액>은 가스 예산(gas-upfront const), , 이상이어야 한다.
트랜잭션 예산(upfront cost)이 다음으로 정의된다고 했을 때,
본 페이퍼에서는 위의 식을 가스 예산(gas-upfront cost)과 금액 예산(value-upfront cost)으로 구분한다.
이 때 트랜잭션 유효성(Transaction Validity)은 다음으로 표현할 수 있다.
philosopher
(10)식을 해석하면
계정 잔액이 모든 upfront cost를 감당하거나, 스테미나가 gas-upfront cost를 감당해야 한다.
비위임 실행은 기존의 이더리움 체인에서의 트랜잭션 처리 과정과 같으며, 다음의 절차를 거친다.
위임실행의 경우 다음의 과정을 거친다.
의사코드는 2.2.3의 위임실행 과정을 구체화하고 있다.스테미나 컨트랙트는 staminaContract객체
로 표현하였다.
tx_traditional_execute()
함수는 기존의 이더리움(traditional ethereum)의 비위임 실행에 대한 의사코드를, tx_delegated_execute()
함수는 위임 실행에 대한 의사코드를 담고있다.
Traditional Ethereum | Delegated Model | 비고 | |
---|---|---|---|
upfront cost 차감 대상 | transactor | transactor or delegatee | |
gas-upfront 차감 대상 | transactor | transactor or delegatee | |
value-upfront 차감 대상 | transactor | transactor | |
Minimum EVM Execution | 1 | 3 |
이 페이퍼에서 제시된 스펙은 실제 go-ethereum과 py-evm을 이용해 구현되었으며, 구체적인 코드와 스펙설명은 다음 페이퍼에 기술되어 있다.
이더리움은 튜링 완전한 블록체인, 네트워크의 부정한 사용 방지라는 두 가지 목적을 달성하기 위해 이더리움 블록체인 위에서 발생하는 모든 컴퓨팅 연산에 수수료를 부과하고 있다. 이 수수료는 가스라 불리며, 이더리움의 모든 사용자들은 이 가스를 트랜잭션의 수수료로 지불한다. 모든 트랜잭션 마다 수수료를 지불함으로써 이더리움은 DoS(Denial of Service)공격을 방지할 수 있지만, 이더리움 위에서 동작하는 서비스를 이용하기 위해서는 항상 트랜잭션 수수료 지불을 위해 잔액을 확인하고 부족할 경우 잔액을 충전해야 한다는 불편함을 갖고 있다. 이러한 불편함은 스팀이나 이오스와 같이 매번 수수료를 지불하지 않아도 되는 블록체인들이 생겨나는 계기가 되었다. 물론 트랜잭션 수수료로 인한 사용성 저하가 스팀이나 이오스가 이더리움에 제기하는 문제점의 전부는 아니지만 PoC1에서는 우선 사용성에 대한 문제를 해결하고자 사용자가 트랜잭션 수수료에 대해 걱정할 필요 없고 DoS와 같은 네트워크 공격에도 대응할 수 있는 실행 모델을 제시했다.
PoC1의 가장 큰 특징은 수수료 위임 쌍(fee-delegation pair)간의 트랜잭션 수수료의 위임이다. 수수료 위임을 위해 PoC1에서는 기존 가스 시스템에 스테미나라는 새로운 개념을 추가하였다. 인간이 활동을 하면 줄어들고 휴식을 취하면 회복되는 스테미나처럼 PoC1에서 이야기하는 스테미나 또한 사용하면 줄어들고 일정 기간이 지나면 회복하는 특성을 가지고 있다. 스태미나를 사용하기 위해서는 수임계정(delegatee)이 위임계정(delegator)을 지정하여 스테미나 쌍(stamina pair)을 형성 해야한다. 수임계정(delegatee)은 스테미나를 미리 예치(deposit) 해놓아야 하며, 스테미나 쌍 설정과 스테미나 예치가 완료되었다면, 위임계정들은 수수료에 대한 직접적인 걱정없이 서비스를 이용할 수 있다. 위임계정(delegator)에 의해 발생하는 트랜잭션이 많을 수록, 수임계정은 더 많은 스테미나가 필요할 것이다. 스테미나가 바닥나면, 위임계정들은 본인의 계정에 있는 잔액을 트랜잭션 수수료로 지불할 수 있고, 어찌되었던 모든 트랜잭션에 수수료가 부과되기 때문에 DoS와 같은 네트워크 공격을 방지 할 수 있다. 또한 수임계정은 위임계정의 이상 행위를 발견했을때 쌍 지정을 해제함으로써 악의를 가진 위임계정이 수임계정의 스태미나를 소모시켜 버리는 것을 막을 수 있다. 만약 특정한 목적을 위해 체인 상에서 운영되는 탈중앙화 어플리케이션(dapp)이 있다고 했을 때, 서비스 제공자(service provider)는 수임계정을 여럿 확보해, 서비스 이용자들을 위임계정으로 지정해 일정한 스테미나를 미리 확보해둔다면, 서비스 이용자는 트랜잭션 수수료에 대한 큰 부담 없이 탈중앙화 어플리케이션(dapp)을 손쉽게 이용 할 수 있다. 이는 PoC1에서 제시하는 모델이 전통적인 이더리움의 실행모델보다 훨씬 사용성을 개선한 것이라고 판단된다.
2.2.5 기존 이더리움 실행모델과 비교에서 보았듯이 이 모델은 스태미나 사용을 위해 트랜잭션 한번에 세 번의 이더리움 가상머신(evm)이 실행되는 구조로 되어 있어서 이더리움 메인넷에 적용을 하면 속도를 더 느리게 할 것이다. 그렇기 때문에 메인넷보다는 프라이빗 체인이나 사이드 체인에서 활용하는 것이 적합하다고 판단된다. 이러한 문제를 해결하기 위해PoC2 : Plasma EVM(https://hackmd.io/s/HyZ2ms8EX)에서는 PoC1에서 제안된 아키텍쳐를 메인넷에 연결된 사이드체인으로 활용할 수 있게 하는 방안에 대해 논의가 이뤄질 예정이다.