solidity實現voting

更新於 發佈於 閱讀時間約 16 分鐘
使用solidity實現基本的投票並且去操作功能,像是投票,發票或是委託票等。

創建contract

raw-image

Solidity by Example — Solidity 0.8.10 documentation (soliditylang.org)

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
/// @title Voting with delegation.
contract Voting {

// 選民
struct Voter {
uint weight; // weight is accumulated by delegation
bool voted; // if true, that person already voted
address delegate; // 被委託人 person delegated to
uint vote; // 投票提案的索引 index of the voted proposal
}

// This is a type for a single proposal.
struct Proposal {
string name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}

address public chairperson;

// This declares a state variable that
// stores a `Voter` struct for each possible address.
mapping(address => Voter) public voters;

// A dynamically-sized array of `Proposal` structs.
Proposal[] public proposals;

// 為`proposalNames` 中的每個提案,創建一個新投票表決 Create a new ballot to choose one of `proposalNames`.
constructor(string[] memory proposalNames) {
chairperson = msg.sender;
voters[chairperson].weight = 1;

// 對每一提案名稱,創建一個新的Proposal並添加到array
for (uint i = 0; i < proposalNames.length; i++) {
// `Proposal({...})` creates a temporary
// Proposal object and `proposals.push(...)`
// appends it to the end of `proposals`.
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}

// 授權voter對這個表決進行投票,只有chairperson能調用此函數
function giveRightToVote(address voter) external {
// If the first argument of `require` evaluates
// to `false`, execution terminates and all
// changes to the state and to Ether balances
// are reverted.
// This used to consume all gas in old EVM versions, but
// not anymore.
// It is often a good idea to use `require` to check if
// functions are called correctly.
// As a second argument, you can also provide an
// explanation about what went wrong.
require(
msg.sender == chairperson,
"Only chairperson can give right to vote."
);
require(
!voters[voter].voted,
"The voter already voted."
);
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}

/// 將您的投票委託給選民 voter `to`.
function delegate(address to) external {
// assigns reference
Voter storage sender = voters[msg.sender];
require(!sender.voted, "You already voted.");

require(to != msg.sender, "Self-delegation is disallowed.");

// Forward the delegation as long as
// `to` also delegated.
// In general, such loops are very dangerous,
// because if they run too long, they might
// need more gas than is available in a block.
// In this case, the delegation will not be executed,
// but in other situations, such loops might
// cause a contract to get "stuck" completely.
while (voters[to].delegate != address(0)) {
to = voters[to].delegate;

// We found a loop in the delegation, not allowed.
require(to != msg.sender, "Found loop in delegation.");
}

// Since `sender` is a reference, this modifies `voters[msg.sender].voted`
sender.voted = true;
sender.delegate = to;
Voter storage delegate_ = voters[to];
if (delegate_.voted) {
// If the delegate already voted,
// directly add to the number of votes
proposals[delegate_.vote].voteCount += sender.weight;
} else {
// If the delegate did not vote yet,
// add to her weight.
delegate_.weight += sender.weight;
}
}

/// 把你的票(包括委託給你的票),投給提案`proposals[proposal].name`.
function vote(uint proposal) external {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;

// If `proposal` is out of the range of the array,
// this will throw automatically and revert all
// changes.
proposals[proposal].voteCount += sender.weight;
}

/// @dev Computes the winning proposal taking all
/// previous votes into account.
function winningProposal() public view
returns (uint winningProposal_)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}

// Calls winningProposal() function to get the index
// of the winner contained in the proposals array and then
// returns the name of the winner
function winnerName() external view
returns (string memory winnerName_)
{
winnerName_ = proposals[winningProposal()].name;
}
}

測試

啟動節點模擬

raw-image

使用Remix

raw-image

Compile

raw-image


Deploy合約

raw-image

Output:

raw-image


測試環節

測試Proposals

raw-image
raw-image


結果

raw-image


chairperson

raw-image
raw-image


chairperson(0xac55502aF00E1F405f115C17F45D43c36C47F7C3)給其他人票:

raw-image


raw-image
raw-image


其他也是:
0xF197FFB0422d7026809210826325bfa719105251
0x7CB7374abE10dDd7e16b3dfe5E68623DAb1b13F3
0x9AD3eB9367f6B123a843AcF946e4D360c445FB9d

測試非Chairperson給其他人票:

raw-image


出現ERROR:

raw-image



Output

raw-image


測試Voter:

raw-image
raw-image
raw-image


接著切換帳戶:
0xF197FFB0422d7026809210826325bfa719105251
將自己的票委託給他人(0x7CB7374abE10dDd7e16b3dfe5E68623DAb1b13F3):

raw-image
raw-image

使用看Voter函數來觀察:

raw-image


測試投票:
0xF197FFB0422d7026809210826325bfa719105251

raw-image
raw-image



(我們把票給別人了,無法投,並且先看一下propsal)

raw-image


能看到沒有投成功

raw-image


切換成其他人開始投票:
0x7CB7374abE10dDd7e16b3dfe5E68623DAb1b13F3
0x9AD3eB9367f6B123a843AcF946e4D360c445FB9d
執行vote

raw-image
raw-image


接著看proposal(Alice, Bob):

raw-image


呼叫WINNERNAME和WINNINGPROPOSAL

raw-image
raw-image


合約內的東西都測試完畢

Reference:

Solidity by Example


歡迎大家來我的Blog看:

1.Blog: 文章連結

