آموزش قدم به قدم ساخت یک بلاک چین ساده با python
اگر شما اینجایید ، احتمالا مثل من مجنون آموزش بلاکچین ارزهای دیجیتال و بلاک چین هستید و می خواهید بدانید که سیستم بلاک چین چگونه کار می کند و تکنولوزی بنیادین پشت آن چیست. اما فهم سیستم های بلاک چینی ساده نیست یا حداقل برای من اینطور نبود. من در فیلم های عمیقی ازهم پاشیدم، آموزش های مختلف زیادی را بررسی کردم و در مواجهه با مثال های اندک دچار ناامیدی زیادی نیز شدم.
من یادگیری را به همراه عمل دوست دارم. این کار مرا در مرحله کد مجبور به مواجهه با صورت مسئله می کند. اگر شما هم همین کار را انجام دهید در پایان این آموزش یک سیستم بلاک چین فعال دارید به علاوه درک صحیحی از نحوه عملکرد آن.
قبل از شروع…
یاد آور می شوم که بلاک چین یک زنجیره متوالی از رکورد های تغییرناپذیر است که بلاک (block) نامیده می شوند. محتویات این بلاک ها میتواند شامل اطلاعات معاملات یا فایل یا هرچیز دیگری که فکر میکنید یا می خواهید باشد. اما مهم ترین چیز این است که این بلاک ها بصورت متوالی و زنجیره وار با استفاده از هش (hash) به یکدیگر وصلند. اگر در مورد hash اطلاعات کافی ندارید می توانید به این لینک مراجعه کنید و توضیح مختصری درباره آن بخوانید.
این آموزش به درد چه کسی میخورد؟
شما باید به زبان python آشنایی داشته باشید بخصوص نحوه تعریف و استفاده از class ها، همچنین آشنایی با نحوه کار پروتکل http (مثلا چه نوع درخواست هایی مبتنی بر بستر http وجود دارد و چگونه کار میکنند) به دلیل اینکه ما با بلاک چین خودمان از طریق پروتکل http مکاتبه و تعامل خواهیم داشت.
برنامه ها وکتابخانه های پیش نیاز:
- Python v۳.۶+
- Flask
- Requests
کد نهایی را از اینجا می توانید دانلود کنید.
گام اول: ساخت یک بلاک چین
نرم افزار ویرایش متن (text editor) یا IDE مورد علاقه خود را باز کنید. یک فایل جدید بنام “blockchain.py” ایجاد کنید . ما فقط از یک فایل استفاده خواهیم کرد. اما اگر چیزی را گم کردید یا از دست دادید میتوانید به سورس کد برنامه مراجعه کنید.
پیاده سازی یک بلاک چین
ما یک کلاس بنام “Blockchain” خواهیم ساخت که متد سازنده ( __init__ ) آن دو لیست خالی اولیه ایجاد می کند که یکی برای ذخیره زنجیره های بلاک هایمان استفاده می شود و دیگری برای ذخیره ی تراکنش ها. نمونه اولیه کد کلاس ما:
class Blockchain(object):
def __init__(self):
self.chain = []
self.current_transactions = []
def new_block(self):
# ایجاد بلاک جدید و اضافه کردن آن به زنجیره
pass
def new_transaction(self):
# اضافه کردن تراکنش جدید به لیست تراکنش ها
pass
@staticmethod
def hash(block):
# هش کردن یک بلاک
pass
@property
def last_block(self):
# بازگرداندن آخرین بلاک در زنجیره
pass
کلاس “Blockchain” ما برای مدیریت زنجیره، پاسخگو است. این کلاس تراکنش ها را ذخیره می کند و تعدادی متد های کمکی برای اضافه کردن بلاک های جدید به زنجیره دارد.
ساختار یک بلاک چه شکلی ست؟
هر بلاک شامل یک شماره (index)، یک برچسب زمانی در قالب سیستم زمانی یونیکس (unix timestamp)، یک لیستی از تراکنش ها (transactions)، یک پروف (proof) و در نهایت هش (hash) بلاک قبلی می باشد.
مثالی از کد بلاک مورد نظر ما :
block = {
‘index’: ۱,
‘timestamp’: ۱۵۰۶۰۵۷۱۲۵.۹۰۰۷۸۵,
‘transactions’: [
{
‘sender’: “۸۵۲۷۱۴۷fe۱f۵۴۲۶f۹dd۵۴۵de۴b۲۷ee۰۰”,
‘recipient’: “a۷۷f۵cdfa۲۹۳۴df۳۹۵۴a۵c۷c۷da۵df۱f”,
‘amount’: ۵,
}
],
‘proof’: ۳۲۴۹۸۴۷۷۴۰۰۰,
‘previous_hash’: “۲cf۲۴dba۵fb۰a۳۰e۲۶e۸۳b۲ac۵b۹e۲۹e۱b۱۶۱e۵c۱fa۷۴۲۵e۷۳۰۴۳۳۶۲۹۳۸b۹۸۲۴”
}
در این نقطه ایده ی زنجیره باید آشکار باشد بدین صورت که هر بلاک، هش بلاک قبلی را در خود دارد. این مسله خیلی حیاتی ست چرا که همین عامل باعث تغییرناپذیریه سیستم بلاک چین می شود. اگر یک حمله کننده (attacker) یکی از بلاک های قبلی در زنجیره را دستکاری یا خراب کند متعاقبا هش همه بلاک های بعد از آن بلاک دستکاری شده، دیگر درست نخواهند بود.
آیا این روش معقول است؟ اگر نه کمی بیشتر وقت بگذارید و روی این موضوع فکر کنید. هسته ی ایده ی پشت بلاک چین همین خاصیت است.
اضافه کردن تراکنش ها به بلاک
ما به روشی نیازمندیم جهت اضافه کردن تراکنش ها به یک بلاک. انجام این کار به عهده ی متد “new_transaction” است:
class Blockchain(object):
…
def new_transaction(self, sender, recipient, amount):
“””
در این متد یک تراکنش جدید ایجاد میشود تا درون بلاک ماین شده ی بعدی ذخیره شود
:param sender: <str> آدرس فرستنده
:param recipient: <str> آدرس گیرنده
:param amount: <int> مقداری که قرار است جابجا شود
:return: <int> شماره بلاکی که اطلاعات این تراکنش را درخود جای خواهد داد
“””
self.current_transactions.append({
‘sender’: sender,
‘recipient’: recipient,
‘amount’: amount,
})
return self.last_block[‘index’] + ۱
بعد از اینکه متد “new_transaction” یک تراکنش را به لیست اضافه کرد شماره بلاکی که تراکنش به آن اضافه خواهد شد را برمی گرداند که همان بلاک بعدی می شود که باید استخراج (mine) شود. این کار برای موارد بعدی که شخصی تراکنشی ارسال می کند مفید خواهد بود.
ساخت بلاک های جدید
وقتی از روی کلاس “Blockchain” ما یک نمونه (instance) ایجاد شد، باید یک بلاک اولیه که آن را “genesis” یا “منشأ” می نامیم، درونش ایجاد کنیم. درواقع با بلاک اولیه بذردهی اش میکنیم. همچنین باید به بلاک اولیه مان یک پروف (proof) اضافه کنیم که نتیجه و جوابش همان نتیجه mine کردن می شود که به آن اثبات کار (proof of work) هم میگیوییم.
خوب ما کد ایجاد بلاک اولیه مان (genesis) را در متد سازنده ( __init__ ) کلاسمان خواهیم نوشت و علاوه بر آن متدهای دیگر را هم بنام های “new_block”، “new_transaction” و “hash” تکمیل خواهیم نمود:
import hashlib
import json
from time import time
class Blockchain(object):
def __init__(self):
self.current_transactions = []
self.chain = []
# ساخت بلاک اولیه
self.new_block(previous_hash=1, proof=۱۰۰)
def new_block(self, proof, previous_hash=None):
“””
ساخت بلاک جدید در زنجیره بلاک چین
:param proof: <int> پروف داده شده توسط الگوریتم اثبات کار
:param previous_hash: (Optional) <str> هش بلاک قبلی
:return: <dict> بلاک جدید
“””
block = {
‘index’: len(self.chain) + ۱,
‘timestamp’: time(),
‘transactions’: self.current_transactions,
‘proof’: proof,
‘previous_hash’: previous_hash or self.hash(self.chain[-1]),
}
# خالی کردن لیست کنونی تراکنش ها
self.current_transactions = []
self.chain.append(block)
return block
def new_transaction(self, sender, recipient, amount):
“””
Creates a new transaction to go into the next mined Block
:param sender: <str> آدرس فرستنده
:param recipient: <str> آدرس گیرنده
:param amount: <int> مقدار
:return: <int> شماره بلاکی که اطلاعات این تراکنش را درخود جای خواهد داد
“””
self.current_transactions.append({
‘sender’: sender,
‘recipient’: recipient,
‘amount’: amount,
})
return self.last_block[‘index’] + ۱
@property
def last_block(self):
return self.chain[-۱]
@staticmethod
def hash(block):
“””
از روی اطلاعات یک بلاک SHA-256 ساخت هش از نوع
:param block: <dict> Block
:return: <str> (hex) هش بلاک در قالب هگز
“””
# باید حتما اطلاعات بلاک را قبل از عملیات هش مرتب سازی کنیم
# تا با هش های نابرابر برای بلاک های با اطلاعات یکسان مواجه نشویم
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha۲۵۶(block_string).hexdigest()
ما تقریبا کد بلاک چینمان را تمام کردیم. اما در این نقطه شما باید از چگونگی ساخت بلاک ها، جعل و استخراج شدنشان در تعجب باشید.
درک الگوریتم اثبات کار (Proof of Work)
یک الگوریتم اثبات کار (PoW) مشخص می کند که چطور بلاک ها در بلاک چین ساخته یا استخراج می شوند. هدف PoW کشف عددی برای حل یک مسله است. این عدد توسط هر شخصی در شبکه می تواند تولید شود و به زبان محاسباتی باید پیدا کردنش سخت ولی تاییدش راحت باشد. هسته ی ایده ی پشت PoW همین است.
خوب برای درک PoW یک مثال ساده خواهیم زد:
بیایید فرض کنیم که انتهای هش یک عدد صحیح x ضربدر عدد صحیح دیگری بنام y باید به صفر ختم شود. بنابراین:
Hash(x*y) = ac23dc…….0
حالا برای این مثال ساده x را عدد ثابت ۵ در نظر میگیریم (x=5). پیاده سازی این مثال در python :
from hashlib import sha256
x = ۵
y = 0 # !چه عددی باید باشد y ما هنوز نمی دانیم که
while sha۲۵۶(f'{x*y}’.encode()).hexdigest()[-۱] != “۰”:
y += ۱
print(f’The solution is y = {y}’)
نتیجه این کد می شود y=۲۱ . زیرا انتهای هش حاصلضرب ۵ و ۲۱ به صفر ختم شد:
hash(۵ * ۲۱) = 1253e9373e…5e3600155e860
در بیت کوین الگوریتم PoW ، Hashcash نامیده می شود و این الگوریتم تفاوت چندانی با مثال ساده ی بالای ما ندارد. الگوریتم PoW ، باعث ایجاد مسابقه بین ماینرها می شود تا بتوانند بلاک جدید ایجاد کنند. به طور کلی میزان سختی الگوریتم براساس تعداد کاراکترهایی که در یک رشته جستجو می شوند مشخص می شود. سپس ماینرها بدلیل زحمتی که برای حل الگوریتم و بدست آوردن جواب کشیدند به عنوان جایزه یک ارز (coin) در قالب یک تراکنش دریافت می کنند.
شبکه هم به سادگی می تواند جوابی که بدست آورده اند را تایید یا رد کند.
پیاده سازی الگوریتم PoW پایه
بیایید یک الگوریتم مشابه برای بلاک چینمان ایجاد کنیم. روش کار ما مشابه روش مثال بالا خواهد بود:
یافتن عدد ‘p که وقتی در کنار عدد نتیجه پروف بلاک قبلی قرار گرفت و هش شد، ۴ عدد صفر در ابتدای هش جدید تولید شود
import hashlib
import json
from time import time
from uuid import uuid۴
class Blockchain(object):
…
def proof_of_work(self, last_proof):
“””
:ساده PoW یک الگوریتم
– شامل ۴ عدد صفر در ابتدایش باشد hash(pp’) به طوری که p’ یافتن عدد
– جواب پروف برای بلاک جدید می باشد p’ نتیجه پروف بلاک قبلی می باشد و p عدد
:param last_proof: <int>
:return: <int>
“””
proof = ۰
while self.valid_proof(last_proof, proof) is False:
proof += ۱
return proof
@staticmethod
def valid_proof(last_proof, proof):
“””
چهار عدد صفر در ابتدایش دارد؟ hash(last_proof, proof) تایید اعتبار: آیا
:param last_proof: <int> پروف بلاک قبلی
:param proof: <int> پروف فعلی
:return: <bool> برمی گرداند False :در غیر این صورت | True :در صورت درستی
“””
guess = f'{last_proof}{proof}’.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:۴] == “۰۰۰۰”
جهت تنظیم درجه ی سختی الگوریتم ما می توانیم تعداد صفرهای ایتدای هش تولیدی را تغییر دهیم. اما تعداد ۴ مناسب است. خودتان خواهید فهمید که اضافه کردن یک عدد صفر بیشتر به ابتدای نتیجه هش نهایی باعث ایجاد تفاوت زمانی بسیار زیادی نسبت به حالت قبلی جهت یافتن جواب می شود.
خوب کلاس ما تقریبا کامل است و ماهم آماده ایم که تعامل با آن را از طریق پروتکل http آغاز کنیم.
گام دوم: بلاک چین ما به عنوان یک API
ما میخواهیم که از فریمورک “Flask” استفاده کنیم. “Flask” یک فریمورک کوچکی ست جهت تسهیل در وصل شدن (map) آدرس های وب به توابع python. این فریمورک به ما اجازه می دهد تا با بلاک چینمان با استفاده از درخواست های مبتنی بر بستر پروتکل “http” ارتباط برقرار کنیم.
ما سه متد ایجاد خواهیم کرد:
- /transactions/new : جهت ساخت یک تراکنش جدید و اضافه کردن آن به یک بلاک
- /mine : برای این که به سرورمان بگوییم که یک بلاک جدید را استخراج (mine) کند
- /chain : جهت برگرداندن لیست کامل بلاک های بلاک چین
اعمال تنظیمات Flask
سرور ما یک گره (node) را در شبکه بلاک چین تشکیل خواهد داد. کد این کار:
import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask
class Blockchain(object):
…
# از روی گره مان (Instantiate) نمونه سازی اولیه
app = Flask(__name__)
# برای این گره (global) ایجاد یک آدرس یکتای جهانی
node_identifier = str(uuid4()).replace(‘-‘, ”)
# نمونه سازی اولیه از بلاک چین
blockchain = Blockchain()
@app.route(‘/mine’, methods=[‘GET’])
def mine():
return “We’ll mine a new Block”
@app.route(‘/transactions/new’, methods=[‘POST’])
def new_transaction():
return “We’ll add a new transaction”
@app.route(‘/chain’, methods=[‘GET’])
def full_chain():
response = {
‘chain’: blockchain.chain,
‘length’: len(blockchain.chain),
}
return jsonify(response), ۲۰۰
if __name__ == ‘__main__’:
app.run(host=’0.0.0.0′, port=۵۰۰۰)
حال توضیحات مختصری شرح خواهیم داد در مورد این که در کد بالا چه چیزهایی اضافه کردیم:
خط ۱۵: یک نمونه سازی اولیه از گره مان انجام دادیم. حهت اطلاعات بیشتر در مورد Flask می توانید به این آدرس مراجعه کنید.
خط ۱۸: ایجاد یک نام تصادفی برای گره مان
خط ۲۱: نمونه سازی اولیه از روی کلاس “Blockchain”
خط ۲۴-۲۶: ساخت آدرس (URI) /mine که درخواست ها را در قالب GET دریافت می کند
خط ۲۸-۳۰: ساخت آدرس (URI) /transactions/new که درخواست ها را به صورت POST دریافت می کند، بدلیل این که اطلاعات (Data) به این آدرس ارسال خواهیم کرد
خط ۳۲-۳۸: ساخت آدرس (URI) /chain که کار آن بازگرداندن اطلاعات کامل بلاک چین به ما است
خط ۴۰-۴۱: سرور را بر روی پورت شماره ۵۰۰۰ راه اندازی می کند
گلوگاه (endpoint) تراکنش ها در سرور
ساختار درخواست برای یک تراکنش مانند شکل زیر است و این چیزی ست که یوزر به سرور ارسال خواهد کرد:
{
“sender”: “my address”,
“recipient”: “someone else’s address”,
“amount”: ۵
}
چون در حال حاضر ما متد لازم برای اضافه کردن تراکنش ها به یک بلاک را داریم ادامه کار راحت است. بیایید تابع لازم برای اضافه کردن تراکنش ها را بنویسیم:
import hashlib
import json
from textwrap import dedent
from time import time
from uuid import uuid4
from flask import Flask, jsonify, request
…
@app.route(‘/transactions/new’, methods=[‘POST’])
def new_transaction():
values = request.get_json()
# چک کردن فیلدهای اجباری در دیتای پست
required = [‘sender’, ‘recipient’, ‘amount’]
if not all(k in values for k in required):
return ‘Missing values’, ۴۰۰
# ایجاد یک تراکنش جدید
index = blockchain.new_transaction(values[‘sender’], values[‘recipient’], values[‘amount’])
response = {‘message’: f’Transaction will be added to Block {index}’}
return jsonify(response), ۲۰۱
گلوگاه (endpoint) ماینینگ
بخش گلوگاه و آدرس ماینینگ جایی ست که اتفاقات عجیبی رخ می دهد و راحتم است. این بخش ۳ کار انجام می دهد:
محاسبه PoW
جایزه دادن به ماینر (ما) با اضافه کردن یک تراکنش و اعطای یک ارز (coin) به ما
ساختن بلاک جدید با اضافه کردن آن به زنجیره
import hashlib
import json
from time import time
from uuid import uuid۴
from flask import Flask, jsonify, request
…
@app.route(‘/mine’, methods=[‘GET’])
def mine():
# ما الگوریتم اثبات کار را اجرا می کنیم تا به پروف بعدی برسیم …
last_block = blockchain.last_block
last_proof = last_block[‘proof’]
proof = blockchain.proof_of_work(last_proof)
# ما باید به ازای یافتن پروف جایزه دریافت کنیم
# فرستنده ‘۰’ بدین معنی ست که گره فعلی یک ارز استخراج کرده
blockchain.new_transaction(
sender=”0″,
recipient=node_identifier,
amount=1,
)
# ساخت بلاک جدید با اضافه کردن آن به زنجیره
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
‘message’: “New Block Forged”,
‘index’: block[‘index’],
‘transactions’: block[‘transactions’],
‘proof’: block[‘proof’],
‘previous_hash’: block[‘previous_hash’],
}
return jsonify(response), ۲۰۰
توجه کنید که گیرنده بلاک استخراج شده (mine شده) آدرس گره ماست و بیشتر کارهایی که ما اینجا انجام دادیم فقط تعامل با متدهای کلاس Blockchain مان بود. خوب ما کارمان تمام شده و می توانیم ارتباط و تعامل با بلاک چین مان را آغاز کنیم.
گام سوم: برقراری ارتباط با بلاک چین مان
شما می توانید از cURL قدیمی یا نرم افزار Postman برای ارتباط با API مان از طریق شبکه استفاده کنید.
با این دستور سرورمان را اجرا می کنیم:
$ python blockchain.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
خوب بیایید بخش استخراج بلاک را از طریق ارسال درخواست نوع GET به آدرس http://localhost:۵۰۰۰/mine تست کنیم :
حال بیایید ایجاد یک تراکنش جدید را با ارسال درخواست از نوع POST به آدرس http://localhost:۵۰۰۰/transactions/new که در بدنه (body) آن اطلاعاتی با ساختار تراکنش مان وجود دارد را تست کنیم:
اگر شما از postman استفاده نمی کنید می توانید درخواست معادل را با استفاده از cURL ساخته و ارسال کنید:
$ curl -X POST -H “Content-Type: application/json” -d ‘{
“sender”: “d۴ee۲۶eee۱۵۱۴۸ee۹۲c۶cd۳۹۴edd۹۷۴e”,
“recipient”: “someone-other-address”,
“amount”: ۵
}’ “http://localhost:5000/transactions/new”
من سرور را رستارت (restart) کردم و دو بلاک استخراج کردم و با بلاک جایزه ام باید تعداد بلاک ها ۳ تا شده باشد. حال بیایید این موضوع را با ارسال درخواست به آدرس http://localhost:۵۰۰۰/chain بررسی کنیم:
{
“chain”: [
{
“index”: ۱,
“previous_hash”: ۱,
“proof”: ۱۰۰,
“timestamp”: ۱۵۰۶۲۸۰۶۵۰.۷۷۰۸۳۹,
“transactions”: []
},
{
“index”: ۲,
“previous_hash”: “c۰۹۹bc…bfb۷”,
“proof”: ۳۵۲۹۳,
“timestamp”: ۱۵۰۶۲۸۰۶۶۴.۷۱۷۹۲۵,
“transactions”: [
{
“amount”: ۱,
“recipient”: “۸bbcb۳۴۷e۰۶۳۴۹۰۵b۰cac۷۹۵۵bae۱۵۲b”,
“sender”: “۰”
}
]
},
{
“index”: ۳,
“previous_hash”: “eff۹۱a…۱۰f۲”,
“proof”: ۳۵۰۸۹,
“timestamp”: ۱۵۰۶۲۸۰۶۶۶.۱۰۸۶۹۷۲,
“transactions”: [
{
“amount”: ۱,
“recipient”: “۸bbcb۳۴۷e۰۶۳۴۹۰۵b۰cac۷۹۵۵bae۱۵۲b”,
“sender”: “۰”
}
]
}
],
“length”: ۳
}
گام چهارم: اجماع و توافق
کار جالبی بود. ما در حال حاضر یک سیستم بلاک چین ساده داریم که تراکنش هایی را قبول می کند و به ما اجازه استخراج بلاک ها را می دهد. اما کل هدف سیستم های بلاک چین این است که نامتمرکز (decentralized) باشند و اگر نامتمرکز هستند چطور روی زمین ما مطمعن باشیم که همه آن ها یک زنجیره یکسان را نشان می دهند؟ این مورد را مشکلات اجماع (problem of Consensus) می نامند. به همین دلیل اگر ما بخواهیم که بیشتر از یک گره در شبکه داشته باشیم باید یک الگوریتم توافق پیاده سازی کنیم.
ثبت گره های جدید
قبل از این که بخواهیم الگوریتم اجماع را پیاده سازی کنیم باید روشی بیابیم که از طریق آن یک گره بتواند گره های همسایه اش را در شبکه شناسایی کند و بشناسد. هر گره در شبکه باید دفتری از اطلاعات (registry) گره های دیگر در شبکه را داشته باشد. پس ما گلوگاه های (endpoint) بیشتری برای این کار لازم داریم:
/nodes/register : جهت قبول کردن لیستی از گره های جدید در قالب مجموعه ای از URL ها
/nodes/resolve : جهت پیاده سازی الگوریتم اجماع که هرگونه تضاد و مغایرت را برطرف می کند تا به یک گره اطمینان دهد که زنجیره درست را دارد
خوب برای این کار باید متد آغازگر کلاس “Blockchain” را تغییر دهیم و متدی را ایجاد کنیم برای ثبت گره ها:
…
from urllib.parse import urlparse
…
class Blockchain(object):
def __init__(self):
…
self.nodes = set()
…
def register_node(self, address):
“””
اضافه کردن گره جدید به لیست گره ها
:param address: <str> ‘http://192.168.0.5:5000’ :آدرس گره – مثال
:return: None
“””
parsed_url = urlparse(address)
self.nodes.add(parsed_url.netloc)
توجه کنید که ما از یک دستور set() جهت نگهداری لیست گره ها استفاده کرده ایم. این کار ارزان ترین روش است جهت اطمینان از این که اضافه شدن گره های جدید آگاهانه است به این معنی که دیگر مهم نیست که یک گره مشخص را چندبار به سیستم اضافه کرده ایم و آن گره دقیقا فقط یکبار ثبت می شود.
پیاده سازی الگوریتم اجماع
همان طور که اشاره شد، برخورد و تضاد زمانی رخ می دهد که زنجیره یک گره با زنجیره گره دیگر متفاوت باشد. جهت حل این مسله ما قانونی ایجاد می کنیم که براساس آن طولانی ترین زنجیره صحیح و بدون اشکال الویت دارد بر زنجیره های دیگر و معتبر است (longest valid chain is authoritative). با استفاده از این قانون ما به اجماع در بین گره های درون شبکه دست میابیم.
…
import requests
class Blockchain(object)
…
def valid_chain(self, chain):
“””
مشخص می کند که آیا زنجیره بلاک ها معتبر است یا نه
:param chain: <list> A blockchain
:return: <bool> True if valid, False if not
“””
last_block = chain[0]
current_index = ۱
while current_index < len(chain):
block = chain[current_index]
print(f'{last_block}’)
print(f'{block}’)
print(“n———–n”)
# هش بلاک را جهت درستی بررسی می کند
if block[‘previous_hash’] != self.hash(last_block):
return False
# بلاک جهت درستی بررسی می شود PoW
if not self.valid_proof(last_block[‘proof’], block[‘proof’]):
return False
last_block = block
current_index += ۱
return True
def resolve_conflicts(self):
“””
این بخش الگوریتم اجماع ما است که با جایگزین کردن
طولانی ترین زنجیره در شبکه تضادها را برطرف می کند
:return: <bool> True if our chain was replaced, False if not
“””
neighbours = self.nodes
new_chain = None
# طول زنجیره خودمان را بدست می آوریم
max_length = len(self.chain)
# گرفتن زنجیره های همه گره های دیگر و بررسی درستی آن ها
for node in neighbours:
response = requests.get(f’http://{node}/chain’)
if response.status_code == ۲۰۰:
length = response.json()[‘length’]
chain = response.json()[‘chain’]
# بررسی می کنیم که آیا طول این زنجیره طولانی تر است و همچنین معتبر است یا نه
if length > max_length and self.valid_chain(chain):
max_length = length
new_chain = chain
# اگر یک زنجیره معتبر طولانی تر از زنجیره خودمان یافتیم آن را بروی زنجیره خودمان جایگزین می کنیم
if new_chain:
self.chain = new_chain
return True
return False
کار متد valid_chain() چک کردن اعتبار زنجیره است. بدین صورت که در تک تک بلاک های زنجیره دو مقدار هش و پروف آن بلاک را چک می کند.
کار متد resolve_conflicts() چک کردن گره های همسایه و دانلود و تایید زنجیره آن ها بوسیله متد بالاست. اگر یک زنجیره معتبر پیدا شود آن زنجیره که بلاک های بیشتری نسبت به زنجیره ما دارد بر روی زنجیره ما جایگزین می شود.
خوب حالا بیایید دو گلوگاه (endpoint) در api مان ایجاد کنیم. یکی برای اضافه کردن گره های همسایه و دیگری برای حل تضاد:
@app.route(‘/nodes/register’, methods=[‘POST’])
def register_nodes():
values = request.get_json()
nodes = values.get(‘nodes’)
if nodes is None:
return “Error: Please supply a valid list of nodes”, ۴۰۰
for node in nodes:
blockchain.register_node(node)
response = {
‘message’: ‘New nodes have been added’,
‘total_nodes’: list(blockchain.nodes),
}
return jsonify(response), ۲۰۱
@app.route(‘/nodes/resolve’, methods=[‘GET’])
def consensus():
replaced = blockchain.resolve_conflicts()
if replaced:
response = {
‘message’: ‘Our chain was replaced’,
‘new_chain’: blockchain.chain
}
else:
response = {
‘message’: ‘Our chain is authoritative’,
‘chain’: blockchain.chain
}
return jsonify(response), ۲۰۰
خوب حال شما می توانید این سیستم را روی یک رایانه دیگر راه اندازی کنید و گره های متفاوتی را ایجاد کنید یا اینکه سیستم را با استفاده از پورت های متفاوت بروی همین رایانه پردازش کنید. من یک گره دیگر روی رایانه فعلیم با شماره پورتی متفاوت ایجاد کردم و آن را با گره فعلیم ثبت نمودم. پس در حال حاضر من دو گره دارم:
http://localhost:۵۰۰۰ و http://localhost:۵۰۰۱
سپس تعدادی بلاک جدید را با دو گره استخراج نمودم تا مطمعن شوم که زنجیره طولانی تر شده. بعد از آن آدرس GET /nodes/resolve را روی گره اول، فراخوانی نمودم.
جایی که زنجیره براساس الگوریتم اجماع جایگزین می شود:
خوب کار تمام است. حالا بروید سراغ دوستانتان و با کمکشان سیستم بلاک چینتان را تست کنید.
من امیدوارم که این آموزش الهامی برای شما باشد جهت ساختن چیزی جدید. من از تولد ارزهای دیجیتال مسرورم چرا که معتقدم بلاک چین ها به سرعت سیستم فکری ما را درباره اقتصاد، دولت ها و ضبط اطلاعات تغییر خواهند داد.
آموزش ساخت توکن رمزارز بر بستر اتریوم، بایننس اسمارتچین و ترون
با توسعه تکنولوژی بلاکچین افراد بیشتری شروع به ساخت ارزهای دیجیتال کردهاند. در این مقاله، نحوه ایجاد توکنهای رمزارز در بلاکچینهای اتریوم، ترون و بایننس اسمارتچین را توضیح خواهیم داد.
در این مقاله آموزش ساخت توکنهای رمزارز را در سه بلاکچین مطرح اتریوم، ترون و بایننس اسمارتچین بررسی خواهیم کرد. ابتدا به نحوه ساخت توکنهای ERC-20 در بلاکچین اتریوم خواهیم پرداخت و کد نوشتهشده در این بستر را بررسی خواهیم کرد. با انجام این کار، ارزی خواهیم داشت که معاملهشدنی است و موجودی عرضهشدنیاش را خودمان تعیین میکنیم. درادامه با داشتن پایهای در ساخت توکن، بهسراغ ساختن توکن BEP20 در بستر بایننس اسمارتچین و درنهایت توکن TRC-20 در بلاکچین ترون خواهیم رفت.
نیازی به گفتن نیست که در این راه داشتن دانش برنامهنویسی به درک کامل فرایند ساخت توکن کمک خواهد کرد. در آموزش حاضر، توکنهای رمزارز را میتوان در هر سیستمعاملی ایجاد کرد. توکنهای ایجادشده بهایی ندارند؛ ولی میتوان آنها را به کیفپول دیجیتالتان منتقل کنید.
نکته مهم اینکه مقاله حاضر صرفا جنبه آموزشی دارد و در ساخت توکنها باید به قوانین کشوری توجه کنید. توکن ساختهشده صرفا در شبکه آزمایشی ایجاد شدهاند و ارزش پولی ندارند.
قراردادهای هوشمند (Smart Contracts)
به زبان ساده، قراردادهای هوشمند کدهایی هستند که روی بلاکچین اجرا و برای اپلیکیشنها یا خدمات خاصی طراحی شدهاند. برای مثال، اگر میخواهید اپلیکیشن رأیگیری طراحی کنید، قرارداد هوشمند منطق رأیگیری موردنیازی است که روی بلاکچین اجرا میشود.
قبل از ساخت رمزارز، باید ابتدا پلتفرم بلاکچینی را انتخاب کنید که مناسب کارتان باشد. بزرگترین بلاکچین قراردادهای هوشمند تاکنون اتریوم است؛ اما کارمزدهای زیاد اتریم باعث شده است توسعهدهندگان به فکر ساخت قراردادهای هوشمندشان روی سایر بلاکچینها ازجمله زنجیرهی هوشمند بایننس یا ترون بیفتند.
آموزش ساخت توکن ERC-20 در بلاکچین اتریوم
توکن رمزارزی که روی ارز دیجیتال اتریوم کار میکند و در این مقاله ساختش را توضیح خواهیم داد، از استاندارد ERC-20 پیروی میکند. برای آشنایی بیشتر با استاندارد ERC-20، میتوانید این مقاله را مطالعه کنید.
۱. ساخت حساب کاربری در والت متامسک
کیف پول دیجیتال متامسک (Metamask) در نقش درگاهی به اپلیکیشنهای بلاکچین عمل میکند. این والت بهعنوان افزونهای به مرورگر اضافه میشود. پیشنهاد میشود که از مرورگر گوگل کروم استفاده کنید. والت متامسک نسخه موبایل نیز دارد که پس از ایجاد توکن، میتوانید بهراحتی از آن برای انتقال و ذخیرهسازی رمزارزهای خود استفاده کنید. برای دانلود افزونه متامسک برای گوگل کروم روی این لینک کلیک کنید. پس از اتمام نصب افزونه، صفحه زیر را مشاهده میکنید. این صفحه را میتوانید از قسمت افزونههای مرورگر نیز باز کنید.
گزینه سمت راست، یعنی ساخت والت را انتخاب کنید.
رمزعبور را وارد کنید. این رمزعبور فقط برای ورود به والت در حالت فعلی سیستم کاربرد دارد و پس از حذف مرورگر، تنها راه ورود به کیفپول دیجیتال ازطریق عبارات بازیابی است که درادامه دریافت خواهید کرد؛ بنابراین در حفظ کلمات بازیابی والت خود بهشدت دقت کنید.
همانگونه که در تصویر بالا مشاهده میکنید با کلیک روی تصویر قفل، ۱۲ کلمه برایتان نمایش داده میشود. این همان عبارات بازیابی ذکر شده است.
درنهایت، موفق میشوید در والت متامسک حساب کاربری بسازید.
۲. تغییر شبکه والت
شبکه والت را از شبکه اصلی اتریوم به شبکه آزمایشی Ropsten تغییر دهید. این کار کمک میکند بدون پرداخت کارمزد و بهطور آزمایشی توکنتان را بسازید. دقت کنید در آینده حتما شبکه را به حالت Main Ethereum Network بازگردانید.
۳. مقداری اتر به والت خود اضافه کنید
برای ساخت توکن به مقداری اتر نیاز دارید. این مقدار اتر صرف پرداخت کارمزدهای شبکه اتریوم هنگام ساخت توکن لازم میشود. از این وبسایت مقداری اتر آزمایشی دریافت کنید. حتما برنامه عبور از تحریمتان را فعال کنید؛ وگرنه اتری به والت شما انتقال داده نمیشود.
همانگونه که در تصویر بالا مشاهده میکنید، مقداری اتر به کیفپول متامسک اضافه میشود.
۴. ساخت توکن
برای شروع فرایند ساخت توکن به وبسایت remix.ethereum وارد شوید و از قسمت اشارهشده در تصویر پایین، فایلی جدید ایجاد کنید.
نام توکنی را وارد کنید که میخواهید ایجاد کنید؛ ولی دقت کنید پسوند sol. را از انتهایش حذف نکنید. سپس کد زیر را در قسمت ویرایشگر کد در سمت راست وارد کنید.
pragma solidity 0.6.6;
// —————————————————————————-
// ‘ZoomitToken’ token contract
//
// Deployed to : 0x8414ECE0334E764fC68d8e37D593BEAcA6c23204
// Symbol : ZIT
// Name : Zoomit
// Total supply: 10000
// Decimals : 0
//
// Enjoy.
//
// (c) by Ahiwe Onyebuchi Valentine.
// —————————————————————————-
// —————————————————————————-
// Safe maths
// —————————————————————————-
contract SafeMath {
function safeAdd(uint a, uint b) public pure returns (uint c) {
c = a + b;
require(c >= a);
}
function safeSub(uint a, uint b) public pure returns (uint c) {
require(b <= a);
c = a – b;
}
function safeMul(uint a, uint b) public pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function safeDiv(uint a, uint b) public pure returns (uint c) {
require(b > 0);
c = a / b;
}
}
// —————————————————————————-
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// —————————————————————————-
abstract contract ERC20Interface {
function totalSupply() virtual public view returns (uint);
function balanceOf(address tokenOwner) virtual public view returns (uint balance);
function allowance(address tokenOwner, address spender) virtual public view returns (uint remaining);
function transfer(address to, uint tokens) virtual public returns (bool success);
function approve(address spender, uint tokens) virtual public returns (bool success);
function transferFrom(address from, address to, uint tokens) virtual public returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
// —————————————————————————-
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// —————————————————————————-
abstract contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 tokens, address token, bytes memory data) virtual public;
}
// —————————————————————————-
// Owned contract
// —————————————————————————-
contract Owned {
address public owner;
address public newOwner;
event OwnershipTransferred(address indexed _from, address indexed _to);
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
function transferOwnership(address _newOwner) public onlyOwner {
newOwner = _newOwner;
}
function acceptOwnership() public {
require(msg.sender == newOwner);
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
newOwner = address(0);
}
}
// —————————————————————————-
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// —————————————————————————-
contract Zoomit is ERC20Interface, Owned, SafeMath {
string public symbol;
string public name;
uint8 public decimals;
uint public _totalSupply;
mapping(address => uint) balances;
mapping(address => mapping(address => uint)) allowed;
// ————————————————————————
// Constructor
// ————————————————————————
constructor() public {
symbol = “ZIT”;
name = “Zoomit”;
decimals = 0;
_totalSupply = 10000;
balances[0x8414ECE0334E764fC68d8e37D593BEAcA6c23204] = _totalSupply;
emit Transfer(address(0), 0x8414ECE0334E764fC68d8e37D593BEAcA6c23204, _totalSupply);
}
// ————————————————————————
// Total supply
// ————————————————————————
function totalSupply() public override view returns (uint) {
return _totalSupply – balances[address(0)];
}
// ————————————————————————
// Get the token balance for account tokenOwner
// ————————————————————————
function balanceOf(address tokenOwner) public override view returns (uint balance) {
return balances[tokenOwner];
}
// ————————————————————————
// Transfer the balance from token owner’s account to to account
// – Owner’s account must have sufficient balance to transfer
// – 0 value transfers are allowed
// ————————————————————————
function transfer(address to, uint tokens) public override returns (bool success) {
balances[msg.sender] = safeSub(balances[msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
emit Transfer(msg.sender, to, tokens);
return true;
}
// ————————————————————————
// Token owner can approve for spender to transferFrom(…) tokens
// from the token owner’s account
//
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// recommends that there are no checks for the approval double-spend attack
// as this should be implemented in user interfaces
// ————————————————————————
function approve(address spender, uint tokens) public override returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
return true;
}
// ————————————————————————
// Transfer tokens from the from account to the to account
//
// The calling account must already have sufficient tokens approve(…)-d
// for spending from the from account and
// – From account must have sufficient balance to transfer
// – Spender must have sufficient allowance to transfer
// – 0 value transfers are allowed
// ————————————————————————
function transferFrom(address from, address to, uint tokens) public override returns (bool success) {
balances[from] = safeSub(balances[from], tokens);
allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
balances[to] = safeAdd(balances[to], tokens);
emit Transfer(from, to, tokens);
return true;
}
// ————————————————————————
// Returns the amount of tokens approved by the owner that can be
// transferred to the spender’s account
// ————————————————————————
function allowance(address tokenOwner, address spender) public override view returns (uint remaining) {
return allowed[tokenOwner][spender];
}
// ————————————————————————
// Token owner can approve for spender to transferFrom(…) tokens
// from the token owner’s account. The spender contract function
// receiveApproval(…) is then executed
// ————————————————————————
function approveAndCall(address spender, uint tokens, bytes memory data) public returns (bool success) {
allowed[msg.sender][spender] = tokens;
emit Approval(msg.sender, spender, tokens);
ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, address(this), data);
return true;
}
// ————————————————————————
// Don’t accept ETH
// ————————————————————————
// function () external payable {
// revert();
// }
// ————————————————————————
// Owner can transfer out any accidentally sent ERC20 tokens
// ————————————————————————
function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
return ERC20Interface(tokenAddress).transfer(owner, tokens);
}
}
۵. کد را ویرایش کنید
برای شخصیسازی توکن ساختهشده، قسمتهای مذکور را به مقادیر دلخواه تغییر میدهیم:
- در خط ۴ (رنگ آبی)، عنوان قرارداد هوشمند را تغییر دهید. در اینجا، ZoomitToken وارد شده است.
- در خطوط ۶ و ۱۲۰ و ۱۲۱ (رنگ سبز) آدرس اتریوم ساختهشده خود را در متامسک که در شبکه راپستن است، با عبارت واردشده جایگزین کنید.
- در خطوط ۷ و ۱۱۶ (رنگ قرمز)، درمقابل عبارت Symbol، نام توکنتان را بهاختصار وارد کنید. در اینجا ZIT وارد شده است.
- خطوط ۸ و ۱۰۲ و ۱۱۷ (رنگ بنفش) را به نام توکنتان تغییر دهید. در اینجا Zoomit وارد شده است.
- در خطوط ۱۱۸ و ۱۱۹ (رنگ زرد)، میتوانید بهترتیب تعداد رقم اعشار را تغییر دهید که نشانگر قابلیت تقسیمپذیری توکن و کل موجودی توکن است. مقدار پیشفرض رقم اعشار ۱۸ است؛ یعنی هر توکن را میتوان به ۱۸ قسمت تقسیم کرد و کوچکترین واحد توکن انتقالپذیر شما یکهجدهم خواهد بود. در این مثال، برای این پارامترها بهترتیب ۱ و ۱۰۰۰۰ وارد شده است؛ یعنی در کل ۱۰۰۰۰ توکن ZIT با یک رقم اعشار، ایجاد خواهیم کرد.
۶. کامپایل کد نوشتهشده
مطابق تصویر بالا، به نماد چکمارک در سمت چپ بروید که مربوط به تب Compile است. در میان گزینهها، «Enable Optimizations» را غیرفعال کنید. همچنین دقت کنید گزینه اول کامپایلر که نشاندهنده نسخه کامپایلر است، مطابق با خط اول کد باشد. حال به تب بعدی در سمت چپ و در زیر تب کامپایل بروید. در قسمت Contract، نام توکنتان را فهرست پایینافتادنی انتخاب کنید و دکمه Deploy را فشار دهید.
پس از زدن Deploy، متامسک از شما درباره خرج مقداری اتر آزمایشی و تأیید تراکنش سؤال خواهد کرد که مطابق تصویر زیر است.
دقت کنید که در شبکه راپستن و نه در شبکه Mainnet باشید. پس از زدن تأیید، دوباره متامسک را باز و روی اولین تراکنش کلیک کنید. درادامه به وبسایت Etherscan، مرورگر بلاکچین اتریوم، بروید تا تراکنشتان را پیگیری کنید. ممکن است تأیید تراکنشها حداکثر ۳۰ ثانیه طول بکشد. دقت کنید در این وبسایت نیز شبکه آزمایش راپستن را انتخاب کرده باشید. بعد از تأیید تراکنش، چیزی شبیه تصویر زیر خواهیم داشت.
به آدرس بالای تراکنش و در قسمت Transaction توجه کنید. این همان آدرس قرارداد هوشمندتان است.
۷. تأیید و انتشار قرارداد هوشمند
روی آدرس قراردادتان کلیک و تب Code را باز کنید.
حال روی لینک «تأیید و انتشار» کلیک کنید. پس از این کار، وارد صفحهای جدیدی خواهید شد. جزئیات مانند نسخه کامپایلر و فعالسازی بهینهسازی را تکمیل کنید و کدی که قبلا پیست کرده بودید، در اینجا نیز وارد کنید.
دوباره از مطابقت نسخه کامپایلر با خط اول کد مطمئن شوید و سپس روی «تأیید و انتشار» کلیک کنید. درصورت موفقیت، ByteCode و ABI همانند تصویر زیر ایجاد خواهد شد.
حال همه میتوانند آدرس قراردادتان و کد منبع آن را مطالعه کنند.
۸. اضافهکردن توکن به کیفپول
حال اگر توکنتان تأیید شده باشد، مقدار اولیه توکنهای ایجادشده (در اینجا ۱۰۰۰۰ توکن) را میتوانید دریافت کنید. همانند تصویر زیر آدرس قرارداد را کپی و در قسمت متامسک > Add Token < Custom token پیست کنید.
پس از تأیید، تمامی توکنها را در والت خود مشاهده خواهید کرد.
آموزش ساخت توکن BEP20 بر بستر اسمارتچین بایننس (Binance Smart Chain)
اگر بهدنبال پلتفرمی هستید که کارمزدهای کمتر و زمان سریعتر در انجام تراکنشها داشته و با قراردادهای هوشمند سازگارتر باشد، پس باید زنجیره هوشمند بایننس با Binance Smart Chain را انتخاب کنید. زنجیره هوشمند بایننس (BSC) که در موازات زنجیره بایننس (BC) اجرا میشود، بهطور ویژه برای خدمت به قراردادهای هوشمند و ساخت اپلیکیشنهای غیرمتمرکز (دَپها) طراحی شده است.
ساخت توکنهای BSC از آنچه فکر میکنید، سادهتر است. این توکنها با استاندارد BEP20 مطابقت دارند که مشابه استاندارد ERC20 در اتریوم است. استاندارد توکن عملکردهای پایهای آن توکن ازجمله انتقال و بازگشت موجودی و مشاهده مالکیت توکن را تعیین میکند. API مربوط به BEP20 را از این لینک میتوانید مشاهده کنید.
بهخاطر بسپارید که توکنهای BSC را میتوان با توکنهای معمولی بایننس چین (BC) مبادله کرد. توکنهای BC بر اساس استاندارد BEP2 هستند. همچنین، تمامی تراکنشهای انجامشده بلاکچین بایننس با بایننس کوین یا BNB پرداخت میشود. این هزینه صرف تأمین امنیت شبکه میشود و به تاییدکنندگان تراکنش پرداخت میشود.
حال که در قسمت قبل مقاله ارزیدو با اساس کار ساختن توکن و کدنویسی آن آشنا شدیم، این بار با اپلیکیشن CoinTool، مراحل ساخت توکن را بسیار سادهتر و سریعتر پیش میبریم. در این اپلیکیشن، توکنهای مربوط به بلاکچینهای مختلفی را میتوان بهسادگی ساخت. حتی توکن اتریوم را نیز میتوان با این اپلیکیشن بهسادگی ایجاد کرد. توجه کنید در مرحله قبل توکن را در شبکهای آزمایشی ایجاد کردیم؛ ولی این بار به پرداخت کارمزدهای ایجاد توکن مجبور هستیم.
۱. ساخت توکن BEP20
- ابتدا ازطریق این لینک وارد اپلیکیشن CoinTool شوید. علاوهبر مرورگر با نصب تراستوالت (لینک دانلود تراست والت)، از قسمت DApps و واردکردن آدرسapp/bnb/BSCCreateToken این مراحل را میتوانید انجام دهید.
- از بالا گوشه سمت راست، با کلیک روی آرم بلاکچینها شبکه اسمارت چین بایننس را انتخاب کنید.
- اطلاعات لازم ازجمله نام توکن، نماد توکن، موجودی اولیه و رقمهای اعشار (مقدار قابلیت تقیسمپذیری توکن) را تکمیل کنید.
- با زدن دکمه Create Token و پرداخت کارمزد، توکنتان را ایجاد کنید. برای پرداخت کارمزد باید مقداری BNB در والتتان داشته باشید. از بالا گوشه سمت راست، میتوانید والتتان را به این اپلیکیشن متصل کنید.
با انجام این مراحل توکنتان ایجاد میشود. از قسمت بالا سمت راست و نماد صفحه سبزرنگ، میتوانید کد قرارداد هوشمند استفادهشده در ساخت توکن را مشاهده کنید. همانطورکه در شکل بالا مشاهده میکنید، گزینههای نیز هنگام ساختن توکن وجود دارد. درادامه، آنها را توضیح خواهیم داد:
Can Burn (امکان توکنسوزی): ازطریق این گزینه میتوان امکان توکنسوزی و کاهش موجودی توکن را فعال کنید. این امر باعث کاهش تورم و درنتیجه افزایش قیمت توکن میشود.
Can Mint (امکان ضرب سکه جدید): ازطریق این گزینه میتوان امکان ضرب سکههای بیشتر علاوهبر موجودی اولیه را فعال کرد.
Can Pause (ایجاد وقفه در عملکرد توکن): با انتخاب این گزینه میتوانید این امکان را فراهم کنید که در زمان دلخواه، تمامی توکنها و عملیات مرتبط با آن را متوقف کنید یا ادامه بدهید. این گزینه زمانی کاربرد دارد که رخنههای نرمافزاری و حملات مخرب وجود دارند. توجه کنید فعالسازی وقفه برای تمام کسانی که مجوز دسترسی به آن را دارند مانند سازنده توکن، اختیار توقف و ادامه را فراهم میکند و این قدرت مرکزی برای بعضی از کابردها مناسب نیست.
Blacklist (فهرست سیاه): حسابهای کاربری که رفتار مخربی دارند، میتواند وارد فهرست سیاه شوند. بر اساس موارد کاربرد، برای بعضی از توکنها بهتر است این گزینه غیرفعال باشد. همانند گزینه وقفه، فعالسازی فهرست سیاه باعث ایجاد قدرت مرکزی شود و برای بعضی از کابردها مناسب نیست.
۲. اضافهکردن توکن BEP20 سفارشی به تراست والت
حال که توکنتان را ایجاد کردید، با انجام مراحل زیر میتوانید آن را درون تراست والت مشاهده کنید:
- از قسمت بالا سمت راست و نماد دو اسکرول، وارد قسمت جستوجو توکن شوید.
- به انتهای فهرست بروید و Add Custom Token را فشار دهید.
- Network را Smart Chain انتخاب کنید.
- آدرس قرارداد هوشمندتان را در زیر قسمت قبلی وارد کنید.
- نام و نماد و رقم اعشار توکن را که هنگام ساخت توکن تعیین کردید، وارد کنید و Done را فشار دهید.
حال اگر به والتتان برگردید، توکنهای ساختهشده خود را مشاهده خواهید کرد.
آموزش ساخت توکن TRC20 در بلاکچین ترون
TRC20 استاندارد توکن در شبکه ترون (Tron) است. شبکه ترون این استاندارد را برای فعالسازی امکان ساخت قراردادهای هوشمند در بلاکچینش ایجاد کرده است. از مزایای توکنهای TRC20 میتوان به سرعت درخورتوجه و کارمزد اندک تراکنش اشاره کرد.
مراحل ساخت توکن TRC20
۱. در مرورگر کروم، افزونه TronLink را ازطریق این لینک دانلود و نصب کنید. همچنین با مراجعه به لینک وبسایت ترون، میتوانید والت آن را دانلود کنید.
۲. برای ساخت توکن حساب کاربری ایجاد کنید. قبل از ایجاد توکن مطئمن شوید که در والت ترون خود ۱۰ توکن TRX دارید.
۳. کد قرارداد هوشمند مبتنیبر TRC20 خود را آماده کنید. از این لینک میتوانید به کدی نمونه دسترسی داشته باشید. از لینک ذکرشده فایل Token.sol را ویرایش کنید و مقادیر token name ،token symbol ،precisoin و totalsupply را تغییر دهید. منظور از precision همان decimals در بخشهای قبلی است.
۴. قرارداد هوشمندتان را ازطریق این لینک اعمال کنید. در لینک ذکرشده، ابتدا به والتتان متصل شوید.
فایل قرارداد هوشمند را بارگذاری کنید.
قرارداد را کامپایل کنید. دقت کنید نسخه کامپایلر 0.5.10 باشد.
اطلاعات نمایشدادهشده در زیر نشاندهنده تکمیل موفقیتآمیز مراحل است.
قراردادتان را ازطریق گزینه Deploy اعمال کنید. توجه کنید که باید قرارداد Token را انتخاب کنید؛ زیرا Token قرارداد اصلی است.
Confirm را انتخاب کنید و سپس در پنجره بازشده که حاوی امضای ترونلینک است، Accept را انتخاب کنید.
پس از اعمال موفقیتآمیز قرارداد، آدرس قرارداد را یادداشت و ذخیره کنید.
۵. توکنهای ساختهشده خود را به کیفپول دیجیتال Tronlink اضافه کنید. ازطریق صفحه Asset Management، آدرس قرارداد یادداشتشده در مرحله قبل را در باکس Add tokens وارد کنید. پس از واردکردن توکن در add token box، پنجره قرارداد اعمالشده باز میشود. دکمه کشویی را فشار دهید تا توکن به والت ترونلینک اضافه شود. بعد از اضافهکردن توکن، میتوان انتقال را انجام داد.
همچنین، میتوانید ازطریق وبسایت tronscan و واردکردن آدرس قرارداد، صفحه اصلی قرارداد را جستوجو کنید.
۶. قرارداد هوشمند TRC20 خود را ازطریق Tronacan (این لینک) تأیید کنید. اطلاعات قرارداد هوشمند شامل آدرس قرارداد، نام قرارداد، نسخه کامپایلر، لایننس، تاریخچه بهینهسازی و دفعات اجرا (Runs) را وارد کنید:
- آدرس قرارداد همانی است که در مراحل قبل یادداشت کردیم.
- نام قرارداد، نام قرارداد اصلی اعمال شده است. در مثال ما، نام «Token» است.
- نسخه کامپایلر 0.5.10 است.
- None را در قسمت لایسنس وارد کنید.
- در قسمت تاریخچه بهینهسازی Yes و تعداد دفعات اجرا بهصورت پیشفرض صفر است.
برای تأیید روی بارگذاری فایل قرارداد کلیک کنید. درادامه تیک I am not robot و سپس تأیید و انتشار را بزنید.
پس از انجام موفقیتآمیز تأیید قرارداد، صفحه تأیید نمایش داده میشود.
۷. با استفاده از Tronacan و ابزار ثبت، توکن TRC20 خود را ثبت کنید (از این لینک). پس از بازکردن لینک، در صفحهنمایشدادهشده نوع توکن را انتخاب کنید.
درادامه، TRC20 و سپس Yes را انتخاب و سپس اطلاعات پایهای، اطلاعات قرارداد، اطلاعات رسانه اجتماعی توکن را وارد کنید. پرکردن فیلدهای ستارهدار ضروری است. در فیلد Issuer، باید امضای دیجیتالتان را وارد کنید. توجه کنید قبلا باید وارد وبسایت شده باشید.
بعد از واردکردن تمامی اطلاعات، Next را بزنید.
اطلاعات توکن را تأیید کنید و Submit را بزنید.
در پنجره بازشده، صدور توکن را باید تأیید کنید. پس از زدن تأیید، ترونلینک از شما امضا درخواست میکند. قبول را بزنید و پیام را امضا کنید.
در این مرحله، توکن TRC20 شما با موفقیت ساخته میشود.