ساخت اپلیکیشن رای دهی تماماً غیر متمرکز با استفاده از زبان Solidity

رأی‌گیری یک جنبه بنیادی از دموکراسی است، اما سیستم‌های رأی‌گیری سنتی اغلب مرکزی هستند که ممکن است منجر به مسائلی مانند تقلب در رأی‌گیری، تحریف و عدم شفافیت شوند. رأی‌گیری غیرمتمرکز از فناوری بلاکچین استفاده می‌کند تا یک سیستم رأی‌گیری شفاف، امن و غیرقابل تغییر ایجاد کند. در این مقاله، ما شما را از طریق فرایند ساخت یک برنامه رأی‌گیری غیرمتمرکز بر روی بلاکچین اتریوم با استفاده از سالیدیتی (Solidity)، زبان برنامه نویسی محبوب برای قراردادهای هوشمند، همراهی خواهیم کرد.

سیستم‌های رأی‌گیری سنتی بیشتر از مرکزیت برای مدیریت فرایند استفاده می‌کنند که ممکن است منجر به مشکلاتی مانند:

  • مغایرت رأی: یک مرکز قدرت می‌تواند با تغییر شمارش رأی‌ها یا ابطال رأی‌های مشروع، نتایج یک انتخابات را تغییر دهد.
  • تقلب: یک مرکز قدرت می‌تواند با دخالت در فرآیند رأی‌گیری، اطمینان حاصل کند که یک کاندیدای خاص یا نتیجه خاصی را برگزیده می‌شود.
  • عدم شفافیت: بدون شفافیت، رای دهندگان هیچ راهی برای اطمینان از صحت شمارش رای خود ندارند.

رأی‌گیری غیرمتمرکز به وسیله تکنولوژی بلاکچین، با ایجاد یک رکورد شفاف و غیرقابل تغییر از فرایند رأی‌گیری، این مسائل را حل می‌کند. با حذف نیاز به مرکزیت، رأی‌گیری غیرمتمرکز به هر کسی امکان مشارکت در فرایند رأی‌گیری را می‌دهد و اطمینان حاصل می‌شود که نتایج دقیق و شفافیت دارند.

در این مقاله، ما به شما فرایند ساخت یک قرارداد رأی‌گیری ابتدایی بر روی بلاکچین اتریوم با استفاده از سالیدیتی را راهنمایی خواهیم کرد.

اولین مرحله در ساخت یک برنامه رأی‌گیری غیرمتمرکز نوشتن کد سالیدیتی برای قرارداد رأی‌گیری است. کد سالیدیتی برای قرارداد رأی‌گیری پایه ما به شرح زیر است:

pragma solidity ^0.8.0;

contract Voting {
    // An array to store the candidates
    bytes32[] public candidates;

    // A mapping to store the votes for each candidate
    mapping(bytes32 => uint256) public votes;

    // Add a new candidate to the list
    function addCandidate(bytes32 candidate) public {
        candidates.push(candidate);
    }

    // Vote for a candidate
    function vote(bytes32 candidate) public {
        require(validCandidate(candidate));
        votes[candidate] += 1;
    }

    // Check if a candidate is valid
    function validCandidate(bytes32 candidate) view public returns (bool) {
        for(uint i = 0; i < candidates.length; i++) {
            if(candidates[i] == candidate) {
                return true;
            }
        }
        return false;
    }
}

بیایید کد را تجزیه کنیم.

در خط اول، نسخه کامپایلر سالیدیتی مشخص شده است که کد باید با آن کامپایل شود. در اینجا، آن ^0.8.0 است که به معنای هر نسخه‌ای از کامپایلر قابل سازگاری بالاتر از 0.8.0، ولی کمتر از نسخه 0.9.0 می‌باشد.

pragma solidity ^0.8.0;

کلمه کلیدی contract برای تعریف قرارداد جدیدی به نام Voting استفاده می‌شود.

contract Voting {
    // ...
}

یک آرایه برای ذخیره نام‌های نامزدها اعلام شده است. این آرایه به عنوان public اعلام شده است، به این معنی که می‌توان به آن از خارج از قرارداد دسترسی داشت.

