('22. 2. 19.) My impression on Ethereum Development
Get your hands dirty to understand the concept of Crypto and so-called "Web3"
말씀을 행하는 사람이 되십시오. 그저 듣기만 하여 자신을 속이는 사람이 되지 마십시오.
— 야고보서 1장 22절, 가톨릭-개신교 공동번역성서 (대한성서공회)
직접 만들어야 알 수 있다
확실히 작은 프로덕트를 내 손으로 직접 만들어봐야, 장점과 단점을 피부로 체감할 수 있습니다. 괜히 Dirt your hands라는 말이 있는 것이 아니고, 말만 하지 말고 실천하라는 격언이 있는 것이 아니라고 느꼈습니다. 세상은 분명 다수의 평론가와, 소수의 실행가로 나뉩니다. 평론하는 것은 쉽고, 비판하는 것은 누구나 할 수 있지만, 변화를 만들어내고 무언가를 스스로 만들어내는 것은 어렵다는 것이죠. 단순히 리서치를 통해 이럴 것이다, 저럴 것이다 라고 탁상공론하는 것은 한계가 분명 있다고 생각합니다.
2018년에도 블록체인과 크립토에서 리서치 RA 인턴으로 일했지만, 정작 내가 파악할 수 있는 범위에 한계가 있다는 사실을 깨닫고 절망한 기억이 있습니다. 그래서 개발을 공부해야 겠다고 결심했고, 2019년 초부터 2020년 8월 입대 전까지 개발 공부에 입문하려고 아등바등했던 기억이 있습니다. 이제 다시 크립토, 블록체인 분야에 돌아왔고, 저는 조금 더 코드를 다루고 싶습니다. 제 미래 커리어의 측면에도, 저는 결국 코드를 작성하는 개발자로서 플레이 하고 싶다는 열망이 강합니다. 제가 크립토를 좋아하는 이유도, 코드를 직접 작성하고 프로덕트를 작게나마 만들어보는 과정을 통해 더욱 깊게 크립토를 이해할 수 있기 때문이라고 생각합니다.
제가 dApp 2개 정도를 직접 만들어보고, 이에 따라 제가 갖게 된 so-called "Web3" 에 대한 생각을 진솔하게 적었더니 사람들에게 폭발적인 반응을 얻었습니다. 저는 계속해서 크립토에 관심을 갖고 있어서 지난 주 토요일부터 오늘까지, 총 3가지의 크립토 토이 프로젝트를 진행해보았습니다.
Compound Protocol 기반, DAI 스테이블 코인을 예치한 사람들끼리 복권 추첨을 할 수 있는 스마트 컨트랙트 시스템. 더 많은 DAI를 예치한 사람에게 당첨 확률이 더 높아지도록 구성했으나, 적은 DAI를 예치한 사람도 당첨이 가능함. 이더리움 기반 PoolTogether 컨트랙트 및 해당 인프런 강의에서 착안했습니다. 깃헙 주소
Sigrid Jin 개인 퍼스널 토큰 v1 런칭. 그 동안 가열차게 공부해 온 Solidity 언어를 바탕으로, ERC20 표준 규격에 맞추어 SIGJ 토큰 발행. 하지만, 토큰 발행 후 Uniswap에 유동성을 공급하려고 보니 liquidity pool 상장 비용이 약 600달러에 수렴. 이거 어쩌지? 이미 토큰 발행은 해 버렸는데? 고민하던 와중에, Layer 2 솔루션을 사용해보기로 결심. 메인넷에 배포한 ERC20 컨트랙트를 Polygon으로 브릿지 연결 후, Polygon 네트워크로 Uniswap에 SIGJ 토큰을 상장했습니다.
Polygon 메인넷에서 Sigrid Name Service을 런칭하였습니다. 저는 최초 민팅자로서 jin.sigrid 주소를 선점하였습니다. 실제 Ethereum Name Service처럼 각각의 도메인을 NFT화 하여 거래할 수 있도록, ERC721 규격을 따라 도메인을 구현하였습니다.
Gas Fee를 아껴라, EVM/Solidity는 말 그대로 bullshit !
사진 출처: Elysia Land Tech Blog
이더리움 메인넷에서 가스비는 상상을 초월할 수 없을 정도로 비쌉니다. 필자가 처음으로 제작한 스마트 컨트랙트인, 동전 뒤집기 게임은 약 50-60줄 정도밖에 되지 않는데 배포 비용이 60만원에 달했습니다. 대단한 비즈니스 로직이 있는 것도 아니에요. 단순히 가상의 동전을 상정하고 해당 동전을 던진다고 생각할 때, 동전의 앞면이 나올까 아니면 뒷면이 나올까를 맞춰보는 게임이었는데요. 이런 간단한 게임을 배포하는데 60만원입니다. Sigrid Jin 개인 토큰을 배포하는 과정에서도, 네트워크가 혼잡하지 않은 상황이었음에도 불구하고, 가스비가 약 15만원 소모되었다. ERC20 토큰을 만들어본 사람이라면 알겠지만, 코드가 복잡하지 않습니다. 그나마 가스비가 15만원 정도밖에 나오지 않은 것도, 내 생각에는 OpenZeppelin이 최적화를 많이 해 주어서 가스비를 절약할 수 있기 때문이라고 생각합니다.
가스비에 대해 한 번 생각해봅시다. 일단, 이더리움은 전 세계 모두가 사용하는, 하나의 단일한 상태로 고정되는, 공통의 데이터베이스라고 생각할 수 있습니다. 모두가 사용하는 데이터베이스에 굳이 기록을 하고 관리해주는 대상에게는 보상을 주어야 합니다. 여기서 보상이 바로 ETH, 즉 이더입니다. 이더리움은 가스비를 도입해서, 이 거대한 월드 컴퓨터를 관리하고 정보를 기록하는 사람에게 보상을 주는 한 편, 네트워크를 마비시킬 수 있는 과도한 요청을 막을 수 있었습니다. 가스비가 소진될 때까지만 요청을 수행해서, 네트워크가 아예 뻑갈 때까지 요청을 무한 수행하지 않도록 막은 것이죠. 이더리움에서 기록해주는 사람을 풀 노드(Full Node) 라고 하며, 해당 노드는 기록을 남기면 네트워크가 주는 기본 보상에 요청자가 주는 가스비를 받게 됩니다.
가스비는 트랜잭션 실행 가스의 총량에 가스의 가격을 곱한 값입니다. 이 때, 가스의 총량은 트랜잭션을 실행하고 연산하는데 필요한 컴퓨터 이진수로 이루어진 명령어(이를 EVM 바이트코드라고 부릅니다)를 고려하여 필요한 가스의 총량을 구합니다. 연산이 많을 수록, 가스의 양이 늘어나구요, 어떤 연산을 수행하느냐에 따라 - 즉 어느 명령어를 사용하느냐에 따라 얼마나 가스를 매길 것인지 이미 정해져 있습니다. 가스 테이블이라고 부르죠. 우리가 이더리움이 느리고 비싸다고 하는 이유는, 현재 대기 중인 요청이 많을 수록 가스 가격이 비싸지기 때문입니다. 경우에 따라 5~20배까지 비싸지는 경우도 있구요. 아침과 밤에 따라 가스 비용이 천차만별 달라지기도 하구요. 이더리움 메인넷 기반으로 새로운 게임이 등장했다던지 NFT가 민팅된다던지 하면 전체 네트워크의 속도 및 가스 가격에 영향을 받게 됩니다. 가스의 가격은 1 가스 당 가격이며, 이는 이더리움의 가격에 비례합니다.
하여간 가스비를 줄여야 합니다. 가스비를 줄이는 방법으로는 1) 연산을 줄인다 2) 가스의 가격을 줄인다 두 가지를 생각해볼 수 있겠습니다. 연산을 줄이기 위하여, 비즈니스 로직 수행 과정에서 불필요한 연산을 최대한 찾아내고 이를 없애려고 합니다. 일종의 최적화라고 볼 수 있겠네요. PoolTogether 컨트랙트를 보면, 복권 추첨 게임에서 사람들이 매 회차마다 DAI를 새롭게 예치할 수 있도록, 즉 돈을 걸 수 있도록 되어 있습니다. 이 때, 각각의 회차를 구현하는 과정에서 회차를 들고 있는 Dynamic Array, 즉 배열로 구현하면 어떻게 될까요? 불필요한 공간을 저장해야 하고, 각각의 회차를 진행하는 도중에 게이머가 베팅을 취소하겠다고 하면, 또는 예치한 금액을 바꾸겠다고 하면, 우리는 해당 사람의 회차를 가져오기 위해 배열에서 추가적인 인덱싱 과정을 거쳐야 합니다. 우리는 기존의 so-called "Web2" 개발에서는 불필요한 연산이 어느 정도 있더라도, 가독성이 좋은 방향으로 개발해야 한다는 이야기를 들었습니다. 그 이유는 유지보수가 가능하려면 명확하게 코드를 작성함으로써 가독성이 높여야 하기 때문입니다. 그런데 Ethereum은 다릅니다. 가독성은 어느 정도 희생하더라도, 당장의 가스 비용을 줄이는 것이 급선무 과제입니다.
// O(n) where n is the number of token holders with stake
for (uint i = 0; i < tokenHolders.length; i++)
if (currentDrawnNumber < tokenHolders[i].segmentEnd)
return tokenHolders[i].address
만약 위와 같이 구현했다고 해 봅시다. 그러면 각 회차마다 큰 비용이 발생합니다. O(현재 회차 수 * 토큰을 예치한 게임 참여자의 수) 만큼의 아주 절망스러운 시간 복잡도를 갖게 됩니다. 게다가 보안 측면에서도 취약한데, 공격자는 최소한의 금액만을 넣는 이더리움 계정을 엄청 많이 만들면 스마트 컨트랙트 자체가 동작하지 않도록 만들 수도 있습니다. 따라서, 기존 개발처럼 for 문을 활용하는 경우 컨트랙트는 상당히 취약해질 수밖에 없습니다. 이러한 사태를 방지하기 위하여, 우리는 이진 탐색 트리 등 다양한 자료구조를 활용함으로써 최대한 효율적인 컨트랙트 구조를 설계해야 합니다. 오히려 Web2보다 Computer Science 적인 지식이 더 많이 쓰인다고 볼 수도 있겠습니다.
저는 최근의 프로그래밍 흐름이 클래스와 함수의 책임을 잘게 쪼개고 상호 분할하는 것에 있다는 점을 주목하고 싶습니다. 프론트엔드에서는 최대한 컴포넌트를 파일 별로 분리하려는 atomic pattern이 주목을 받고 있고, 백엔드에서도 기존의 계층형 아키텍쳐보다 더욱 명확하게 책임을 분산하고자 하는 hexagonal architecture가 큰 화두가 되고 있습니다. 그런데, 스마트 컨트랙트 개발은 이를 역행하는 것으로 보입니다. 잘게 쪼개지는 못할 망정, 자꾸 하나의 파일에 합쳐야 하고, 계속 상속하고 import 해야 하므로 클래스 간의 관계가 복잡해지고 유지 보수가 요원해집니다. 이 과정에서, unit test를 제외하고는 실질적으로 클라이언트 단위에서 테스트를 진행하기가 참 난감합니다. ATDD 인수테스트, CI/CD 통합 배포 및 지속적 관리, 그리고 프론트엔드와 묶어서 서로 통합 테스트를 진행하기가 참 어렵습니다. Mastering Ethereum을 봐도 Reentrance 공격 등 취약점에 대한 이야기가 책 전체의 20%를 차지하는데, 보안의 측면, 코딩 스타일의 취약점을 모두 고려하면서 contract를 짜는 난이도가 다소 높다고 생각하게 되었습니다.
할 수 있는 것은 테스트넷에 faucet을 받아서 무한히 배포해보고 컨트랙트가 잘 돌아가나 살펴보는 것입니다. 아무래도 스마트 컨트랙트는 한 번 배포하면 upgradeable 하기가 다소 까다로운 만큼, 신중히 배포해야 할 것입니다. 이는 agile하게 배포해보고 수정한다고 하는 기존 so-called "Web2" 시대의 생각과 많이 다른 것 같습니다. 전통 레거시 은행의 인프라를 생각해보면, 오히려 waterfall 형태로 조심조심 하며 최소한의 비즈니스 로직(trustless한 경우만 최소한으로 선별해야 함. 예를 들어 지분 토큰화를 했을 때, 크립토로 급여를 지급하는 경우. 월급과 관련된 부분이니 크립토로 준다고 하면 블록체인에 묶어야 함.) 만을 스마트 컨트랙트로 올려야 할 것입니다. 요약하자면, on-chain의 computation price도 상당하고 리소스가 제한되는 만큼, "trustless한 layer에서 꼭 필요한 연산만을, 최소한으로 코딩하여 컨트랙트를 짜는 전략이 필요하다고 느꼈습니다.
아무래도 가스비가 많이 들다보니, Solidity 언어 자체가 쓸 만하게 성장하지 못하는 장벽이 되기도 합니다. Solidity에 overflow check 및 try-catch 구문도 추가된 지 몇 달 되지 않았고, 해당 구문도 exception을 던지는 것이 아니라 HALT를 내뱉고 끝나버립니다. 오버플로 체크의 경우에도, 오버플로를 체크하는 과정 속에서 가스비가 추가로 발생하기에 개발자가 비즈니스 로직 상 overflow가 일어나지 않을 것이라 확신한다면 다 unsafe니 unchecked니 구문을 붙여서 오버플로 체크를 하지 않도록 코드를 작성합니다. 이를 통하여 가스비를 아끼려고 하는, 아주 눈물의 똥꼬쇼를 하고 있는 것이죠. 참고, 제 페이스북 담벼락의 Daniel Hong님 댓글을 가져왔습니다.
가스비와 연관이 있어서 그런 지 모르겠지만, Solidity에서는 문자열의 길이를 측정하는 기능, 그리고 sequence의 length 등 complex data의 size를 제공하는 기능도 제대로 지원하지 않습니다. byte-length로 바꾸어서 return type을 uint256으로 명시해야 합니다. 이 과정에서도 사람들이 가스비를 아끼기 위해 수 많은 라이브러리를 오픈소스로 만들어서 코드를 서로 공유하고 있습니다. 언어 차원에서 네이티브하게 지원하지 않는다는 것 자체가, 말이 되는 일이 결코 아닙니다.
// https://ethereum.stackexchange.com/questions/55070/calculate-string-length-in-bytes
function mine(string s) public view returns (uint256) {
return bytes(s).length;
}
사실 deterministic 해야 하는 이더리움 특징, 즉 전 세계 어디를 가더라도 같은 연산에 대해 같은 결과값을 내놓아야 하는 특징 때문에 가스비의 제한이 명확할 수밖에 없습니다. 블록체인이 trustless 한 기계이지만, 이 trustless하다는 특징이 비즈니스 로직을 풍부하게 적용하지 못하도록 합니다. 예를 들어, 솔리디티에는 정규표현식(Regular Expression) 을 지원하지 않습니다. 지원하도록 만드려면 별도의 라이브러리를 만들어, 해당 라이브러리가 서로 재귀함수를 이루어 텍스트 하나하나를 검사하여 false를 리턴하면 전체 재귀함수가 false로 return 되도록 구현해야 합니다. 그리고, 정규표현식을 사용하고자 하는 솔리디티 컨트랙트에 라이브러리 컨트랙트를 import 해야 합니다. 이거 뭐하는 짓인가요? 물론 regex는 표현식 엔진을 사용하느냐에 따라 패턴 매칭 결과가 달라질ㅂ 수 있기 때문에, deterministic machine이라는 이더리움의 철학을 지키기 위하여 언어 부분에서 도입하지 않은 지점도 있을 수 있겠습니다.
Contract는 꼭 공개되지 않는다, 다만 Bytecode만 공개될 뿐이다
개발을 하지 않으시는 사람들이 주로 착각하는 것 중 하나는, 스마트 컨트랙트 코드를 만들어 블록체인에 배포하면 해당 코드를 누구나 볼 수 있다는 것입니다. 하지만, 실제는 그렇지 않습니다. 이더리움의 경우 솔리디티 코드를 배포하면 바이트코드로 해석되어 EVM 상에 실행되는 것입니다. 따라서, 바이트코드가 저장될 뿐 코드 그 자체가 어떻게 짜여져 있는 지는 알 수 없습니다. 바이트코드를 사람이 읽을 수 있는 형태의 코드로 다시 번역은 가능하지만, 원래 코드가 아닌 만큼 작성자의 의도를 정확하게 파악하기 어렵습니다.
따라서 이더스캔이라는 Web2 방식의 중앙화된 사이트는, 개발자가 해당 컨트랙트를 배포했을 때 사용한 원래 솔리디티 코드를 업로드할 수 있도록 기능을 제공하고 있습니다. 실제 배포한 코드와, 이더스캔 사이트에 업로드 하려는 코드가 동일한 지 확인해야 겠지요? 그래서 개발자가 올리려는 코드를 바이트코드로 해독한 뒤, 해당 바이트 코드가 이더리움 네트워크에 업로드 된 바이트코드와 동일한 지 확인합니다. 만약 동일하다면 이더스캔이라는 중앙화 사이트는 해당 컨트랙트의 코드가 공개되었음을 verify 합니다. 정말 재미있지요?
lesson learned: fuck EVM - the compiled bytecode is SIGNIFICANTLY differed according to your solidity version at the time of compilation. If you are not aware of it, it is expected to resolve it by finding the record or one-by-one attempts to remind it.
탈중앙화된 세계를 항해하기 위해서 중앙화된 사이트를 신뢰해야 합니다. 탈중앙화된 세계는 정말 만인에 대한 만인의 투쟁입니다. 그 누구도 여러분을 보호해주지 않습니다. 이 때, 중앙화된 Web2 식의 서비스는 일반 사용자를 보호해줄 것입니다. Infura, Alchemy, Etherscan... 이들은 모두 우리의 친구입니다. 탈중앙 세계를 항해하는 데 도움을 주는 중앙화 서비스이기 때문입니다. 아, 참고로 솔리디티는 컴파일러 버전이 다르면 같은 컨트랙트 코드라고 하더라도 바이트코드가 다소 달라지나 봅니다. 따라서, 개발자가 본인이 컨트랙트를 배포한 시점의 컴파일러 버전을 기억하지 못하면 verify하기 정말 난감해집니다. 일일이 모든 버전을 돌려보고 맞는 바이트코드가 나올 때까지 반복해야 합니다.
같은 논리에서, 이더리움 블록체인에 공개된 컨트랙트의 함수를 호출하기 위해서는 개발자가 컨트랙트 코드를 깃헙 저장소든 이더스캔이든 공개해두어야 합니다. 그래야 ABI 라고 하는 json 파일 형식의 컨트랙트 정보를 받을 수 있고 (바이트코드를 해독할 수 있는 열쇠라고 보시면 될 것 같아요.) 사용자가 해당 컨트랙트를 활용할 수 있습니다. 저는 이 점이 정말 재미있다고 생각하는데, 더 설명해주실 수 있는 분이 계시면 댓글 부탁드립니다.
L2, bullshit !
이 부분부터는 경어체가 아니니 놀라지 마세요!
이번에 Sigrid Jin 퍼스널 토큰을 런칭하면서 느꼈다. Ethereum은 정말 쓸 수 있는 도구가 아니구나, 라고 말이다. 특히, Layer 2에 bearish한 관점을 분명하게 가지게 되었고 Ethereum은 user-level에서 사용이 어렵다는 것을 확신했다. 물론, Ethereum은 multi-chain layer 세상에서 디지털 금고, 스위스 은행과 같이 높은 수준의 보안을 제공해주는 역할을 할 것이다. 가스비가 비싸다는 것은, 그리고 네트워크 시가총액이 크고 네트워크 사용도가 높다는 것은, 51% 공격을 수행하기 어렵다는 것을 의미하기 때문이다.
본인이 퍼스널 토큰을 런칭하는 과정을 설명하면 다음과 같다. 먼저, OpenZeppelin의 ERC20 토큰을 발행한다. 이후, Uniswap에 상장하려고 보니 liquidity pool listing 비용이 600달러 이상이었다. 이건 배보다 배꼽이 큰 상황이니, Layer 2인 Polygon을 선택했다. 하지만, Ethereum Mainnet에 배포한 기존 토큰을 Polygon으로 어떻게 옮길 지도 참 난감했다. 각종 Documentation 등을 뒤져서 브릿지로 배포했다. 이 과정도 제대로 나와있는 곳이 없고, 내 스스로 trial and error (돈을 잃어가며) 하면서 깨달았다. 개인적으로 coinvise.co 라는 곳을 살펴보기를 권하는데, 클릭 몇 번으로 Social Token의 발행, Polygon으로의 전환, Quickswap DEX로의 상장 등을 지원한다. 이 곳을 한 번 살펴보기를 바란다.
아무튼 나는 현재 Uniswap에 Polygon의 메인 토큰인 MATIC으로 SIGJ 토큰을 구매할 수 있도록 유동성을 공급해두었다. 그런데 한국 4대 거래소에서 Polygon 토큰인 MATIC을 Polygon 메인넷으로 바로 보내기가 참 어렵다. 왜냐하면 한국 거래소 모두 MATIC 토큰 송금 및 수신을 Polygon 메인넷이 아니라 ERC20 형태로 지원하기 때문이다. 이와 달리, Coinbase와 FTX는 MATIC의 Polygon 메인넷 전송을 지원한다. 진짜, 한국 거래소가 Crypto 사용을 어렵게 하는구나 생각했다. 우리 한국 거래소도 하고 싶은 플레이가 참 많을텐데, 여러 기술적 및 규제의 장벽으로 인해 플레이하기 어려운 점이 많겠다 생각하게 되었다.
아무튼, 내가 상장한 Polygon Uniswap 토큰을 KRW 원화로 구매하려면 거래소에서 ETH 구매 -> 2~3일 정도 기다려야 함 -> ETH를 이더 메인넷으로 송금 -> 이더 메인넷에서 ETH : MATIC ERC20 스왑 -> MATIC ERC20을 Polygon 메인넷으로 보냄 -> MATIC 토큰을 Uniswap에서 이용 이라는 유저 플로우를 거쳐야 한다. 이거 Layer 및 단계가 너무 많으니 Product level로 사용하기에 매우 비현실적이다.
이 지점을 보고 생각한 것은 1) Toss 앱을 보면 Web Automation Team이 있어서 복잡한 구닥다리 웹사이트에 아이디 비밀번호 입력, 비밀번호 찾기 등의 모든 로직을 자동화했다. Toss 수준의 인력과 노가다를 갈아넣어서 Crypto 인프라를 자동화하지 않는다면, 혹은 Crypto 인프라 자체가 Layer를 많이 줄이지 않는다면 mass-adoption은 요원한 일이 될 것이다. 2) Layer 2, 나아가 Ethereum을 활용하지 않았다면, 즉 Layer 1 및 Layer 1 토큰이었으면 절차가 1~3단계 정도 제거되었을 문제인데. 애시당초에 내가 퍼스널 토큰을 ERC20 으로 런칭한 것이 문제이다. v2에는 Solana나 Terra 네트워크를 검토한 후, 네트워크를 옮겨야겠다.
인프라, 인프라, 인프라!
인프라가 경쟁한다는 것은 신선한 일이다. 우리는 태어나서 애시당초에 주어진 플랫폼을 썼다. 뒷 단에서 어떤 플레이가 이루어지는 지 보기가 어렵다. 여러분 중에서 DNS 서버가 어떻게 경쟁하는 지 아시는 분이 얼마나 계실까. 그런데 우리는 Klaytn Naming Service에서 그 경쟁을 보고 있다. 이번에 Klaytn Name Service가 나왔는데, 출시 예정 기념으로 lucky draw 이벤트를 진행하고 있다. 그런데 다른 곳에서도 Klaytn Name Service를 만들겠다고 하는 곳이 있다. 와 뭐지? 그렇다. 인프라는 누구나 만들 수 있다. 코드만 짜면 된다.
http://revoke.cash도 이더리움 서비스를 이용하면서 자기도 모르게 막 Approve 버튼 누른 것을 관리하고 승인 취소할 수 있는 시스템이다. 이거 보니까 주민등록번호 무단 사용하는데, 소비자가 사이트 들어가서 불필요한 서비스 제공자를 차단하는 장면이 떠올랐다. 이제 누가 정치적 싸움에서 승리하여, 클레이튼 생태계 서비스에서 누가 더 많은 선택을 받느냐에 달려 있다.
나도 이번에 Polygon 메인넷 위에서 Sigrid Name Service를 시범 삼아 만들어 보았다. 심지어 도메인을 NFT로 발행해서 OpenSea에도 판매할 수 있다. 나같은 나부랭이도 만들 수 있는게 ENS다. 사실 네이밍 서비스가 대단한 것은 아니고, 사용자의 Ethereum 지갑 주소와 도메인 이름을 매칭할 수 있는 mapping 만 만들어주고, 해당 도메인 이름에 대응하는 레코드 mapping만 만들어 주면 핵심 로직은 얼추 비슷하게 시범삼아 proof-of-concept 으로 만들 수 있다. 만들기는 쉽다. 이 과정에서 정작 이 섹터를 crypto 라고 부르면서도 많은 실제 유저 엔드 서비스의 구현 과정에서 cryptography가 들어가지 않는 게 정말 이상하다고 말한 Moxie의 글이 다시 한번 떠오른다.
크립토는 정치 싸움이다. 내가 만든 Sigrid Name Service의 컨트랙트를 Ethereum 네트워크를 사용하는 각종 서비스에서 지원해주지 않을 것이다. 이미 ENS가 차지하고 있는 세상이기 때문이다. 하지만, 바꾸어 말하면 기존의 ENS 서비스가 제대로 동작하지 않는다면 누구나 대체품을 만들 수 있다는 뜻이다. 그럼에도 불구하고 인프라를 선택하는 것은 Ethereum 네트워크를 이용하는 OpenSea 같은 중앙화 서비스다.
애시당초에 크립토는 레거시 인프라 세력과의 정치 싸움이기도 하다. 그리고 크립토 내부에서도 인프라를 두고 정치 싸움을 벌이고 있다. 확장되는 디지털 세계의 인프라를 누가 차지할 것인가? 그래서 누워서 떡 먹기를 누가 할 수 있을까? 이 고민인 것이다. 이 과정에서 탈중앙화라는 개념은 중요하지 않다. 물론, Web2 보다는 탈중앙화될 것이다. 왜냐하면 Web2는 개인의 자아를 브랜딩할 수 있는 수단이 마땅치 않았다. 그런데 Web3는 이를 가능하게 만든다는 "이유로" 사람들을 끌어들이기 때문이다. 하지만, Web2 시대의 논리가 갑자기 Web3가 되었다고 성립되지 않을 이유는 하나도 없어보인다.
결론
한 때 어느 블록체인 네트워크가 EVM-compatible하년 기술적으로 유리하다는 취급을 받은 적이 있었다. 이더리움이라는 큰 생태계의 dApp 컨트랙트를 그대로 가져다 사용할 수 있기 때문에, 초기 개발자를 쉽게 끌어올 수 있으리라는 기대 때문이었다. 실제로 NEAR Protocol이 EVM-compatible하면서, 탄탄한 생태계를 만들어가고 있다. 클레이튼도 이더리움에서 인기를 끈 프로젝트를 그대로 가져오는 것 아니냐는 비판이 있지만, 그럼에도 불구하고 클레이튼이 이더리움포크이기에 사용자들에게 더 빨리 다가갈 수 있었음은 분명하다.
하지만 우리는 EVM의 폐혜, 단점, 그리고 한계점이 분명하다는 것을 알고 있다. 기존 so-called "Web2" 개발자라면스마트 컨트랙트 개발에 뛰어들면 정말 당황할 것이다. 응당히 있어야 하는 개발 도구가 전무하기 때문이다. 이더리움과 솔리디티는 극우 아나키스트들이 만든 결과물이다. 이더리움의 그 아마추어리즘을 벗어 던지고 실제 비즈니스가 동작할수 있을 만한 기술적 지원을 보여줄 녀석이 바로 이더리움 2.0이다. 이더리움 2.0은 CosmWasm이라는, EVM을 대체하리라 기대되는 코어 엔진이다. 그런데 이더리움 2.0이 언제 안정화되어 서비스할 수 있을 지는 모르겠다. EVM을 쓰지않아야, 즉 이더리움 2.0이 이더리움 1.0을 지원하지 않아야 말끔한 체인 전환이 이루어질 수 있지 않을까? 만약 하위호환성(backward compatibility)을 지원해야 한다면 아예 처음부터 언어와 엔진을 설계하는 점이 편하지 않을까?
"요한계시록 21:1-8, 또 내가 새 하늘과 새 땅을 보니 처음 하늘과 처음 땅이 없어졌고 바다도 다시 있지 않더라"
요한계시록에서 '새 하늘 새 땅' 이 이루어질 하나님 나라를 기약하는 것처럼, Ethereum 2.0은 척박한 Layer 1 생태계에 '새 하늘 새 땅' 이 도래할 것이라 언약하고 있다. 나에게 Ethereum 2.0은 요한계시록에서 언급된 '하나님 나라' 처럼이해된다.
그런데 시간이 지나도 '하나님 나라' 는 찾아오지 않는다. 언약을 기다리다 지친 사람들은 '하나님 나라' 를 새롭게 해석하려고 한다. 어떤 교주들은 '하나님 나라' 는 본인들의 사이비 종파에 들어와야 체험할 수 있다고 말한다. 대표적인 예시가이만희씨, 신천지다. 이와 마찬가지로, 우리 Layer 2 사이드체인을 체험하면 low gas fee, fast performance를 누릴수 있다고 말한다.
하지만 Layer 2의 존재 가치에 대해 여전히 나를 충분히 설득하지 못했다. 말 그대로 메인넷(현실 세계)와 접점이 없기때문이다. 그렇다면, Ethereum에 '새 하늘 새 땅' 은 언제 찾아올 것인가? 실존을 고민한다면 언제까지 문서상의 언약만을 손꼽아 기다릴 노릇이 아니다. 결국 다른 Layer 1 생태계에 눈을 돌리게 되는 것이다. 대표적으로 Solana, Luna, Avalanche를 꼽아볼 수 있는데, 나는 Solana에 특히 관심이 있다.
Solana에서 쓰이는 Rust는 low level language인데, 비동기 코루틴 지원이 언어 레벨에서 가능하도록 조치해준다 하니 관심이 간다. 표를 보면 EVM 기반 언어는 사양세를 겆고 있고, Rust는 점점 인기가 올라가는 모습을 볼 수 있다.
나는 Solana를 써보며 개발 스케일업의 한계가 분명한 EVM/Solidity와 비교해보고 싶다. 그럼에도 블록체인은 블록체인이다. 세상 어디를 가더라도 실행 결과는 동일해야 하고 예측 가능해야 한다. 아무리 Rust의 개발 환경이 높다고 하더라고, 기존 DB보다 비효율적인 것은 사실이다. 그래서 블록체인은 최소한의 컴퓨팅 연산, 신뢰가 꼭 필요한, 그리고 토큰을 옮기고 교환하는 데 사용하는 것이 옳다. 복잡한 비즈니스 로직은 기존의 Web2 방식 대로 클라이언트-백엔드 관계를유지해야 한다. 이 점에서 Web3는 Web2와 별개의 것이 아니고, 같이 가야한다는 것을 강조하고 싶다.