یاد بگیرید چگونه یک کیف پول امن ارز دیجیتال را از صفر با پایتون بسازید. این راهنمای جامع مفاهیم کلیدی، رمزنگاری، کتابخانهها و مثالهای عملی کد را پوشش میدهد.
ساخت کیف پول ارز دیجیتال با پایتون: راهنمای جامع
در دنیای به سرعت در حال تحول مالی دیجیتال، ارزهای دیجیتال به عنوان نیرویی متحولکننده ظاهر شدهاند. در قلب این انقلاب، مفهوم کیف پول قرار دارد—دروازه شخصی شما برای تعامل با شبکههای بلاکچین. در حالی که بسیاری از کیف پولهای تجاری وجود دارند، درک نحوه عملکرد آنها از درون، یک مهارت ارزشمند برای هر توسعهدهنده یا علاقهمند به فناوری است. این راهنما با آموزش ایجاد یک کیف پول ارز دیجیتال کاربردی از صفر با استفاده از پایتون، این فرآیند را رمزگشایی خواهد کرد.
ما اصول اساسی رمزنگاری، کتابخانههای ضروری پایتون و پیادهسازی گام به گام برای تولید کلیدها، ایجاد آدرس برای هر دو بیت کوین و اتریوم، و امضای تراکنشها را پوشش خواهیم داد. در پایان این مقاله، شما درک محکمی از مکانیسمهای کیف پول و یک کیف پول خط فرمان عملی خود را خواهید داشت.
سلب مسئولیت: کد و مفاهیم ارائه شده در این راهنما فقط برای اهداف آموزشی هستند. ساخت یک کیف پول در سطح تولید نیاز به بررسیهای امنیتی دقیق، آزمایشهای گسترده و اقدامات امنیتی پیشرفته دارد. از کیف پول ایجاد شده در اینجا برای ذخیره وجوه واقعی استفاده نکنید.
درک مفاهیم اصلی یک کیف پول ارز دیجیتال
قبل از اینکه حتی یک خط کد بنویسیم، بسیار مهم است که درک کنیم کیف پول ارز دیجیتال واقعاً چیست. برخلاف نامش، یک کیف پول سکههای شما را "ذخیره" نمیکند. ارز دیجیتال شما به عنوان سوابقی در یک دفتر کل توزیعشده — بلاکچین — وجود دارد. کیف پول قطعهای از نرمافزار است که کلیدهای رمزنگاری را مدیریت میکند که به شما مالکیت و کنترل بر داراییهایتان در آن دفتر کل را میدهد.
اجزای اصلی هر کیف پول غیرحضانتی عبارتند از:
1. کلیدهای خصوصی: راز دیجیتالی شما
یک کلید خصوصی مهمترین بخش اطلاعات در کیف پول شماست. این یک عدد بسیار بزرگ و به صورت تصادفی تولید شده است که محرمانه نگه داشته میشود و فقط شما از آن اطلاع دارید. هدف آن ایجاد یک امضای دیجیتال است که به عنوان اثبات غیرقابل انکار برای تایید تراکنش توسط شما عمل میکند. اگر کلید خصوصی خود را از دست بدهید، دسترسی به وجوه خود را برای همیشه از دست میدهید. اگر شخص دیگری به آن دسترسی پیدا کند، کنترل کامل بر وجوه شما را خواهد داشت.
- تشبیه: کلید خصوصی را به عنوان کلید اصلی گاوصندوق دیجیتالی خود در نظر بگیرید. این کلید میتواند گاوصندوق را باز کرده و جابجایی محتویات آن را تایید کند.
2. کلیدهای عمومی: شناسه قابل اشتراکگذاری شما
یک کلید عمومی به صورت ریاضی از کلید خصوصی شما با استفاده از یک تابع رمزنگاری یکطرفه معروف به رمزنگاری منحنی بیضوی (ECC) مشتق میشود. در حالی که تولید یک کلید عمومی از یک کلید خصوصی امکانپذیر است، انجام عکس آن از نظر محاسباتی غیرممکن است. این رابطه یکطرفه اساس امنیت ارز دیجیتال است.
- تشبیه: کلید عمومی مانند شماره حساب بانکی شماست. میتوانید آن را با دیگران به اشتراک بگذارید تا بتوانند برای شما پول ارسال کنند، اما به آنها توانایی برداشت وجوه را نمیدهد.
3. آدرسها: مقصد عمومی شما
یک آدرس کیف پول، نمایش کوتاهتر و کاربرپسندتر از کلید عمومی شماست. این آدرس با اعمال الگوریتمهای هشینگ اضافی (مانند SHA-256 و RIPEMD-160) بر روی کلید عمومی تولید میشود و اغلب شامل یک چکسام برای جلوگیری از اشتباهات تایپی هنگام ارسال وجوه است. این رشتهای از کاراکترها است که شما با دیگران برای دریافت ارز دیجیتال به اشتراک میگذارید.
- تشبیه: اگر کلید عمومی شماره حساب شما باشد، آدرس مانند یک شماره فاکتور خاص و فرمتبندی شده است که شامل ویژگیهای بررسی خطا میباشد.
4. پیوند رمزنگاری: یک خیابان یکطرفه
رابطه بین این اجزا یک سلسلهمراتب دقیق و یکطرفه است:
کلید خصوصی → کلید عمومی → آدرس
این طراحی تضمین میکند که شما میتوانید آدرس خود را بدون افشای مستقیم کلید عمومی (در برخی موارد) و قطعاً بدون افشای کلید خصوصی خود به اشتراک بگذارید.
5. امضاهای دیجیتال: اثبات مالکیت
هنگامی که میخواهید ارز دیجیتال ارسال کنید، یک پیام تراکنش ایجاد میکنید (به عنوان مثال، "ارسال 0.5 BTC از آدرس A به آدرس B"). نرمافزار کیف پول شما سپس از کلید خصوصی شما برای ایجاد یک امضای دیجیتال منحصر به فرد برای آن تراکنش خاص استفاده میکند. این امضا همراه با تراکنش به شبکه پخش میشود. ماینرها و نودهای شبکه میتوانند از کلید عمومی شما برای تأیید اعتبار امضا استفاده کنند و بدین ترتیب تأیید کنند که تراکنش توسط مالک قانونی وجوه بدون نیاز به مشاهده کلید خصوصی شما تأیید شده است.
راهاندازی محیط توسعه پایتون شما
برای ساخت کیف پول خود، به چند کتابخانه تخصصی پایتون نیاز داریم که رمزنگاری پیچیده مربوطه را مدیریت میکنند. اطمینان حاصل کنید که پایتون 3.6 یا جدیدتر را نصب کردهاید. میتوانید بستههای لازم را با استفاده از pip نصب کنید:
pip install ecdsa pysha3 base58
بیایید بررسی کنیم که هر کتابخانه چه کاری انجام میدهد:
- ecdsa: این یک کتابخانه حیاتی برای پیادهسازی الگوریتم امضای دیجیتال منحنی بیضوی (ECDSA) است. ما از آن برای تولید کلیدهای خصوصی و عمومی بر اساس منحنی
SECP256k1استفاده خواهیم کرد که استاندارد مورد استفاده بیت کوین، اتریوم و بسیاری دیگر از ارزهای دیجیتال است. همچنین ایجاد و تأیید امضاهای دیجیتال را نیز مدیریت میکند. - pysha3: در حالی که
hashlibداخلی پایتون از بسیاری از الگوریتمهای هشینگ پشتیبانی میکند، شامل Keccak-256 نیست که برای تولید آدرسهای اتریوم مورد نیاز است. این کتابخانه این قابلیت را فراهم میکند. - base58: این کتابخانه کدگذاری Base58Check را پیادهسازی میکند، فرمتی که برای ایجاد آدرسهای بیت کوین خوانا استفاده میشود. این کدگذاری شامل یک چکسام برای کمک به جلوگیری از خطاهای تایپی است.
- hashlib: این کتابخانه داخلی پایتون برای هشینگ SHA-256 و RIPEMD-160 استفاده خواهد شد که مراحل ضروری در ایجاد آدرس بیت کوین هستند.
پیادهسازی گام به گام: ساخت منطق کیف پول
اکنون، بیایید به کد بپردازیم. ما عملکردهای اصلی کیف پول خود را قطعه به قطعه میسازیم و هر مرحله را در طول مسیر توضیح میدهیم.
گام 1: تولید یک کلید خصوصی
یک کلید خصوصی اساساً یک عدد 256 بیتی (32 بایتی) است. مهمترین نیاز این است که باید با تصادفی واقعی تولید شود. استفاده از یک مولد اعداد تصادفی ضعیف میتواند منجر به کلیدهای قابل پیشبینی شود که یک مهاجم میتواند آنها را حدس بزند.
ماژول secrets داخلی پایتون برای تولید اعداد تصادفی امن رمزنگاری شده طراحی شده است، که آن را برای نیازهای ما عالی میکند.
import os
import hashlib
import base58
import ecdsa
from sha3 import keccak_256
def generate_private_key():
"""Generate a secure 32-byte private key."""
private_key_bytes = os.urandom(32)
return private_key_bytes
در اینجا، os.urandom(32) 32 بایت تصادفی امن رمزنگاری شده را فراهم میکند که دقیقاً همان چیزی است که برای یک کلید خصوصی 256 بیتی نیاز داریم.
گام 2: استخراج کلید عمومی
سپس، کلید عمومی را از کلید خصوصی با استفاده از منحنی بیضوی SECP256k1 استخراج میکنیم. کتابخانه ecdsa این فرآیند را ساده میکند.
def private_key_to_public_key(private_key_bytes):
"""Convert a private key to its corresponding public key."""
# SECP256k1 is the curve used by Bitcoin and Ethereum
sk = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1)
# Get the public key in uncompressed format (starts with 0x04)
vk = sk.verifying_key
public_key_bytes = vk.to_string("uncompressed")
return public_key_bytes
شیء ecdsa.SigningKey نشاندهنده کلید خصوصی ماست. سپس verifying_key (کلید عمومی) مربوطه را دریافت کرده و آن را در فرمت "فشردهنشده" (uncompressed) استخراج میکنیم. یک کلید عمومی فشردهنشده 65 بایت طول دارد: یک پیشوند 0x04 که به دنبال آن مختصات X 32 بایتی و مختصات Y 32 بایتی یک نقطه روی منحنی بیضوی میآیند.
گام 3: ایجاد یک آدرس بیت کوین
تولید یک آدرس بیت کوین از یک کلید عمومی یک فرآیند چند مرحلهای است که برای امنیت و بررسی خطا طراحی شده است. در اینجا جریان استاندارد تولید آدرس P2PKH (پرداخت به هش کلید عمومی) آمده است:
- هشینگ SHA-256: کلید عمومی را با استفاده از SHA-256 هش کنید.
- هشینگ RIPEMD-160: نتیجه گام قبلی را با استفاده از RIPEMD-160 هش کنید.
- افزودن بایت نسخه: یک پیشوند بایت نسخه به هش RIPEMD-160 اضافه کنید. برای شبکه اصلی بیت کوین، این
0x00است. - محاسبه چکسام: هش SHA-256 را دو بار روی هش توسعهیافته انجام دهید و 4 بایت اول هش نهایی را بگیرید. این چکسام است.
- الحاق چکسام: چکسام 4 بایتی را به انتهای هش دارای پیشوند نسخه الحاق کنید.
- کدگذاری Base58Check: کل رشته بایت را با استفاده از Base58Check کدگذاری کنید تا آدرس نهایی و خوانا را بدست آورید.
بیایید این را در پایتون پیادهسازی کنیم:
def public_key_to_btc_address(public_key_bytes):
"""Convert a public key to a Bitcoin P2PKH address."""
# Step 1 & 2: SHA-256 then RIPEMD-160
sha256_hash = hashlib.sha256(public_key_bytes).digest()
ripemd160_hash = hashlib.new('ripemd160')
ripemd160_hash.update(sha256_hash)
hashed_public_key = ripemd160_hash.digest()
# Step 3: Add version byte (0x00 for Mainnet)
version_byte = b'\x00'
versioned_hash = version_byte + hashed_public_key
# Step 4 & 5: Create checksum and append
# Double SHA-256 hash
checksum_hash_1 = hashlib.sha256(versioned_hash).digest()
checksum_hash_2 = hashlib.sha256(checksum_hash_1).digest()
checksum = checksum_hash_2[:4]
binary_address = versioned_hash + checksum
# Step 6: Base58Check encode
btc_address = base58.b58encode(binary_address).decode('utf-8')
return btc_address
گام 4: ایجاد یک آدرس اتریوم
تولید آدرس اتریوم در مقایسه با بیت کوین سادهتر است. این کار شامل گرفتن هش Keccak-256 از کلید عمومی و استفاده از 20 بایت آخر نتیجه است.
- هشینگ Keccak-256: هش Keccak-256 کلید عمومی را بگیرید. توجه داشته باشید که ما باید از کلید عمومی *بدون* پیشوند
0x04استفاده کنیم. - گرفتن 20 بایت آخر: آدرس اتریوم 20 بایت آخر (40 کاراکتر هگزادسیمال) این هش است.
- قالببندی: استاندارد است که آدرس با
0xپیشوند شود.
بیایید این را با استفاده از pysha3 پیادهسازی کنیم:
def public_key_to_eth_address(public_key_bytes):
"""Convert a public key to an Ethereum address."""
# Ethereum address generation uses the uncompressed public key without the 0x04 prefix
uncompressed_pk = public_key_bytes[1:]
# Step 1: Keccak-256 hash
keccak_hash = keccak_256(uncompressed_pk).digest()
# Step 2: Take the last 20 bytes
eth_address_bytes = keccak_hash[-20:]
# Step 3: Format with '0x' prefix
eth_address = '0x' + eth_address_bytes.hex()
return eth_address
گام 5: امضای یک پیام
یک امضای دیجیتال ثابت میکند که صاحب یک کلید خصوصی، پیامی (مانند یک تراکنش) را تأیید کرده است. این فرآیند شامل امضای هش پیام، و نه خود پیام خام، برای کارایی و امنیت است.
def sign_message(private_key_bytes, message):
"""Sign a message with the given private key."""
# It's standard practice to sign the hash of the message
message_hash = hashlib.sha256(message.encode('utf-8')).digest()
sk = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1)
signature = sk.sign(message_hash)
return signature
گام 6: تأیید یک امضا
تأیید فرآیند معکوس است. هر کسی با کلید عمومی، پیام اصلی و امضا میتواند تأیید کند که امضا معتبر است. اینگونه شبکه بلاکچین تراکنشها را تأیید میکند.
def verify_signature(public_key_bytes, signature, message):
"""Verify a signature for a message with the given public key."""
message_hash = hashlib.sha256(message.encode('utf-8')).digest()
vk = ecdsa.VerifyingKey.from_string(public_key_bytes, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
try:
# The verify method will return True if valid, or raise an exception
return vk.verify(signature, message_hash)
except ecdsa.BadSignatureError:
return False
اسمبل کردن کیف پول: یک رابط خط فرمان ساده (CLI)
اکنون که تمام توابع اصلی را داریم، بیایید آنها را در یک ابزار خط فرمان ساده و قابل استفاده گردآوری کنیم. ما یک کلاس Wallet برای کپسولهسازی منطق ایجاد خواهیم کرد و از ماژول argparse پایتون برای مدیریت دستورات کاربر استفاده میکنیم.
در اینجا یک اسکریپت کامل که تمام توابع ما را در یک برنامه منسجم ادغام میکند، آورده شده است.
#!/usr/bin/env python3
import os
import hashlib
import base58
import ecdsa
import argparse
from sha3 import keccak_256
class Wallet:
"""Represents a cryptocurrency wallet with key management and address generation."""
def __init__(self, private_key_hex=None):
if private_key_hex:
self.private_key = bytes.fromhex(private_key_hex)
else:
self.private_key = self._generate_private_key()
self.public_key = self._private_to_public_key(self.private_key)
self.btc_address = self._public_to_btc_address(self.public_key)
self.eth_address = self._public_to_eth_address(self.public_key)
def _generate_private_key(self):
return os.urandom(32)
def _private_to_public_key(self, private_key):
sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
return sk.verifying_key.to_string("uncompressed")
def _public_to_btc_address(self, public_key):
sha256_hash = hashlib.sha256(public_key).digest()
ripemd160 = hashlib.new('ripemd160')
ripemd160.update(sha256_hash)
hashed_pk = ripemd160.digest()
versioned_hash = b'\x00' + hashed_pk
checksum = hashlib.sha256(hashlib.sha256(versioned_hash).digest()).digest()[:4]
binary_address = versioned_hash + checksum
return base58.b58encode(binary_address).decode('utf-8')
def _public_to_eth_address(self, public_key):
uncompressed_pk = public_key[1:]
keccak_hash = keccak_256(uncompressed_pk).digest()
return '0x' + keccak_hash[-20:].hex()
def display_details(self):
print(f"Private Key (hex): {self.private_key.hex()}")
print(f"Public Key (hex): {self.public_key.hex()}")
print(f"Bitcoin Address: {self.btc_address}")
print(f"Ethereum Address: {self.eth_address}")
def main():
parser = argparse.ArgumentParser(description="A simple command-line cryptocurrency wallet.")
parser.add_argument("command", choices=["create", "details"], help="The command to execute.")
parser.add_argument("--privatekey", help="An existing private key in hex format to get details from.")
args = parser.parse_args()
if args.command == "create":
wallet = Wallet()
print("--- New Wallet Created ---")
wallet.display_details()
print("\n*** IMPORTANT ***")
print("Save your private key in a secure location. It is the only way to access your funds.")
elif args.command == "details":
if not args.privatekey:
print("Error: The 'details' command requires a private key using the --privatekey flag.")
return
try:
wallet = Wallet(private_key_hex=args.privatekey)
print("--- Wallet Details ---")
wallet.display_details()
except Exception as e:
print(f"Error loading wallet from private key: {e}")
if __name__ == "__main__":
main()
نحوه استفاده از این ابزار CLI:
- کد بالا را به عنوان یک فایل پایتون ذخیره کنید (مثلاً
cli_wallet.py). - ترمینال یا خط فرمان خود را باز کنید.
- برای ایجاد یک کیف پول جدید:
python cli_wallet.py create - برای مشاهده جزئیات از یک کلید خصوصی موجود:
python cli_wallet.py details --privatekey YOUR_PRIVATE_KEY_IN_HEX
بهترین روشهای امنیتی و ملاحظات مهم
ما با موفقیت یک کیف پول پایه ساختیم، اما یک برنامه آماده تولید نیاز به تمرکز بسیار عمیقتری بر امنیت دارد. در اینجا چند نکته حیاتی برای بررسی وجود دارد.
1. هرگز کلیدهای خصوصی را به صورت متن ساده ذخیره نکنید
اسکریپت ما کلید خصوصی را در کنسول چاپ میکند که بسیار ناامن است. در یک برنامه واقعی، کلیدهای خصوصی باید در حالت سکون با استفاده از یک رمز عبور قوی رمزگذاری شوند. آنها فقط باید در حافظه هنگام نیاز برای امضا رمزگشایی شوند. راه حلهای حرفهای اغلب از ماژولهای امنیتی سختافزاری (HSM) یا فضاهای امن در دستگاهها برای محافظت از کلیدها استفاده میکنند.
2. اهمیت آنتروپی
امنیت کیف پول شما با تصادفی بودن (آنتروپی) استفاده شده برای تولید کلید خصوصی آغاز میشود. os.urandom یک منبع خوب در اکثر سیستم عاملهای مدرن است، اما برای برنامههای با ارزش بالا، توسعهدهندگان اغلب آنتروپی را از منابع متعدد جمعآوری میکنند تا غیرقابل پیشبینی بودن را تضمین کنند.
3. عبارات یادآور (Seed Phrases) - استاندارد صنعت
پشتیبانگیری دستی از کلیدهای خصوصی هگزادسیمال طولانی، دست و پا گیر و مستعد خطا است. صنعت این مشکل را با کیف پولهای سلسلهمراتبی قطعی (HD) (تعریف شده در BIP-32) و عبارات یادآور (BIP-39) حل کرد. عبارت یادآور دنبالهای از 12-24 کلمه رایج است که میتوان از آن برای بازتولید قطعی کلید خصوصی اصلی و تمام کلیدهای بعدی استفاده کرد. این کار پشتیبانگیری و بازیابی کیف پول را بسیار کاربرپسندتر میکند.
4. این یک ابزار آموزشی است، نه یک کیف پول تولیدی
تأکید مجدد بر این نکته حیاتی است که این پیادهسازی یک مدل سادهشده است. یک کیف پول واقعی باید چندین آدرس را مدیریت کند، با نودهای بلاکچین برای دریافت موجودیها و ساخت تراکنشها تعامل داشته باشد، کارمزدها را محاسبه کند و تراکنشهای امضا شده را به شبکه پخش کند. همچنین نیاز به یک رابط کاربری امن و مدیریت خطای قوی دارد.
5. تعامل شبکه
کیف پول ما میتواند کلید تولید کرده و پیامها را امضا کند، اما نمیتواند با شبکه بلاکچین ارتباط برقرار کند. برای ساخت یک برنامه کامل، باید کتابخانههایی را ادغام کنید که بتوانند از طریق RPC (فراخوانی رویه از راه دور) به نودهای بلاکچین متصل شوند. برای اتریوم، web3.py کتابخانه استاندارد است. برای بیت کوین، کتابخانههایی مانند python-bitcoinlib میتوانند استفاده شوند.
نتیجهگیری و گامهای بعدی
تبریک میگوییم! شما با موفقیت هسته رمزنگاری یک کیف پول ارز دیجیتال را با استفاده از پایتون ساختید. ما از نظریه اساسی رمزنگاری کلید عمومی/خصوصی به یک پیادهسازی عملی رسیدیم که آدرسهای معتبر را برای هر دو شبکه بیت کوین و اتریوم تولید میکند.
این پروژه یک پایه قوی برای کاوش عمیقتر در فناوری بلاکچین فراهم میکند. شما از نزدیک دیدهاید که یک کیف پول، در هسته خود، یک سیستم مدیریت کلید پیچیده است که بر مبنای اصول رمزنگاری اثباتشده ساخته شده است.
از اینجا به کجا میروید؟ این چالشها را به عنوان گامهای بعدی خود در نظر بگیرید:
- پیادهسازی کیف پولهای HD: استانداردهای BIP-32، BIP-39 و BIP-44 را بررسی کنید تا کیف پولی ایجاد کنید که بتواند میلیونها آدرس را از یک عبارت یادآور (seed phrase) واحد مدیریت کند.
- اتصال به شبکه: از
web3.pyبرای اتصال به یک نود اتریوم (مانند Infura یا Alchemy)، بررسی موجودی آدرس و ساخت یک تراکنش خام استفاده کنید. - ساخت یک رابط کاربری: یک رابط کاربری گرافیکی (GUI) ساده با استفاده از چارچوبی مانند Tkinter یا یک رابط وب با استفاده از Flask/Django ایجاد کنید تا کیف پول خود را کاربرپسندتر کنید.
- کاوش در سایر بلاکچینها: نحوه تولید آدرسها توسط سایر پلتفرمهای بلاکچین را بررسی کنید و کد خود را برای پشتیبانی از آنها تطبیق دهید.
دنیای بلاکچین بر همکاری منبع باز و عطش برای دانش بنا شده است. با ساخت ابزارهایی مانند این، شما فقط کدنویسی را یاد نمیگیرید – شما در حال یادگیری زبان یک اقتصاد دیجیتال جدید هستید. به آزمایش، ساخت و کاوش پتانسیل عظیم فناوری غیرمتمرکز ادامه دهید.