์ ๋ด์ฉ๋ค์ 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();
}
}
์ฐ์ , ๋ธ๋ก์ฒด์ธ์ ๊ตฌ์ฑํ ๋ธ๋ก ํด๋์ค๋ฅผ ์์ฑํด์ค๋๋ค.
๋ธ๋ก์ ๋ธ๋ก์ฒด์ธ ๋ด์์
์ด์ธ์ ๊ฒ๋ค์ ์ ์ธํ๊ณ 5๊ฐ๋ก ๊ตฌ์ฑ๋ ๋ธ๋ก ํด๋์ค๋ฅผ ์์ฑํด์ฃผ์์ต๋๋ค.
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
);
}
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 ํด์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ํด์๊ฐ์ ์์ฑํฉ๋๋ค.
์ด ํด์ ๊ฐ์ ํ์ฌ ๋ธ๋ก์ ๊ณ ์ ์๋ณ์ ์ญํ ์ ํ๋ฉฐ ๊ฐ ๋ธ๋ก์ ์ด์ ๋ธ๋ก๊ณผ ์ฐ๊ฒฐํ์ฌ ๋ธ๋ก์ฒด์ธ์ ๋ฌด๊ฒฐ์ฑ๊ณผ ๋ณด์์ ๋ณด์ฅํฉ๋๋ค.
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);
}
}
์ด๋ ๊ฒํด์ ๊ฐ๋จํ๊ฒ ๋ธ๋ก์ฒด์ธ์ด ์์ฑ๋ฉ๋๋ค.
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๊ฐ์ด ์ผ์น ์ฌ๋ถ๋ก ๋ธ๋ก์ฒด์ธ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์งํํ์์ต๋๋ค.
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);
}
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์ด ์ ๋ ๊ฑธ๋ ธ์ต๋๋ค.
๋ํ, ๋์ด๋ ๋ณ๋์ ๋ฐ๋ผ ์ฑ๊ตด ์๊ฐ์ ์ํฅ์๋ค๋ ๊ฒ๋ ํ์ธํ์์ต๋๋ค !