๊ธฐ์กด์ ์ํธ ํํ์ ๋ํ ๊ด์ฌ์ผ๋ก ์ธํด ๋ธ๋ก ์ฒด์ธ์ ๋ํด ํ์ตํด์ผ๊ฒ ๋ค๊ณ ์๊ฐํด์๋๋ฐ, ๋ง์นจ ์ฃผ์ ๋ฅผ ์์ ๋กญ๊ฒ ์ ์ ํ๊ณ ๋์ ํ ์ ์๋ ๊ธฐํ๊ฐ ์๊ฒจ ํด๋น ์ฃผ์ ๋ฅผ ์ ์ ํ๊ฒ ๋์์ต๋๋ค.
๋ธ๋ก ์ฒด์ธ์ ๋ํ ์ดํด, ๊ตฌํ, ํ์ฅ ๋ฐ ์๋ฐ ํ๋ก๊ทธ๋๋ฐ ๋ฅ๋ ฅ ํฅ์
ํฌ๊ด์ ์ธ ํ๋ฆ์ผ๋ก ํ์ต โ ๊ตฌํ โ ํ์ฅ์ ํํ๋ก ์งํํฉ๋๋ค. ํ๋ฆฌ์ฝ์ค ๊ณผ์ ์ ํผ๋๋ฐฑ์ ๋ฐํ์ผ๋ก ์๋ฐ๋ฅผ ํตํด ๊ตฌํ ๋ฐ ํ์ฅ ํ ์์ ์ ๋๋ค.
๋ธ๋ก์ฒด์ธ์ ๋ํ ์ดํด๋๊ฐ ์๋ ์ํ์์ ์ธ๋ถ์ ์ธ ๊ณํ์ ์ก๋ ๊ฑด ํ๋ค๋ค๊ณ ํ๋จํ์ฌ, ํ๋์ ๋ชฉํ๋ฅผ ์ค์ ํ๊ณ ๋ชฉํ ๋ฌ์ฑ ์ ๋ค์ ๋ชฉํ๋ฅผ ์ธ์ฐ๊ณ ๋ค์ ์งํํ๋ ๋ฐฉ์์ผ๋ก ์ํ ํ๊ฒ ์ต๋๋ค.
์๋ฃ ์ถ์ฒ1 : bitcoin Devloper Guides
์๋ฃ ์ถ์ฒ2: https://kwjdnjs.tistory.com
ํ์ต ์ดํ ๋ธ๋ก์ฒด์ธ์ ๋ํ ์ดํด์, ์ด๋๋ฆฌ์์ ์ค๋งํธ ์ปจํธ๋ํธ์ ๊ฐ์ ๋ด์ฉ์์ ์ธ์ฌ์ดํธ๋ฅผ ์ป์ด ๋ค์๊ณผ ๊ฐ์ ์ฃผ์ ๋ฅผ ์ ์ ํ์์ต๋๋ค.
๋ธ๋ก์ฒด์ธ ๋คํธ์ํฌ ์์์ย 1:1 ํน์ n:n ๊ด๊ณ์์ ๊ณ์ฝ์ด ์ด๋ฃจ์ด์ง๋ค๊ณ ๊ฐ์ ํ์ ๋:
- ๊ณ์ฝ ๋ด์ฉ๊ณผ ๊ณ์ฝ ์ดํ ์ ๋ฐ์ ๊ธ์ก์ย ๋ด๋ถ์๋ค๋ผ๋ฆฌ๋ง ์ ์ ์์
- ๊ณ์ฝ ์ดํ ์ฌ๋ถ๋ย ๋ด๋ถ์๋ค์ ํฌํ๋ก ๊ฒฐ์
- ํฌํ๋ก ์น์ธ๋ ๊ฒฝ์ฐ ๊ณ์ฝ ๊ธ์ก์ ํด๋นํ๋ ํธ๋์ญ์ ์คํ
txid: ํธ๋์ญ์ IDtimestamp: ์์ฑ ์๊ฐ- ์ก๊ธ ๊ธ์ก
- ๊ณ์ฝ ๋ด์ฉ
- ์ก์ ์/์์ ์
- ํธ๋์ญ์ ๋ง๋ค ์๋ก์ด ๊ฐ์ธํค๋ฅผ ํตํด ์ง๊ฐ ์ฃผ์๋ฅผ ์์ฑํ๊ณ , ํด๋น output์ ํด๋นํ๋ ๋ด๋ถ์์๊ฒ ํธ๋์ญ์ ๋ฒํธ์, ๊ฐ์ธํค๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์
- ๊ฑฐ๋๋ฅผ ์ฌ๋ฌ ๋ฒ ์งํํด๋, ๊ฐ๊ฐ ๋ค๋ฅธ ์ง๊ฐ ์ฃผ์๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ๋นํธ ์ฝ์ธ ๊ตฌ์กฐ๋ณด๋ค ๊ฑฐ๋์ ํน์ ์ด ์ด๋ ต์ต๋๋ค.
- ๋ด๋ถ์ ๋ช ๋จ
- ํฌํ๋ฅผ ํตํด ํธ๋์ญ์ ์คํ ๊ฒฐ์
- ์น์ธ ์ ๋ด๋ถ์๋ค์๊ฒย Private Key ์ ๊ณต
- Private Key๋ก ๋น๊ณต๊ฐ ์ ๋ณด ๋ณตํธํ
- ์ธ๋ถ ๋ ธ๋๋ ์กฐํ ๋ถ๊ฐ๋ฅ
- ์ ์ฒด ๋คํธ์ํฌ์ Mempool์ ํธ๋์ญ์ ์ถ๊ฐ
- ๊ธฐ์กด ๋ธ๋ก์ฒด์ธ(๋นํธ์ฝ์ธ) ๋ฐฉ์์ผ๋ก ๋ธ๋ก ์์ฑ ๋ฐ ์ถ๊ฐ
์์ ๊ฐ์ด ๊ณต๊ฐ์ ๋น๊ณต๊ฐ ์ ๋ณด๋ฅผ ๋๋์ด, ๋น๊ณต๊ฐ ์ ๋ณด์ ๊ฒฝ์ฐ ํฌํ๋ฅผ ํตํด ํธ๋์ญ์ ์ด ์คํ๋ ๋ ๋ด๋ถ์๋ค์๊ฒ private key๋ฅผ ์ ๊ณตํ์ฌ ๋์ค์ ๋น๊ณต๊ฐ ๋ด์ฉ์ ์ ์ ์๊ฒ ํ๊ณ ์ธ๋ถ ๋ ธ๋๋ค์ ์กฐํ ๋ถ๊ฐ๋ฅํ๊ฒ ํ๋ค.
์ ์ฒด ๋คํธ์ํฌ์ mempool์ ํด๋น ํธ๋์ญ์ ์ ์ถ๊ฐํ๊ณ , ๊ธฐ์กด ๋ธ๋ก์ฒด์ธ ๋คํธ์ํฌ(๋นํธ์ฝ์ธ)๊ฐ ๋์ํ๋ ๋ฐฉ์์ผ๋ก ๋ธ๋ก์ ์์ฑํ๊ณ , ๋ธ๋ก์ ์ถ๊ฐํ๋ค.
๋ธ๋ก์ฒด์ธ ๋คํธ์ํฌ ์์์ย 1:1 ํน์ n:n ๊ด๊ณ์์ ๊ณ์ฝ์ด ์ด๋ฃจ์ด์ง๋ค๊ณ ๊ฐ์ ํ์ ๋:
- ๊ณ์ฝ ๋ด์ฉ๊ณผ ๊ณ์ฝ ์ดํ ์ ๋ฐ์ ๊ธ์ก์ย ๋ด๋ถ์๋ค๋ผ๋ฆฌ๋ง ์ ์ ์์
- ๊ณ์ฝ ์ดํ ์ฌ๋ถ๋ย ๋ด๋ถ์๋ค์ ํฌํ๋ก ๊ฒฐ์
- ํฌํ๋ก ์น์ธ๋ ๊ฒฝ์ฐ ๊ณ์ฝ ๊ธ์ก์ ํด๋นํ๋ ํธ๋์ญ์ ์คํ
classDiagram
direction BT
class AdminSetup {
- String ADMIN_SEED
- String ADMIN_STORAGE_PATH
}
class BalanceCommand
class Block {
- long timestamp
- byte[] version
- int txNum
- byte[] blockHash
- byte[] prevHash
- int size
- byte[] nonce
- byte[] merkleRoot
- List~Transaction~ transactions
}
class BlockCommand
class BlockHeader {
~ byte[] merkleRoot
~ byte[] bit
~ byte[] prevHash
~ byte[] nounce
}
class Blockchain {
- long GENESIS_REWARD
- List~Block~ chain
}
class BlockchainStorage {
- String META_CHAIN_HEIGHT
- RocksDB txDB
- RocksDB utxoDB
- RocksDB blocksDB
- String dbPath
- RocksDB metaDB
- String META_PRIVATE_KEY
- String META_BEST_BLOCK_HASH
- ObjectMapper objectMapper
}
class BytesUtil
class CLI {
- CommandContext context
- Scanner scanner
- Map~String, Command~ commands
}
class CLIIntegrationTest {
- CommandContext context1
- Node node2
- CommandContext context2
- String STORAGE_PATH_1
- String STORAGE_PATH_2
- Node node3
- PrintStream originalOut
- CommandContext context3
- Node node1
- ByteArrayOutputStream outContent
- String STORAGE_PATH_3
}
class Command {
<<Interface>>
}
class CommandContext {
- Node node
- Mempool mempool
- boolean running
}
class ConnectCommand
class ContractTransaction
class EncryptedContract {
- byte[] encryptedContent
- Map~String, byte[]~ encryptedKeys
}
class EncryptionUtil {
- String AES_ALGORITHM
- int AES_KEY_SIZE
- int GCM_NONCE_LENGTH
- int GCM_TAG_LENGTH
}
class ExitCommand
class GenesisBlock {
- String GENESIS_MINER
- long GENESIS_REWARD
- byte[] GENESIS_PREV_HASH
- String GENESIS_MESSAGE
- Block cachedGenesisBlock
- byte[] GENESIS_VERSION
- long GENESIS_TIMESTAMP
}
class Hash
class HelpCommand {
- Map~String, Command~ commands
}
class JsonMessage {
- MessageType type
- long timestamp
- ObjectMapper mapper
- String senderId
- String payloadJson
- long serialVersionUID
}
class KeyGenerator {
- BigInteger N
}
class ListCommand
class Main
class MainTest
class Mempool {
- TransactionValidator validator
- Map~String, Transaction~ transactions
- long MIN_FEE_RATE
- int MAX_POOL_SIZE
}
class MempoolCommand
class MerkleTree
class Message {
- MessageType type
- long serialVersionUID
- Object payload
- String senderId
- long timestamp
}
class MineCommand
class Miner {
- Node node
- int currentDifficulty
- byte[] BLOCK_VERSION
- long BLOCK_REWARD
- Mempool mempool
}
class Node {
- int p2pPort
- List~Block~ blockList
- byte[] privateKey
- BlockchainStorage storage
- UTXOSet utxoSet
- TransactionValidator validator
- P2PNetwork p2pNetwork
}
class Operation {
- byte[] messageHash
~ Stack~byte[]~ stack
- byte[] sigScriptValue
}
class P2PNetwork {
- P2PServer server
- List~Peer~ peers
- Node node
- ConcurrentHashMap~String, Peer~ peerMap
- String nodeId
}
class P2PServer {
- ServerSocket serverSocket
- boolean running
- int port
- P2PNetwork network
- ExecutorService executorService
}
class Peer {
- Socket socket
- ObjectInputStream in
- String address
- int port
- ObjectOutputStream out
- boolean connected
}
class PeersCommand
class ProofOfWork {
- int MAX_NONCE
- int DIFFICULTY_ADJUSTMENT_INTERVAL
- long TARGET_BLOCK_TIME
}
class Random
class Script
class SendCommand
class Signature
class Spender {
- byte[] txid
- int inputIndex
- long serialVersionUID
}
class StartCommand
class StatusCommand
class SyncCommand
class TXBlockInfo {
- long serialVersionUID
- int height
- byte[] blockHash
}
class Transaction {
- byte[] txid
- boolean deleted
- DateTimeFormatter TIME_FORMATTER
- long fee
- String time
- List~TransactionInput~ inputs
- List~String~ voteList
- List~TransactionOutput~ outputs
- String contract
- int size
- TXBlockInfo block
}
class TransactionInput {
~ int outputIdx
~ List~byte[]~ sigScript
~ byte[] pkScript
~ byte[] prevTXID
~ long value
- Boolean isCoinbase
~ String address
}
class TransactionOutput {
- Spender spender
- byte[] address
- boolean spent
- long value
- byte[] pkscript
}
class TransactionValidator {
- UTXOSet utxoSet
}
class UTXO {
- TransactionOutput output
- long blockHeight
- byte[] txid
- int outputIndex
}
class UTXOSet {
- Map~String, UTXO~ utxos
}
class ValidationResult {
- String message
- boolean valid
}
class Vote {
- String voterAddress
- long timestamp
- VoteType voteType
- byte[] signature
}
class VoteResult {
- long finalizedAt
- int totalParticipants
- boolean approved
- int rejections
- int abstentions
- int approvals
}
class VoteStatus {
- int voteCount
- boolean finalized
- int totalParticipants
- int approvals
- int rejections
- long votingDeadline
- int abstentions
}
class VotingContract {
- Map~String, Vote~ votes
- long votingDeadline
- boolean finalized
- EncryptedContract encryptedContract
- List~String~ participants
- VoteResult finalResult
- int requiredApprovals
}
class Wallet {
- Node node
}
class WalletManager {
- Node node
- Map~String, byte[]~ wallets
}
class build
class settings
BalanceCommand ..> Command
Block "1" *--> "transactions *" Transaction
BlockCommand ..> Command
Blockchain "1" *--> "chain *" Block
CLI ..> BalanceCommand : ยซcreateยป
CLI ..> BlockCommand : ยซcreateยป
CLI "1" *--> "commands *" Command
CLI "1" *--> "context 1" CommandContext
CLI ..> CommandContext : ยซcreateยป
CLI ..> ConnectCommand : ยซcreateยป
CLI ..> ExitCommand : ยซcreateยป
CLI ..> HelpCommand : ยซcreateยป
CLI ..> ListCommand : ยซcreateยป
CLI ..> MempoolCommand : ยซcreateยป
CLI ..> MineCommand : ยซcreateยป
CLI ..> PeersCommand : ยซcreateยป
CLI ..> SendCommand : ยซcreateยป
CLI ..> StartCommand : ยซcreateยป
CLI ..> StatusCommand : ยซcreateยป
CLI ..> SyncCommand : ยซcreateยป
CLIIntegrationTest "1" *--> "context1 1" CommandContext
CLIIntegrationTest "1" *--> "node1 1" Node
CommandContext "1" *--> "mempool 1" Mempool
CommandContext "1" *--> "node 1" Node
ConnectCommand ..> Command
ExitCommand ..> Command
GenesisBlock "1" *--> "cachedGenesisBlock 1" Block
HelpCommand ..> Command
HelpCommand "1" *--> "commands *" Command
ListCommand ..> Command
Mempool "1" *--> "transactions *" Transaction
Mempool "1" *--> "validator 1" TransactionValidator
MempoolCommand ..> Command
MineCommand ..> Command
MineCommand ..> Miner : ยซcreateยป
Miner "1" *--> "mempool 1" Mempool
Miner "1" *--> "node 1" Node
Node "1" *--> "blockList *" Block
Node "1" *--> "storage 1" BlockchainStorage
Node "1" *--> "p2pNetwork 1" P2PNetwork
Node "1" *--> "validator 1" TransactionValidator
Node "1" *--> "utxoSet 1" UTXOSet
P2PNetwork "1" *--> "node 1" Node
P2PNetwork "1" *--> "server 1" P2PServer
P2PNetwork "1" *--> "peers *" Peer
P2PServer "1" *--> "network 1" P2PNetwork
PeersCommand ..> Command
SendCommand ..> Command
StartCommand ..> Command
StartCommand ..> Mempool : ยซcreateยป
StartCommand ..> Node : ยซcreateยป
StatusCommand ..> Command
SyncCommand ..> Command
Transaction "1" *--> "block 1" TXBlockInfo
Transaction "1" *--> "inputs *" TransactionInput
Transaction "1" *--> "outputs *" TransactionOutput
TransactionOutput "1" *--> "spender 1" Spender
TransactionValidator "1" *--> "utxoSet 1" UTXOSet
UTXO "1" *--> "output 1" TransactionOutput
UTXOSet "1" *--> "utxos *" UTXO
VotingContract "1" *--> "encryptedContract 1" EncryptedContract
VotingContract "1" *--> "votes *" Vote
VotingContract "1" *--> "finalResult 1" VoteResult
Wallet "1" *--> "node 1" Node
WalletManager "1" *--> "node 1" Node
- UTXO ๋ชจ๋ธ: ๋นํธ์ฝ์ธ๊ณผ ๋์ผํ ๋ฏธ์ฌ์ฉ ์ถ๋ ฅ ๊ธฐ๋ฐ ํธ๋์ญ์
- Proof of Work: SHA-256 ๊ธฐ๋ฐ ์์ ์ฆ๋ช
- P2P ๋คํธ์ํฌ: TCP ์์ผ ๊ธฐ๋ฐ ๋ ธ๋ ๊ฐ ํต์
- ์ํธํ ํฌํ: ์ฐธ์ฌ์๋ง ๊ณ์ฝ ๋ด์ฉ ํ์ธ ๊ฐ๋ฅ
- RocksDB ์์์ฑ: Key-Value ๊ธฐ๋ฐ ๊ณ ์ฑ๋ฅ ์ ์ฅ
- CLI ์ธํฐํ์ด์ค: Command ํจํด ๊ธฐ๋ฐ ๋ช ๋ น์ด ์ฒ๋ฆฌ
- ๋จธํด ํธ๋ฆฌ: ํธ๋์ญ์ ๋ฌด๊ฒฐ์ฑ ๊ฒ์ฆ
- ๋์งํธ ์๋ช : ECDSA ๊ธฐ๋ฐ ์ธ์ฆ
์ ๊ธฐ๋ฅ๋ค์ CLI๋ฅผ ํตํด ์ฌ์ฉํ ์ ์๊ฒ ๊ตฌํํ์์ต๋๋ค.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ BLOCKCHAIN CLI - HELP โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Available Commands:
mine mine [difficulty] - Mine a new block (default difficulty: 3)
mempool mempool - Display pending transactions
start start <port> [storage_path] - Start a blockchain node
peers peers - Display connected peers
list list [start] [count] - List blocks (recent 10 by default)
sync sync - Request blockchain synchronization from peers
help help - Display this help message
exit exit - Shutdown node and exit
balance balance [address] - Check balance (yours or specific address)
block block <height> - Display detailed block information
send send <to_address> <amount> - Send coins to an address
connect connect <host> <port> - Connect to a peer node
status status - Display node status๋์ : ๋ธ๋ก์ฒด์ธ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ๋จ์ํด ๋ณด์์ง๋ง, ์ค์ ๊ตฌํ์ ํจ์ฌ ๋ณต์กํ์ต๋๋ค. ํนํ UTXO ๊ด๋ฆฌ, P2P ๋๊ธฐํ, ์ํธํ ์์คํ ์ด ์ ๊ธฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด์ผ ํ์ต๋๋ค.
ํด๊ฒฐ: ํฐ ๋ชฉํ๋ฅผ ์์ ๋จ๊ณ๋ก ๋๋์ด ์งํํ์ต๋๋ค. ๋จผ์ ๋จ์ผ ๋ ธ๋์์ ๋ธ๋ก ์์ฑ์ ๊ตฌํํ๊ณ , ์ดํ P2P ๋คํธ์ํฌ๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์ ์ง์ ์ผ๋ก ํ์ฅํ์ต๋๋ค.
๋์ : ์ฌ๋ฌ ๋ ธ๋๊ฐ ๋์์ ๋ธ๋ก์ ์์ฑํ๊ฑฐ๋ ์ค์๊ฐ์ผ๋ก ํต์ ํ๋ ํ๊ฒฝ์์, ๊ตฌํ๊ณผ ๋์์ ํ ์คํธ๋ฅผ ์งํํ๋ ๊ฒ์ด ์ฝ์ง ์์์ต๋๋ค. ํนํ ๋คํธ์ํฌ ์ง์ฐ์ด๋ ๋๊ธฐํ ์ด์๋ฅผ ์ฌํํ๊ณ ๋๋ฒ๊น ํ๋ ๊ณผ์ ์ด ๊น๋ค๋ก์ ์ต๋๋ค.
ํด๊ฒฐ: ๋ก์ปฌ ํ๊ฒฝ์์ ์ฌ๋ฌ ํฌํธ๋ก ๋ค์ค ๋ ธ๋๋ฅผ ์คํํ๋ฉฐ ์๋๋ฆฌ์ค๋ณ๋ก ํ ์คํธํ์ต๋๋ค. Longest Chain Rule์ ์ ์ฉํด ๋ถ๊ธฐ(Fork) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ , ๊ฐ ๋ ธ๋์ ์ํ๋ฅผ ๋ก๊ทธ๋ก ์ถ์ ํ๋ฉฐ ๋ฌธ์ ๋ฅผ ํ์ ํ์ต๋๋ค.
๋์ : ์ฒ์ ๊ณํํ๋ ์ํธํ ํฌํ ์์คํ ์ ๊ตฌํ ๋์ด๋๊ฐ ๋์ ์๋ฒฝํ ๊ตฌํํ์ง ๋ชปํ์ต๋๋ค.
๋์: ๊ธฐ๋ณธ ๋ธ๋ก์ฒด์ธ ๊ธฐ๋ฅ์ ๋จผ์ ์์ฑํ๊ณ , ํฌํ ์์คํ ์ ๊ธฐ๋ฐ ๊ตฌ์กฐ(VotingContract, EncryptedContract)๋ง ๊ตฌํํ์ต๋๋ค. ์ด๋ ํฅํ ํ์ฅ์ ์ํ ํ ๋๊ฐ ๋์์ต๋๋ค.
ํ๋ฆฌ์ฝ์ค์์ ๋ฐฐ์ด ์์น๋ค์ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ค ๋ ธ๋ ฅํ์ต๋๋ค
์ ์ฉ ์ฌํญ:
Command ํจํด: CLI ๋ช ๋ น์ด๋ฅผ ๋ ๋ฆฝ์ ์ธ ํด๋์ค๋ก ๋ถ๋ฆฌํ์ฌ ํ์ฅ ๊ฐ๋ฅํ ๊ตฌ์กฐ ๊ตฌ์ถ
์ผ๊ธ ์ปฌ๋ ์ : Mempool, UTXOSet, Blockchain ํด๋์ค๋ก ์ปฌ๋ ์ ์ ์บก์ํํ์ฌ ๋น์ฆ๋์ค ๋ก์ง ์์ง
Enum ํ์ฉ: MessageType์ผ๋ก ํ์ ์์ ์ฑ ํ๋ณด ๋ฐ ๋งค์ง ์คํธ๋ง ์ ๊ฑฐ
๋จ์ผ ์ฑ ์ ์์น: ๊ฐ ํด๋์ค๊ฐ ํ๋์ ์ฑ ์๋ง ๊ฐ์ง๋๋ก ์ค๊ณํ์ฌ ์ ์ง๋ณด์์ฑ ํฅ์
ํ์ง๋ง ๋ธ๋กยทํธ๋์ญ์ ยท๋ ธ๋์ฒ๋ผ ๋ณต์กํ๊ฒ ์ฝํ ๋๋ฉ์ธ์์๋ ๋จ์ผ ์ฑ ์์ ๋ช ํํ ๋ถ๋ฆฌํ๊ฑฐ๋ ๊ฒฐํฉ๋๋ฅผ ์ต์ํํ๋ ๊ฒ์ด ์ฝ์ง ์์์ต๋๋ค. ์ด๋ก ์์ ๋ฐฐ์ด ์ถ์ํ์ ์ฑ ์ ๋ถ๋ฆฌ๊ฐ ์ค์ ์์คํ ์์๋ ์ฌ๋ฌ ์ ์ฝ๊ณผ ํ์ค์ ์ธ ์ ํ์ ๋๋ฐํ๋ค๋ ์ ์ ๊นจ๋ฌ์์ต๋๋ค.