๐Ÿ”” ๊ฐ„๋‹จํ•œ ๋ธ”๋ก์ฒด์ธ ๋งŒ๋“ค๊ธฐ.

๋™๋™ยท2024๋…„ 4์›” 14์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
12/13
post-thumbnail
  • ๋ธ”๋ก ํด๋ž˜์Šค
    • ํ•ด์‹œ
    • ์ด์ „ ๋ธ”๋ก์˜ ํ•ด์‹œ
    • ๋‹ด๊ธด ๋ฐ์ดํ„ฐ
    • ํƒ€์ž„์Šคํƒฌํ”„
    • ๋…ผ์Šค
  • ๋ธ”๋ก ํ•ด์‹œ ์ƒ์„ฑ
  • ๋ธ”๋ก์ฒด์ธ ์ƒ์„ฑ
  • ๋ธ”๋ก์ฒด์ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
  • ์ฑ„๊ตด (PoW)

  • ํ…Œ์ŠคํŠธ / ๋ธ”๋ก์ฒด์ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
  • ํ…Œ์ŠคํŠธ / ์ฑ„๊ตด (PoW)

์œ„ ๋‚ด์šฉ๋“ค์„ Java๋กœ ๋ธ”๋ก์ฒด์ธ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ์„ฑํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

๐Ÿงฑ ๋ธ”๋ก ํด๋ž˜์Šค ์ƒ์„ฑ

Block.java

public class Block {
    public String hash;
    public String previousHash;
    private String data;
    private long timeStamp;
    private int nonce;

    public Block(String data, String previousHash) {
        this.data = data;
        this.previousHash = previousHash;
        this.timeStamp = new Date().getTime();
    }
}

์šฐ์„ , ๋ธ”๋ก์ฒด์ธ์„ ๊ตฌ์„ฑํ•  ๋ธ”๋ก ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

๋ธ”๋ก์€ ๋ธ”๋ก์ฒด์ธ ๋‚ด์—์„œ

  • ํ•ด์‹œ๊ฐ’
  • ์ด์ „ ๋ธ”๋ก์˜ ํ•ด์‹œ๊ฐ’ (์ œ๋„ค์‹œ์Šค ๋ธ”๋ก์˜ ๊ฒฝ์šฐ๋Š” X)
  • ๋ฐ์ดํ„ฐ
  • ํƒ€์ž„์Šคํƒฌํ”„
  • ๋‚œ์Šค

์ด์™ธ์˜ ๊ฒƒ๋“ค์€ ์ œ์™ธํ•˜๊ณ  5๊ฐœ๋กœ ๊ตฌ์„ฑ๋œ ๋ธ”๋ก ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.


๋ธ”๋ก ํ•ด์‹œ ์ƒ์„ฑ

Block.java

public Block(String data, String previousHash) {
        this.data = data;
        this.previousHash = previousHash;
        this.timeStamp = new Date().getTime();
        this.hash = calculateHash();
    }
    
public String calculateHash() {
        return BlockChainUtils.generateHash(
                previousHash,
                Long.toString(timeStamp),
                data
        );
    }

BlockChainUtils.java

