Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize centralized Voting DApp and Intelligent contract in Yi Tai Fang

2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the relevant knowledge of "how to achieve centralized voting DApp and intelligent contract in Ethernet Square". The editor shows you the operation process through an actual case. The method of operation is simple and fast, and it is practical. I hope this article "how to achieve centralized voting DApp and intelligent contract in Taifang" can help you solve the problem.

Why develop decentralized voting applications?

In essence, decentralized applications using blockchain technology allow you to perform the same operations (such as transferring funds) without a trusted third party. The best dApp has specific real-world use cases to take advantage of the unique characteristics of the blockchain.

In essence, blockchain is a shared, programmable, encrypted, secure, reliable ledger that no one user can control and anyone can query. -Klaus Schwab

Even though the voting app may not be a great application for all of you, I chose to use it as this guide because the main problems solved by the blockchain: transparency, security, accessibility, and trustworthiness are the main problems plaguing current democratic elections.

Because blockchain is a permanent record of decentralized transactions (voting), each vote can be irrefutably traced back to when and where it took place without revealing the identity of voters. In addition, voting in the past cannot be changed, and now it cannot be attacked by hackers, because every transaction is verified by every node in the network. Any external or internal attacker must control 51% of the nodes to change the record.

Even if attackers can do this when forging users to enter real ID cards to vote, the end-to-end voting system allows voters to verify that their votes are entered correctly in the system, which makes the system extremely secure.

The core component of Ethernet Square

I hope you learned about blockchain and Ethernet Square before reading the rest of this guide. Here's a great guide with a brief overview of the core components I want you to know.

Smart contracts act as back-end logic and storage. The contract is written in Solidity, an intelligent contract language, and is a collection of code and data that resides at a specific address of the etheric block chain. It is very similar to classes in object-oriented programming in that it contains functions and state variables. Smart contracts and blockchain are the foundation of all decentralized applications. Like Blockchain, they are immutable and distributed, which means that upgrading them will be painful if they are already on the Ethernet Fong network. Fortunately, there are some ways to do this.

The Ethernet Square Virtual Machine (EVM) handles the internal state and calculations of the entire Ethernet Fong network. Think of EVM as such a massively decentralized computer that contains addresses that can execute code, change data, and interact with each other.

Web3.js is a Javascript API that allows you to interact with blockchains, including trading and invoking smart contracts. This API abstracts communication with Ethernet Square clients, allowing developers to focus on the content of their applications. You must embed an instance of web3 in your browser to perform this operation.

Other tools that we will use

Truffle is a popular test development framework for ethernet. It includes development zone block chain, compilation and migration scripts for deploying contracts to block chains, contract testing, etc. It makes development easier!

Truffle Contracts is an abstraction on top of Web3 Javascript API that allows you to easily connect and interact with smart contracts.

Metamask will bring ethernet to your browser. It is a browser extension that provides a secure web3 instance that links to your Ethernet Square address, allowing you to use decentralized applications. We won't use Metamask in this tutorial, but it's a way for people to interact with DApp in production. Instead, we will inject our own web3 instances during development. For more information, see this link.

Let's go!

For simplicity, we won't actually build the complete voting system I described earlier. For illustration purposes, it is just a single-page application where users can enter their ID and vote for candidates. There will also be a button to calculate and display the number of votes for each candidate.

In this way, we will be able to focus on the process of creating and interacting with smart contracts in the application. The source code for the entire application will be in this repository, and you need to install Node.js and npm.

1. First, let's install Truffle globally. Npm install-g truffle

To use the Truffle command, you must run them in an existing project.

Git clone https://github.com/tko22/truffle-webpack-boilerplatecd truffle-webpack-boilerplatenpm install

This repository is just a framework for Truffle Box, a template or sample application that can be obtained in a command-truffle unbox [box name]. However, Truffle box with webpack is not updated with the latest version and includes a sample application. So, I created this repo.

two。 Directory structure

Your directory structure should include the following:

Contracts/: includes folders for all contracts. Do not delete Migrations.sol.

Migrations/: contains a folder of Migration files to help you deploy smart contracts into the blockchain.

Src/: saves the application's HTML/CSS and Javascript files.

Truffle.js:truffle configuration file.

You will not see this folder until build/: compiles the contract. This folder contains build files, so do not modify any of these files! The build file describes the functionality and architecture of the contract and provides Truffle Contracts and web3 information on how to interact with smart contracts in the blockchain.

1. Write down your smart contract.

After setting up and introducing, let's start writing code! First, we will write our smart contract, which is written in Solidity (other languages are less popular). This may seem uncomfortable, but this is not the case.

