در بخش اول در مورد ویژگی های ابزار geth توضیح داده شد، و به نحوه نصب و اجرای آن اشاره شد. در این مقاله قصد داریم به کمک geth یک بلاکچین خصوصی ایجاد کنیم، بلاک های آن را ماین کنیم و در نهایت یک تراکنش روی این شبکه انجام دهیم.
ایجاد اکانت اتریوم
قبل از ایجاد یک بلاکچین خصوصی نیاز داریم تا یک حساب اتریوم ایجاد کنیم با استفاده از دستور زیر:
$ geth account new
با اجرای این دستور، چنین تصویری مشاهده خواهید کرد. توجه داشته باشید که رمز عبور را به خاطر بسپارید.
همان طور که در تصویر مشاهده می کنید در قسمت path of the secret key file
آدرس محل ذخیره سازی کلید خصوصی مربوط به آدرس ایجاد شده به صورت رمزنگاری شده مشخص شده است. محل ذخیره سازی این کلید در پوشه keystore
مربوط به نود شبکه اصلی است. (هنگامی که اولین اکانت رو میسازید، پوشه keystore ایجاد میشه.)
ساخت بلاکچین خصوصی
قبل از هر چیز یک پوشه برای بلاکچین خصوصی خود بر روی سیستم ایجاد کنید.
ساخت هر بلاکچین با یک بلاک آغازین یا بلاک genesis آغاز می شود. برای این کار می بایست یک فایل با فرمت json ایجاد کنیم و تنظیمات بلاک آغازین را در آن قرار دهیم. یک فایل با نام genesis.json
داخل پوشه بلاکچین خود ایجاد کنید و محتویات زیر را داخل آن کپی کنید.
{
"config": {
"chainId": 4568,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"difficulty" : "400",
"extraData" : "",
"gasLimit" : "15000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
در ادامه بخش های مختلف فایل genesis توضیح داده می شود:
-
config: تنظیمات مربوط به بلاکچین خصوصی در این بخش تعریف می شود:
1.1 chainId: مشخص کننده بلاکچین است. زنجیره اصلی اتریوم با شماره 1 مشخص می شود؛ شبکه تست
Ropsten با شماره زنجیره 3 مشخص می شود؛ Rinkeby شماره 4 و Kovan شماره 42 است. شبکه خصوصی ای که ما ایجاد می کنیم دارای شماره زنجیره 4568 است. این عدد می تواند هر شماره دلخواهی که قبلا استفاده نشده است؛ باشد. با یک کلاینت مشترک می توان به انواع شبکه های اتریوم متصل شد.
1.2 homesteadBlock: این فیلد و سه فیلد بعدی مشخص کننده این است که از کدام شماره بلاک تغییرات مربوط به هارد فورک ها آغاز می شود. در اینجا ما بلاکچین خود را داریم و از بلاک آغازین شروع می کنیم، بنابراین تمام فیلدها را صفر قرار ی دهیم. -
alloc: در این بخش می توانیم به محض ایجاد بلاکچین، آدرس ایجاد کنیم و آن ها را شارژ کنیم. ما با این قسمت کاری نداریم. برای شارژ اکانت ها از ماین کردن کمک می گیریم.
-
difficulty: میزان سختی برای یافتن یک هش بلاک معتبر را مشخص می کند. و یا به عبارت دیگر هدف ماینینگ را شخص می کند. این مقدار در حال نوسان است تا زمان تولید یک بلاک را تقریبا در 15 ثانیه نگه دارد. در اینجا برای اینکه سریع به جواب برسیم میزان سختی را پایین درنظر می گیریم.
-
extraData: یک مقدار اختیاری به اندازه 32 بایت است که هر عبارت دلخواهی می تواند باشد.
-
gasLimit: حداکثر مقدار مجاز gas برای هر بلاک را مشخص می کند. عدد 15,000,000 مقدار در حال حاضر بر روی شبکه اصلی است.
-
parentHash: مقدار هش هدر بلاک قبلی یا والد را مشخص می کند. درواقع همین اشاره گر به بلاک قبلی، زنجیره بلاک ها را ایجاد می کند.
-
timestamp: زمان به فرمت یونیکس در هنگام ساخت بلاک را مشخص می کند. این پارامتر به ما کمک می کند چه زمانی سطح سختی می بایست تغییر کند تا میانگین زمان تولید یک بلاک ثابت بماند. همچنین به کمک این پارامتر می توان صحت ترتیب بلاک ها را داخل یک زنجیره تایید کرد.
سپس زنجیره خصوصی خود را با استفاده از فایل genesis ساخته شده، ایجاد می کنیم. دستور زیر را در پوشه مربوط به بلاکچین خصوصی که ساخته اید، اجرا کنید.
$ geth --datadir . init genesis.json
پیش از آنکه سراغ اجرای نود برویم با استفاده از دستور geth دو اکانت ایجاد می کنیم. اکانت اول به عنوان اکانت اصلی یا آدرس ماینر و اکانت دوم برای انجام تراکنش استفاده می شود. در پوشه مربوط به شبکه خصوصی دستور زیر را اجرا کنید، فراموش نکنید که رمز عبور را به خاطر بسپارید و همچنین آدرس های تولید شده را در جایی نگه دارید.
geth --datadir . account new
حالا می توانیم بلاکچین خود را اجرا کنیم و بلاک های زنجیره را ماین کنیم. برای اجرای نود وارد پوشه شبکه خود شوید و دستور زیر را اجرا کنید:
$ geth --allow-insecure-unlock --datadir . --keystore keystore --networkid 4568 --http --http.corsdomain "*" --http.port 8502 --http.api personal,eth,net,web3,txpool,miner --mine --miner.etherbase=0xD04E55037Cab53E4d711BBC81f275e9d37629C9c
با اجرای دستور، چنین چیزی می بایست مشاهده کنید:
حالا می توانیم به زنجیره خصوصی خود متصل شویم. با توجه به اینکه نود مورد نظر بر روی سیستم خودمان است می توانیم از پروتکل IPC استفاده کنیم. پیش از آن در هنگام اجرای دستور قبل عبارت IPC endpoint opened
را می توان مشاهده کرد. این آدرس بر روی سیستم عامل های مختلف ممکن است متفاوت باشد. به عنوان مثال بر روی سیستم عامل ویندوز به شکل زیر وجود دارد:
همانطور که در بخش اول آموزش گفته شد می توانیم یک ترمینال جدید باز کنیم و از طریق ایجاد یک بستر IPC به نود مورد نظر متصل شویم.
پس از اتصال به نود می بایست چنین چیزی شاهده کنیم:
به پارامترهای datadir
و coinbase
دقت کنید که به ترتیب آدرس محل ذخیره سازی بلاکچین خصوصی و آدرس اتریوم معرفی شده توسط شما به عنوان ماینر یا همان آدرس اصلی هستند.
در کنسول باز شده می توانید دستورات مورد نظر را برای ارتباط با نود خصوصی، اجرا کنید.
بررسی اکانت
شما می توانید به تمام اکانت های geth از طریق eth.accounts
دسترسی داشته باشید.
> eth.accounts
["0x1c29b7832ad2e4731d816e60f767777cbf374e15", "0x01058d7d56a216b3f1ff8f41c20ad58888424de7"]
همچنین می توانید موجودی هر حساب را با استفاده از متد ()eth.getBalance
مشاهده کنید.
> eth.getBalance(eth.accounts[0])
0
اولین حساب ایجاد شده یا حساب اصلی از طریق eth.coinbase
نیز در دسترس است.
ماینینگ
از آنجایی که شبکه خصوصی ایجاد شده همانند شبکه اتریوم از مکانیزم اجماع اثبات کار استفاده می کند، برای اجرای تراکنش ها می بایست بلاک ها را ماین کنیم.
برای شروع ماینینگ کافیست دستور ()miner.start
را اجرا کنیم. می توانید فرآیند ماینینگ را بر روی ترمینال نود مشاهده کنید. بعد از آنکه تعدادی بلاک ماین شد با دستور ()miner.stop
می توانید فرآیند را متوقف کنید. حالا می توانید موجودی حساب اصلی خود را مجددا چک کنید که باید شامل مقداری اتر باشد.
ارسال تراکنش
باتوجه به اینکه مقداری اتر در حساب خود داریم می توانیم یک تراکنش انجام دهیم و به یک حساب دیگر اتر واریز کنیم. برای انجام تراکنش در کنسول geth از متد ()eth.sendTransaction
استفاده می کنیم. ولی پش از آن ی بایست بدانیم یک تراکنش اتریوم شامل چه داده های است:
-
from: از نوع
String
، آدرس ارسال کننده را مشخص می کند. -
to: از نوع
String
، آدرس گیرنده یا مقصد را شخص می کند. -
value: فیلد اختیاری، از نوع
Number
,String
و یاBigNumber
می تواند باشد. مبلغی که در تراکنش منتقل می شود بر حسب wei. -
gas: فیلد اختیاری، از نوع
Number
,String
و یاBigNumber
می تواند باشد. میزان gas ای که برای تراکنش مصرف می شود. -
gasPrice:فیلد اختیاری، از نوع
Number
,String
و یاBigNumber
. هزینه gas برای این تراکنش برحسب wei. مقدار پیشفرض براساس حداقل هزینه gas شبکه در نظر گرفته می شود. -
data: فیلد اختیاری، از نوع
String
. -
nonce: فیلد اختیاری، از نوع
Number
. یک عدد صحیح است به ما اجازه میدهد تراکنشی را که هنوز در حال انجام است جایگزین کنیم با تراکنشی که دارای همان عدد nonce باشد.
برای ارسال اتر به یک حساب دیگر تنها نیاز دارید ارسال کننده، دریافت کننده و مقدار را مشخص کنید. مانند عبارت زیر:
> eth.sendTransaction({to: eth.accounts[1], from: eth.accounts[0], value: 100})
در هنگام اجرای این دستور با خطای Error: authentication needed
مواجه می شوید. بنابراین می بایست اصطلاحا حسابی که می خواهید با آن اتر ارسال کنید یعنی تراکنش انجام دهید را unlock کنید با وارد کردن رمز عبور به صورت زیر:
> personal.unlockAccount(eth.coinbase)
Unlock account 0xabc...
true
حال می توانید دستور اجرای تراکنش را مجددا اجرا کنید. بعد از انجام تراکنش موجودی حساب 1 را چک کنید:
> eth.getBalance(eth.accounts[1])
0
مشاهده می کنید که موجودی حساب صفر است به این خاطر که تراکنش انجام شده هنوز ماین نشده و داخل بلاکچین ثبت نشده است. با اجرای دستور ماینینگ و سپس توقف آن بعد از ماین یک بلاک حالا می توانیم دوباره موجودی حساب 1 را چک کنیم:
> eth.getBalance(eth.accounts[1])
100
موجودی حساب می بایست مقدار 100 باشد.
در این لینک دموی ساخت بلاکچین خصوصی بر روی سیستم عامل ویندوز آورده شده است.