Blokzincir ve rastgele sayı üretilmesi sorunsalı

doğa özcan
2 min readNov 1, 2021

--

Bugün blokzincir üzerindeki rastgele sayı üretilememe durumunu ele alacağız, bu durumun anlaşılması ile node’ların veritabanlarını nasıl diğer node veritabanları ile eşitlediklerini de anlamış olacağız.

Rastgelelik (randomness) genel olarak belirli bir pattern’e ve tahmin edilebilir sıraya uymama hali olarak tanımlanabilir. Gelişigüzel ve sonucu önceden tahmin edilemeyen olguya verilen isimdir.

Yazılım dillerinde genellikle rastgele sayı üreteçlerini kullanırız, yazılım dillerinin doğasının rastgele sayı üretim sonucunu garanti etmesini bekler buna güveniriz. Örneğin javascript dili içerisinde Math.random() metodu ile rastgele sayı üretebiliriz ve bu sayının sonucunu da bir oyun içerisinde kullanabiliriz. Ancak durum blokzincire geldiği zaman maalesef bu süreci yönetmek zorlaşıyor peki neden?

Blokzincir üzerinden bir akıllı sözleşmek düşünelim

function rastgeleSayiUret() external returns (uint256 ){

//rastgele sayı ureten opcode assembly veya degil

uint256 rastgele_sayi = opcode_rastgele_sayi_uret()

//diyelim ki rulet üzerinde 0–36 arasında kadar numara vardır.

uint256 rulet_hangi_numara = rastgele_sayi % 36

//her zaman farklı sonuclar global değişkene yazılıacaktır

return global_kazanan_numara = rulet_hangi_numara;
}

Burada eğer rastgele sayı üreten bir opcode ( opcode_rastgele_sayi_uret())

olsa idi, global değişkenimiz her zaman farklı sonuç ile final state olarak
güncellenirdi. Bu durumun sakıncalarına bakalım.

Klasik veritabanları mimarileri genellikle master-slave şeklinde bir tane referans düğüm ile çalışır, bu düğüm diğer düğümlere yol gösterir,
slave veritabanları master veritabanından belirlenen dakikalarda verileri çeker(sync olur) yani bir mutabakat olacağının garantisi yoktur. Bu durum için kullanılan bazı mimariler vardır bunları inceleyeyim.

Eventual consistency
Düşünün ki dağıtık bir veritabanı yapınız var ancak sizin için verinin en son güncellenmiş hali önceliğiniz değil ve hız önemli bu senaryoda veri tüm node yapılarına eşitlenmeden veriyi çektiğiniz için (bazı node yapıları sync olmadığı için) verinin son halini çekemeyebilirsiniz.

Strong consistency
Bu durum hızdan feragat edip verinin tüm node yapılarına dağıtılmasına beklersiniz böylece daha yavaş şekilde ama verinin en son halini
almayı garantilemiş olursunuz.

Peki ya blokzincir?

Şimdi blokzincire dönersek, her node eklenecek verilere kendisi karar verir, diğer node yapıları ile etkileşimleri veritabanlarına insert(veri ekleme) sürecinde yoktur ve bağımsızdırlar. Her node eklenecek blok verilerini alır ve içerisindeki işlemlerde fraud yok ise(merkle ağacı) her işlemi çalıştırarak veritabanını günceller.

Yukarıdaki akıllı sözleşmemizin function send(tüm ağa) ile veritabanına eklendiğini düşünelim, rastgeleSayiUret her node çalıştırmasında farklı değerleri üretecektir ve final global değer farklı olacaktır böylece her node içerisindeki state farklı olacaktır bu da blokzincirin tasarımına uygun değildir.

Şimdi başka bir örnek düşünelim;

function buyTicket() payable public
{
if(msg.value==p && block.timestamp<=endTime)
{
n = n+1;
participants[n]=msg.sender;
}
}

function draw() public
{
if(block.timestamp>endTime)
{
uint x = random(1,n);
address winner = participants[x];
winner.send(this.balance);
}
}

burada bir piyango uygulaması mevcut, draw metodunda random değer farklı adreslerin seçilmesine yol açarsa her node işlemi çalıştırırken farklı adresleri kazanan olarak duyurur ve istenmeyen sonuçlar oluşur. Bu gibi sözleşmelerde
rastgelelik genellikle blok zamanı üzerinden veya bir seed değeri ile üretilir.

peki blokzincir üzerinde rastgele sayılara nasıl ulaşırız ?

1) oracle vasıtasıyla
2) bir dao yapısı ile (randao)
3) blockhash ile

farklı bir makale olması açısından Probabilistic Smart Contracts:
Secure Randomness on the Blockchain
makalesi de okunmalıdır

https://arxiv.org/ftp/arxiv/papers/1902/1902.07986.pdf

--

--

No responses yet