This is an example project to demonstrate the use of modern web techniques with Web3.
View the application live here.
This project is no longer maintained, however, the System Design concepts still apply.
The business requirements are as follows:
- ability to search for a specific transaction hash or block number
- display recent transactions and blocks
- a time-series chart displaying the previous 7 days transactions count, network throughput, and average latency.
// Install Packages
yarn
// Execute Lint
yarn lint
// Execute Tests
yarn test
You may start the web application locally, but may need access to Vercel environment variables to properly run the app. If you are part of the project team, do run the following commands to obtain the appropriate environment variables
yarn vercel link
yarn vercel env pull
Refer to package.json
, for the full list of available commands.
The purpose of system design is to translate business requirements into actionable artefacts that can be iterated upon by stakeholders throughout the system lifecycle. My approach to system design incorporates elements of Domain Driven Design (DDD), demonstrated in the stages below.
The goal of strategic design is to formalize the language used by all stakeholders in the context of the system domain. There are multiple methods to achieve this, but I rely on a simple domain user story diagram that identifies the various personas interacting with the system and the actions performed.
Once the domain story diagram is done up, it can be translated into a formal language that can be categorized into 3 categories: (1) Events; (2) Objects; (3) Transactions.
Events represent the past and act as the source of truth. Objects are models that represent the current state of the domain. Transactions within the domain, create events that changes the various models of the domain.
The domain of Etherscan-Clone
is as follows:
There are two personas that can be identified: (1) Passer-By; (2) Crypto Natives. As the application will be accesible to anyone in the public, we will need to take into account people who visit the site by chance or through social links.
Events | Objects | Transactions |
---|---|---|
Transaction | NetworkStats | - |
Block | RecentBlocks | - |
As the application is currently read-only, there are no domain transactions. The domain events stated are created from the Ethereum domain, and the Etherscan-Clone domain will be subscribing to those events. The identified objects are derived from the expected interactions of the users.
The goal of the tactical design stage is to come up with software artefacts that model the software architecture of the system. Software engineers rely on these artefacts to ensure that the system is built correctly.
Based on the events and objects identified in the Strategic Design stage, the above Entity-Relationship diagram is drawn.
For this project, we will be relying on Infura to retrieve information from the ethereum blockchain. As an API key will be required, we will encapsulate the Infura calls within our own edge functions as follows:
/api/v1/recent/
/api/v1/transaction/?hash={string}
/api/v1/block/?number={number}
The endpoinds are derived from the needs of the personas identified in the Strategic Design stage.
Ethereum Block Time | Traffic Estimation | Requests Estimation | 7-days Storage |
---|---|---|---|
~10 seconds | ~1M DAU or ~10 users/sec | ~10 requests/sec | ~19.32MB |
By referencing the number of daily active address, along with the fact that there are passer-by visiting the site, we can assume 1 million daily active users (source).
The ethereum block time can be estimated to be at least 10 seconds (source).
Based on the information above, we can estimate that visitors to the Home page will trigger approximately 10 API requests every second.
Based on the needs of the project, a subset of the Block
object will be stored in a database to enable efficient calculation of the NetworkStats
object:
- Int: 4 bytes
- Char: 2 byte * size
- Block: 132 bytes + 132 bytes + 4 bytes + 4 bytes + 4 bytes = 276 bytes
Given that there are approximately 10 thousand blocks produced in a day, the storage needed to store 7 days worth of objects can be calculated as follows:
- ( 276 bytes * 10,000 ) * 7 = 19,320,000 bytes = ~19.32MB
Passer-by visiting the Home page do not need to trigger any API requests as the initial content will be prerendered onto the HTML page and deployed on the CDN.
Crypto natives tend to stay longer on the site, and may trigger the /recent
endpoint to rehydrate the Home page with up-to-date content. By interacting with the search bar, they may also trigger additional requests.
A database service is used to store at least 7 days worth of transaction information to allow for efficient lookup of recent transactions, hence allowing the prerendering of the Home page with the appropriate content.
React's useContext
, useState
and other hooks, will be used to manage the application state.
Navigating to src/tests
, one can see that the tests are written in a way that mimics the actual User Story
. This acts as a contract between developers and the product owner as to what features have been completed, and will carry on to exist throughout the product lifecycle. With React Testing Library (RTL)
, writing User Story
tests that mimics actual user behavior is made possible, while also being able to execute as fast as how traditonal unit tests do.