For any application, you want smart contracts to be as simple as possible, or even very simple. Remember, you have to pay for every calculation / transaction you do, and your smart contract will always be in the blockchain. So, you really want it to work perfectly-that is, the more complex it is, the more likely it is to make mistakes.

Our contract will include:

State variable: a variable that contains values that are permanently stored in the block chain. We will use status variables to keep the list and number of voters and candidates.

Function: a function is an executable file for an intelligent contract. They are what we require to interact with the blockchain, with different levels of internal and external visibility. Remember, whenever you want to change the value / state of a variable, you have to trade-it costs etheric money. You can also calls the blockchain, which will not cost any ethernet, because your changes will be destroyed (there will be more below when we actually do transactions and call).

Event: whenever an event is called, the value passed to the event is recorded in the transaction log. This allows the Javascript callback function or the parsed promises to view the specific value you want to return after the transaction. This is because the transaction log is returned every time a transaction is made. We will use an event to record the ID of the newly created candidate, and we will display the ID.

Structure type-this is very similar to the C structure. Structs allows you to save multiple variables, and it's great for things with multiple properties. Candidates will only have their names and parties, but you can definitely add more attributes to them.

Mapping-think of them as hash maps or dictionaries, which have key-value pairs. We will use two mappings.

No more types are listed here, but some are slightly more complex. These five contain most of the structures commonly used by smart contracts. These types are explained in more depth here.

For reference, this is the code for the smart contract. Note that this file should be called Voting.sol, but I want Github gist to have style, so I give it a .js extension. As with the rest of this guide, I will provide comments in the code to explain what it is doing, and then I will explain the general idea while pointing out some warnings and logic.

