검수요청.png검수요청.png

"랜덤"의 두 판 사이의 차이

위키원
이동: 둘러보기, 검색
(난수 생성 문제)
 
(사용자 2명의 중간 판 25개는 보이지 않습니다)
1번째 줄: 1번째 줄:
'''랜덤'''(random)<!--random-->이란, 사전적인 의미로 일정한 법칙이나 규칙 또는 버릇이 붙어 있지 않는, 또는 사람의 의사(意思)가 개입하지 않은 무작위(無作爲)한 것을 말한다.
+
'''랜덤'''<!--난수, 랜덤함수, 랜덤 함수-->(random)<!--random-->이란, '일정한 법칙이나 규칙 또는 버릇이 붙어 있지 않은, 또는 의사(意思)가 개입하지 않은 무작위(無作爲)한 것을 뜻한다.<ref>〈[https://terms.naver.com/entry.nhn?docId=1617560&cid=50293&categoryId=50293 랜덤]〉, 《네이버 지식백과》</ref>
  
 
==개요==
 
==개요==
블록체인에서의 랜덤은 랜덤 함수를 의미한다. [[스마트계약]]이 있는 [[블록체인]]([[이더리움]], [[이오스]])랜덤 함수를 제공하지 않는다. 블록체인의 특성상 [[트랜잭션]]이 검증되려면 어떤 [[노드]]에서도 같은 결과가 나와야 하기 때문이다.<ref>NEOWIZ PLAY STUDIO Blockchain Lab,〈[https://medium.com/nblab/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90%EC%84%9C-%EB%82%9C%EC%88%98%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-1fe42e65e4e8 블록체인에서 난수를 생성하는 방법]〉, 《Medium》, 2018-09-12</ref> 이는 확률 요소가 있는 게임이나 도박 응용을 구현하는데 문제가 된다. 트랜잭션을 미리 실행시켜보고 그 결과가 자신에게 불리할 경우 네트워크에 전파하지 않을 것이기 때문이다.<ref name="티스토리">joojis,〈[https://joojis.tistory.com/entry/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80%EC%97%90%EC%84%9C%EC%9D%98-%EB%9E%9C%EB%8D%A4-%EA%B5%AC%ED%98%84 이더리움에서의 랜덤 구현]〉, 《티스토리》, 2018-01-30</ref>
+
블록체인에서의 랜덤은 랜덤 함수를 의미한다. [[스마트계약]]이 있는 [[블록체인]]([[이더리움]], [[이오스]])랜덤 함수를 제공하지 않는다. 블록체인의 특성상 [[트랜잭션]]이 검증되려면 어떤 [[노드]]에서도 같은 결과가 나와야 하기 때문이다.<ref>NEOWIZ PLAY STUDIO Blockchain Lab, 〈[https://medium.com/nblab/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90%EC%84%9C-%EB%82%9C%EC%88%98%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-1fe42e65e4e8 블록체인에서 난수를 생성하는 방법]〉, 《Medium》, 2018-09-12</ref> 이는 확률 요소가 있는 게임이나 도박 응용을 구현하는데 문제가 된다. 트랜잭션을 미리 실행시켜보고 그 결과가 자신에게 불리할 경우 네트워크에 전파하지 않을 것이기 때문이다.<ref name="티스토리">joojis, 〈[https://joojis.tistory.com/entry/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80%EC%97%90%EC%84%9C%EC%9D%98-%EB%9E%9C%EB%8D%A4-%EA%B5%AC%ED%98%84 이더리움에서의 랜덤 구현]〉, 《티스토리》, 2018-01-30</ref>
  
 
==블록 변수==
 
==블록 변수==
Solidity를 기준으로 랜덤 [[시드]]가 될 수 있는 블록 변수들이 있다.
+
Solidity를 기준으로 랜덤 [[시드]]가 될 수 있는 [[블록]] 변수들이 있다.
  
 
* 블록의 번호
 
* 블록의 번호
 
* 블록의 시간
 
* 블록의 시간
* 블록해시
+
* 블록 해시
  
그러나 기본적으로 블록 변수들은 [[마이너]]에 의해 통제된다. 만약 [[트랜잭션]]의 결과가 [[블록]] 보상 이상의 인센티브가 있는 경우 이를 랜덤 시드로 쓰는 것은 적절하지 않다. 예를 들어 블록 보상이 3 이더인데, 100 이더짜리 도박판이 열리면 마이너는 [[작업증명]](Proof of Work; PoW)에 성공했더라도 그 블록에 자신이 도박판에서 지는 트랜잭션이 포함될 경우 그 블록을 발표하지 않고 버릴 수도 있음을 염두에 두어야 한다. 블록의 번호를 쓸 경우 마이너 뿐만 아니라 유저에게도 예측될 수 있다. 예를 들어 1~6의 주사위를 던져 짝수가 나오면 이기는 게임이라 했을 때, 블록의 번호를 하나씩 올려가보면서 시뮬레이션하여 짝수가 나오는 블록에 포함되도록 트랜잭션 발표를 조정할 수 있다. 블록의 시간은 마이너에 의해 통제된다고 볼 수 있다. 블록의 해시는 마이너와 사용자 모두 예측하기 어렵지만, 마이너가 이해관계에 놓여있는 경우 위에서 언급한 것처럼 블록 자체를 발표 안 할 가능성이 존재한다.<ref name="티스토리"></ref>
+
그러나 기본적으로 블록 변수들은 [[마이너]]에 의해 통제된다. 만약 [[트랜잭션]]의 결과가 [[블록]] 보상 이상의 인센티브가 있는 경우 이를 랜덤 시드로 쓰는 것은 적절하지 않다. 예를 들어 블록 보상이 3이더인데, 100이더짜리 도박판이 열리면 마이너는 [[작업증명]](Proof of Work; PoW)에 성공했더라도 그 블록에 자신이 도박판에서 지는 트랜잭션이 포함될 경우 그 블록을 발표하지 않고 버릴 수도 있음을 염두에 두어야 한다. 블록의 번호를 쓸 경우 마이너뿐만 아니라 유저에게도 예측될 수 있다. 예를 들어 1~6의 주사위를 던져 짝수가 나오면 이기는 게임이라 했을 때, 블록의 번호를 하나씩 올려보면서 시뮬레이션하여 짝수가 나오는 블록에 포함되도록 트랜잭션 발표를 조정할 수 있다. 블록의 시간은 마이너에 의해 통제된다고 볼 수 있다. 블록의 해시는 마이너와 사용자 모두 예측하기 어렵지만, 마이너가 이해관계에 놓여있는 경우 위에서 언급한 것처럼 블록 자체를 발표 안 할 가능성이 존재한다.<ref name="티스토리"></ref>
  
==예제==
+
==난수==
===Keccak256===
+
===난수 생성 문제===
솔리디티에서 난수를 만들려면 keccak256 해시 함수를 사용하면 된다.
+
* '''일상생활 속의 난수'''
 +
: 대표적인 예로 주사위 던지기, 동전 던지기, 카드 섞기 등이 있다. 이들의 첫 번째 공통점은 결과가 편향되지 않는다는 것이다. 주사위를 던지면 보통 여섯 면이 골고루 나오고, 동전 던지기에서는 앞면과 뒷면 어느 한쪽으로도 치우침 없이 골고루 결과가 나온다. 이를 비 편향성이라고 한다. 두 번째 공통점은 매번 결과가 다른 패턴으로 나오기 때문에 예측할 수 없다는 것이다. 마지막 세 번째 공통점은 결과를 조작할 수 없다는 것이다. 무작위성 혹은 난수를 얘기하는 대부분의 경우에 요구되는 요소들도 대부분 위의 세 특징에 포함된다. 그리고 이 무작위성은 우리가 정확히 파악하지도 못하고, 조종하지도 못하는 물리계를 원천으로 활용하고 있기에 우리는 위의 세 특징을 쉽게 얻고 있다.
 +
 
 +
* '''컴퓨터 과학에서의 난수'''
 +
: 컴퓨터는 여러 함수를 이용해 편향되지 않은 수를 생성하는 것은 잘 할 수 있다. 하지만 예측할 수도 없고 조종 불가능한 특성을 원한다면 얘기는 완전히 달라진다. 컴퓨터는 이전에 입력받은 순서대로 정해진 행동을 하도록 설계돼 있다. 컴퓨터는 자신이 가지고 있는 공간 내에서만 작동하기 때문에 우리와는 다르게 자신이 정확히 파악하지도 못하고 조종할 수 없는 다른 환경들로부터 새로운 정보를 얻는 것도 잘 못 한다. 그래서 컴퓨터는 우리가 흔히들 무작위성의 원천으로 사용하고 있는 물리계와 같은 요소를 쉽게 활용할 수가 없다. 이러한 컴퓨터의 한계로 인해 컴퓨터 과학에서는 난수를 크게 두 부류로 나누어서 설명한다.
 +
 
 +
* [[유사 난수]](Pseudo Random)는 컴퓨터 내부에 있는 값들과 알고리즘의 실행을 통해 얻은 결과값을 말한다. 이 값들은 알고리즘에 의해 생성되었기 때문에 특정 패턴을 가지고 있고 예측도 가능하다.
 +
 
 +
*[[진짜 난수]](True Random)는 컴퓨터 외부로부터 불확실성을 충분히 끌어온 상태에서 생성해낸 값이다. 여러 프로그래밍 언어, 프로그램에서 제공해주는 난수 생성 함수들은 [[해시 함수]] 등의 복잡한 함수를 통해서 결과의 비 편향성만 만족시키는 유사 난수 생성기인 경우가 많다. 이 함수의 결과는 편향되지 않았다는 측면에서 난수처럼 보이지만 실제로는 예측할 수 있고 이를 통해 결과값을 어느 정도 조종할 수도 있기 때문에 진짜 난수라고 보기 어렵다. 암호키 생성과 같은 분야에서는 진짜 난수를 필요로 한다. 그래서 컴퓨터에서 사용할 만한 진짜 난수를 생성하려는 시도 또한 활발히 이루어지고 있다.
 +
 
 +
1998년부터 운영되어온 [[random.org]] 사이트가 대표적이다. 이 사이트는 컴퓨터에서 사용할 수 있는 여러 난수 생성 방법을 정리해두고 이를 사용자에게 제공한다. 이런 시도들에서는 컴퓨터를 임의로 무작위적으로 행동하게 하는 것은 불가능하니 어떻게든 물리 현상에서 예측하지도, 조종하지도 못한 값을 가져오려 한다. 여기서 사용하는 물리 현상의 예로 방사성 붕괴, 열역학적인 현상 등의 물리적 수치 변화 등이 있다. 진짜 난수 생성은 효율성 문제를 가지고 있다. 진짜 난수 생성을 생성하기 위해서는 물리 현상을 특정 시간 동안 관찰해야 한다. 아무래도 이 경우에는 컴퓨터에 내재해 있는 값을 사용하는 유사 난수보다 아주 느리고 비용이 많이 들 수밖에 없다. 그래서 난수의 활용 용도에 따라 진짜 난수와 유사 난수 중 적절한 방법을 선택하는 것이 중요하다. 예를 들어 음악 랜덤 재생, 오늘의 명언 추천 등 조작이 큰 문제가 안 되는 경우, 유사 난수로도 충분하다.
 +
 
 +
* '''블록체인에서의 난수'''
 +
: [[블록체인]]은 신뢰 문제를 해결하는 방식과 난수 생성에 필요한 요소들은 상충하는 부분들이 많기 때문에 블록체인에서 난수를 생성하는 것은 더 어렵다. 블록체인에서는 [[분산 원장]] 속 데이터 간 합의 및 무결성 보장을 위해 블록체인 내부에서 일어나는 모든 동작은 결정적인(deterministic) 방식으로만 일어나게 된다. 결정적인 방식이라는 것은 정해진 상태 값과 인풋 값이 있을 때 그 결괏값 또한 예측한 그대로 똑같은 값만 내뱉어야 한다는 것을 의미한다. 결정적이라는 특징은 블록체인이 한 블록 동안 발생한 [[트랜잭션]]을 다시 재생시킨 결과가 현재 자신이 보유한 데이터 상태와 일치한다는 것을 보일 수 있게 함으로써 원장의 무결성을 증명하는 것을 쉽게 해준다.
 +
 
 +
: 하지만 우리가 난수를 생성할 때 기대하는 특성은 이와 정반대이다. 난수를 생성할 때 사용하려는 무작위적인 요소들은 결정적이어서는 안된다. 왜냐하면 상황마다 예측하지 못한 다른 값이 나와야 난수가 필요로 하는 예측 불가능성과 조작 불가능성을 만족하기 때문이다. 그 결과, 블록체인을 통해서는 난수를 생성하는 과정에서 사용된 여러 무작위적인 요소들이 정말 무작위적인 요소들인지 검증할 수가 없다.
 +
 
 +
: 블록체인이라는 누구도 믿을 수 없고, 모든 것이 공개된 환경에서 난수를 안전하게 생성하기 위해서는 이렇게 생성된 난수가 정말 난수라는 것을 증명해야 한다. 그래서 블록체인상의 난수 생성 문제를 다루고 있는 해결책은 대부분 글의 도입부에서 소개한 비 편향성, 예측 불가능성, 조작 불가능성에 더하여 증명 가능성까지 염두에 두어야 한다. 무작위적으로 일어난 결과가 정말로 무작위적으로 일어난 결과인지를 어떻게 증명할 것인지가 핵심이 된다.<ref>디콘, 〈[https://www.coindeskkorea.com/38243/ 블록체인 난수 생성, 왜 중요하고 어떻게 하는 걸까?]〉, 《코인데스크코리아》, 2019-01-30</ref>
 +
 
 +
===예제===
 +
====Keccak256====
 +
[[솔리디티]](Solidity)에서 난수를 만들려면 keccak256 [[해시 함수]]를 사용하면 된다.
 
  uint randNonce <font color="#D73A49">=</font> <font color=blue>0</font>;
 
  uint randNonce <font color="#D73A49">=</font> <font color=blue>0</font>;
 
  uint random <font color="#D73A49">=</font> <font color="#6F42C1">uint</font>(<font color="#6F42C1">keccak256</font>(now, msg.sender, randNounce)) <font color="#D73A49">%</font> <font color=blue>100</font>;
 
  uint random <font color="#D73A49">=</font> <font color="#6F42C1">uint</font>(<font color="#6F42C1">keccak256</font>(now, msg.sender, randNounce)) <font color="#D73A49">%</font> <font color=blue>100</font>;
23번째 줄: 44번째 줄:
 
실행 시 0~99까지 난수를 만들 수 있다.<ref>bear2u, 〈[https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie4.md Keccak256을 통한 난수 생성]〉, 《Github》, 2018-03-16</ref>
 
실행 시 0~99까지 난수를 만들 수 있다.<ref>bear2u, 〈[https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie4.md Keccak256을 통한 난수 생성]〉, 《Github》, 2018-03-16</ref>
  
===C언어===
+
====C====
 
<code>rand()</code>함수 사용
 
<code>rand()</code>함수 사용
  
 
  <font color="#BC7A00">#include</font> <font color="#408080"><stdio.h></font>
 
  <font color="#BC7A00">#include</font> <font color="#408080"><stdio.h></font>
  <font color="#BC7A00">#include</font> <font color="#408080"><stdlib.h></font> ''<font color="#009E48">// rand()함수 포함 라이브러리</font>''
+
  <font color="#BC7A00">#include</font> <font color="#408080"><stdlib.h></font> ''<font color="#009E48">// rand() 함수 포함 라이브러리</font>''
  <font color="#BC7A00">#include</font> <font color="#408080"><time.h></font> ''<font color="#009E48">// time()함수 포함 라이브러리</font>''
+
  <font color="#BC7A00">#include</font> <font color="#408080"><time.h></font> ''<font color="#009E48">// time() 함수 포함 라이브러리</font>''
 
   
 
   
 
  <font color="#B00040">int</font> <font color=blue>main</font>()
 
  <font color="#B00040">int</font> <font color=blue>main</font>()
 
  {
 
  {
 
     srand(time(NULL)); ''<font color="#009E48">// 매번 다른 시드값 생성</font>''
 
     srand(time(NULL)); ''<font color="#009E48">// 매번 다른 시드값 생성</font>''
     <font color="#B00040">int</font> random = <font color=blue>0</font>; ''<font color="#009E48">// 정수형 변수 선언</font>''
+
     <font color="#B00040">int</font> random <font color="#D73A49">=</font> <font color=blue>0</font>; ''<font color="#009E48">// 정수형 변수 선언</font>''
     <font color="#B00040">for</font> (<font color="#B00040">int</font> i = <font color=blue>0</font>; i < <font color=blue>10</font>; i++) ''<font color="#009E48">// 10번 반복</font>''
+
     <font color="#B00040">for</font> (<font color="#B00040">int</font> i <font color="#D73A49">=</font> <font color=blue>0</font>; i <font color="#D73A49"><</font> <font color=blue>10</font>; i<font color="#D73A49">++</font>) ''<font color="#009E48">// 10번 반복</font>''
 
     {
 
     {
           random = rand()%9; ''<font color="#009E48">// 난수 생성</font>''
+
           random <font color="#D73A49">=</font> rand() <font color="#D73A49">%</font> <font color=blue>9</font>; ''<font color="#009E48">// 난수 생성</font>''
 
           printf(<font color=#FF1493>"%d\n"</font>, random); ''<font color="#009E48">// 출력</font>''
 
           printf(<font color=#FF1493>"%d\n"</font>, random); ''<font color="#009E48">// 출력</font>''
 
     }
 
     }
 
  }
 
  }
  
* <code>random = rand()%9;</code> : <code>rand()</code>함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드이다.
+
* <code>random = rand() % 9;</code> : <code>rand()</code> 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드이다.
* <code>srand(time(NULL));</code> : <code>srand()</code>함수는 <code>rand()</code>라는 함수에 무작위 시드값을 주기 위한 함수이며, 그 파라미터로 <code>time(NULL)</code>이라는 매개변수를 전달한다.
+
* <code>srand(time(NULL));</code> : <code>srand()</code> 함수는 <code>rand()</code>라는 함수에 무작위 시드값을 주기 위한 함수이며, 그 파라미터로 <code>time(NULL)</code>이라는 매개변수를 전달한다.
* <code>time(NULL)</code> : 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수이다. <code>time()</code>함수를 사용하기 위해서는 <code><font color="#BC7A00">#include</font> <font color="#408080"><time.h></font></code>를 꼭 추가해야한다.<ref>열코, 〈[https://yeolco.tistory.com/64 C 랜덤 - 난수 생성하기]〉, 《티스토리》, 2018-09-06</ref>
+
* <code>time(NULL)</code> : 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수이다. <code>time()</code> 함수를 사용하기 위해서는 <code><font color="#BC7A00">#include</font> <font color="#408080"><time.h></font></code>를 꼭 추가해야 한다.<ref>열코, 〈[https://yeolco.tistory.com/64 C 랜덤 - 난수 생성하기]〉, 《티스토리》, 2018-09-06</ref>
  
 
==활용==
 
==활용==
 
* '''NBLab'''
 
* '''NBLab'''
: 국내 메이저 게임 개발사인 네오위즈 계열사 '네오위즈 플레이 스튜디오' 산하의 블록체인 랩에서 블록체인상의 무작위 난수 생성(RNG) 연구를 반영한 테스트 게임 [[디앱]](dApp) 'Three Stars Slot'을 [[이오스]](EOS) 메인체인 상에 런칭했다. 해당 댑은 난수 발생 방식의 접목 뿐만 아니라 컨트랙트 상 사용자의 계정 보안을 위한 다양한 방식의 보안 체계를 함께 적용한 테스트 디앱이다.<ref>서리,〈[https://koreos.io/KOREOS/302740 NEOWIZ PLAY STUDIO BLOCKCHAIN LAB, 블록체인상 랜덤 함수 생성 연구를 반영한 테스트 게임 런칭]〉, 《코리오스》, 2018-09-14</ref> Signidice 알고리즘 방식의 유일한 문제는 기존에 사용되었던 시드(seed)를 사용하지 않기 위해 사용되었던 시드를 모두 컨트랙트(contract)에 기록한다는 것이다. 이를 해결하기 위해 그리고 블록의 제공하는 상태 값 또한 시드로 활용하였다. 블록에서 제공하는 상태 값 그리고 난수 요청자가 제공하는 시드가 결합된 요청은 사실상 기존에 요청되지 않은 요청이라고 볼 수 있다. 따라서 이 방식을 사용할 경우 요청자의 시드를 매번 컨트렉트에 기록할 필요가 없게 된다. NBLab은 블록체인 기술 연구 뿐만 아니라 새로운 사업 가능성을 찾고 도전하는 것을 목표로 설립된 조직이다. NBLab의 비전은 'PLAY THE CRYPTO WORLD'로 차별화된 플레이 경험을 통해 유저들이 크립토 세상을 놀이터처럼 즐길 수 있도록 만들어 나갈 것이다. NBLab은 설립 이후, 다양한 연구와 사업을 진행하고 있으며, 오랜기간 게임을 개발하고 서비스를 직접 운영하고 있는 회사인 만큼 블록체인 기술의 실제적인 활용에 많은 초점을 맞추고 있다.<ref>EOSeoul,〈[https://medium.com/eoseoul/three-stars-slot-eos-%EB%A9%94%EC%9D%B8%EB%84%B7-%EB%9F%B0%EC%B9%AD-%EC%86%8C%EC%8B%9D-816c033be8f0 Three Stars Slot EOS 메인넷 런칭 소식]〉, 《Medium》, 2018-09-13</ref>
+
: 국내 메이저 게임 개발사인 네오위즈 계열사 '네오위즈 플레이 스튜디오' 산하의 블록체인 랩에서 블록체인상의 무작위 난수 생성(RNG) 연구를 반영한 테스트 게임 [[디앱]](dApp) 'Three Stars Slot'을 [[이오스]](EOS) 메인체인 상에 런칭했다. 해당 댑은 난수 발생 방식의 접목뿐만 아니라 컨트랙트 상 사용자의 계정 보안을 위한 다양한 방식의 보안 체계를 함께 적용한 테스트 디앱이다.<ref>서리, 〈[https://koreos.io/KOREOS/302740 NEOWIZ PLAY STUDIO BLOCKCHAIN LAB, 블록체인상 랜덤 함수 생성 연구를 반영한 테스트 게임 런칭]〉, 《코리오스》, 2018-09-14</ref> Signidice 알고리즘 방식의 유일한 문제는 기존에 사용되었던 [[시드]](seed)를 사용하지 않기 위해 사용되었던 시드를 모두 컨트랙트(contract)에 기록한다는 것이다. 이를 해결하기 위해 그리고 [[블록]]의 제공하는 상태 값 또한 시드로 활용하였다. 블록에서 제공하는 상태 값 그리고 난수 요청자가 제공하는 시드가 결합한 요청은 사실상 기존에 요청되지 않은 요청이라고 볼 수 있다. 따라서 이 방식을 사용할 경우 요청자의 시드를 매번 컨트렉트에 기록할 필요가 없게 된다. NBLab은 블록체인 기술 연구뿐만 아니라 새로운 사업 가능성을 찾고 도전하는 것을 목표로 설립된 조직이다. NBLab의 비전은 'PLAY THE CRYPTO WORLD'로 차별화된 플레이 경험을 통해 유저들이 크립토 세상을 놀이터처럼 즐길 수 있도록 만들어나갈 것이다. NBLab은 설립 이후, 다양한 연구와 사업을 진행하고 있으며, 오랜 기간 게임을 개발하고 서비스를 직접 운영하는 회사인 만큼 블록체인 기술의 실제적인 활용에 많은 초점을 맞추고 있다.<ref>EOSeoul, 〈[https://medium.com/eoseoul/three-stars-slot-eos-%EB%A9%94%EC%9D%B8%EB%84%B7-%EB%9F%B0%EC%B9%AD-%EC%86%8C%EC%8B%9D-816c033be8f0 Three Stars Slot EOS 메인넷 런칭 소식]〉, 《Medium》, 2018-09-13</ref>
 +
 
 +
* '''[[이더리움]]'''
 +
: 이더리움 재단이 난수 생성을 가능케 하는 검증 가능한 [[지연함수]](Verifiable Delay Functions; VDFs) 관련 기술에 1500만 달러 규모 자금을 투입했다. 이더리움 2.0에 적용될 예정인 차세대 [[지분증명]](Proof of Stake; PoS) [[합의 메커니즘]]에 지연함수 기술을 적용할 수 있을지 여부를 결정하기 위한 시도이다. 지분증명 합의 메커니즘에선 다음 [[블록]]을 생성할 권한을 누가 가질지 아무도 모르게 해야 한다. 안전한 난수를 만드는 역량이 세레니티로도 불리는 이더리움 2.0 플랫폼에서 구현되면 이더리움 기반 모든 [[디앱]]에서도 활용할 수 있게 될 것이다. 이더리움 재단의 저스틴 드레이크 연구원은 지연함수 기술과 관련해 의사 결정 과정이 다 계층화 된다는 점을 강조했다. 이더리움이 지연함수 기술을 합의 메커니즘에 투입할지 여부는 아직 결정되지 않았다. 이더리움 2.0에 적용할지 말지 결정하기 전 필수적인 많은 테스트가 이더리움 개발자들에 의해 진행될 예정이다.<ref>황치규 기자, 〈[http://www.thebchain.co.kr/news/articleView.html?idxno=3252 이더리움재단, 난수생성 기술 'VDF' 개발에 1500만 달러 투입]〉, 《더 비체인》, 2019-02-07</ref>
  
 
{{각주}}
 
{{각주}}
53번째 줄: 77번째 줄:
 
==참고자료==
 
==참고자료==
 
* 〈[https://terms.naver.com/entry.nhn?docId=1617560&cid=50293&categoryId=50293 랜덤]〉, 《네이버 지식백과》
 
* 〈[https://terms.naver.com/entry.nhn?docId=1617560&cid=50293&categoryId=50293 랜덤]〉, 《네이버 지식백과》
* NEOWIZ PLAY STUDIO Blockchain Lab,〈[https://medium.com/nblab/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90%EC%84%9C-%EB%82%9C%EC%88%98%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-1fe42e65e4e8 블록체인에서 난수를 생성하는 방법]〉, 《Medium》, 2018-09-12
+
* NEOWIZ PLAY STUDIO Blockchain Lab, 〈[https://medium.com/nblab/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8%EC%97%90%EC%84%9C-%EB%82%9C%EC%88%98%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-1fe42e65e4e8 블록체인에서 난수를 생성하는 방법]〉, 《Medium》, 2018-09-12
* 서리,〈[https://koreos.io/KOREOS/302740 NEOWIZ PLAY STUDIO BLOCKCHAIN LAB, 블록체인상 랜덤 함수 생성 연구를 반영한 테스트 게임 런칭]〉, 《코리오스》, 2018-09-14
+
* 서리, 〈[https://koreos.io/KOREOS/302740 NEOWIZ PLAY STUDIO BLOCKCHAIN LAB, 블록체인상 랜덤 함수 생성 연구를 반영한 테스트 게임 런칭]〉, 《코리오스》, 2018-09-14
* EOSeoul,〈[https://medium.com/eoseoul/three-stars-slot-eos-%EB%A9%94%EC%9D%B8%EB%84%B7-%EB%9F%B0%EC%B9%AD-%EC%86%8C%EC%8B%9D-816c033be8f0 Three Stars Slot EOS 메인넷 런칭 소식]〉, 《Medium》, 2018-09-13
+
* EOSeoul, 〈[https://medium.com/eoseoul/three-stars-slot-eos-%EB%A9%94%EC%9D%B8%EB%84%B7-%EB%9F%B0%EC%B9%AD-%EC%86%8C%EC%8B%9D-816c033be8f0 Three Stars Slot EOS 메인넷 런칭 소식]〉, 《Medium》, 2018-09-13
* joojis,〈[https://joojis.tistory.com/entry/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80%EC%97%90%EC%84%9C%EC%9D%98-%EB%9E%9C%EB%8D%A4-%EA%B5%AC%ED%98%84 이더리움에서의 랜덤 구현]〉, 《티스토리》, 2018-01-30
+
* joojis, 〈[https://joojis.tistory.com/entry/%EC%9D%B4%EB%8D%94%EB%A6%AC%EC%9B%80%EC%97%90%EC%84%9C%EC%9D%98-%EB%9E%9C%EB%8D%A4-%EA%B5%AC%ED%98%84 이더리움에서의 랜덤 구현]〉, 《티스토리》, 2018-01-30
 
* bear2u, 〈[https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie4.md Keccak256을 통한 난수 생성]〉, 《Github》, 2018-03-16
 
* bear2u, 〈[https://github.com/bear2u/til/blob/master/blockchain/zombies/zombie4.md Keccak256을 통한 난수 생성]〉, 《Github》, 2018-03-16
 
* 열코, 〈[https://yeolco.tistory.com/64 C 랜덤 - 난수 생성하기]〉, 《티스토리》, 2018-09-06
 
* 열코, 〈[https://yeolco.tistory.com/64 C 랜덤 - 난수 생성하기]〉, 《티스토리》, 2018-09-06
 +
* 디콘, 〈[https://www.coindeskkorea.com/38243/ 블록체인 난수 생성, 왜 중요하고 어떻게 하는 걸까?]〉, 《코인데스크코리아》, 2019-01-30
 +
* 황치규 기자, 〈[http://www.thebchain.co.kr/news/articleView.html?idxno=3252 이더리움재단, 난수생성 기술 'VDF' 개발에 1500만 달러 투입]〉, 《더 비체인》, 2019-02-07
  
 
==같이 보기==
 
==같이 보기==
 
* [[확률]]
 
* [[확률]]
 +
* [[블록]]
 +
* [[이오스]]
 +
* [[노드]]
 +
* [[C]]
 +
* [[Keccak256]]
 +
* [[솔리디티]]
 +
* [[디앱]]
  
 
{{블록체인 기술|검토 필요}}
 
{{블록체인 기술|검토 필요}}

2019년 9월 17일 (화) 19:40 기준 최신판

랜덤(random)이란, '일정한 법칙이나 규칙 또는 버릇이 붙어 있지 않은, 또는 의사(意思)가 개입하지 않은 무작위(無作爲)한 것을 뜻한다.[1]

개요[편집]

블록체인에서의 랜덤은 랜덤 함수를 의미한다. 스마트계약이 있는 블록체인(이더리움, 이오스)은 랜덤 함수를 제공하지 않는다. 블록체인의 특성상 트랜잭션이 검증되려면 어떤 노드에서도 같은 결과가 나와야 하기 때문이다.[2] 이는 확률 요소가 있는 게임이나 도박 응용을 구현하는데 문제가 된다. 트랜잭션을 미리 실행시켜보고 그 결과가 자신에게 불리할 경우 네트워크에 전파하지 않을 것이기 때문이다.[3]

블록 변수[편집]

Solidity를 기준으로 랜덤 시드가 될 수 있는 블록 변수들이 있다.

  • 블록의 번호
  • 블록의 시간
  • 블록 해시

그러나 기본적으로 블록 변수들은 마이너에 의해 통제된다. 만약 트랜잭션의 결과가 블록 보상 이상의 인센티브가 있는 경우 이를 랜덤 시드로 쓰는 것은 적절하지 않다. 예를 들어 블록 보상이 3이더인데, 100이더짜리 도박판이 열리면 마이너는 작업증명(Proof of Work; PoW)에 성공했더라도 그 블록에 자신이 도박판에서 지는 트랜잭션이 포함될 경우 그 블록을 발표하지 않고 버릴 수도 있음을 염두에 두어야 한다. 블록의 번호를 쓸 경우 마이너뿐만 아니라 유저에게도 예측될 수 있다. 예를 들어 1~6의 주사위를 던져 짝수가 나오면 이기는 게임이라 했을 때, 블록의 번호를 하나씩 올려보면서 시뮬레이션하여 짝수가 나오는 블록에 포함되도록 트랜잭션 발표를 조정할 수 있다. 블록의 시간은 마이너에 의해 통제된다고 볼 수 있다. 블록의 해시는 마이너와 사용자 모두 예측하기 어렵지만, 마이너가 이해관계에 놓여있는 경우 위에서 언급한 것처럼 블록 자체를 발표 안 할 가능성이 존재한다.[3]

난수[편집]

난수 생성 문제[편집]

  • 일상생활 속의 난수
대표적인 예로 주사위 던지기, 동전 던지기, 카드 섞기 등이 있다. 이들의 첫 번째 공통점은 결과가 편향되지 않는다는 것이다. 주사위를 던지면 보통 여섯 면이 골고루 나오고, 동전 던지기에서는 앞면과 뒷면 어느 한쪽으로도 치우침 없이 골고루 결과가 나온다. 이를 비 편향성이라고 한다. 두 번째 공통점은 매번 결과가 다른 패턴으로 나오기 때문에 예측할 수 없다는 것이다. 마지막 세 번째 공통점은 결과를 조작할 수 없다는 것이다. 무작위성 혹은 난수를 얘기하는 대부분의 경우에 요구되는 요소들도 대부분 위의 세 특징에 포함된다. 그리고 이 무작위성은 우리가 정확히 파악하지도 못하고, 조종하지도 못하는 물리계를 원천으로 활용하고 있기에 우리는 위의 세 특징을 쉽게 얻고 있다.
  • 컴퓨터 과학에서의 난수
컴퓨터는 여러 함수를 이용해 편향되지 않은 수를 생성하는 것은 잘 할 수 있다. 하지만 예측할 수도 없고 조종 불가능한 특성을 원한다면 얘기는 완전히 달라진다. 컴퓨터는 이전에 입력받은 순서대로 정해진 행동을 하도록 설계돼 있다. 컴퓨터는 자신이 가지고 있는 공간 내에서만 작동하기 때문에 우리와는 다르게 자신이 정확히 파악하지도 못하고 조종할 수 없는 다른 환경들로부터 새로운 정보를 얻는 것도 잘 못 한다. 그래서 컴퓨터는 우리가 흔히들 무작위성의 원천으로 사용하고 있는 물리계와 같은 요소를 쉽게 활용할 수가 없다. 이러한 컴퓨터의 한계로 인해 컴퓨터 과학에서는 난수를 크게 두 부류로 나누어서 설명한다.
  • 유사 난수(Pseudo Random)는 컴퓨터 내부에 있는 값들과 알고리즘의 실행을 통해 얻은 결과값을 말한다. 이 값들은 알고리즘에 의해 생성되었기 때문에 특정 패턴을 가지고 있고 예측도 가능하다.
  • 진짜 난수(True Random)는 컴퓨터 외부로부터 불확실성을 충분히 끌어온 상태에서 생성해낸 값이다. 여러 프로그래밍 언어, 프로그램에서 제공해주는 난수 생성 함수들은 해시 함수 등의 복잡한 함수를 통해서 결과의 비 편향성만 만족시키는 유사 난수 생성기인 경우가 많다. 이 함수의 결과는 편향되지 않았다는 측면에서 난수처럼 보이지만 실제로는 예측할 수 있고 이를 통해 결과값을 어느 정도 조종할 수도 있기 때문에 진짜 난수라고 보기 어렵다. 암호키 생성과 같은 분야에서는 진짜 난수를 필요로 한다. 그래서 컴퓨터에서 사용할 만한 진짜 난수를 생성하려는 시도 또한 활발히 이루어지고 있다.

1998년부터 운영되어온 random.org 사이트가 대표적이다. 이 사이트는 컴퓨터에서 사용할 수 있는 여러 난수 생성 방법을 정리해두고 이를 사용자에게 제공한다. 이런 시도들에서는 컴퓨터를 임의로 무작위적으로 행동하게 하는 것은 불가능하니 어떻게든 물리 현상에서 예측하지도, 조종하지도 못한 값을 가져오려 한다. 여기서 사용하는 물리 현상의 예로 방사성 붕괴, 열역학적인 현상 등의 물리적 수치 변화 등이 있다. 진짜 난수 생성은 효율성 문제를 가지고 있다. 진짜 난수 생성을 생성하기 위해서는 물리 현상을 특정 시간 동안 관찰해야 한다. 아무래도 이 경우에는 컴퓨터에 내재해 있는 값을 사용하는 유사 난수보다 아주 느리고 비용이 많이 들 수밖에 없다. 그래서 난수의 활용 용도에 따라 진짜 난수와 유사 난수 중 적절한 방법을 선택하는 것이 중요하다. 예를 들어 음악 랜덤 재생, 오늘의 명언 추천 등 조작이 큰 문제가 안 되는 경우, 유사 난수로도 충분하다.

  • 블록체인에서의 난수
블록체인은 신뢰 문제를 해결하는 방식과 난수 생성에 필요한 요소들은 상충하는 부분들이 많기 때문에 블록체인에서 난수를 생성하는 것은 더 어렵다. 블록체인에서는 분산 원장 속 데이터 간 합의 및 무결성 보장을 위해 블록체인 내부에서 일어나는 모든 동작은 결정적인(deterministic) 방식으로만 일어나게 된다. 결정적인 방식이라는 것은 정해진 상태 값과 인풋 값이 있을 때 그 결괏값 또한 예측한 그대로 똑같은 값만 내뱉어야 한다는 것을 의미한다. 결정적이라는 특징은 블록체인이 한 블록 동안 발생한 트랜잭션을 다시 재생시킨 결과가 현재 자신이 보유한 데이터 상태와 일치한다는 것을 보일 수 있게 함으로써 원장의 무결성을 증명하는 것을 쉽게 해준다.
하지만 우리가 난수를 생성할 때 기대하는 특성은 이와 정반대이다. 난수를 생성할 때 사용하려는 무작위적인 요소들은 결정적이어서는 안된다. 왜냐하면 상황마다 예측하지 못한 다른 값이 나와야 난수가 필요로 하는 예측 불가능성과 조작 불가능성을 만족하기 때문이다. 그 결과, 블록체인을 통해서는 난수를 생성하는 과정에서 사용된 여러 무작위적인 요소들이 정말 무작위적인 요소들인지 검증할 수가 없다.
블록체인이라는 누구도 믿을 수 없고, 모든 것이 공개된 환경에서 난수를 안전하게 생성하기 위해서는 이렇게 생성된 난수가 정말 난수라는 것을 증명해야 한다. 그래서 블록체인상의 난수 생성 문제를 다루고 있는 해결책은 대부분 글의 도입부에서 소개한 비 편향성, 예측 불가능성, 조작 불가능성에 더하여 증명 가능성까지 염두에 두어야 한다. 무작위적으로 일어난 결과가 정말로 무작위적으로 일어난 결과인지를 어떻게 증명할 것인지가 핵심이 된다.[4]

예제[편집]

Keccak256[편집]

솔리디티(Solidity)에서 난수를 만들려면 keccak256 해시 함수를 사용하면 된다.

uint randNonce = 0;
uint random = uint(keccak256(now, msg.sender, randNounce)) % 100;
randNonce++;
uint random2 = uint(keccak256(now, msg.sender, randNounce)) % 100;

now → 타임스탬프 값 실행 시 0~99까지 난수를 만들 수 있다.[5]

C[편집]

rand()함수 사용

#include <stdio.h>
#include <stdlib.h> // rand() 함수 포함 라이브러리
#include <time.h> // time() 함수 포함 라이브러리

int main()
{
    srand(time(NULL)); // 매번 다른 시드값 생성
    int random = 0; // 정수형 변수 선언
    for (int i = 0; i < 10; i++) // 10번 반복
    {
         random = rand() % 9; // 난수 생성
         printf("%d\n", random); // 출력
    }
}
  • random = rand() % 9; : rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드이다.
  • srand(time(NULL)); : srand() 함수는 rand()라는 함수에 무작위 시드값을 주기 위한 함수이며, 그 파라미터로 time(NULL)이라는 매개변수를 전달한다.
  • time(NULL) : 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수이다. time() 함수를 사용하기 위해서는 #include <time.h>를 꼭 추가해야 한다.[6]

활용[편집]

  • NBLab
국내 메이저 게임 개발사인 네오위즈 계열사 '네오위즈 플레이 스튜디오' 산하의 블록체인 랩에서 블록체인상의 무작위 난수 생성(RNG) 연구를 반영한 테스트 게임 디앱(dApp) 'Three Stars Slot'을 이오스(EOS) 메인체인 상에 런칭했다. 해당 댑은 난수 발생 방식의 접목뿐만 아니라 컨트랙트 상 사용자의 계정 보안을 위한 다양한 방식의 보안 체계를 함께 적용한 테스트 디앱이다.[7] Signidice 알고리즘 방식의 유일한 문제는 기존에 사용되었던 시드(seed)를 사용하지 않기 위해 사용되었던 시드를 모두 컨트랙트(contract)에 기록한다는 것이다. 이를 해결하기 위해 그리고 블록의 제공하는 상태 값 또한 시드로 활용하였다. 블록에서 제공하는 상태 값 그리고 난수 요청자가 제공하는 시드가 결합한 요청은 사실상 기존에 요청되지 않은 요청이라고 볼 수 있다. 따라서 이 방식을 사용할 경우 요청자의 시드를 매번 컨트렉트에 기록할 필요가 없게 된다. NBLab은 블록체인 기술 연구뿐만 아니라 새로운 사업 가능성을 찾고 도전하는 것을 목표로 설립된 조직이다. NBLab의 비전은 'PLAY THE CRYPTO WORLD'로 차별화된 플레이 경험을 통해 유저들이 크립토 세상을 놀이터처럼 즐길 수 있도록 만들어나갈 것이다. NBLab은 설립 이후, 다양한 연구와 사업을 진행하고 있으며, 오랜 기간 게임을 개발하고 서비스를 직접 운영하는 회사인 만큼 블록체인 기술의 실제적인 활용에 많은 초점을 맞추고 있다.[8]
이더리움 재단이 난수 생성을 가능케 하는 검증 가능한 지연함수(Verifiable Delay Functions; VDFs) 관련 기술에 1500만 달러 규모 자금을 투입했다. 이더리움 2.0에 적용될 예정인 차세대 지분증명(Proof of Stake; PoS) 합의 메커니즘에 지연함수 기술을 적용할 수 있을지 여부를 결정하기 위한 시도이다. 지분증명 합의 메커니즘에선 다음 블록을 생성할 권한을 누가 가질지 아무도 모르게 해야 한다. 안전한 난수를 만드는 역량이 세레니티로도 불리는 이더리움 2.0 플랫폼에서 구현되면 이더리움 기반 모든 디앱에서도 활용할 수 있게 될 것이다. 이더리움 재단의 저스틴 드레이크 연구원은 지연함수 기술과 관련해 의사 결정 과정이 다 계층화 된다는 점을 강조했다. 이더리움이 지연함수 기술을 합의 메커니즘에 투입할지 여부는 아직 결정되지 않았다. 이더리움 2.0에 적용할지 말지 결정하기 전 필수적인 많은 테스트가 이더리움 개발자들에 의해 진행될 예정이다.[9]

각주[편집]

  1. 랜덤〉, 《네이버 지식백과》
  2. NEOWIZ PLAY STUDIO Blockchain Lab, 〈블록체인에서 난수를 생성하는 방법〉, 《Medium》, 2018-09-12
  3. 3.0 3.1 joojis, 〈이더리움에서의 랜덤 구현〉, 《티스토리》, 2018-01-30
  4. 디콘, 〈블록체인 난수 생성, 왜 중요하고 어떻게 하는 걸까?〉, 《코인데스크코리아》, 2019-01-30
  5. bear2u, 〈Keccak256을 통한 난수 생성〉, 《Github》, 2018-03-16
  6. 열코, 〈C 랜덤 - 난수 생성하기〉, 《티스토리》, 2018-09-06
  7. 서리, 〈NEOWIZ PLAY STUDIO BLOCKCHAIN LAB, 블록체인상 랜덤 함수 생성 연구를 반영한 테스트 게임 런칭〉, 《코리오스》, 2018-09-14
  8. EOSeoul, 〈Three Stars Slot EOS 메인넷 런칭 소식〉, 《Medium》, 2018-09-13
  9. 황치규 기자, 〈이더리움재단, 난수생성 기술 'VDF' 개발에 1500만 달러 투입〉, 《더 비체인》, 2019-02-07

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 랜덤 문서는 블록체인 기술에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.