留言
avatar-img
留言分享你的想法!
avatar-img
Fufu的沙龍
0會員
4內容數
Fufu的沙龍的其他內容
2022/04/25
此篇文是在練習並熟悉solidity與remix的操作
Thumbnail
2022/04/25
此篇文是在練習並熟悉solidity與remix的操作
Thumbnail
2022/04/24
開發工具與環境設置 安裝所需要工具 啟動 ganache-cli來啟動乙太坊測試環境 建立智能合約 HelloWorld.sol: 編譯 編譯成功的話,在build/contracts/目錄下會多出HelloWorld.json這個檔案 部署 2\_deploy\_contracts.js: 測試
Thumbnail
2022/04/24
開發工具與環境設置 安裝所需要工具 啟動 ganache-cli來啟動乙太坊測試環境 建立智能合約 HelloWorld.sol: 編譯 編譯成功的話,在build/contracts/目錄下會多出HelloWorld.json這個檔案 部署 2\_deploy\_contracts.js: 測試
Thumbnail
2022/04/24
在flutter內實現當鼠標懸停時圖片縮放
Thumbnail
2022/04/24
在flutter內實現當鼠標懸停時圖片縮放
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
好旺社區過去選任管理委員會的住戶態度並不踴躍,於是想藉由變更選任委員的投票方式,希望能藉此增加住戶參與度,可不可以在選舉當天才臨時動議提議採用新的投票方法?
Thumbnail
好旺社區過去選任管理委員會的住戶態度並不踴躍,於是想藉由變更選任委員的投票方式,希望能藉此增加住戶參與度,可不可以在選舉當天才臨時動議提議採用新的投票方法?
Thumbnail
本校模擬自治鄉長選舉已經實施二十多年了,雖然投票人口不到百人,學校還是按規矩展開一連串選舉活動,讓一到六年級學生都能體驗選舉流程。
Thumbnail
本校模擬自治鄉長選舉已經實施二十多年了,雖然投票人口不到百人,學校還是按規矩展開一連串選舉活動,讓一到六年級學生都能體驗選舉流程。
Thumbnail
以下我想提出一個好玩的觀點 或許可以解決民主的問題 一個讀醫學的工程師 沒有政治學背景 也不懂政治 甚至不認識台灣九成以上的政治明星 或許你們會覺得,這樣的人有什麼資格來寫關於民主或政治的文章 歡迎大家挑戰,指責,提出任何意見 但我更喜歡有建設性的一起討論 希望我沒有背景和立場的言論,能給大家一點新
Thumbnail
以下我想提出一個好玩的觀點 或許可以解決民主的問題 一個讀醫學的工程師 沒有政治學背景 也不懂政治 甚至不認識台灣九成以上的政治明星 或許你們會覺得,這樣的人有什麼資格來寫關於民主或政治的文章 歡迎大家挑戰,指責,提出任何意見 但我更喜歡有建設性的一起討論 希望我沒有背景和立場的言論,能給大家一點新
Thumbnail
記得111年年底才結束地方縣市長、議員及里長的選舉,大家從選舉的熱情中冷卻,回復柴米油鹽的生活,很快的,113年年初又要進行第16任總統、副總統及立法委員選舉,只能說又要陷入選舉無限輪迴。
Thumbnail
記得111年年底才結束地方縣市長、議員及里長的選舉,大家從選舉的熱情中冷卻,回復柴米油鹽的生活,很快的,113年年初又要進行第16任總統、副總統及立法委員選舉,只能說又要陷入選舉無限輪迴。
Thumbnail
民意代表,換句話說就是代表民意的人,以現行機制雖然可以每4年透過選舉,檢驗民意代表是否認真行使職權,為民喉舌,不過,4年才檢驗一次時間有點久。
Thumbnail
民意代表,換句話說就是代表民意的人,以現行機制雖然可以每4年透過選舉,檢驗民意代表是否認真行使職權,為民喉舌,不過,4年才檢驗一次時間有點久。
Thumbnail
投票日當天不只有投票。
Thumbnail
投票日當天不只有投票。
Thumbnail
是非的建立 應該在學習科技之前 而邏輯學,又應該架構在 有科技常識下 了解法律,社會契約前 必須先學會基本邏輯 然後,最後才去談思想 談想法,去討論什麼民主 不然,連權利義務都沒搞清楚 權利義務 有些地方是沒有民主的範疇的 你跑到別人家,然後舉行投票 ”他的房子,應該歸我們“ 然後,說這叫「民主精神
Thumbnail
是非的建立 應該在學習科技之前 而邏輯學,又應該架構在 有科技常識下 了解法律,社會契約前 必須先學會基本邏輯 然後,最後才去談思想 談想法,去討論什麼民主 不然,連權利義務都沒搞清楚 權利義務 有些地方是沒有民主的範疇的 你跑到別人家,然後舉行投票 ”他的房子,應該歸我們“ 然後,說這叫「民主精神
Thumbnail
學習並操作solidity裡的投票,並做一些小修改,顯示出來的被投票者不再是byte,而是string。
Thumbnail
學習並操作solidity裡的投票,並做一些小修改,顯示出來的被投票者不再是byte,而是string。
Thumbnail
◎授課重點:帶領學生了解公民投票,並且運用公投公報的形式,引導他們以理性思維表達對於體制的意見,參與公共事務,打造公民素養。此外,學生在陳述建議與解決反方可能提出的質疑時,可以鍛鍊議論文的寫作技巧。 ◎適合對象:高年級、國中 ◎附學生範文、公投公報表格
Thumbnail
◎授課重點:帶領學生了解公民投票,並且運用公投公報的形式,引導他們以理性思維表達對於體制的意見,參與公共事務,打造公民素養。此外,學生在陳述建議與解決反方可能提出的質疑時,可以鍛鍊議論文的寫作技巧。 ◎適合對象:高年級、國中 ◎附學生範文、公投公報表格
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News