فرق تابع اولی و دومی چیه چون تابع اولی کاربردی رو کلیت نداره همون تابع دومی کار رو انجام میده با توجه به اینکه گفتید تابع اولی مشکل داره از لحاظ امنیتی , درست میگم ؟
سلام
تفاوتشون اینه که تابع اول یک ورودی رو در proof ذخیره میکنه و state برنامه رو تغییر میده و تابع دوم چون از pure استفاده کرده نمیتونه به state برنامه دسترسی داشته باشه یعنی نه میتونه بخونه و نه میتونه تغییر بده. فقط میتونه از پارامترهای خودش استفاده کنه
سلام خسته نباشین
یه سوال داشتم من مفهوم constructor رو درست متوجه نشدم، اینکه کابردش چیه اصلا؟
مثلا اگه من یه کانترکت تعریف کنم بعد بیام یه سری variable تعریف کنم بدون دستور contructor با اینکه یه سری variable با دستور constructor چه فرقی داره؟
مثلا فرق contract A با contract B چیه ؟
contract A {
address public owner;
uint public x = 5;
bool public locked;
constructor() {
owner = msg.sender;
}
}
contract B {
address public owner = msg.sender;
uint public x = 5;
bool public locked;
}
درسته ولی هدفمون در این تمرین ساخت یک poe هست با توجه به این تابع دومی برا ساختش کفایت می کنه درست میگم ؟ و سوال دیگه ام در جلسه گفته شد تابع اول امنیت ندارد برای اینکه داده در شبکه مشخص است آیا برای تابع دوم هم به همین صورت میباشد؟
چیزی که طبق یه ویدیو دیدم متوجه شدم که متغیر که داخل constructor باشه توسط قرار داده دیگه ای نمیشه صداش زد . که برای متغیر های حساس می تونه استفاده شه مثلا اینجا msg.sender که این کار امنیتش رو بیشتر میکنه. حالا این مطالبی بود که تا حدودی متوجه شدم حالا اگه اشتباه گفتم یا اگه تفاوت های دیگه نسبت به متغیر ساده داره ممنون میشم اگه کسی میدونه بگه …
سلام،
تو این نمونه ساده میشه همشو همونجا نوشت.
ولی در کل برمیگرده به ساده و جدا نگه داشتن توابع و کارکردها.
اینجا یه تابع داریم که کارش اپدیت state بلاکچینه و یه تابع که کارش برگردوندنه هش ورودیه.
ترکیب اینا در راستای تمیز نوشتن کد نیست و این مختص سالیدیتی نیست.
ممنون
وقتی ما state variable تعریف میکنیم مگه بیشتر از یکبار و یا همون زمان دیپلوی مقداردهی نمیشن؟
الان تو این دو قراردادی که این پایین کدشون رو گذاشتم در هر دو در زمان دیپلوی به x مقدار 5 رو میدن و همون موقع و یکبار میدن. پس چه فرقی داره؟
contract A {
uint public x = 5;
}
contract B {
constructor() {
uint public x = 5;
}
}
آره حق با شماست (My bad) تفاوتی ندارن.
به نظر تو تعداد opcode ها هم خیلی کم فرق دارن و خیلی تو چشم نیست.
و تصمیم شماست که بخوایین کدومو استفاده کنید. مثلا ممکنه در نظر بگیرید برای آپگریدهای بعدی ممکنه منطقی بخوایین اضافه کنین به این مقداردهی و میخوایین دستتون بازتر باشه یا نه, کدوم به نظرتون تمیزتز میشه, آیا همیشه مقدار ثابت خواهد بود و …
جواب قبلی رو حذف میکنم که کسی رو به اشتباه نندازه.
همونطوری که گفتن در قطعه کد شما فرقی نداره اما اگر وابستگی ای قبل اجرای constructor باشه یکم فرق میکنه
مثلا قطعه کد زیر خروجی برای شما (1,2,1) بر میگردونه به خاطر اینکه قبل از اجرای constructor مقدار متغیر b = 0 است.
در نتیجه c = 0 + 1
contract C {
uint a = 1;
uint b;
uint c = b + 1;
constructor() {
b = 2;
}
function get() public view returns (uint, uint, uint) {
return (a, b, c);
}
}
ممنون
ببینید درست متوجه شدم؟ یعنی در زمان دیپلوی قبل از state variableها اول constructor اجرا میشه پس b برابر 2 میشه ولی بعد که سراغ state variable میریم a رو برابر 1 قرار میده و مقدار b رو صفر میکنه؟ با اینکه قبلا تو constructor مقدار 2 داده شده؟ پس اون 2 تبدیل به دیفالت b نمیشه ؟ و در زمان تعریف state variableها مقدار b به صفر تغییر میکنه ؟
پس باز هم عملا استفاده از constructor معنایی نداشته برای ما
من یکم مشکل با اینه که بفهمم constructor برای تعریف یه متغییر در عمل کاربردش چیه که نمیشه با state variable همون متغییر رو تعریف کنیم؟
اگه مثالی پیدا کنم که نشون بده که اینجا فقط درستش اینه که از constructor استفاده کرد، شاید بهتر کاربردش رو درک کنم.
نه برعکس متوجه شدید اول state variable ها مقدار دهی میشن
که b به صورت دیفالت برابر 0 است
پس در خط بعدی c = 0 + 1
بعد constructor اجرا میشه مقدار b =2 میشه
و هنگام return مقدار b =2 , c=1 است.
یکی از کاربرد های constructor زمانیه که شما نمیخوایید value به صورت ثابت به متغیر بدید
مثلا یک قرارداد مینویسید که میخوایید از اون در چند کانترکت دیگه ارث بری و هنگام دیپلوی اون کانترکت ها مقادیر مختلف به عنوان ورودی کانترکت parent در نظر بگیرید
contract C {
uint a = 1;
uint b;
constructor(uint _b) public {
b = _b;
}
}
حالا زمانی که شما میخواهید از کانترکتت C ارث بری کنی باید مقدار اولیه تعیین کنی براش
مثلا
چون موقع دیپلوی قبل اینکه گزینه دیپلوی زده بشه تو کادر جلوش، میشه مقدار b رو داد بهش
ولی ظاهرا اینجور که میگین درسته که در زمان دیپیولی ما مقدار میدیم ولی باز اول state variableها رو نگاه میکنه مقدار میده بعد دستور constructor رو اجرا میکنه.
یعنی چون تابع اول state برنامه رو تغییر میده ورودی رو همه میتونن بخونن و امنیت میاد پایین؟ من درست متوجه نشدم چرا امنیت اولی پایینه و اصلا چرا بقیه ورودی تابع اول رو میتونن بخونن ولی تابع دوم را نه؟
وقتی به تابع notarize ورودی میدید یه تراکنش روی شبکه ثبت میشه و مقدار ورودی شما روی شبکه به صورت شفاف مشخصه برای این میگن امنیت نداره که اطلاعات ورودی شما روی شبکه ثبت میشه
ولی تابع دوم proofFor که pure است هنگامی که بهش ورودی میدید تراکنشی روی شبکه ثبت نمیشه و ورودی شما برای بقیه اشخاص قابل مشاهده نیست
سلام
وقتی ما یک تابع از کانترکت دیگه که کانترکت ما ازش ارث بری کره فراخوانی کنیم این عمل یه تراکنش در بلاکچین ثبت می کنه که هزینه بر است خوب به صرفه نیست ما سعی کنیم توابع رو در کانترکت خودمون تعریف کنیم ؟ و کمتر از توابع دیگر کانترکت ها استفاده کنیم؟
مرسی
اگه بشه که بهتره ولی معمولا اون تابع به تابع های دیگه ای وابستس به خاطر همین داخل یک کانترکت اومده و ممکنه به کانترکت دیگه ای هم وابسته باشه ولی اگه دیدی فقط یک تابش کارتو راه میندازه و به متغیر های دیگه ای وابسته نیست آره میتونه و بهتره به صورت جدا ازش استفاده کنی .