Kiedy wybieramy termin na [integracje](https://forum.sealcode.org/tags/integracja) lub [inne wydarzenia](https://forum.sealcode.org/tags/wydarzenia), używamy [ankiet na forum](https://meta.discourse.org/t/how-to-create-polls/77548), aby znaleźć termin pasujący jak największej ilości osób. Ale co zrobić, jeżeli jest kilka najpopularniejszych opcji, i mają równą ilość głosów?
Przed organizatorem wydarzenia stoi trudne wyzwanie - ponieważ wybór konkretnego terminu wiąże się z wybraniem konkretnej grupy osób. Jak zdecydować, kto nie będzie brał udziału w wydarzeniu, bo wybrany zostanie termin który mu/jej nie pasuje?
Aby zdjąć tę stresującą odpowiedzialność z barków organizatora, potrzebowaliśmy mieć rozwiązanie, które w weryfikowalny sposób wybierze jakąś opcję bez udziału organizatora, korzystając z metody na którą nie można wpłynąć i której wynik nie jest znany przed zakończeniem ankiety. I znaleźliśmy takie!
W Sealcode korzystamy w tym celu z Randomness Beacons, generowanych przez [NIST](https://csrc.nist.gov/projects/interoperable-randomness-beacons). Co określony interwał czasu generują one losowe liczby, korzystając z różnych generatorów entropii oraz haszy wcześniej wygenerowanych liczb. Przechowują każdą z tych liczb i udostępniają API do przeglądania ich historii, wraz z datami i godzinami. Kluczowym jest fakt, że //nie można poznać wartości Beacona dla daty/godziny w przyszłości//
Przy ich użyciu sposób ustalania terminów jest następujący:
1. Organizator wprowadza do ankiety możliwe do wyboru terminy i określa termin udzielania odpowiedzi (np. 4-08-2019, godz 23:59)
2. Organizator przed otwarciem ankiety informację o tym, z jakiego dnia i godziny będzie pobrana liczba z Randomness Beacons, np: "5 Aug 2019 00:00:00 GMT"
3. Organizator otwiera ankietę
4. Osoby chętne do udziału w wydarzeniu wybierają wszystkie pasujące im opcje
5. Nadchodzi termin zamknięcia ankiety i organizator wyłącza możliwość oddawania nowych głosów
6. Jeżeli jest tylko jeden wygrywający ankietę termin, to ten termin jest wybrany.
7. W przeciwnym wypadku, po minięciu momentu w czasie określonego w punkcie 2 organizator odczytuje wartość Beaconu i bierze resztę z dzielenia tej wartości przez liczbę zwycięskich w ankiecie opcji. Dostajemy w ten sposób indeks opcji, która została wskazana przez Beaconową Wyrocznię. Organizator sortuje opcje chronologicznie (opcja najwcześniejsza ma indeks 0) i ujawnia opcję o indeksie wskazaną przez Wyrocznię jako wybrany termin wydarzenia.
8. Uczestnicy mogą samodzielnie sprawdzić wybór Wyroczni i jego zgodność z wybranym terminem
W praktyce pobieranie wartości Beaconu i wykonanie operacji modulo można wykonać następującym skryptem:
```
lang=bash, name=wyrocznia.sh
BEACON_DATE="14 Jul 2019 00:00:00 GMT";
OPTIONS=3;
URL=https://beacon.nist.gov/beacon/2.0/pulse/time/previous/`node -p "Date.parse(\"$BEACON_DATE\")"`;
BEACON=`curl $URL | jq '.pulse.listValues[] | select(.type | contains("day")).value' | sed 's/"//g' | tail -c 16`;
echo "the decimal beacon value is:" $((16#$BEACON));
echo "the oracle chose option with index:" $(( $((16#$BEACON)) % $OPTIONS ));
```
(w tym przykładzie wybieramy ostatnie 16 cyfr liczby wygenerowanej przez Beacon, co i tak daje nam wystarczającą ilość entropii dla naszego zastosowania)
Polecam używanie tej metody także do rozstrzygania innego typu remisów zarówno w pracy (kto będzie jutro zamykał biuro?) czy w życiu osobistym (idziemy w piątek na pizzę czy na ramen?)