Pragma solidity ^ 0.4.18 vote / written for Solidity version 0.4.18 and above that doesnt break functionalitycontract Voting {/ / an event that is called whenever a Candidate is added so the frontend could / / appropriately display the candidate with the right element id (it is used / / to vote for the candidate, since it is one of arguments for the function "vote") event AddedCandidate (uint candidateID); / / describes a Voter, which has an id and the ID of the candidate they voted for struct Voter {bytes32 uid / / bytes32 type are basically strings uint candidateIDVote;} / / describes a Candidate struct Candidate {bytes32 name; bytes32 party; / / "bool doesExist" is to check if this Struct exists / / This is so we can keep track of the candidates bool doesExist;} / / These state variables are used keep track of the number of Candidates/Voters / / and used to as a way to index them uint numCandidates / / declares a state variable-number Of Candidates uint numVoters; / / Think of these as a hash table, with the key as a uint and value of / / the struct Candidate/Voter These mappings will be used in the majority / / of our transactions/calls / / These mappings will hold all the candidates and Voters respectively mapping (uint = > Candidate) candidates; mapping (uint = > Voter) voters / * These functions perform transactions Editing the mappings * / function addCandidate (bytes32 name, bytes32 party) public {/ / candidateID is the return variable uint candidateID = numCandidates++ / / Create new Candidate Struct with name and saves it to storage. Candidates [candidateID] = Candidate (name,party,true); AddedCandidate (candidateID);} function vote (bytes32 uid, uint candidateID) public {/ / checks if the struct exists for that candidate if (candidates [candidateID] .doesExist = = true) {uint voterID = numVoters++; / / voterID is the return variable voters [voterID] = Voter (uid,candidateID) }} / * Getter Functions Marked by the key word "view" * / / finds the total amount of votes for a specific candidate by looping / / through voters function totalVotes (uint candidateID) view public returns (uint) {uint numOfVotes = 0 / / we will return this for (uint I = 0; I

< numVoters; i++) { // if the voter votes for this specific candidate, we increment the number if (voters[i].candidateIDVote == candidateID) { numOfVotes++; } } return numOfVotes; } function getNumOfCandidates() public view returns(uint) { return numCandidates; } function getNumOfVoters() public view returns(uint) { return numVoters; } // returns candidate information, including its ID, name, and party function getCandidate(uint candidateID) public view returns (uint,bytes32, bytes32) { return (candidateID,candidates[candidateID].name,candidates[candidateID].party); }} 基本上,我们有两个Structs(包含多个变量的类型),用于描述选民和候选人。使用Structs,我们可以为它们分配多个属性,例如电子邮件,地址等。 为了跟踪选民和候选人,我们将它们放入单独的映射中,它们是整数索引的。候选人或选民的索引/密钥--让我们称之为ID--是函数访问它们的唯一方式。 我们还会跟踪选民和候选人的数量,这将有助于我们为他们编制索引。此外,不要忘记第8行中的事件,该事件将在添加时记录候选人的ID。我们的界面将使用此事件,因为我们需要跟踪候选人的ID以便为候选人投票。 1.我知道,与我之前所说的关于使合约变得非常简单的说法相反,我认为这个合约与这个应用实际上做的相比有点复杂。但是,我这样做是为了让你们更容易进行编辑并在之后为此应用程序添加功能(最后更多内容)。如果你想制作一个更简单的投票应用程序,智能合约可以在不到15行代码。 2.请注意,状态变量numCandidates和numVoters未声明为public。默认情况下,这些变量具有internal可见性,这意味着它们只能由当前合约或派生合约直接访问(不用担心,我们不会使用它)。 3.我们使用32bytes用于字符串而不是使用string类型。我们的EVM具有32字节的字大小,因此它被optimized以处理32字节的块中的数据。(当数据不是32字节的块时,编译器,例如Solidity,必须做更多的工作并生成更多的字节码,这实际上会导致更高的天然气成本。) 4.当用户投票时,会创建一个新的Voter结构并将其添加到映射中。为了计算某个候选人的投票数,你必须遍历所有选民并计算投票数。候选人的行为相同。因此,这些映射将保留所有候选人和选民的历史。 2.实例化web3和合约 完成我们的智能合约后,我们现在需要运行我们的测试区块链并将此合约部署到区块链上。我们还需要一种方法来与它交互,这将通过web3.js完成。 在我们开始测试区块链之前,我们必须在/contracts文件夹中创建一个名为2_deploy_contracts.js的文件,告诉它在迁移时包含你的投票智能合约。 var Voting = artifacts.require("Voting")module.exports = function(deployer) { deployer.deploy(Voting)} 要开始开发以太坊区块链,请转到命令行并运行: truffle develop 由于Solidity是一种编译语言,我们必须首先将其编译为字节码,以便EVM执行。 compile 你现在应该在目录中看到一个文件夹build/。此文件夹包含构建文件,这对Truffle的内部工作至关重要,因此请勿修改它们! 接下来,我们必须迁移合约。migrations是一个truffle脚本,可帮助你在开发时更改应用程序合约的状态。请记住,你的合约已部署到区块链上的某个地址,因此无论何时进行更改,你的合约都将位于不同的地址。 迁移可帮助你执行此操作,还可帮助你移动数据。 migrate 恭喜!你的智能合约现在永远在区块链上。好吧,还不是真的...... 因为truffle develop会在每次停止时刷新。 如果你想拥有一个持久的区块链,可以考虑一下由Truffle开发的Ganache。如果你使用的是Ganache,则无需调用truffle develop。相反,你将运行truffle compile和truffle migrate。要了解在没有Truffle的情况下部署合约需要什么,请查看此博客文章。 一旦我们将智能合约部署到区块链,我们将不得不在应用程序启动时在浏览器上使用Javascript设置web3.0实例。因此,下一段代码将放在js/app.js的底部。请注意,我们使用的是web3.0版本0.20.1。 // When the page loads, we create a web3 instance and set a provider. We then set up the appwindow.addEventListener("load", function() { // Is there an injected web3 instance? if (typeof web3 !== "undefined") { console.warn("Using web3 detected from external source like Metamask") // If there is a web3 instance(in Mist/Metamask), then we use its provider to create our web3object window.web3 = new Web3(web3.currentProvider) } else { console.warn("No web3 detected. Falling back to http://localhost:9545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask") // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) window.web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:9545")) } // initializing the App window.App.start()}) 如果你不理解这段代码,你真的不必太担心。只要知道这将在应用程序启动时运行,并将检查浏览器中是否已存在web3实例(Metamask)。如果没有,我们将创建一个与localhost:9545交互Truffle开发区块链。 如果你正在使用Ganache,你必须将端口更改为7545.一旦创建了一个实例,我们将调用start函数。 3.添加功能 我们需要做的最后一件事是为应用程序编写接口。这涉及任何Web应用程序的基本要素--HTML,CSS和Javascript(我们已经编写了一些用于创建web3实例的Javascript)。首先,让我们创建我们的HTML文件。 Ethereum Voting Dapp Ethereum Voting Dapp Add ID and click candidate to vote Count Votes 这是一个非常简单的页面,带有用户ID的输入表单,以及用于投票和计票的按钮。点击这些按钮后,他们将调用投票的特定功能,并找到候选人的投票数。 但是有三个重要的div元素,其中有id:candidate-box,msg和vote-box,它们分别包含每个候选者的复选框,一条消息和一个投票数。我们还导入了JQuery,Bootstrap和app.js。 现在,我们只需要与合约互动并实施投票和计算每个候选人的投票数量的功能。JQuery将控制DOM,当我们进行交易或调用Blockchain时,我们将使用Promises。以下是app.js的代码。 // import CSS. Webpack with deal with itimport "../css/style.css"// Import libraries we need.import { default as Web3} from "web3"import { default as contract } from "truffle-contract"// get build artifacts from compiled smart contract and create the truffle contractimport votingArtifacts from "../../build/contracts/Voting.json"var VotingContract = contract(votingArtifacts)/* * This holds all the functions for the app */window.App = { // called when web3 is set up start: function() { // setting up contract providers and transaction defaults for ALL contract instances VotingContract.setProvider(window.web3.currentProvider) VotingContract.defaults({from: window.web3.eth.accounts[0],gas:6721975}) // creates an VotingContract instance that represents default address managed by VotingContract VotingContract.deployed().then(function(instance){ // calls getNumOfCandidates() function in Smart Contract, // this is not a transaction though, since the function is marked with "view" and // truffle contract automatically knows this instance.getNumOfCandidates().then(function(numOfCandidates){ // adds candidates to Contract if there aren't any if (numOfCandidates == 0){ // calls addCandidate() function in Smart Contract and adds candidate with name "Candidate1" // the return value "result" is just the transaction, which holds the logs, // which is an array of trigger events (1 item in this case - "addedCandidate" event) // We use this to get the candidateID instance.addCandidate("Candidate1","Democratic").then(function(result){ $("#candidate-box").append(`Candidate1`) }) instance.addCandidate("Candidate2","Republican").then(function(result){ $("#candidate-box").append(`Candidate1`) }) // the global variable will take the value of this variable numOfCandidates = 2 } else { // if candidates were already added to the contract we loop through them and display them for (var i = 0; i < numOfCandidates; i++ ){ // gets candidates and displays them instance.getCandidate(i).then(function(data){ $("#candidate-box").append(`${window.web3.toAscii(data[1])}`) }) } } // sets global variable for number of Candidates // displaying and counting the number of Votes depends on this window.numOfCandidates = numOfCandidates }) }).catch(function(err){ console.error("ERROR! " + err.message) }) }, // Function that is called when user clicks the "vote" button vote: function() { var uid = $("#id-input").val() //getting user inputted id // Application Logic if (uid == ""){ $("#msg").html(" Please enter id. ") return } // Checks whether a candidate is chosen or not. // if it is, we get the Candidate's ID, which we will use // when we call the vote function in Smart Contracts if ($("#candidate-box :checkbox:checked").length >

0) {/ / just takes the first checked box and gets its id var candidateID = $("# candidate-box: checkbox:checked") [0] .id} else {/ / print message if user didn't vote for candidate $("# msg") .html ("

Please vote for a candidate.

") return} / / Actually voting for the Candidate using the Contract and displaying" Voted "VotingContract.deployed (). Then (function (instance) {instance.vote (uid,parseInt (candidateID)). Then (function (result) {$(" # msg ") .html ("

Voted

Catch (function (err) {console.error ("ERROR!" + err.message)})}) / / function called when the "Count Votes" button is clicked findNumOfVotes: function () {VotingContract.deployed () .then (function (instance) {/ / this is where we will add the candidate vote Info before replacing whatever is in # vote-box var box = $(") / / loop through the number of candidates and display their votes for (var I = 0) I < window.numOfCandidates; iTunes +) {/ / calls two smart contract functions var candidatePromise = instance.getCandidate (I) var votesPromise = instance.totalVotes (I) / resolves Promises by adding them to the variable box Promise.all ([candidatePromise,votesPromise]) .then (function (data) {box.append (`)

${window.web3.toAscii (data [0] [1])}: ${data [1]}

Catch (function (err) {console.error ("ERROR!" + err.message)})} $("# vote-box") .html (box) / / displays the "box" and replaces everything that was in it before})}} / / When the page loads, we create a web3 instance and set a provider. We then set up the appwindow.addEventListener ("load", function () {/ / Is there an injected web3 instance? If (typeof web3! = = "undefined") {console.warn ("Using web3 detected from external source like Metamask") / / If there is a web3 instance (in Mist/Metamask), then we use its provider to create our web3object window.web3 = new Web3 (web3.currentProvider)} else {console.warn ("No web3 detected. Falling back to http://localhost:9545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for deployment. More info here: http://truffleframework.com/tutorials/truffle-and-metamask") / / fallback-use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) window.web3 = new Web3 ("http://localhost:9545"))} / / initializing the App window.App.start ()})

