-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from comnics/dev-init
블록생성과 채굴
- Loading branch information
Showing
5 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" path="src"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | ||
<classpathentry kind="output" path="bin"/> | ||
</classpath> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>kbda-blockchain</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.kbda.blockchain; | ||
|
||
import org.kbda.bockchain.core.Block; | ||
|
||
public class KbdaBlockchain { | ||
|
||
public static int difficulty = 5; | ||
|
||
public static void main(String[] arg) { | ||
|
||
//블럭을 만듭니다. | ||
Block block = new Block("Genesis block", "0"); | ||
block.mineBlock(difficulty); | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.kbda.blockchain.util; | ||
|
||
import java.security.Key; | ||
import java.security.MessageDigest; | ||
import java.security.PrivateKey; | ||
import java.security.PublicKey; | ||
import java.security.Signature; | ||
import java.util.Base64; | ||
|
||
public class StringUtil { | ||
public static String applySha256(String input) { | ||
try { | ||
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); | ||
} | ||
} | ||
|
||
// Applies ECDSA Signature and returns the result ( as bytes ). | ||
public static byte[] applyECDSASig(PrivateKey privateKey, String input) { | ||
Signature dsa; | ||
byte[] output = new byte[0]; | ||
try { | ||
dsa = Signature.getInstance("ECDSA", "BC"); | ||
dsa.initSign(privateKey); | ||
byte[] strByte = input.getBytes(); | ||
dsa.update(strByte); | ||
byte[] realSig = dsa.sign(); | ||
output = realSig; | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
return output; | ||
} | ||
|
||
// Verifies a String signature | ||
public static boolean verifyECDSASig(PublicKey publicKey, String data, byte[] signature) { | ||
try { | ||
Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC"); | ||
ecdsaVerify.initVerify(publicKey); | ||
ecdsaVerify.update(data.getBytes()); | ||
return ecdsaVerify.verify(signature); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static String getStringFromKey(Key key) { | ||
return Base64.getEncoder().encodeToString(key.getEncoded()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package org.kbda.bockchain.core; | ||
|
||
import java.util.Date; | ||
|
||
import org.kbda.blockchain.util.StringUtil; | ||
|
||
public class Block { | ||
|
||
public String hash; /* 해시값 */ | ||
public String previousHash; /* 이전 블럭의 해시값 */ | ||
private String data; /* 블럭의 data */ | ||
private long timestamp; /* timestamp */ | ||
|
||
private int nonce; | ||
|
||
/** | ||
* 새로운 블럭을 생성합니다. | ||
* | ||
* @param data | ||
* @param previousHash | ||
*/ | ||
public Block(String data, String previousHash ) { | ||
this.data = data; | ||
this.previousHash = previousHash; | ||
this.timestamp = new Date().getTime(); | ||
this.hash = calculateHash(); //생성시 먼저 hash 값을 하나 만들어 넣어둡니다. | ||
} | ||
|
||
/** | ||
* 새로운 해시값을 생성합니다. | ||
* @return | ||
*/ | ||
public String calculateHash() { | ||
String calculatedhash = StringUtil.applySha256( | ||
previousHash + | ||
Long.toString(timestamp) + | ||
Integer.toString(nonce) + | ||
data | ||
); | ||
return calculatedhash; | ||
} | ||
|
||
/** | ||
* 채굴합니다. | ||
* | ||
* @param difficulty | ||
*/ | ||
public void mineBlock(int difficulty) { | ||
//간단한 테스트와 이해를 돕기위해 target을 difficulty 숫자 만큼 앞에 0으로 채웁니다. | ||
String target = new String(new char[difficulty]).replace('\0', '0'); | ||
|
||
//생성된 hash가 target과 동일하면 채굴 성공입니다. | ||
//ex) difficulty가 3이면 target은 000이 되고, 생성된 hash가 000으로 시작하는 값이면 채굴 성공입니다. | ||
// 채굴된 모든 hash가 000으로 시작하겠죠...ㅋㅋ | ||
while(!hash.substring( 0, difficulty).equals(target)) { | ||
nonce ++; | ||
hash = calculateHash(); | ||
|
||
System.out.printf("\nGEN Hash #%d : %s", nonce, hash); | ||
} | ||
System.out.println("\n채굴 성공!!! : " + hash); | ||
} | ||
} |