public static String generateHash (String ... inputValues) {
        try {
            StringBuffer stringBuffer = new StringBuffer();

            for (String inputValue : inputValues) {
                stringBuffer.append(inputValue);
            }

            String input = stringBuffer.toString();

            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer();

            for (int i = 0; i < hash.length; i++) {
                String hex = Integer.toHexString(0xff & hash[i]);

                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

์ด์ „ ๋ธ”๋ก์˜ ํ•ด์‹œ๊ฐ’, ๋ฐ์ดํ„ฐ, ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ SHA-256 ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์‹œ๊ฐ’์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด ํ•ด์‹œ ๊ฐ’์€ ํ˜„์žฌ ๋ธ”๋ก์˜ ๊ณ ์œ  ์‹๋ณ„์ž ์—ญํ• ์„ ํ•˜๋ฉฐ ๊ฐ ๋ธ”๋ก์„ ์ด์ „ ๋ธ”๋ก๊ณผ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ธ”๋ก์ฒด์ธ์˜ ๋ฌด๊ฒฐ์„ฑ๊ณผ ๋ณด์•ˆ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.


๋ธ”๋ก์ฒด์ธ ์ƒ์„ฑ

BlockChain.java

public class BlockChain {
    public ArrayList<Block> blockChain;

    public BlockChain() {
        blockChain = new ArrayList<>();
        addBlock("Genesis Block", "0");
    }

    public void addBlock(String data, String previousHash) {
        Block block = new Block(data, previousHash);
        blockChain.add(block);
    }

    public Block getLatestBlock() {
        return blockChain.get(blockChain.size() - 1);
    }
}
  • ์ œ๋„ค์‹œ์Šค ๋ธ”๋ก์˜ ๊ฒฝ์šฐ, ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ์ƒ์„ฑ๋œ ๋ธ”๋Ÿญ์ด๋ฏ€๋กœ ์ด์ „ ๋ธ”๋ก์˜ ํ•ด์‹œ๊ฐ’์€ 0์œผ๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ธ”๋ก์ฒด์ธ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.


๐Ÿค” ๋ธ”๋ก์ฒด์ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

BlockChain.java

public boolean isChainValid() {
        for (int i = 1; i < blockChain.size(); i++) {
            Block currentBlock = blockChain.get(i);
            Block previousBlock = blockChain.get(i - 1);

            if (!currentBlock.getHash().equals(currentBlock.calculateHash())) {
                return false;
            }

            if (!currentBlock.getPreviousHash().equals(previousBlock.getHash())) {
                return false;
            }
        }
        return true;
    }

ํ˜„์žฌ ๋ธ”๋ก ๋‚ด previousHash์™€ ์ด์ „ ๋ธ”๋ก์˜ hash๊ฐ’์ด ์ผ์น˜ ์—ฌ๋ถ€๋กœ ๋ธ”๋ก์ฒด์ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


โ›๏ธ ์ฑ„๊ตด (Proof of Work / ์ž‘์—… ์ฆ๋ช… ์‹œ์Šคํ…œ)

  • Proof of Work : Difficulty์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ ํŠน์ • ๊ธฐ์ค€(ํ•ด์‹œ๊ฐ’์ด ๋งŒ์กฑํ•ด์•ผ ํ•˜๋Š” ์กฐ๊ฑด)์„ ์ถฉ์กฑํ•˜๋Š” ์ƒˆ ๋ธ”๋ก์˜ ํ•ด์‹œ ๊ฐ’์„ ์ฐพ๋Š” ๊ฒƒ.

Block.java

public void mineBlock(int difficulty) {
        String target = new String(new char[difficulty]).replace('\0', '0');
        while (!hash.substring(0, difficulty).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("Mined ! : " + hash);
    }

BlockChain.java

public void addBlock(String data, String previousHash) {
        Block block;
        if (blockChain.isEmpty()) {
            block = new Block(data, previousHash);
        } else {
            block = new Block(data, blockChain.get(blockChain.size() - 1).getHash());
            block.mineBlock(difficulty);
        }
        System.out.println("\n" + block.toString());
        blockChain.add(block);
    }

๋‚œ์ด๋„์— ์ถฉ์กฑํ•˜๋Š” ํ•ด์‹œ๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ nonce ๊ฐ’์„ ์ฆ๊ฐ€์‹œ์ผœ ๋ธ”๋ก์˜ ํ•ด์‹œ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฑ„๊ตด ๊ณผ์ •์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์œ„ ์ฝ”๋“œ๋กœ ๊ฐ ๋ธ”๋ก ๋‹น ์ฑ„๊ตด ์‹œ๊ฐ„์€ ์•ฝ 2์ดˆ ์ •๋„ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, ๋‚œ์ด๋„ ๋ณ€๋™์— ๋”ฐ๋ผ ์ฑ„๊ตด ์‹œ๊ฐ„์— ์˜ํ–ฅ์žˆ๋‹ค๋Š” ๊ฒƒ๋„ ํ™•์ธํ•˜์˜€์Šต๋‹ˆ๋‹ค !


์ „์ฒด ์ฝ”๋“œ (๊นƒํ—ˆ๋ธŒ)
์ฐธ๊ณ  ์‚ฌ์ดํŠธ

profile
โœ๏ธ ๋„์ ๋„์ 

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด