Python ile Adım Adım Bitcoin Adresi Hesaplama
Bir para transferi işlemi nasıl ki gönderici ve alıcı hesap bilgilerini içeriyorsa, bir bitcoin işleminde de gönderici ve alıcının bitcoin adres bilgileri bulunmaktadır. Bitcoin protokolü aslında açık anahtar kriptografisi yöntemi olan elliptik eğri kriptografisi üzerine inşa edilmiştir. Bu sebeple de her şey gizli ve açık anahtar etrafında döner. Peki bitcoin adresi nereden çıktı? Bitcoin işlemlerindeki adresin rolü tam olarak nedir? Bu yazıda python ile adım adım bitcoin adresi hesaplama konusuna değineceğiz.
Açık anahtarın hesaplanması
Varsayalım ki aşağıdaki değeri gizli anahtarınız olarak belirlediniz. Burada beklenilen 256-bit uzunluğunda bir tam sayı değerinin belirlenmesidir.
1 2 3 4 5 |
privateKey = 11253563012059685825953619222107823549092147699031672238385790369351542642469 |
Bitcoin protokolü yukarıdaki elliptik eğriyi kullanmaktadır. Bu eğri üzerindeki başlangıç noktasının değeri protokol tanımlanırken aşağıdaki şekilde belirlenmiştir.
x0 =
5506626302227734366957871889516
8534326250603453777594175500187
360389116729240
y0 =
326705100207588169780830851
305070431844712733806592432
75938904335757337482424
Bu durumda açık anahtar aşağıdaki değer olacaktır. Dikkat edilirse açık anahtar x ve y eksen değerlerini içeren bir noktadan ibarettir. Bu hesaplama için elliptik eğriler üzerinde toplama işlemi kuralından kuralından yararlanılmıştır. Bugünkü hesaplama kabiliyetimiz ile bu hesap hızlı bir işlemken geriye dönülmesi hiç de kolay değildir.
publIc key = (
3642219147190724102988392534
22518316242009213885860253441
28047678873736520530,
202771108870563038036994317
553960037350403747601189647
34768299847012543114150
)
Artık açık anahtara sahibiz ve adresi hesaplamaya geçebiliriz. İlk olarak açık anahtarın içeriğini hexadecimal’e dönüştürmemiz gerekiyor. Python’da hex komutu bu işlemi yapmakta ancak ön ek olarak 0x’i eklemekte. Hexadecimal dönüşümü yaptıktan sonra başlangıç indeksini belirterek bu ön ekten kurtulabiliriz. Sonrasında da 04 ön ekini eklememiz gerekiyor.
1 2 3 4 5 |
publicKeyHex = "04"+hex(publicKey[0])[2:]+hex(publicKey[1])[2:] |
Böylelikle açık anahtarımızı aşağıdaki şekilde gösterebiliyoruz.
publIc key (hex):
0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511
dad8a04887e5b23522cd470243453a299fa9e77237716103
abc11a1df38855ed6f2ee187e9c582ba6
Açık anahtarın özetinin alınması
Açık anahtar hesaplandıktan sonra bir dizi hash fonksiyonları ile özetleyeceğiz. Genel bir hash mekanizması kurulması için aşağıdaki fonksiyonları kullanabiliriz.
1 2 3 4 5 6 7 8 9 10 11 |
def hexStringToByte(content): return codecs.decode(content.encode("utf-8"), 'hex') def hashHex(algorithm, content): my_sha = hashlib.new(algorithm) my_sha.update(hexStringToByte(content)) return my_sha.hexdigest() |
Açık anahtarı ilk olarak SHA-256 sonrasında da RIPEMD160 özet fonksiyonlarına sokmamız gerekiyor. Sonrasında da iki kez özetlenmiş değerin başına 00 ön ekini ekleyeceğiz.
1 2 3 4 5 6 7 8 9 10 11 12 |
output = hashHex('sha256', publicKeyHex) print("apply sha-256 to public key: ",output) output = hashHex('ripemd160', output) print("apply ripemd160 to sha-256 applied public key: ", output) output = "00"+output print("add network bytes to ripemd160 applied hash - extended ripemd160: ", output,"n") |
Bu işlem aşağıdaki özet değerlerini üretecektir.
apply sha-256 to publIc key hex:
600ffe422b4e00731a59557a5cca46cc1
83944191006324a447bdb2d98d4b408
apply rIpemd160 to sha-256 applIed publIc key: 010966776006953d5567439e5e39f86a0d273bee
add network bytes to rIpemd160 applIed hash – extended rIpemd160: 00010966776006953d5567439e5e39f86a0d273bee
Sağlama (Checksum)
Açık anahtar özetlendikten sonra sağlama işlemi uygulayacağız. Sağlama değerinin üretilmesi için açık anahtarın bir önceki bölümde hesaplanmış özetine iki kez SHA-256 fonksiyonunu uygulayacağız. Bu yeni özet değerin ilk 8 karakteri de bizim için sağlama değeri olacak.
1 2 3 4 5 6 |
checksum = hashHex('sha256', hashHex('sha256', output)) checksum = checksum[0:8] |
Açık anahtarımız için sağlama değeri de aşağıdaki gibi olacaktır.
extract fIrst 8 characters as checksum: d61967f6
Adres
Açık anahtarın özetine bu sağlama değerini ekleyeceğiz.
1 2 3 4 5 |
address = output+checksum |
Bu şekilde ham adresi üretmiş oluyoruz.
checksum appended publIc key hash:
00010966776006953d5567439
e5e39f86a0d273beed61967f6
Son olarak bu ham adrese base-58 kodlamasını uygulayarak adres üretimini tamamlayacağız. Bu kodlama için GitHub’tan bulduğum mükemmel implementasyon‘u kullanacağım.
1 2 3 4 5 6 |
address = base58.b58encode(hexStringToByte(address)) print("this is your bitcoin address:",str(address)[2:len(address)-2]) |
Böylelikle bitcoin adresimizin üretimi tamamlanmış oldu.
16UwLL9Risc3QfPqBUvKofHmBQ7wM
Toparlarken..
Başlangıçta rastgele bir gizli anahtar seçtik ve kendi açık anahtarımızı hesapladık. Sonrasında açık anahtara bir takım özetleme fonksiyonları uygulayarak bitcoin adresimizi hesapladık. İlgimiz olan tüm işlemler bitcoin adresimizi içerecekken bize ait gizli anahtar ile bu işlemleri imzalayacağız. Bitcoin ağının diğer kullanıcıları da bize ait açık anahtar ile bu işlemi doğrulayacaklar.
Son olarak, bu yazıyı yazarken kullandığım kaynak kodunu GitHub‘da paylaştım.
Bu yazı “A Step by Step Bitcoin Address Example” yazısından Türkçe’ye çevrilmiştir.