Notice that the code I used to create the web3 instance in the previous step is also here. First, we import the necessary library and webpack content, including web3 and Truffle Contracts. We will use Truffle Contracts, which is built on top of web3 and interacts with Blockchain.

To use it, we will take the build files that are automatically built when the voting smart contract is compiled and use them to create the Truffle Contracts. Finally, we set the function in the global variable windows to start the application, vote for candidates, and find the number of votes.

To actually interact with the blockchain, we must use the functionality of deployed to create an instance of the truffle contract. In turn, this will return a promise as the return value that you will use to call the function from the smart contract.

There are two ways to interact with these functions: transactions and invocations. A transaction is a write operation that will be broadcast to the entire network and processed by miners (therefore, the cost is Ether). If you want to change the state variable, you must execute the transaction because it will change the state of the blockchain.

Call is a read operation that simulates a transaction but discards a state change. Therefore, it will not cost the ether. This is perfect for calling the getter function (see the four getter functions we wrote earlier in the smart contract).

To use Truffle Contracts for trading, you can write instance.functionName (param1,param2) that returns instance as an instance of the deployed function (for example, check line 36). This transaction will return a promise with transaction data as the return value. Therefore, if a value is returned in a smart contract function, but the transaction is performed using the same function, the value is not returned.

That's why we have an event that records anything you want to write to the transaction data you want to return. On lines 36-37, we make a transaction to add a candidate, Candidate. When we determine promise, we have transaction data in the results.

