Intro
크립토, 블록체인 시장을 기술적인 관점으로 공부한지 몇달이 지났다.
백서, 미디엄, 트위터 등을 통해 각종 L1, Dapp 들을 공부를 해오면서 느낀 건 ‘결국 엔지니어라면 직접 만들어봐야한다.’라는 것이었고, 서비스 분석을 넘어서 개발을 해봐야지만 아는 것들이 분명히 있다는 것을 느꼈다.
그렇지만 무작정 개발해봐야지 보다는 명분을 잡는게 스스로에게 동기부여가 되기 때문에 명분을 찾다가 Solana Riptide 해커톤을 알게 되었다.
솔라나는 투자도 해보고 백서도 읽어보아서 친숙했지만, 개발은 한번도 안해봤기에 할 수 있을까 싶더라. 그래도 정글에서 배운 것 처럼 '하면 되겠지' 라는 마인드로 제출을 목표로 해커톤 준비를 시작했다.
주제는 'NFT 합성(Composable NFT)'으로 정했다. 생각해놨던 주제가 아니고 브레인스토밍을 하다 나온 주제이다보니 처음에는 “이거 그래서 어떻게 만들지?”라는 생각만 들었음 ㅎㅎ
아이디어 자체는 그렇게 어렵지 않았지만 이더리움 진영의 ERC998 같이 제안된 표준과 달리
솔라나 진영은 뚜렷한 제안도 없고 딱 'NFT 표준'만 있는 상황이다보니 1달 중에 솔라나 개발 환경, NFT 발행 , 관련 라이브러리, 러스트 문법 공부에만 70% 정도 시간을 썼던 것 같다.
그래서 이 글을 통해 솔라나, 개발 환경, 종합적으로 느낀점에 대해서 얘기해보려고 한다.
Solana
- 우선 솔라나가 어떤 블록체인인지부터 간략하게 짚고 넘어가보자.
- 솔라나는 비트코인, 이더리움 등과 같이 묶이는 레이어 1 블록체인이다.
- 솔라나가 기술적으로 다른 블록체인보다 더 낫다고 얘기하는 건
1.저렴한 비용
2.빠른 거래 처리 가능
라고 볼 수 있다.
통상 비트코인은 초당 7건, 이더리움1.0은 초당 30건 처리인 반면 솔라나는 (이론 상) 초당 50,000건의 거래 처리가 가능하다고 한다.
그래서 솔라나는 크립토계의 나스닥이 되고 싶어하고, ‘단일 노드 환경의 성능과 동일한 분산형 노드 네트워크’라는 목표를 가지고 있다.
솔라나는 다음과 같은 3가지 강점을 가지고 있다.
- Scalability: Solana is capable of supporting over 50,000 transactions per second, while maintaining block times of 400 milliseconds.
- Decentralization: with the use of Turbine block propagation protocol, the platform can support thousands of nodes while remaining performant and scalable.
⇒ 여기서 Turbine은 블록 전파 기법이다. 솔라나는 DPoS 기반이다.
- Inexpensive execution: transactions costs on the network are estimated to cost 10 USD for 1 million transactions.
⇒ 거래 1건 당 약 $0.0001 정도가 들기 때문에 매우 저렴하다.
아래는 솔라나가 만든 8가지 기술혁신이다. 솔라나 파운딩 팀 자체가 퀄컴 엔지니어 출신이라 하드웨어, 통신쪽에서 쓰는 기법을 차용한게 많다.
- Proof of History - a clock before consensus.
- Tower Byzantine Fault Tolerance - a PoH-optimized version of PBFT.
- Turbine - a block propagation protocol.
- Gulfstream - a Mempool-less transaction forwarding protocol.
- Sealevel - the world’s first parallel smart contracts run-time.
- Pipelining - a transaction processing unit for validation.
- Cloudbreak - a horizontally-scaled accounts database.
- Archivers - for distributed ledger storage.
위에 나온 기술과 솔라나에 대해 더 알고 싶으면, 백서를 읽어보거나 아래의 링크들을 참고해보자.
암튼 대략 정리하면 솔라나는 짱짱 빠른, 덜 탈중앙화 된 L1 체인이라고 볼 수 있다.
Development
Rust
- 솔라나의 기반 언어는 ‘러스트'이다. 러스트는 재밌는 특징을 가진 언어인데 러스트 얘기를 많이 다루기엔 분량이 많기도하고, 좋은 책이 있으니 저 책을 보시길 추천한다.
- 러스트는 unmanaged language로 분류되는 언어라서 그런가 python, javascript 같은 대중적인 언어보다 학습 난이도가 높고 참고 자료도 많지 않은 편이다.
그러다보니 바닐라 러스트로 솔라나 개발을 하기 부담스러울 수 있다. 그래서 그 문제를 해결해주는게 바로 Anchor 프레임워크이다.
Anchor
- https://github.com/project-serum/anchor는 솔라나 프로그램 작성을 위해 개발된 SeaLevel 프레임워크이다.
- SeaLevel은 위에 나온 솔라나 기술혁신 중 1가지로 병렬 스마트 컨트랙트 런타임이다.
- 즉 솔라나 프로그램을 원활하게 작성하기 위해 러스트 라이브러리 등을 가지고 있는 프레임워크라고 보면 된다.
또한 IDL
이라고 이더리움 진영의 ABI 같은 스마트 컨트랙트 인터페이스를 만들어주기 때문에 클라이언트 쪽에서 개발하기 수월해진다. 비교하자면 이더리움 진영의 Truffle과 유사하다고 볼 수 있다.
SPL
- 솔라나는 개발자들을 데리고 오기 위해 개발자에게 필요한 리소스를 계속 만들고 있는데 그 중 하나가 Solana Program Library(SPL)이다.
- SPL은 클라이언트를 위한 오픈 소스 라이브러리이다.
토큰 전송, 토큰 제작, 토큰 스왑 등 자바스크립트 개발자가 좀 더 쉽게 쓰기 위한 리소스를 제공한다.
주요 개념
- 위에서 계속 Program이라는 용어가 나오는데, Program은 솔라나 개발을 위해 알아야 할 가장 중요한 개념이다. 이더리움 진영의 컨트랙트와 비슷하다고 볼 수 있다.
- 솔라나도 이더리움과 마찬가지로 account를 가지는 블록체인인데, 이더리움은 Contract가 상태(state)를 가질 수 있는 반면에, 솔라나는 Program은 오직 코드만 가질 수 있고 상태(혹은 데이터)를 가질 수 없다.
- 따라서 Program은 Data account라는 별도의 계정을 통해 상태를 저장해야 한다.
Accounts
- Program accounts
- 솔라나에서 “Program”이라 불리는 계정이며, 계정 metadata에 ‘executable’이라 표시된 계정이다.
- 솔라나의 Program은 기본적으로 upgrade가 가능하다.
- Data accounts
- 상태를 저장하는 계정이다. 솔라나에선 OS의 file과 유사한 개념이라고 설명한다.
이 계정들은 validator들의 memory에 저장되는데, 여기서 ‘rent’라는 재밌는 개념이 나온다.
- OS에서 쓰는 file의 경우에 저장하는 데이터의 lifetime은 데이터를 사용하는 program의 lifetime과 같다.
솔라나도 file을 차용했다보니 상태는 validator의 memory에 올라가있는 lifetime에 한정 된다.
개발자는 memory 확보를 위해 validator에게 일정량의 돈(lamports)을 내고 공간을 rent한다.
- 계정이 만들어지는 트랜잭션을 보면 일정량의 SOL이 나가는 것을 볼 수 있는데, 이 rent fee라고 보면 된다.
- 더 자세한건 docs를 읽어보자.
- Data accounts는 read-only/writable, initialized/deinitialized로 구분할 수 있다.
- Read-only는 말 그대로 수정이 불가한 계정이며, Writable은 program에 의해 수정 가능한 계정이다.
- Initialized는 rent를 통해 활성화된 상태이며, 반대로 계정에서 돈이 없어서 rent를 못하면 deinitialize 상태가 된다.
- Native accounts
- System, Vote, Clock 등과 같이 기본적으로 솔라나에서 쓰는 program을 의미한다.
Program
- 솔라나에서 기본적으로 어떤 연산을 하기 위해선 Instruction을 만들어서 특정 Program을 호출해야한다.
- 예를 들어 토큰을 만들거나 토큰을 다른 사람에게 전송하고 싶을 땐 Token Program을 호출해야 한다.
- 우리는 NFT를 다뤘기 때문에 이 Token Program을 자세히 봤는데, 참고로 솔라나에서 NFT는 발행 개수가 1개인 토큰을 의미한다. 그러므로 솔라나에선 FT, NFT 모두 Token Program을 통해 발행되는 것이다.
- Program을 통해 발급된 토큰은 통상
Token Mint
라고 불리는 Data account에 담긴다.
- 이때 내가 어떤 NFT를 소유한다는건 이
Token Mint
의 account에 대한 authority를 내 account가 가지고 있다는 뜻이다.
(솔라나에 owner라는 개념도 있는데 헷갈릴 수 있다. 이는 프로그램의 쓰기 권한이라 다른 개념이다.)
- 나의 NFT를 Mint하거나 소유권을 이전하고 싶을 때는 Associated Token Account(ATA)라는 개념을 사용한다.
이 부분을 이해할 때 고생을 했는데, ATA란 나의 지갑 주소(KeyPair)와 해당 Token Mint
계정을 가지고 만든 별도의 sub-account라고 보면 된다.
즉 Token Mint를 위해 쓰는 보조 계정으로서 ATA를 만들면 나는 ATA의 소유자가 된다. Token Mint
와 내 계정 사이의 연결고리가 생기는 것이다.
- 이 트랜잭션 예시를 보면, Holders에
4HTZyZZjwKw39pAGbf5wcFDyQsSdr38tubiQKS5MyC93
라는 주소가 있고, Owner가 `6J24eGqaKGTWtxW~~~로 되어있는데, 여기서
4HT~가 ATA이고,
6J~` 가 NFT를 민팅하려는 개인의 지갑 주소이다. 즉 실제 민팅은 ATA를 가지고 하게 되고, 나는 그 ATA를 소유하고 있음으로써 소유권 증명을 하게 되는 원리이다.
Token Mint
에 대한 거래 또한 ATA를 활용한다. 내가 X라는 Token Mint
(NFT)를 B에게 보내고 싶으면 내 ATA에서 B의 ATA로 X의 Holder를 이전시킨다. 그러면 결국 X NFT는 B의 소유가 되는 것이다. 한번 더 정리하면 ATA는 Token 소유, 거래를 용이하게 하기 위한 보조 계정이라고 볼 수 있다.
- 솔라나에선 연산을 위해 Program을 호출해야하기 때문에 ATA를 다루기 위해선
Associated Token Account Program
이라는 걸 호출해야 한다.
PDA
- ATA의 정의를 보면 Program Derived Address(PDA)라는 개념이 나온다.
ATA도 복잡한데, PDA까지 보게되면 머리를 움켜쥘지 모른다.
- PDA란 쉽게 말해서 Program이 상태를 가지고 있는 별도의 계정의 주소를 의미하는데, 어떤 Program이 토큰 같은걸 보유할 때 PDA를 사용한다고 보면 된다.
- PDA는 또한 Cross Program Invocation(CPI)를 할 때도 사용되는데, Program은 개인 지갑과 다르게 개인키를 가지고 있지않기 때문에 트랜잭션의 signer로 개인키를 사용할 수 없다. 그러나 CPI를 하기 위해선 트랜잭션을 보내야하기 때문에 PDA를 signer로 사용한다.(PDA는 공개키 역할을 한다.) 공개키 역할이지만 트랜잭션 서명을 할 수 있는 이유는 PDA가 그 program의 id와 seeds를 사용해 만들어지기 때문이다.
- 즉, 그 프로그램이 아니라 다른 계정이 PDA를 제어할 수가 없기 때문에 트랜잭션에 사용할 수 있다고 보면 된다.
- PDA를 만드는 원리에 타원 곡선이 들어가는데 더욱 자세한건 docs를 읽어보길 바란다.
여기까지 기본적으로 솔라나에서 쓰는 기본 개념들을 알아봤다. 헌데 저것들을 다 이해하고 NFT를 발행하려면 많은 사람들이 멘붕에 빠질 것이다. 그래서 많은 사람들을 이롭게 하기 위해 Metaplex라는 회사가 등장했다.
- Metaplex는 사실상 솔라나의 NFT 표준을 만든 곳으로, NFT 민팅, NFT Metadata, Master Edition 제작 등 사람들이 NFT를 더 손쉽게 발행하기 위해 라이브러리를 만들어서 배포했다.
- 대표적으로 Candy Machine이라는 CLI가 있는데 NFT 업로드,민팅, 업데이트 등을 비교적 쉽게 명령어 입력을 통해 해주는 툴이라고 보면 된다.
- 그래서 솔라나에서 발행하는 NFT는 모두 메타플렉스 환경 아래에서 만들어졌다고 보면 된다.
위에서 설명한 개념, CandyMachine을 잘 설명한 블로그 글이 있는데 일독 추천드린다.
우리가 한 것
- 우리도 기본적으로 NFT를 만드는것이기 때문에 메타플렉스의 코드를 많이 참고했다.
- 다만 메타플렉스 코드를 그대로 쓰기에는 필요 없는 부분들이 많아서(화이트리스트, Master Edition 등) proof of concept을 위해 불필요한 부분을 버리고 메타플렉스 스펙인 NFT Metadata만 취했다.
(Metaplex 코드를 이해해 무엇이 필요하고, 무엇이 불필요한지를 판단하는데 굉장한 시간이 들었다😭)
- 나머지는 위에서 설명한 솔라나 개념을 활용해 NFT를 발행하고, 소유권을 이전시키고, 자식 정보를 부모의 메타데이터에 넣었다.
- 우리는 NFT 합성/분해를 구현했는데, 핵심은 합성을 하면 자식의 소유권을 우리 프로그램(Mixture)에 귀속시키고 자식의 정보를 담은 부모 NFT를 발행, 민팅하고, 분해를 하면 자식의 소유권을 원 소유주에게 다시 귀속시키는 것이다.
- 내 역할은 합성 NFT는 유저의 요청으로 동적으로 업로드해야하기 때문에 NFT를 업로드하고, 해당 NFT의 메타데이터를 온체인에 올리는 Mixture 프로그램 initialize API를 만드는 것이었다. (이번에 타입스크립트, NodeJS를 처음 써봤다.😂)
- 자세한 로직은 깃헙 레포를 통해 볼 수 있다.
느낀점
- 개인적으로 솔라나 개발을 하고나서 느낀 점은, 블록체인 개발 입문자 혹은 새로운 NFT 개념을 시도해보는 개발자에겐 솔라나의 입문 매력이 별로 없다는 것이었다.😂
- 이더/솔리디티 같은 경우 재단에서 제공하는 개발 튜토리얼 외에 CryptoZombie 같은 튜토리얼이 많고, 관련 자료도 이제는 꽤 쌓여있는 편이다. Solidity docs도 잘 되어있다.
반면에 솔라나의 경우 공식 docs 정도가 아니면 괜찮은 튜토리얼이 별로 없고, 특히 Rust 라이브러리 docs 같은 경우는 설명이 처참하다..
- 이더/솔리디티의 경우 NFT 표준이 인터페이스 형태이고, 상속을 통해 표준을 확장하기 쉽다. 또한 컨트랙트가 상태를 가질 수 있다보니, 기본적인 메소드(transfer, burn 등)를 구현하기 쉽다.
반면에 솔라나/러스트의 경우 NFT만의 인터페이스는 없다보니 NFT 특성을 살린 데이터 구조를 확장하기 쉽지 않다. 프로그램 계정과 데이터 계정이 분리되어있다보니, 하나의 메소드 구현에도 필요한 input들이 많다.
- 또한 위에서 설명한 것처럼 개발 시 신경써야할 개념들이 더 많다. 필요한 account들이 많기 때문에 누가 signer가 되어야하고, 누가 데이터를 가지고 있어야 하고, 누가 transfer의 대상이 되어야 하는지 분류를 잘 해야 한다.
- 단점만 있는 건 아니다. 프로그램 배포는 솔라나가 훨씬 쉽다. 이더리움의 스마트 컨트랙트는 기본적으로는 한번 배포하면 변경하기 쉽지않은 구조이다. Upgradable contract라는게 있지만 디자인 패턴을 활용한 응용이라고 봐야한다.
반면에 솔라나는 기존 서버 개발 같이 동일한 프로그램에 변경사항을 적용할 수 있다. 그래서 개발 할 땐 저수준 언어를 활용한 서버 개발 하는 느낌이 들었다.
- 그리고 가스비가 확실히 싸고, 트랜잭션 속도도 빠르다. 이더는 가스비 때문에 고통 받는 것 생각하면 굉장히 중요한 포인트이긴 하다. 그리고 속도 또한 개발 하면서 중요한 요소이기 때문에 강점이라고 느끼게 되었다.
- 솔라나 재단 차원에서 주기적으로 해커톤도 열고, 개발에 필요한 리소스를 제공해주기 위해 많이 노력한다는걸 느꼈다.
오피셜 디스코드는 개발 질문에 답을 잘 안해주긴 하지만, Metaplex 같은 써드파티 디스코드는 굉장히 활발한 편이고, 꾸준히 솔라나 에코시스템 위에서 서비스들이 나오고 있으니 솔라나 개발 환경이 앞으로 더 좋아질거라는 기대는 많이 된다.
다시 한번 솔라나 Summer가 올 수 있을지 지켜보자 ☺️