bytes32[] public candidates;

یک مپینگ برای ذخیره تعداد آرا دریافتی هر نامزد اعلام می‌شود. این مپینگ نام یک نامزد را که به صورت یک مقدار bytes32 نشان داده می‌شود، با تعداد آرا که به صورت یک مقدار uint256 نشان داده می‌شود، ارتباط می‌دهد. این مپینگ به عنوان public اعلام شده است، که به این معنی است که می‌توان از خارج از قرارداد به آن دسترسی داشت.

mapping(bytes32 => uint256) public votes;

تابع addCandidate برای افزودن کاندید جدید به لیست تعریف شده است. این تابع یک مقدار bytes32 به عنوان ورودی دریافت می‌کند که نام کاندید را نشان می‌دهد و این مقدار را با استفاده از تابع push به انتهای آرایه candidates اضافه می‌کند.

function addCandidate(bytes32 candidate) public {
    candidates.push(candidate);
}

تابع vote برای اجازه به کاربران برای رای دادن به یک کاندید ایجاد شده است. این تابع یک مقدار bytes32 را به عنوان ورودی دریافت می کند که نام کاندید را نشان می دهد و با فراخوانی تابع validCandidate اعتبار کاندید را بررسی می کند. اگر کاندید معتبر باشد، تعداد رای های آن کاندید در مپینگ votes افزایش می یابد.

function vote(bytes32 candidate) public {
    require(validCandidate(candidate));
    votes[candidate] += 1;
}

تابع validCandidate برای بررسی اعتبار یک کاندید را تعریف می‌کند. این تابع یک مقدار bytes32 را به عنوان آرگومان دریافت می‌کند که نام کاندید را نشان می‌دهد و با استفاده از یک حلقه for بر روی آرایه‌ی کاندیدها پیمایش می‌کند. اگر نام کاندید با یکی از نام‌های موجود در آرایه مطابقت داشته باشد، تابع true برمی‌گرداند تا اعتبار کاندید را نشان دهد. اگر هیچ مطابقتی یافت نشود، تابع false برمی‌گرداند.

function validCandidate(bytes32 candidate) view public returns (bool) {
    for(uint i = 0; i < candidates.length; i++) {
        if(candidates[i] == candidate) {
            return true;
        }
    }
    return false;
}

این توابع با هم یک سیستم رأی‌گیری ابتدایی را ایجاد می‌کنند که به کاربران امکان اضافه کردن نامزدها به لیست و رأی دادن به آن‌ها را می‌دهد. نگاشت رأی‌ها به ما امکان می‌دهد تا تعداد رأی‌ها برای هر نامزد را ردیابی کنیم و تابع validCandidate مطمئن می‌شود که کاربران تنها می‌توانند برای نامزدهای معتبر رأی دهند.

با این حال، این قرارداد هنوز دارای برخی از ویژگی‌های کلیدی مورد نیاز یک سیستم رأی‌گیری واقعی در جهان است. به عنوان مثال، هیچ محدودیتی در مورد افرادی که می‌توانند رأی دهند وجود ندارد و هیچ راهی برای جلوگیری از رأی دادن چند بار توسط کاربران وجود ندارد. علاوه بر این، در حال حاضر، این قرارداد هیچ مکانیزمی برای اعلام نتایج انتخابات یا حل اختلافات ندارد.

برای ساختن یک سیستم رأی‌گیری غیرمتمرکز و پایدارتر، باید ویژگی‌ها و قابلیت‌های اضافی را به قرارداد خود اضافه کنیم. این می‌تواند شامل اضافه کردن مکانیزم‌های تأیید هویت، پیاده‌سازی یک سیستم رأی‌گیری بر اساس زمان و ایجاد مکانیزم‌هایی برای حل اختلافات باشد.

کلیتا، برنامه رأی‌گیری غیرمتمرکز تنها یک مثال از فراوانی امکاناتی است که فناوری بلاکچین می‌تواند ارائه دهد. با پیشرفت و دسترسی آسان‌تر به این فناوری، انتظار داریم که بسیاری از برنامه‌های نوآورانه بر پایه بلاکچین ساخته شوند.