To get the candidate ID that we recorded with event AddedCandidate () (check the smart contract to see it 0), we must check the log and retrieve it: result.logs [0] .args.candidateID.

To really understand what's going on, use the Chrome developer tool to print the result and look at its result structure.

To make the call, you will write instance.functionName.call (param1,param2). However, if a function has the keyword view, Truffle Contracts automatically creates a call, so you don't need to add .call`.

This is why our getter function has the view keyword. Unlike making a transaction, the returned call promise will have any return value returned by the smart contract function.

I'll briefly explain these three functions now, but this should be familiar if you build an application that retrieves / changes data from the data store and manipulates DOM accordingly. Think of Blockchain as your database and Truffle Contracts as the API that fetches data from the database.

App.start ()

This function is called immediately after the web3 instance is created. For Truffle Contracts to work properly, we must set the interface to the created web3 instance and set default values (such as the account you are using and the amount of gas you want to pay for the transaction).

Since we are in development mode, we can use any number of gas and any account. During the production process, we will use the account provided by MetaMask and try to find out the minimum amount of gas you can use because it is actually real money.

With all the content set up, we will now display a check box for each candidate for the user to vote on. To do this, we must create a contract instance and get information about the candidate. If there are no candidates, we will create them. In order for users to vote for a candidate, we must provide the ID of that particular candidate. Therefore, we make each checkbox element have the id (HTML element attribute) of the candidate ID. In addition, we will add the number of candidates to the global variable numOfCandidates, which we will use in App.findNumOfVotes (). JQuery is used to append each check box and its candidate name to .check-box.

App.vote ()

This feature votes for a candidate based on the check box you click and its id property.

1. We will check whether the user has entered their userID, which is their identity. If they don't, we will display a message telling them that they need to do so.

two。 We will check whether the user is voting for the candidate and whether there is at least one check box that has been clicked. If you do not click any check boxes, we will also display a message telling them to vote for the candidate. If we click one of the check boxes, we will get the id property of the check box, which is also the ID of the linked candidate, and use this property to vote for the candidate.

After the transaction is completed, we will resolve the return commitment and show that Voted has completed the vote.

App.findNumOfVotes ()

The last function will find the number of votes for each candidate and display them. We will pass the candidate and call two smart contract functions, getCandidate and totalVotes. We will address these commitments and create HTML elements for that particular candidate.

Now, start the application and you will see it on `http://localhost:8080/!

Npm run dev resources

I know, it's a lot. As you slowly develop the application and really understand what's going on, you may open this article for a while. But that's learning! Please use Ethernet, truffle and all the documentation I provide below to supplement this guide. I have tried to click on many of the key points in this article, but this is only a brief overview, and these resources will be of great help.

Everything about Solidity and Smart Contracts: I mean everything.

Everything about truffle

Truffle contract document

Web3 Javascript API: this will be good knowledge and reference, but the truffle contract abstracts a lot of parts.

Useful DApp mode

Ethersquare file: look at the directory, there are a lot of things.

CryptoKitties code description: the author introduces an important part of CryptoKitties's smart contract.

Best practice of smart contracts: required reading.

This is the end of the content about "how to centralize voting DApp and intelligent contract in Ethernet Square". Thank you for your reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report