Transaction Fee(GAS) Delegated Execution Model in Py-EVM

Image for post
Image for post
https://www.pinterest.co.kr/pin/396598310919054878/

Stamina Contract

우선 Stamina Contract(developed by 4000d)의 코드는 여기서 확인이 가능합니다.

Image for post
https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369
  1. setDelegator
    : delegatee는 setDelegator 함수를 호출해서 delegator를 지정합니다.
  2. getDelegatee
    : getDelegatee 함수를 호출했을 때, Transaction의 sender가 만약 delegatee가 지정한 delegator라면 delegatee의 주소를 리턴하게 됩니다.
  3. deposit
    : deposit 함수를 통해 ETH를 deposit하고, deposit한 ETH만큼 delegatee는 Stamina를 얻게됩니다.
  4. getStamina
    : delegatee의 남은 Stamina 양을 조회하는 함수입니다.
  5. subtractStamina
    : GAS를 Stamina로 구입할 때 호출되는 함수입니다. 이 때 구매한 GAS만큼 delegatee의 Stamina는 차감됩니다.
  6. addStamina
    : Transaction을 실행하고 남은 GAS는 delegatee의 Stamina로 refund됩니다. 단, Stamina로 GAS를 구매했을 때만 해당됩니다. Stamina의 또 다른 특징은 특정 기간이 되었을 때 ETH를 deposit한 만큼 Stamina가 새로 충전된다는 것입니다. 여기서 특정 기간은 init 함수에서 지정한 recoveryEpochLength입니다.

Transaction Fee(GAS) Delegated Execution Model

Py-EVM에서는 본 모델을 구현하기 위해서는 다음과 같은 일을 진행해야 합니다.

  1. Transaction Execution 과정에서 Stamina Contract 함수 호출

Genesis State에 Stamina Contract Account를 지정

Ethereum의 Account는 nonce, balance, codeHash, storageRoot의 자료구조로 이루어져 있습니다. 또한 Ethereum의 Account는 EOA(Eternally Owned Account) 그리고 CA(Contract Account) 두 종류로 나뉩니다. 두 개의 Account 자료 구조는 같지만, EOA는 codeHash와 storageRoot의 값이 empty입니다. 이에 반해 CA는 codeHash와 storageRoot에 값이 존재합니다.

Image for post
https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369

Transaction Execution 과정에서 Stamina Contract 함수 호출

Transaction Execution 과정에서 Stamina Contract의 어떤 함수가 호출되어야 할까요?

  1. transaction signature 체크
  2. upfront cost 체크
  3. nonce 체크
  4. buy gas
  5. increment nonce
  6. set up VM message
  7. execute message
  8. refund self-destruct
  9. gas refund
  10. process self-destructs

Transaction Fee(GAS) Delegated Execution Model in Py-EVM

여기서부터는 본 모델을 Py-EVM에서 어떻게 구현했는지에 대해 좀더 자세한 내용으로 이루어지게 됩니다.

Py-EVM의 VM 클래스 구조

Py-EVM의 VM 클래스 구조를 추상화하면 다음과 같습니다.

Image for post
Image for post

apply_transaction

Image for post
Image for post
https://www.google.com/search?q=Ethereum+transaction&tbm=isch#imgrc=t-0-N-FM_UWU0M:
Image for post
Image for post
  • vm.apply_transaction
    : block gasLimit을 체크하고 state.apply_transaction 함수를 호출합니다. state.apply_transaction 함수 호출의 결과 값을 바탕으로 Receipt를 만들고 new block header를 만들고 리턴하게 됩니다.
  • state.apply_tranasction
    : Transaction을 가지고 실제 EVM을 구동시킵니다. 이 때 위에서 말했던 11가지의 과정이 수행됩니다(FrontierVM 기준).

구현

EVM을 구동하기 위해서는 Chain 객체와 그 안에 VM 객체 등 여러 객체가 필요합니다. scripts/benchmark 디렉토리에는 쉽게 EVM을 구동시킬 수 있도록 여러 스크립트들이 존재합니다. 그 중 get_chain 함수를 이용하면 쉽게 EVM을 구동시킬 수 있습니다. get_chain 함수는 Memory DB를 사용하며, difficulty가 1인 MiningChain을 리턴합니다. get_chain 함수는 parameter로 VM 객체를 가지는데 자신이 원하는 VM 객체 타입을 넣어주면, 해당 VM 객체로 Transaction을 Execute합니다. get_chain 함수는 2개의 EOA를 Genesis State에 지정합니다.

Setting Genesis State

get_chain 함수는 두 개의 EOA를 Genesis State에 지정했습니다. FUNDED_ADDRESS의 Account는 EOA이기 때문에 code를 가지지 않습니다.

AddressSetup(
address=FUNDED_ADDRESS,
balance=DEFAULT_INITIAL_BALANCE,
code=b''
)
AddressSetup(
address=STAMINA_CONTRACT_ADDRESS,
balance=0,
code=b'`\x80`@R`\x046\x10a\x01\x12W`\x005|\x01\x00\x0...'
)

Call Stamina Contract

Transaction을 Execute하는 과정에서 Stamina Contract의 함수가 호출되어야 합니다. 호출되어야 하는 Stamina Contract의 함수는 위에서 설명드린 것처럼 getDelegatee, getStamina, subtractStamina, addStamina 4개의 함수입니다. 따라서 이 함수를 호출하기 위한 코드를 작성해야 합니다. 단 주의할 점은 이 4가지의 함수 호출이 Transaction으로 포함되는 것이 아니라, 단지 Stamina Contract의 상태만을 변경시켜야한다는 것입니다. 즉 apply_transaction 함수를 호출하는 것이 아니라 Stamina Contract의 상태를 변경시킬 Message를 만들고 Message를 Execute해야 합니다(apply_message 함수 호출).

  1. delegatee가 존재하면, delegatee의 Stamina를 가져옵니다.
  2. 이후 validate_stamina_transaction 함수를 호출하여 delegatee의 Stamina가 gasPrice * gasLimit보다 큰 지 확인합니다. (현재 구현체는 Stamina가 gasPrice * gasLimit보다 작으면 revert합니다. 하지만 본 모델은 Stamina가 gasPrice * gasLimit보다 작으면 Transaction Sender의 balance로 GAS를 구매합니다.)
  3. 마지막으로 Transaction Execution 이후 남은 GAS는 다시 delegatee의 Stamina로 refund됩니다.

마치며

본 모델은 기존 모델에 비해 EVM을 최대 4번 더 구동시킵니다(Stamina Contract 함수 호출을 해야 하기 때문에). 따라서 기존 모델보다 실행 속도는 떨어집니다. 하지만 GAS를 제 3자에게 위임할 수 있기 때문에 서비스 제공자(delegatee), 서비스 사용자(delegator)의 구조를 만들 수 있습니다. 즉 이런 구조에서 서비스 사용자는 GAS를 부담하지 않아도 되기 때문에 좀더 유저 친화적입니다. 본 모델은 온더에서 연구하고 있는 Plasma EVM의 실행 모델로 사용될 계획입니다. 긴 글 읽어주셔서 감사합니다.

Onther

Building an Ethereum Blockchain ECO system to Change the…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store