Blockchain 02
2019-09-26
Proof of Work
내장형시스템 과제로 나온 작업 증명의 간단한 예제를 만들어 보았다.
String bc = "blockchain";
이 프로그램의 목적은 주어진 목표값 이하의 해시를 가지는 논스를 찾는 것이다.
String “blockcahin”과 해시값을 목표값 이하로 만들어주는 nonce로 간이 블록을 구성한다.
class SimpleBlock implements Serializable {
public String value = "";
public int nonce = 0;
public SimpleBlock(String s){
this.value = s;
}
}
블록 객체를 생성하기 위한 class SimpleBlock을 byte 형태로 데이터를 변환(직렬화)하기 위해 Serializable를 상속한다.
public static byte[] getSHA(byte[] input) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(input);
}
public static byte[] Hash(SimpleBlock sb) throws IOException, NoSuchAlgorithmException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(sb);
oos.flush();
byte[] hash = getSHA(bos.toByteArray());
return hash;
}
SimpleBlock을 바이트 배열로 변환한 값을 SHA-256 해시값으로 변환하여 바이트 배열로 return한다.
public static SimpleBlock pow(String bc, int diff) throws IOException, NoSuchAlgorithmException {
BigInteger difficulty = BigInteger.ONE.shiftLeft(256-diff).add(BigInteger.valueOf(-1));
SimpleBlock sb = new SimpleBlock(bc);
while(true){
BigInteger hash = new BigInteger(1, getSHA(Hash(sb)));
if(hash.compareTo(difficulty) == -1){
System.out.println("SHA-256: " + String.format("%64s", hash.toString(16)).replace(' ', '0'));
return sb;
}
else sb.nonce++;
}
}
매개변수 String bc는 SimpleBlock 의 value이며, int diff는 작업 난이도이다.
BigInteger difficulty = BigInteger.ONE.shiftLeft(256-diff).add(BigInteger.valueOf(-1));
작업 난이도는 매개변수로 왼쪽 시프트 연산을 조절하며 정해진다.
if(hash.compareTo(difficulty) == -1){
System.out.println("SHA-256: " + String.format("%64s", hash.toString(16)).replace(' ', '0'));
return sb;
}
else sb.nonce++;
}
목표값 이하의 해시를 찾는 데 성공하였다면 결과를 반환하고, 실패하였다면 SimpleBlock의 nonce값을 올려서 다시 시도한다.