Solidity์ Web3 ๊ธฐ์ ์ ์ฐ๊ฒฐํ๋ ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ ํตํฉ์ ํฅ๋ฏธ๋ก์ด ์ธ๊ณ๋ฅผ ํํํ์ธ์. ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ธ๋ก์ฒด์ธ ๋ก์ง์ ์ฐ๊ฒฐํ๋ ๋ถ์ฐํ ์ ํ๋ฆฌ์ผ์ด์ (dApp)์ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๊ณ , ์ค์ฉ์ ์ธ ์์์ ํต์ฐฐ๋ ฅ์ผ๋ก ๊ธ๋ก๋ฒ ๊ฐ๋ฐ์์๊ฒ ํ์ ์ค์ด์ค๋๋ค.
ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ: ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ์ํํ Solidity ๋ฐ Web3 ํตํฉ
๋ถ์ฐํ ์น, ์ฆ Web3๋ ๋น ๋ฅด๊ฒ ์งํํ๋ฉฐ ๊ฐ์ธ๊ณผ ๊ธฐ์ ์๊ฒ ๋ฐ์ดํฐ ๋ฐ ๋์งํธ ์์ฐ์ ๋ํ ์ ๋ก ์๋ ํต์ ๊ถ์ ๋ถ์ฌํ๊ณ ์์ต๋๋ค. ์ด ํ๋ช ์ ํต์ฌ์๋ ์ฃผ๋ก ์ด๋๋ฆฌ์๊ณผ ๊ฐ์ ํ๋ซํผ์์ ์ฝ๋๋ก ์์ฑ๋ ์์ฒด ์คํ ๊ณ์ฝ์ธ ์ค๋งํธ ๊ณ์ฝ์ด ์์ต๋๋ค. ๋ฐฑ์๋ ๋ก์ง์ ๋ธ๋ก์ฒด์ธ์ ์์ง๋ง, ์ด๋ฌํ ๊ฐ๋ ฅํ ๊ณ์ฝ๊ณผ ์ํธ์์ฉํ๋ ์ฌ์ฉ์ ๊ฒฝํ์ ํ๋ฐํธ์๋์ ์ํด ๋ง๋ค์ด์ง๋๋ค. ์ด ๋ธ๋ก๊ทธ ๊ฒ์๋ฌผ์ ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ ํตํฉ์ ๋ณต์กํ ์ธ๊ณ๋ฅผ ์ฌ์ธต์ ์ผ๋ก ๋ค๋ฃจ๋ฉฐ, ๊ฐ๋ฐ์๊ฐ ์ธ๊ธฐ ์๋ ํ๋ฐํธ์๋ ํ๋ ์์ํฌ๋ก ๊ตฌ์ถ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ Solidity ์ค๋งํธ ๊ณ์ฝ์ ๊ฒฌ๊ณ ํ ๋ก์ง ์ฌ์ด์ ๊ฐ๊ทน์ ํจ๊ณผ์ ์ผ๋ก ์ฐ๊ฒฐํ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์ด ๋ชจ๋ ๊ฒ์ ๋ค์ํ ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํด ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ์ด์ ์ ๋ง์ถฅ๋๋ค.
ํต์ฌ ๊ตฌ์ฑ ์์ ์ดํด: Solidity ๋ฐ Web3
ํตํฉ์ ๋ฐ์ด๋ค๊ธฐ ์ ์, ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์ฑ ์์๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
Solidity: ์ค๋งํธ ๊ณ์ฝ์ ์ธ์ด
Solidity๋ ์ด๋๋ฆฌ์ ๋ฐ EVM ํธํ ์ฒด์ธ๊ณผ ๊ฐ์ ๋ค์ํ ๋ธ๋ก์ฒด์ธ ํ๋ซํผ์์ ์ค๋งํธ ๊ณ์ฝ์ ์์ฑํ๊ธฐ ์ํด ํน๋ณํ ์ค๊ณ๋ ๊ณ ์์ค ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋๋ค. ๊ทธ ๊ตฌ๋ฌธ์ JavaScript, Python, C++์ ์ ์ฌํ์ฌ ๋ธ๋ก์ฒด์ธ์ผ๋ก ์ ํํ๋ ๊ฐ๋ฐ์๋ค์ด ๋น๊ต์ ์ฝ๊ฒ ์ ๊ทผํ ์ ์์ต๋๋ค. Solidity ์ฝ๋๋ ๋ฐ์ดํธ์ฝ๋๋ก ์ปดํ์ผ๋ ๋ค์ ๋ธ๋ก์ฒด์ธ์ ๊ฐ์ ๋จธ์ ์ ๋ฐฐํฌ๋๊ณ ์คํ๋ฉ๋๋ค.
Solidity์ ์ฃผ์ ํน์ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ์ ์ ํ์ ์ง์ : ๋ณ์๋ ๊ณ ์ ๋ ํ์ ์ ๊ฐ์ง๋ฉฐ ์ปดํ์ผ ์ ์ค๋ฅ ๊ฐ์ง๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
- ๊ณ์ฝ ์งํฅ: ์ฝ๋๋ ๊ณ์ฝ์ผ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ด๋ ๋ฐฐํฌ์ ๊ธฐ๋ณธ ๋จ์์ ๋๋ค.
- ์ด๋ฒคํธ ๋ฐฉ์ถ: ๊ณ์ฝ์ ์ํ ๋ณ๊ฒฝ์ ๋ํด ์คํ์ฒด์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ฆฌ๊ธฐ ์ํด ์ด๋ฒคํธ๋ฅผ ๋ฐฉ์ถํ ์ ์์ต๋๋ค.
- ์์: ์์์ ํตํด ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ง์ํฉ๋๋ค.
- ์์ ์ ํจ์: ํจ์์ ๋ํ ์คํ ์ ํ ๊ฒ์ฌ๋ฅผ ํ์ฉํฉ๋๋ค.
๊ฐ๋จํ Solidity ๊ณ์ฝ ์์ (๊ฐ๋ตํ):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 public storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
Web3: ๋ธ๋ก์ฒด์ธ์ผ๋ก์ ๋ค๋ฆฌ
Web3๋ ๋ธ๋ก์ฒด์ธ ๊ธฐ์ ๊ณผ P2P ๋คํธ์ํฌ๋ฅผ ํน์ง์ผ๋ก ํ๋ ์ ํฅ ๋ถ์ฐํ ์ธํฐ๋ท์ ์๋ฏธํฉ๋๋ค. ํ๋ฐํธ์๋ ๊ฐ๋ฐ์ ๋งฅ๋ฝ์์, Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ด๋๋ฆฌ์ ๋ธ๋ก์ฒด์ธ๊ณผ ํต์ ํ ์ ์๋๋ก ํ๋ ํ์ ๋๊ตฌ์ ๋๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๋ธ๋ก์ฒด์ธ ๋ ธ๋์ ์ง์ ์ํธ์์ฉํ๋ ๋ณต์ก์ฑ์ ์ถ์ํํ๊ณ ๋ค์๊ณผ ๊ฐ์ ํธ๋ฆฌํ ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค:
- ๋ธ๋ก์ฒด์ธ ์ฐ๊ฒฐ (HTTP ๋๋ WebSockets๋ฅผ ํตํด).
- ๊ณ์ ์ ๋ณด ์ ๊ทผ.
- ํธ๋์ญ์ ์ ์ก.
- ์ค๋งํธ ๊ณ์ฝ ํจ์ ํธ์ถ.
- ๋ธ๋ก์ฒด์ธ ์ด๋ฒคํธ ์์ .
๊ฐ์ฅ ์ ๋ช ํ ๋ ๊ฐ์ง Web3 JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- web3.js: ์ด๋๋ฆฌ์ ๋ธ๋ก์ฒด์ธ๊ณผ ์ํธ์์ฉํ๊ธฐ ์ํ ๊ด๋ฒ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ํฌ๊ด์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ์ค๋ซ๋์ Web3 ๊ฐ๋ฐ์ ์ด์์ด ๋์ด์์ต๋๋ค.
- ethers.js: ์ฌ์ฉ ํธ์์ฑ, ๋ณด์ ๋ฐ ์ฑ๋ฅ์ ์ค์ ์ ๋ ๋ณด๋ค ํ๋์ ์ด๊ณ ๊ฐ๋ฒผ์ฐ๋ฉฐ ์ข ์ข ์ ํธ๋๋ ๋์์ ๋๋ค. ๋ ๋ชจ๋ํ๋ ๋์์ธ์ ์ ๊ณตํ๋ฉฐ ๋ง์ ์์ ์์ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ๋ฐ์ ์นํ์ ์ด๋ผ๊ณ ์ฌ๊ฒจ์ง๋๋ค.
ํ๋ฐํธ์๋-๋ฐฑ์๋ ์ฐ๊ฒฐ: ์๋ ๋ฐฉ์
ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ ํตํฉ์ ๋ง๋ฒ์ ํ๋ฐํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ธ๋ก์ฒด์ธ์์ ์์ ์ ํธ๋ฆฌ๊ฑฐํ๊ณ ๊ทธ ์ํ๋ฅผ ์ฌ์ฉ์์๊ฒ ํ์ํ ์ ์๋ ๋ฅ๋ ฅ์ ์์ต๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ๋ค์ ํ๋ฆ์ ํฌํจํฉ๋๋ค:
- ์ฌ์ฉ์ ์ํธ์์ฉ: ์ฌ์ฉ์๋ ํ๋ฐํธ์๋ UI์ ์ํธ์์ฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ํธํํ๋ฅผ ๋ณด๋ด๊ฑฐ๋ ์ค๋งํธ ๊ณ์ฝ์ ๊ธฐ๋ก์ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
- Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํธ์ถ: ํ๋ฐํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ(์: ethers.js)๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ฒฐ๋ ์ํธํํ ์ง๊ฐ(์: MetaMask)์ ํตํด ์ฌ์ฉ์์๊ฒ ์์ ์ ํ์ธํ๋๋ก ์์ฒญํฉ๋๋ค.
- ํธ๋์ญ์ ์์ฑ: Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋์ ์ค๋งํธ ๊ณ์ฝ ์ฃผ์, ํธ์ถํ ํจ์, ๋ชจ๋ ์ ๋ ฅ ๋งค๊ฐ๋ณ์์ ๊ฐ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ํธ๋์ญ์ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- ์ง๊ฐ ์๋ช : ์ฌ์ฉ์์ ์ํธํํ ์ง๊ฐ์ ๊ฐ์ธ ํค๋ฅผ ์ฌ์ฉํ์ฌ ์ด ํธ๋์ญ์ ์ ์๋ช ํ์ฌ ์์ ์ ์น์ธํฉ๋๋ค.
- ํธ๋์ญ์ ๋ธ๋ก๋์บ์คํธ: ์๋ช ๋ ํธ๋์ญ์ ์ ์ด๋๋ฆฌ์ ๋คํธ์ํฌ(๋๋ ๋ค๋ฅธ ํธํ๋๋ ๋ธ๋ก์ฒด์ธ)๋ก ๋ธ๋ก๋์บ์คํธ๋ฉ๋๋ค.
- ๋ธ๋ก์ฒด์ธ ์คํ: ๋คํธ์ํฌ์ ๋ ธ๋๊ฐ ํธ๋์ญ์ ์ ์์ ํ์ฌ ์ ํจ์ฑ์ ๊ฒ์ฌํ๊ณ ์ค๋งํธ ๊ณ์ฝ ๋ด์์ ํด๋น ํจ์๋ฅผ ์คํํฉ๋๋ค.
- ์ํ ์ ๋ฐ์ดํธ: ์ค๋งํธ ๊ณ์ฝ ์คํ์ด ์ํ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ(์: ๋ณ์ ๋ณ๊ฒฝ), ์ด ์ ๋ฐ์ดํธ๋ ๋ธ๋ก์ฒด์ธ์ ๊ธฐ๋ก๋ฉ๋๋ค.
- ํ๋ฐํธ์๋ ํผ๋๋ฐฑ: ํ๋ฐํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํธ๋์ญ์ ์ํ๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ ์ค๋งํธ ๊ณ์ฝ์ด ๋ฐฉ์ถํ๋ ์ด๋ฒคํธ๋ฅผ ์์ ํ์ฌ ์ฌ์ฉ์์๊ฒ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค(์: "ํธ๋์ญ์ ์ฑ๊ณต!" ๋๋ ์ ๋ฐ์ดํธ๋ ๋ฐ์ดํฐ ํ์).
ํ๋ฐํธ์๋ ํ๋ ์์ํฌ ๋ฐ Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ํ
ํ๋ฐํธ์๋ ํ๋ ์์ํฌ ๋ฐ Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ํ์ ๊ฐ๋ฐ ๊ฒฝํ๊ณผ ๊ฒฐ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํคํ ์ฒ์ ํฐ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ๋ชจ๋ ์ต์ JavaScript ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง, ์ผ๋ถ๋ Web3 ๊ณต๊ฐ์์ ์ํ๊ณ ๋ฐ ์ปค๋ฎค๋ํฐ ์ง์์ผ๋ก ์ธํด ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฑํ๋ฉ๋๋ค.
์ธ๊ธฐ ์๋ ํ๋ฐํธ์๋ ํ๋ ์์ํฌ:
- React: ์ฌ์ฉ์ ์ธํฐํ์ด์ค ๊ตฌ์ถ์ ์ํ ์ ์ธํ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ์ปดํฌ๋ํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ์ ๋ฐฉ๋ํ ์ํ๊ณ๋ก ์ ์๋ ค์ ธ ์์ต๋๋ค. React๋ dApp์ ์ํ ์ผ๋ฐ์ ์ธ ์ ํ์ ๋๋ค.
- Vue.js: ๋ํ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ์ด๋ฉฐ ์ฌ์ฉ ํธ์์ฑ๊ณผ ์๋งํ ํ์ต ๊ณก์ ์ผ๋ก ์นญ์ฐฌ๋ฐ๋ ์ง๋ณด์ ์ธ JavaScript ํ๋ ์์ํฌ์ ๋๋ค.
- Angular: ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ถ์ ์ํ ํฌ๊ด์ ์ธ TypeScript ๊ธฐ๋ฐ ํ๋ ์์ํฌ์ ๋๋ค.
- Svelte: ์์ ์ ๋ธ๋ผ์ฐ์ ์์ ๋น๋ ๋จ๊ณ๋ก ์ ํํ์ฌ ๊ณ ์ฑ๋ฅ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๋ ์ปดํ์ผ๋ฌ์ ๋๋ค.
Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ณ ๋ ค ์ฌํญ:
- ethers.js: ํ๋์ ์ธ ๋์์ธ, ํฅ์๋ ๋ณด์ ๊ธฐ๋ฅ ๋ฐ ํฌ๊ด์ ์ธ ๋ฌธ์ ๋๋ถ์ ์ผ๋ฐ์ ์ผ๋ก ์๋ก์ด ํ๋ก์ ํธ์ ๊ถ์ฅ๋ฉ๋๋ค. ์ง๊ฐ ๊ด๋ฆฌ, ๊ณ์ฝ ์ํธ์์ฉ ๋ฐ ๊ณต๊ธ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ๊ฐ๋ ฅํ ์ ํธ๋ฆฌํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- web3.js: ํนํ ๋ ๊ฑฐ์ ํ๋ก์ ํธ์์ ์ฌ์ ํ ๋๋ฆฌ ์ฌ์ฉ๋ฉ๋๋ค. ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด์ง๋ง ํน์ ์์ ์์๋ ethers.js๋ณด๋ค ๋ ์ฅํฉํ๊ณ ์ง๊ด์ ์ด์ง ์์ ์ ์์ต๋๋ค.
ํตํฉ์ ์์ฐํ๊ธฐ ์ํด, ์ฐ๋ฆฌ๋ ์ฃผ๋ก React์ ethers.js๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๋๋ค. ์ด๋ ํ๋ dApp ๊ฐ๋ฐ์ ์ํ ์ผ๋ฐ์ ์ด๊ณ ํจ๊ณผ์ ์ธ ์คํ์ ๋ํํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋จ๊ณ๋ณ ํตํฉ ๊ฐ์ด๋ (React ๋ฐ ethers.js ์ฌ์ฉ)
ํ๋ฐํธ์๋๋ฅผ Solidity ์ค๋งํธ ๊ณ์ฝ๊ณผ ํตํฉํ๋ ์ค์ฉ์ ์ธ ์์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ฌ๊ธฐ์๋ ๊ฐ๋จํ SimpleStorage ๊ณ์ฝ(์์์ ๋ณด์ฌ์ค ๊ฒ๊ณผ ๊ฐ์ด)์ด ์ปดํ์ผ๋์ด ํ
์คํธ๋ท ๋๋ ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์ ๋ฐฐํฌ๋์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ ์ ์กฐ๊ฑด:
- Node.js ๋ฐ npm/yarn: ์ปดํจํฐ์ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
- React ํ๋ก์ ํธ: Create React App ๋๋ ์ ์ฌํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๋์ด ์์ด์ผ ํฉ๋๋ค.
- ์ค๋งํธ ๊ณ์ฝ: ๋ฐฐํฌ๋์๊ณ ํด๋น ABI (Application Binary Interface) ๋ฐ ์ฃผ์๋ฅผ ์๊ณ ์์ด์ผ ํฉ๋๋ค.
- ์ํธํํ ์ง๊ฐ: MetaMask์ ๊ฐ์ ์ง๊ฐ์ด ํ ์คํธ๋ท ๊ณ์ ์ผ๋ก ์ค์น ๋ฐ ๊ตฌ์ฑ๋์ด ์์ด์ผ ํฉ๋๋ค.
1. ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น:
React ํ๋ก์ ํธ์ ๋ฃจํธ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋ํ์ฌ ethers.js๋ฅผ ์ค์นํฉ๋๋ค:
npm install ethers
# or
yarn add ethers
2. ์ค๋งํธ ๊ณ์ฝ ์ธ๋ถ ์ ๋ณด ์ป๊ธฐ:
๋ฐฐํฌ๋ ์ค๋งํธ ๊ณ์ฝ์์ ๋ ๊ฐ์ง ์ค์ํ ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค:
- ๊ณ์ฝ ์ฃผ์ (Contract Address): ๋ธ๋ก์ฒด์ธ์์ ๊ณ์ฝ์ ๊ณ ์ ์๋ณ์์ ๋๋ค.
- ๊ณ์ฝ ABI (Application Binary Interface): ๊ณ์ฝ์ ํจ์, ์ด๋ฒคํธ ๋ฐ ์ํ ๋ณ์๋ฅผ ์ค๋ช ํ๋ JSON ํ์ผ๋ก, ํ๋ฐํธ์๋๊ฐ ๊ณ์ฝ๊ณผ ์ํธ์์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ ์ ์๋๋ก ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก Hardhat ๋๋ Truffle๊ณผ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ Solidity ๊ณ์ฝ์ ์ปดํ์ผํ๋ฉด ABI ๋ฐ ๋ฐ์ดํธ์ฝ๋๊ฐ ํฌํจ๋ ์ํฐํฉํธ ํ์ผ์ ์ป๊ฒ ๋ฉ๋๋ค.
3. Web3 Provider ์ค์ :
ํ๋ฐํธ์๋ ์ฝ๋์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ๋ธ๋ก์ฒด์ธ์ ๋ํ ์ฐ๊ฒฐ์ ์ค์ ํ๋ ๊ฒ์ ๋๋ค. ์ด๋ ํ๋ก๋ฐ์ด๋(provider)๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฉ๋๋ค. ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์๋ MetaMask์ ๊ฐ์ ์ง๊ฐ์์ ์ฃผ์ ๋ Web3 ํ๋ก๋ฐ์ด๋๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค.
import { ethers } from 'ethers';
import React, { useState, useEffect } from 'react';
// --- Contract Details ---
const contractAddress = "YOUR_CONTRACT_ADDRESS"; // Replace with your contract's address
const contractABI = [ /* Your contract's ABI as a JSON array */ ];
function App() {
const [account, setAccount] = useState(null);
const [storedValue, setStoredValue] = useState(0);
const [inputValue, setInputValue] = useState('');
const [signer, setSigner] = useState(null);
const [contract, setContract] = useState(null);
useEffect(() => {
const loadBlockchainData = async () => {
if (window.ethereum) {
const provider = new ethers.providers.Web3Provider(window.ethereum);
setSigner(provider.getSigner());
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
setAccount(accounts[0]);
const contractInstance = new ethers.Contract(contractAddress, contractABI, provider);
setContract(contractInstance);
const currentValue = await contractInstance.storedData();
setStoredValue(currentValue.toString());
} else {
alert('MetaMask or another Ethereum-compatible wallet is required!');
}
};
loadBlockchainData();
// Listen for account changes
window.ethereum.on('accountsChanged', (accounts) => {
if (accounts.length > 0) {
setAccount(accounts[0]);
} else {
setAccount(null);
}
});
}, []);
// ... rest of the component
}
export default App;
์ค๋ช :
ethers๋ฅผ ๊ฐ์ ธ์ต๋๋ค.contractAddress์contractABI๋ฅผ ์ํ ํ๋ ์ด์คํ๋๋ฅผ ์ ์ํฉ๋๋ค.useStateํ ์ ์ฐ๊ฒฐ๋ ๊ณ์ , ๊ณ์ฝ์์ ์ฝ์ ๊ฐ, ๊ฐ ์ค์ ์ ์ํ ์ ๋ ฅ, ์๋ช ์ ๊ฐ์ฒด ๋ฐ ๊ณ์ฝ ์ธ์คํด์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.useEffectํ ์ ์ปดํฌ๋ํธ ๋ง์ดํธ ์ ํ ๋ฒ ์คํ๋ฉ๋๋ค.window.ethereum์ Web3 ํ๋ก๋ฐ์ด๋(์: MetaMask)๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ์ง ํ์ธํฉ๋๋ค.new ethers.providers.Web3Provider(window.ethereum)์ ์ฌ์ฉ์ ์ง๊ฐ์ ์ฐ๊ฒฐ๋ ํ๋ก๋ฐ์ด๋ ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค.provider.getSigner()๋ ์ฐ๊ฒฐ๋ ์ฌ์ฉ์๋ฅผ ๋ํ๋ด๋ ํธ๋์ญ์ ์ ์๋ช ํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค.window.ethereum.request({ method: 'eth_requestAccounts' })๋ ์ฌ์ฉ์์๊ฒ ์ง๊ฐ ์ฐ๊ฒฐ์ ์์ฒญํฉ๋๋ค.new ethers.Contract(contractAddress, contractABI, provider)๋ ์ค๋งํธ ๊ณ์ฝ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ์ํธ์์ฉํ ์ ์๋๋ก ํฉ๋๋ค. ์ฒ์์๋provider๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ต๋๋ค.- ์ด๊ธฐ
storedData๋ฅผ ๊ฐ์ ธ์์ ํ์ํฉ๋๋ค. - ์ฌ์ฉ์๊ฐ ์ง๊ฐ์์ ๊ณ์ ์ ์ ํํ๋ฉด UI๋ฅผ ์
๋ฐ์ดํธํ๊ธฐ ์ํด
accountsChanged์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ค์ ํฉ๋๋ค.
4. ์ค๋งํธ ๊ณ์ฝ๊ณผ ์ํธ์์ฉ (๋ฐ์ดํฐ ์ฝ๊ธฐ):
์ค๋งํธ ๊ณ์ฝ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ฒ์ ์ฝ๊ธฐ ์ ์ฉ ์์ ์ด๋ฉฐ ๊ฐ์ค ๋น์ฉ์ด ๋ค์ง ์์ต๋๋ค. ํ๋ก๋ฐ์ด๋๋ก ์ป์ ๊ณ์ฝ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ฌ view ๋๋ pure ํจ์๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
// Inside the App component, after setting up the contract instance:
const refreshValue = async () => {
if (contract) {
const currentValue = await contract.storedData();
setStoredValue(currentValue.toString());
}
};
// In your JSX, you would have a button to call this:
//
5. ์ค๋งํธ ๊ณ์ฝ๊ณผ ์ํธ์์ฉ (๋ฐ์ดํฐ ์ฐ๊ธฐ):
์ค๋งํธ ๊ณ์ฝ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ ๊ฒ(์ํ๋ฅผ ์์ ํ๋ ํจ์ ํธ์ถ)์ ์๋ช ์(signer)๊ฐ ํ์ํ๋ฉฐ ๊ฐ์ค ์์๋ฃ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ฌ๊ธฐ์ ์ฌ์ฉ์์ ์ง๊ฐ์ ํธ๋์ญ์ ์ ์น์ธํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค.
// Inside the App component:
const handleInputChange = (event) => {
setInputValue(event.target.value);
};
const updateStoredValue = async () => {
if (contract && signer && inputValue) {
try {
// Create a contract instance with the signer to send transactions
const contractWithSigner = contract.connect(signer);
const tx = await contractWithSigner.set(ethers.utils.parseUnits(inputValue, "ether")); // Assuming 'set' expects uint256
// Wait for the transaction to be mined
await tx.wait();
setInputValue(''); // Clear input after successful update
refreshValue(); // Refresh the displayed value
alert("Value updated successfully!");
} catch (error) {
console.error("Error updating value:", error);
alert("Failed to update value. Check console for details.");
}
} else {
alert("Please enter a value and ensure your wallet is connected.");
}
};
// In your JSX:
//
//
์ค๋ช :
inputValue์handleInputChange๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ๋ ฅ์ ์บก์ฒํฉ๋๋ค.- ๊ฒฐ์ ์ ์ผ๋ก,
contract.connect(signer)๋ฅผ ์ฌ์ฉํ์ฌ ์๋ก์ด ๊ณ์ฝ ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค. ์ด๋signer์ ํธ๋์ญ์ ์ ์ก ๊ธฐ๋ฅ์ ์ฐ๋ฆฌ ๊ณ์ฝ ์ํธ์์ฉ์ ๋ฐ์ธ๋ฉํฉ๋๋ค. ethers.utils.parseUnits(inputValue, "ether")๋ ์ ๋ ฅ ๋ฌธ์์ด์ Solidity์uint256์ ์ ํฉํ BigNumber ํ์์ผ๋ก ๋ณํํฉ๋๋ค(๊ณ์ฝ์ ์์ ์ ๋ ฅ์ ๋ฐ๋ผ ๋จ์ ์กฐ์ ํ์).await tx.wait()๋ ํธ๋์ญ์ ์ด ๋ธ๋ก์ฒด์ธ์์ ํ์ธ๋ ๋๊น์ง ์คํ์ ์ผ์ ์ค์งํฉ๋๋ค.- ํธ๋์ญ์ ์ด ์คํจํ ๊ฒฝ์ฐ ์ฌ์ฉ์์๊ฒ ์๋ฆฌ๊ธฐ ์ํด ์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ํ์์ ์ ๋๋ค.
6. ์ง๊ฐ ์ฐ๊ฒฐ ๋ฐ ์ฐ๊ฒฐ ํด์ ์ฒ๋ฆฌ:
๊ฒฌ๊ณ ํ dApp์ ์ฌ์ฉ์๊ฐ ์ง๊ฐ์ ์ฐ๊ฒฐํ๊ณ ์ฐ๊ฒฐ ํด์ ํ๋ ๊ฒ์ ์ํํ๊ฒ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
// In your App component's JSX:
const connectWallet = async () => {
if (window.ethereum) {
try {
const provider = new ethers.providers.Web3Provider(window.ethereum);
await window.ethereum.request({ method: 'eth_requestAccounts' });
setSigner(provider.getSigner());
const accounts = await provider.listAccounts();
setAccount(accounts[0]);
// Re-initialize contract with signer if needed for write operations immediately
const contractInstance = new ethers.Contract(contractAddress, contractABI, provider);
setContract(contractInstance.connect(provider.getSigner())); // Connect to the contract with the signer
alert("Wallet connected!");
} catch (error) {
console.error("Error connecting wallet:", error);
alert("Failed to connect wallet.");
}
} else {
alert("MetaMask or another Ethereum-compatible wallet is required!");
}
};
const disconnectWallet = () => {
setAccount(null);
setSigner(null);
setContract(null);
// Optionally, you might want to trigger a full page reload or clear state more aggressively
alert("Wallet disconnected.");
};
// In your JSX:
// {!account ? (
//
// ) : (
//
// Connected Account: {account}
//
//
// )}
7. ์ค๋งํธ ๊ณ์ฝ ์ด๋ฒคํธ ์์ :
์ค๋งํธ ๊ณ์ฝ์ ์ค์ํ ์ํ ๋ณ๊ฒฝ์ ๋ํด ํ๋ฐํธ์๋์ ์๋ฆฌ๊ธฐ ์ํด ์ด๋ฒคํธ๋ฅผ ๋ฐฉ์ถํ ์ ์์ต๋๋ค. ์ด๋ ์ง์์ ์ธ ํด๋ง(polling)๋ณด๋ค UI๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค.
// Inside the useEffect hook, after setting up the contract instance:
if (contract) {
// Example: Listening for a hypothetical 'ValueChanged' event from SimpleStorage
contract.on("ValueChanged", (newValue, event) => {
console.log("ValueChanged event received:", newValue.toString());
setStoredValue(newValue.toString());
});
// Clean up the event listener when the component unmounts
return () => {
if (contract) {
contract.removeAllListeners(); // Or specify the event name
}
};
}
์ฐธ๊ณ : ์ด๊ฒ์ด ์๋ํ๋ ค๋ฉด SimpleStorage ๊ณ์ฝ์ด ์๋ฅผ ๋ค์ด set ํจ์์์ ์ด๋ฒคํธ๋ฅผ ๋ฐฉ์ถํด์ผ ํฉ๋๋ค:
// Inside the SimpleStorage contract:
// ...
event ValueChanged(uint256 newValue);
function set(uint256 x) public {
storedData = x;
emit ValueChanged(x); // Emit the event
}
// ...
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ ๊ณ ๊ธ ๊ณ ๋ ค ์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํ dApp์ ๊ตฌ์ถํ๋ ค๋ฉด ๊ธฐ๋ณธ์ ์ธ ํตํฉ์ ๋์ด ๋ค์ํ ์์๋ฅผ ์ ์คํ๊ฒ ๊ณ ๋ คํด์ผ ํฉ๋๋ค:
1. ์ฌ์ฉ์ ๊ฒฝํ ๋ฐ ์ง๊ฐ ์ถ์ํ:
- ์จ๋ณด๋ฉ: ๋ง์ ์ฌ์ฉ์๊ฐ ์ํธํํ ์ง๊ฐ์ ์ต์ํ์ง ์์ต๋๋ค. MetaMask, Trust Wallet ๋๋ Coinbase Wallet๊ณผ ๊ฐ์ ์ง๊ฐ์ ์ค์ ํ๊ณ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ํํ ์ง์นจ๊ณผ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํ์ธ์.
- ์ง๊ฐ ์ฐ๊ฒฐ(Wallet Connect): WalletConnect์ ํตํฉํ์ฌ ๋ ๋์ ๋ฒ์์ ๋ชจ๋ฐ์ผ ๋ฐ ๋ฐ์คํฌํฑ ์ง๊ฐ์ ์ง์ํ๊ณ , MetaMask๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ฌ์ฉ์๋ฅผ ์ํ ์ ๊ทผ์ฑ์ ํฅ์์ํค์ธ์.
@web3-react/walletconnect-connector๋๋rainbow-kit์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด๋ฅผ ๊ฐ์ํํ ์ ์์ต๋๋ค. - ๋คํธ์ํฌ ์ธ์: ์ฌ์ฉ์๊ฐ ์ฌ๋ฐ๋ฅธ ๋ธ๋ก์ฒด์ธ ๋คํธ์ํฌ(์: ์ด๋๋ฆฌ์ ๋ฉ์ธ๋ท, ํด๋ฆฌ๊ณค, ๋ฐ์ด๋ธ์ค ์ค๋งํธ ์ฒด์ธ)์ ์๋์ง ํ์ธํ์ธ์. ๋คํธ์ํฌ ์ ๋ณด๋ฅผ ํ์ํ๊ณ ํ์ํ ๊ฒฝ์ฐ ์ ํํ๋๋ก ์๋ดํ์ธ์.
- ๊ฐ์ค ์๊ธ: ๊ฐ์ค ์๊ธ์ ๋ณ๋์ฑ์ด ํฌ๊ณ ๋คํธ์ํฌ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ฌ์ฉ์์๊ฒ ์ ์ฌ์ ์ธ ๊ฐ์ค ๋น์ฉ ๋ฐ ํธ๋์ญ์ ํ์ธ ์๊ฐ์ ๋ํด ์๋ ค์ฃผ์ธ์. ๊ฐ์ค ์ง๋ถ์ ์ถ์ํํ๊ธฐ ์ํด ๋ฉํ ํธ๋์ญ์ ๊ณผ ๊ฐ์ ์ ๋ต์ ๊ณ ๋ คํ ์ ์์ต๋๋ค.
2. ๊ตญ์ ํ (i18n) ๋ฐ ํ์งํ (l10n):
- ์ธ์ด ์ง์: UI ์์, ์ค๋ฅ ๋ฉ์์ง ๋ฐ ์ง์นจ์ ์ฌ๋ฌ ์ธ์ด๋ก ๋ฒ์ญํ์ธ์.
react-intl๋๋i18next์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋งค์ฐ ์ ์ฉํ ์ ์์ต๋๋ค. - ๋ฌธํ์ ์ฐจ์ด: ๋์์ธ, ์์ ๊ตฌ์ฑํ ๋ฐ ์ปค๋ฎค๋์ผ์ด์ ์คํ์ผ์ ๋ฌธํ์ ์ฐจ์ด์ ์ ์ํ์ธ์. ํ ๋ฌธํ๊ถ์์ ํ์ฉ๋๊ฑฐ๋ ๋งค๋ ฅ์ ์ธ ๊ฒ์ด ๋ค๋ฅธ ๋ฌธํ๊ถ์์๋ ๊ทธ๋ ์ง ์์ ์ ์์ต๋๋ค.
- ๋ ์ง ๋ฐ ์๊ฐ ํ์: ๋ ์ง ๋ฐ ์๊ฐ์ ์ฌ์ฉ์ ์นํ์ ์ธ ํ์งํ๋ ํ์์ผ๋ก ํ์ํ์ธ์.
- ์ซ์ ๋ฐ ํตํ ํ์ ์ง์ : ์ซ์ ๋ฐ ํ์๋๋ ์ํธํํ ๊ธ์ก์ ํ์ง ๊ด์ต์ ๋ฐ๋ผ ํ์ํํ์ธ์. ์ค๋งํธ ๊ณ์ฝ์ ์ ํํ ์ซ์ ๊ฐ์ผ๋ก ์๋ํ์ง๋ง, ํ๋ฐํธ์๋ ํ์๋ ํ์งํ๋ ์ ์์ต๋๋ค.
3. ์ฑ๋ฅ ๋ฐ ํ์ฅ์ฑ:
- RPC ์๋ํฌ์ธํธ: ๋ชจ๋ ์ํธ์์ฉ์ MetaMask์๋ง ์์กดํ๋ ๊ฒ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๋๋ฆด ์ ์์ต๋๋ค. ๋ ๋น ๋ฅธ ์ฝ๊ธฐ ์์ ์ ์ํด ์ ์ฉ RPC ํ๋ก๋ฐ์ด๋(์: Infura, Alchemy)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
- ์บ์ฑ: ์์ฃผ ์ ๊ทผํ๋ ๋ฏผ๊ฐํ์ง ์์ ๋ฐ์ดํฐ์ ๋ํด ํด๋ผ์ด์ธํธ ์ธก ์บ์ฑ์ ๊ตฌํํ์ฌ ๋ธ๋ก์ฒด์ธ ์ฟผ๋ฆฌ๋ฅผ ์ค์ด์ธ์.
- ๋๊ด์ ์ ๋ฐ์ดํธ: ๋ธ๋ก์ฒด์ธ ํธ๋์ญ์ ์ด ํ์ธ๋๊ธฐ ์ ์๋ ์์ ์ ์์ํ์๋ง์ ์ฌ์ฉ์์๊ฒ ์ฆ๊ฐ์ ์ธ ์๊ฐ์ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ธ์.
- ๋ ์ด์ด 2 ์๋ฃจ์ : ๋์ ์ฒ๋ฆฌ๋๊ณผ ๋ฎ์ ํธ๋์ญ์ ์์๋ฃ๊ฐ ํ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ Optimism, Arbitrum ๋๋ zkSync์ ๊ฐ์ ๋ ์ด์ด 2 ์ค์ผ์ผ๋ง ์๋ฃจ์ ๊ณผ ํตํฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ธ์.
4. ๋ณด์ ๋ชจ๋ฒ ์ฌ๋ก:
- ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ: ํญ์ ํ๋ฐํธ์๋์์ ์ฌ์ฉ์ ์ ๋ ฅ์ ์ ํจ์ฑ ๊ฒ์ฌํ์ง๋ง, ํ๋ฐํธ์๋ ์ ํจ์ฑ ๊ฒ์ฌ์๋ง ์์กดํ์ง ๋ง์ญ์์ค. ์ค๋งํธ ๊ณ์ฝ ์์ฒด๋ ์ ์์ ์ธ ์ ๋ ฅ์ ๋ฐฉ์งํ๊ธฐ ์ํ ๊ฒฌ๊ณ ํ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.
- ABI ๋ณด์: ์ค๋งํธ ๊ณ์ฝ์ ๋ํด ์ ํํ๊ณ ๊ฒ์ฆ๋ ABI๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ์ธํ์ธ์. ์๋ชป๋ ABI๋ ์๋์น ์์ ํจ์ ํธ์ถ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- HTTPS: ์ค๊ฐ์ ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด ํญ์ HTTPS๋ฅผ ํตํด ํ๋ฐํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋น์คํ์ธ์.
- ์ข ์์ฑ ๊ด๋ฆฌ: ๋ณด์ ์ทจ์ฝ์ ์ ํจ์นํ๊ธฐ ์ํด ํ๋ก์ ํธ ์ข ์์ฑ(Web3 ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌํจ)์ ์ต์ ์ํ๋ก ์ ์งํ์ธ์.
- ์ค๋งํธ ๊ณ์ฝ ๊ฐ์ฌ: ํ๋ก๋์ dApp์ ๊ฒฝ์ฐ ์ค๋งํธ ๊ณ์ฝ์ด ์ ๋ฌธ ๋ณด์ ๊ฐ์ฌ๋ฅผ ๋ฐ์๋์ง ํ์ธํ์ธ์.
- ๊ฐ์ธ ํค ๊ด๋ฆฌ: ์ฌ์ฉ์๋ ๊ฐ์ธ ํค๋ ์๋ ๋ฌธ๊ตฌ๋ฅผ ์ ๋ ๊ณต์ ํด์๋ ์ ๋๋ค๋ ์ ์ ๊ฐ์กฐํ์ธ์. ํ๋ฐํธ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ธ ํค๋ฅผ ์ง์ ์์ฒญํ๊ฑฐ๋ ์ฒ๋ฆฌํด์๋ ์ ๋ฉ๋๋ค.
5. ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์ฌ์ฉ์ ํผ๋๋ฐฑ:
- ๋ช ํํ ์ค๋ฅ ๋ฉ์์ง: ์ฌ์ฉ์์๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๋ดํ๋ ๊ตฌ์ฒด์ ์ด๊ณ ์คํ ๊ฐ๋ฅํ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ์ธ์(์: "์์ก ๋ถ์กฑ", "ํด๋ฆฌ๊ณค ๋คํธ์ํฌ๋ก ์ ํํด ์ฃผ์ธ์", "์ง๊ฐ์์ ํธ๋์ญ์ ๊ฑฐ๋ถ๋จ").
- ๋ก๋ฉ ์ํ: ํธ๋์ญ์ ์ด ๋ณด๋ฅ ์ค์ด๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ค์์ ๋ํ๋ด์ธ์.
- ํธ๋์ญ์ ์ถ์ : ์ฌ์ฉ์๊ฐ ๋ธ๋ก ํ์๊ธฐ(์: Etherscan)์์ ์งํ ์ค์ธ ํธ๋์ญ์ ์ ์ถ์ ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ธ์.
๋๊ตฌ ๋ฐ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ
๊ฐ์ํ๋ ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ๋ dApp์ ํจ์จ์ ์ผ๋ก ๊ตฌ์ถํ๊ณ ๋ฐฐํฌํ๋ ๋ฐ ์ค์ํฉ๋๋ค. ์ฃผ์ ๋๊ตฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- Hardhat / Truffle: ์ค๋งํธ ๊ณ์ฝ์ ์ปดํ์ผ, ๋ฐฐํฌ, ํ ์คํธ ๋ฐ ๋๋ฒ๊น ํ๊ธฐ ์ํ ๊ฐ๋ฐ ํ๊ฒฝ์ ๋๋ค. ๋ํ ํ๋ฐํธ์๋ ํตํฉ์ ํ์์ ์ธ ๊ณ์ฝ ์ํฐํฉํธ(ABI ํฌํจ)๋ฅผ ์์ฑํฉ๋๋ค.
- Ganache: ๋ก์ปฌ ํ ์คํธ ๋ฐ ๋๋ฒ๊น ์ ์คํํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ด๋๋ฆฌ์ ๊ฐ๋ฐ์ฉ ๊ฐ์ธ ๋ธ๋ก์ฒด์ธ์ ๋๋ค.
- Etherscan / Polygonscan / ๋ฑ: ๊ณ์ฝ ์ฝ๋๋ฅผ ํ์ธํ๊ณ ํธ๋์ญ์ ์ ์ถ์ ํ๋ฉฐ ๋ธ๋ก์ฒด์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฌํ๊ธฐ ์ํ ๋ธ๋ก ํ์๊ธฐ์ ๋๋ค.
- IPFS (InterPlanetary File System): ์ ์ ํ๋ฐํธ์๋ ์์ฐ์ ๋ถ์ฐํ ์ ์ฅ์ ์ํ ๊ฒ์ผ๋ก, ์ ์ฒด dApp์ ๊ฒ์ด์ ์ ํญํ๊ฒ ๋ง๋ญ๋๋ค.
- The Graph: ๋ธ๋ก์ฒด์ธ ๋ฐ์ดํฐ๋ฅผ ์ธ๋ฑ์ฑํ๊ณ ์ฟผ๋ฆฌํ๊ธฐ ์ํ ๋ถ์ฐํ ํ๋กํ ์ฝ๋ก, ๋ธ๋ก์ฒด์ธ์ ์ง์ ์ฟผ๋ฆฌํ๋ ๋์ ์ธ๋ฑ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ์ฌ dApp ํ๋ฐํธ์๋์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ: ๊ธ๋ก๋ฒ dApp ์์
Solidity ๋ฐ Web3 ํตํฉ์ผ๋ก ๊ตฌ์ถ๋ ์๋ง์ dApp์ด ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์๋น์ค๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค:
- ๋ถ์ฐํ ๊ธ์ต(DeFi) ํ๋ซํผ: Uniswap(๋ถ์ฐํ ๊ฑฐ๋์), Aave(๋์ถ ๋ฐ ์ฐจ์ฉ), Compound(๋์ถ ํ๋กํ ์ฝ)๋ ์ ์ธ๊ณ ์ฌ์ฉ์๊ฐ ์ค๊ฐ์ ์์ด ๊ธ์ต ์๋น์ค์ ์ ๊ทผํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ค์ ํ๋ฐํธ์๋๋ ๋ณต์กํ DeFi ์ค๋งํธ ๊ณ์ฝ๊ณผ ์ํํ๊ฒ ์ํธ์์ฉํฉ๋๋ค.
- ๋์ฒด ๋ถ๊ฐ๋ฅ ํ ํฐ(NFT) ๋ง์ผํ๋ ์ด์ค: OpenSea, Rarible, Foundation์ ์ ์ธ๊ณ ์์ ๊ฐ์ ์์ง๊ฐ๊ฐ ๊ณ ์ ํ ๋์งํธ ์์ฐ์ ๋ฐํ, ๊ตฌ๋งค ๋ฐ ํ๋งคํ ์ ์๋๋ก ํ๋ฉฐ, ํ๋ฐํธ์๋ UI๋ NFT ์ค๋งํธ ๊ณ์ฝ(ERC-721 ๋๋ ERC-1155 ๋ฑ)๊ณผ ์ง์ ์ํธ์์ฉํฉ๋๋ค.
- ๋ถ์ฐํ ์์จ ์กฐ์ง(DAO): Snapshot๊ณผ ๊ฐ์ ํ๋ซํผ์ ๊ธ๋ก๋ฒ ์ปค๋ฎค๋ํฐ๊ฐ ํ ํฐ ๋ณด์ ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์์ ํฌํํ ์ ์๋๋ก ํ๋ฉฐ, ํ๋ฐํธ์๋๋ ๊ฑฐ๋ฒ๋์ค ์ค๋งํธ ๊ณ์ฝ๊ณผ ์ํธ์์ฉํ์ฌ ์ ์ ์์ฑ ๋ฐ ํฌํ๋ฅผ ์ฉ์ดํ๊ฒ ํฉ๋๋ค.
- ํ๋ ์ด-ํฌ-์ธ(P2E) ๊ฒ์: Axie Infinity ๋ฐ ์ ์ฌํ ๋ธ๋ก์ฒด์ธ ๊ฒ์์ ๊ฒ์ ๋ด ์์ฐ์ NFT ๋ฐ ํ ํฐ์ ํ์ฉํ๋ฉฐ, ํ๋ฐํธ์๋ ๊ฒ์ ์ธํฐํ์ด์ค๋ ์ด๋ฌํ ์์ฐ ๊ฑฐ๋ ๋ฐ ๊ด๋ฆฌ๋ฅผ ์ํด ์ค๋งํธ ๊ณ์ฝ์ ์ฐ๊ฒฐ๋ฉ๋๋ค.
์ด๋ฌํ ์์๋ ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ ํตํฉ์ ํ๊ณผ ๋๋ฌ ๋ฒ์๋ฅผ ๊ฐ์กฐํ๋ฉฐ, ์ ์ธ๊ณ ์๋ฐฑ๋ง ๋ช ์ ์ฌ์ฉ์๋ฅผ ๋ถ์ฐํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฐ๊ฒฐํฉ๋๋ค.
๊ฒฐ๋ก : ๋ถ์ฐํ ๋ฏธ๋๋ฅผ ์ํ ์ญ๋ ๊ฐํ
ํ๋ฐํธ์๋ ์ค๋งํธ ๊ณ์ฝ ํตํฉ์ ์ฐจ์ธ๋ ๋ถ์ฐํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ์ค์ํ ๋ถ์ผ์ ๋๋ค. Solidity ์ค๋งํธ ๊ณ์ฝ๊ณผ Web3 JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ์ ์ํธ์์ฉ์ ๋ง์คํฐํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ๋ธ๋ก์ฒด์ธ ๊ธฐ์ ์ ์ด์ ์ ํ์ฉํ๋ ์ฌ์ฉ์ ์นํ์ ์ด๊ณ ์์ ํ๋ฉฐ ๊ฐ๋ ฅํ dApp์ ๋ง๋ค ์ ์์ต๋๋ค. ๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ์ํด์๋ ์ฌ์ฉ์ ๊ฒฝํ, ๊ตญ์ ํ, ์ฑ๋ฅ ๋ฐ ๋ณด์์ ๋ํ ์ธ์ฌํ ์ฃผ์๊ฐ ๊ฐ์ฅ ์ค์ํฉ๋๋ค. Web3 ์ํ๊ณ๊ฐ ๊ณ์ ์ฑ์ํจ์ ๋ฐ๋ผ ์ฌ์ฉ์ ์ธํฐํ์ด์ค์ ๋ธ๋ก์ฒด์ธ ๋ก์ง ์ฌ์ด์ ๊ฐ๊ทน์ ์ํํ๊ฒ ์ฐ๊ฒฐํ ์ ์๋ ์๋ จ๋ ํ๋ฐํธ์๋ ๊ฐ๋ฐ์์ ๋ํ ์์๋ ์ฆ๊ฐํ ๊ฒ์ด๋ฉฐ, ์ด๋ ๋ชจ๋ ์ฌ๋์ ์ํ ๋ณด๋ค ๋ถ์ฐ๋๊ณ ํฌ๋ช ํ๋ฉฐ ์ฌ์ฉ์ ์ค์ฌ์ ์ธ ๋์งํธ ๋ฏธ๋๋ฅผ ์ด ๊ฒ์ ๋๋ค.
๊ธ๋ก๋ฒ dApp ๊ฐ๋ฐ์ ์ํ ํต์ฌ ์์ฝ:
- ์ฌ์ฉ์ ์จ๋ณด๋ฉ ๋ฐ ์ง๊ฐ ํธํ์ฑ์ ์ต์ฐ์ ์ผ๋ก ํ์ธ์.
- ๋ ๋์ ๋๋ฌ ๋ฒ์๋ฅผ ์ํด ๊ฒฌ๊ณ ํ ๊ตญ์ ํ๋ฅผ ๊ตฌํํ์ธ์.
- ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ ์บ์ฑ์ ์ฌ์ฉํ์ฌ ์ฑ๋ฅ์ ์ต์ ํํ์ธ์.
- ํ๋ฐํธ์๋ ๋ฐ ์ค๋งํธ ๊ณ์ฝ ์ฝ๋ ๋ชจ๋์ ๋ํด ์๊ฒฉํ ๋ณด์ ๊ดํ์ ์ค์ํ์ธ์.
- ๋ช ํํ๊ณ ํ์งํ๋ ํผ๋๋ฐฑ ๋ฐ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ ๊ณตํ์ธ์.
ํ๋ฐํธ์๋ ๊ฒฝํ๊ณผ ์ค๋งํธ ๊ณ์ฝ์ ํ์ ํตํฉํ๋ ์ฌ์ ์ ํฅ๋ฏธ๋กญ๊ณ ๋ณด๋ ์๋ ์ผ์ ๋๋ค. ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๊ณ ์งํํ๋ ๋๊ตฌ๋ฅผ ์์ฉํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ ์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ์ํ ์ง์ ์ผ๋ก ๋ถ์ฐ๋๊ณ ์ ๊ทผ ๊ฐ๋ฅํ ์ธํฐ๋ท์ ๊ตฌ์ถํ๋ ๋ฐ ๊ธฐ์ฌํ ์ ์์ต๋๋ค.