This project is a rust version of nomadcoin. There's a online class called 'Nomadcoin', where you can learn how to create your simple blockchain with golang. Although the main language of the lecture is golang, I studied Rust recently, and wanted to use it in my project to get used to the language. That's why I started this project with Rust.
So, I have two objectives for this project.
- Understand blockchain technically and how to create it on my own.
- Get used to Rust so that I can confidently say I am a rustcean even if I'm not that good at it.
-
Created simple blockchain (Lecture #4)
- I created Block and Blockchain struct and some functions.
- Blockchain hashes data when adding block to its chain.
-
Created explorer html webpage with rocket (Lecture #5)
- I used rocket crate to do this and create rest api in the next section.
-
Created rest api with rocket (Lecture #6)
- At this point, I used workspace to support both explorer and rest api. But I decided to remove explorer in the next section and only supports restapi as main entrypoint.
- In the lecture, nico uses reference of block, but it was somewhat hard to use reference of block in Rust because of lifetime issue. So, I asked a question about it to Korean Rust Discord, and I got an answer from someone that it's okay to use clone() and it's not that costly most of the time, and optimization should be done later.
-
Used database for persisting blockchain snapshot and blocks (Lecture #8)
- I used
nut
which is a rust version of Bolt DB. I changed it to PickleDB because it felt like the library has some bug at that time. - From this section, blockchain persisted even after server restarted.
- I used
-
Applied 'proof of work' concept to mine block and changed database to PickleDB (Lecture #9)
-
Created testutils to drop databse after each test
- I wanted to drop database resource after each test. I created
DBResource
struct and usedDrop
trait to do that. But I don't think that its interface is good and I want to know a better way to do this in Rust. (Actually I removed this later because I thought saving to/tmp
is okay, but I still want to know a cool way)
- I wanted to drop database resource after each test. I created
-
Implemented transaction feature in blockchain network (Lecture #10)
- This was kind of difficult part to make it work correctly, but I managed to do it.
- In the lecture, golang suffered some race condition situations. but Rust felt safe in those conditions, because in concurreny situation, Rust forces us to use
mutex
lock on the compilation level.
-
Implemented wallet(auth) feature to verify transaction (Lecture #11)
- I used
p256
crate to use p256 Elliptic Curves algorithm for cryptography andhex
crate to create hax string.
- I used
-
- I used SSE (Server Sent Event) to implement this feature instead of websocket, because
Rocket
didn't support websocket at the time. I implemented this feature, but did somewhat little dirty things (like sleep 1 sec to give time to ensure inter-connection) - I used
tokio
crate to support async concurrency. - I learned
Arc
to control lifetime in concurreny situation.
- I used SSE (Server Sent Event) to implement this feature instead of websocket, because
-
Refactored some codes about p2p feature
- Used the same parameters for event handling to enhance its adaptibility in the future.
-
Refactored entire code and test
- Created repository layer and used test double(stub) for testing blockchain.
- I learned that I should use
Box
smart pointer to abstract a trait like repository patteren. - I learned that I should use
Mutex
(OrRefCell
) to borrow immutables as mutables. I used this inTestRepository
andPickleDBRepository
, which are required to borrow as mutables to write to db, whereas some database library don't have to do that.
-
Create dockerfile and docker-compose and refactored http file
- I refered to this blog post
This is just my toy project, so I have no plan to add new features, or maintain it. But I want to get feedback about my code like what I'm doing wrong in Rust, and how to improve my rust code. I want to be a good rustcean.
It was very meaningful to do this project. I can confidently say that I kind of achieved both objectives. (Not that good though). I understood the basics of blockchain and got used to program with Rust.