336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

이더리움에서는 랜덤 함수가 없습니다. 어떤 노드가 실행하더라도 같은 결과가 나와야만 트랜잭션을 검증할 수 있는 구조이기 때문입니다. 이는 확률 요소가 있는 게임이나 도박 응용을 구현하는데 문제가 됩니다. 트랜잭션을 미리 실행시켜보고 그 결과가 자신에게 불리할 경우 네트워크에 전파하지 않을 것이기 때문입니다. 이번 포스팅에서는 어떻게 랜덤 함수를 구현할 수 있는지에 대해 알아보겠습니다.



블록 스페셜 변수

우선 Solidity를 기준으로 랜덤 시드가 될 수 있는 스페셜한 블록 변수들이 있습니다.


- 블록의 번호

- 블록의 시간

- 블록해시


그러나 기본적으로 블록 변수들은 마이너에 의제 통제됩니다. 만약 트랜잭션의 결과가 블록 보상 이상의 인센티브가 있는 경우 이를 랜덤 시드로 쓰는 것은 적절하지 않습니다. 예를 들어 블록 보상이 3 이더인데, 100 이더짜리 도박판이 열리면 마이너는 PoW에 성공했더라도 그 블록에 자신이 도박판에서 지는 트랜잭션이 포함될 경우 그 블록을 발표하지 않고 버릴 수도 있음을 염두에 두어야 합니다.



블록의 번호를 쓸 경우 마이너 뿐만 아니라 유저에게도 예측될 수 있습니다. 예를 들어 1~6의 주사위를 던져 짝수가 나오면 이기는 게임이라 했을 때, 블록의 번호를 하나씩 올려가보면서 시뮬레이션하여 짝수가 나오는 블록에 포함되도록 트랜잭션 발표를 조정할 수 있습니다.


블록의 시간은 마이너에 의해 통제된다고 볼 수 있습니다.


블록의 해시는 마이너와 사용자 모두 예측하기 어렵지만, 마이너가 이해관계에 놓여있는 경우 위에서 언급한 것처럼 블록 자체를 발표 안 할 가능성이 존재합니다.



유저가 제출한 랜덤 시드를 XOR

블록 변수를 쓰는 것은 마이너가 이해당사자일 경우 동작을 안하는 단점이 있기 때문에, 이를 피하기 위해 유저가 직접 랜덤 시드를 제공하는 방법이 있습니다.


A, B가 1~6 주사위를 굴려서 홀짝을 가리는 게임을 한다고 가정해봅시다.


1. A는 랜덤한 값 x, B는 랜덤한 값 y를 생성해 자신만 알 수 있도록 기록해 둡니다. 생성한 랜덤 값 원본을 pre-image라 부릅니다

2. A, B는 pre-image를 해시한 값을 드러내는 트랜잭션을 합니다. 네트워크 상에선 hash(x), hash(y)가 발표되고 서로의 pre-image는 모르는 상태가 됩니다.

3. A, B 모두 해시값을 발표했으면 pre-image를 드러내는 트랜잭션을 합니다. A, B는 pre-image와 그 해시값을 검증한 뒤 (x XOR y) 값을 랜덤 시드로 쓰일 수 있습니다.


이는 A, B, C, D, ...로 확장되어도 똑같은 구성으로 랜덤 시드를 생성할 수 있습니다. 랜덤 시드를 제공한 사람들 중 일부가 담합하더라도, 그 중에서 단 한 명만이라도 랜덤한 값을 생성하였다면 결과 값이 랜덤해지는 속성이 있습니다.




유저가 제출한 랜덤 시드를 사용할 때 두 가지 주의점이 있습니다.

1. Replay

- A, B, C가 주사위 게임을 하고 B, C가 담합한 상태라고 가정합니다.

- B는 A를 따라 합니다.

  - A가 해시를 발표하면 B는 pre-image는 모르지만 해시를 똑같이 발표할 수는 있습니다.

  - pre-image를 발표하는 단계에서 B는 A가 발표하는 pre-image를 본 뒤에 똑같이 발표합니다.

- A와 B의 pre-image는 똑같으므로 XOR 연산에 의해 0이 되어서 C의 pre-image가 랜덤 시드가 됩니다.


해시를 만들때 [자신의 주소(공개키), pre-image]를 해시하도록 하면 B가 따라하더라도 검증 단계에서 걸러지게 됩니다.


2. DoS

pre-image를 발표하는 단계에서 마지막으로 발표를 하는 사람은 그 결과를 예측하고 자신의 pre-image를 발표하지 않을 수도 있습니다. 이를 위해 처음에 해시를 발표할 때 Timelock을 이용해서 일정 시간 안에 pre-image를 발표하지 않으면 패널티를 주는 장치를 해두어야 합니다.






참고:


http://solidity.readthedocs.io/en/develop/units-and-global-variables.html#special-variables-and-functions


+ Recent posts