以太坊去中心化_开发以太坊去中心化投票应用程序的指南
以太坊去中心化
by Timothy Ko
蒂莫西·高(Timothy Ko)
开发以太坊去中心化投票应用程序的指南 (A guide to developing an Ethereum decentralized voting application)
After the entire cryptocurrency market passed 700 billion dollars in market cap, the cryptocurrency space exploded over these last couple months. But this is just the beginning. As blockchain systems continue to evolve and scale, one great way to dip into this new space and leverage this technology is with decentralized applications, otherwise known as dApps.
在整个加密货币市场的市值超过7,000亿美元之后,在过去的几个月中,加密货币的市场出现了爆炸式增长。 但这仅仅是开始。 随着区块链系统的不断发展和扩展,采用这种分散应用程序(也称为dApps)来进入这一新领域并利用该技术的一种好方法。
CryptoKitties, famous for its congestion of the Ethereum Blockchain, is a great example of a dApp, uniquely combining concepts of breedable and collectible cats with the blockchain. This sensational game is just one creative example out of a virtually unlimited number of opportunities.
以充斥以太坊区块链而闻名的CryptoKitties是dApp的一个很好的例子,它将可繁殖和可收藏的猫的概念与区块链独特地结合在一起。 这种轰动性的游戏只是无限数量机会中的一个创新示例。
Although seemingly very complicated, certain frameworks and tools have been developed to abstract your interactions with the blockchain and smart contracts. In this blog post, I will go over one way to create a decentralized voting app on Ethereum. I will briefly go over Ethereum, but you probably should have an understanding of it to use this guide to the fullest. In addition, I do expect you to know Javascript.
尽管看似非常复杂,但已开发出某些框架和工具来抽象您与区块链和智能合约的交互。 在这篇博客文章中,我将介绍一种在以太坊上创建去中心化投票应用程序的方法。 我将简要介绍一下以太坊,但您可能应该对它有所了解,以便充分利用本指南。 另外,我希望您会了解Javascript。
为什么要制作去中心化投票应用程序? (Why make a Decentralized Voting app?)
Essentially, a great decentralized application utilizing blockchain technology allows you perform the same actions you would today (like transferring money) without a trusted third party. The best dApps have a specific real world use-case that leverages the unique characteristics of blockchain.
本质上,利用区块链技术的出色的去中心化应用程序可让您无需信任的第三方即可执行与当今相同的操作(例如转账)。 最好的dApp有一个特定的现实世界用例,它利用了区块链的独特特性。
In essence, the blockchain is a shared, programmable, cryptographically secure and therefore trusted ledger which no single user controls and which can be inspected by anyone.- Klaus Schwab
从本质上讲,区块链是一个共享的,可编程的,加密的,因此受信任的分类帐,没有任何一个用户可以控制并且任何人都可以检查它。-Klaus Schwab
Even though a voting app might not be a great app for consumers, I’ve chosen to use it for this guide because the main issues blockchain solves — transparency, security, accessibility, audibility — are the main problems plaguing current democratic elections.
即使投票应用程序可能不是适合消费者的应用程序,我还是选择将其用于本指南,因为区块链解决的主要问题(透明性,安全性,可访问性,可听性)是困扰当前民主选举的主要问题。
Since a blockchain is a permanent record of transactions (votes) that are distributed, every vote can irrefutably be traced back to exactly when and where it happened without revealing the voter’s identity. In addition, past votes cannot be changed, while the present can’t be hacked, because every transaction is verified by every single node in the network. And any outside or inside attacker must have control of 51% of the nodes to alter the record.
由于区块链是分配的交易(投票)的永久记录,因此,每一次投票都可以准确地追溯到发生的确切时间和地点,而无需透露选民的身份。 此外,过去的票数无法更改,而现在的票数不能被破解,因为每笔交易都由网络中的每个节点进行验证。 并且任何外部或内部攻击者都必须控制51%的节点才能更改记录。
Even if the attacker was able to achieve that while incorrectly entering user votes with their real IDs under the radar, end to end voting systems could allow voters to verify whether their vote was correctly entered in the system, making the system extremely safe.
即使攻击者能够在雷达下用真实ID错误输入用户投票时实现这一目标,端对端投票系统也可以允许选民验证他们的投票是否正确输入了系统,从而使该系统极为安全。
以太坊的核心组成 (Core Components of Ethereum)
I do expect you to have an understanding of Blockchain and Ethereum for the remainder of this guide. Here is an awesome guide about it, and I’ve written a brief overview of the core components I’d like you to know.
我希望您在本指南的其余部分中对区块链和以太坊有所了解。 这是一个很棒的指南,我已经简要介绍了我希望您知道的核心组件。
Smart Contracts act as the back-end logic and storage. A contract is written in Solidity, a smart contract language, and is a collection of code and data that resides at a specific address on the Ethereum blockchain. It’s very similar to a class in Object Oriented Programming, where it includes functions and state variables. Smart Contracts, along with the Blockchain, are the basis of all Decentralized Applications. They are, like Blockchain, immutable and distributed, which means upgrading them will be a pain if they are already on the Ethereum Network. Fortunately, here are some ways to do that.
智能合约充当后端逻辑和存储。 合同是写在密实度 ,智能合同语言,是一个代码收集和数据驻留在对复仇blockchain一个特定的地址。 它与面向对象编程中的类非常相似,其中包含函数和状态变量。 智能合约以及区块链是所有去中心化应用程序的基础。 就像区块链一样,它们是不可变的并且是分布式的,这意味着如果它们已经在以太坊网络中,那么升级它们将是一件痛苦的事情。 幸运的是, 这里有一些方法可以做到这一点。
The Ethereum Virtual Machine(EVM) handles the internal state and computation of the entire Ethereum Network. Think of the EVM as this massive decentralized computer that contains “addresses” that are capable of executing code, changing data, and interacting with each other.
以太坊虚拟机(EVM)处理整个以太坊网络的内部状态和计算。 可以将EVM视为这种大型的分散式计算机,其中包含能够执行代码,更改数据以及彼此交互的“地址”。
Web3.js is a Javascript API that allows you to interact with the Blockchain, including making transactions and calls to smart contracts. This API abstracts the communication with Ethereum Clients, allowing developers to focus on the content of their application. You must have a web3 instance imbedded in your browser to do so.
Web3.js 是一个Javascript API,可让您与区块链进行交互,包括进行交易和调用智能合约。 该API抽象了与以太坊客户端的通信,使开发人员可以专注于其应用程序的内容。 为此,您必须在浏览器中嵌入一个web3实例。
我们将使用的其他工具 (Other Tools we will use)
Truffle is a popular testing development framework for Ethereum. It includes a development blockchain, compilation and migration scripts to deploy your contract to the Blockchain, contract testing, and so on. It makes development easier!
松露 是以太坊的流行测试开发框架。 它包括开发区块链,编译和迁移脚本,以将您的合同部署到区块链,合同测试等。 它使开发更加轻松!
Truffle Contracts is an abstraction on top of the Web3 Javascript API, allowing you to easily connect and interact with your Smart Contract.
Truffle Contracts是Web3 Javascript API之上的抽象,可让您轻松连接智能合约并与之交互。
Metamask brings Ethereum to your browser. It is a browser extension that provides a secure web3 instance linked to your Ethereum address, allowing you to use Decentralized Applications. We will not be using Metamask in this tutorial, but it is a way for people to interact with your DApp in production. Instead, we will inject our own web3 instance during development. For more information, check out this link.
Metamask将以太坊带入您的浏览器。 它是一个浏览器扩展,提供与您的以太坊地址链接的安全web3实例,使您可以使用分散式应用程序。 在本教程中,我们不会使用Metamask,但它是人们在生产环境中与您的DApp交互的一种方式。 相反,我们将在开发期间注入自己的web3实例。 有关更多信息,请查看此链接。
开始吧! (Let’s Start!)
For simplicity, we actually won’t be building the full voting system I described earlier. For ease of explanation, it will just be a one page application where a user can enter their ID and vote for a candidate. There will also be a button that counts and displays the number of votes per candidate.
为简单起见,我们实际上将不会构建我之前描述的完整投票系统。 为了便于说明,它只是一个单页应用程序,用户可以在其中输入其ID并为候选人投票。 还有一个按钮可以计数并显示每个候选人的投票数。
This way, we will be able to focus the process of creating and interacting with the smart contracts within an application. The source code for this entire application will be in this repository, and you will need to have Node.js and npm installed.
这样,我们将能够集中精力在应用程序中创建智能合约并与之交互的过程。 整个应用程序的源代码将在此存储库中 ,并且您将需要安装Node.js和npm。
First, let’s install Truffle globally.
首先,让我们全局安装Truffle。
npm install -g truffle
To use Truffle commands, you must run them in an existing project.
要使用Truffle命令,必须在现有项目中运行它们。
git clone https://github.com/tko22/truffle-webpack-boilerplatecd truffle-webpack-boilerplatenpm install
This repository is just a skeleton of a Truffle Box, which are boilerplates or example applications that you can get in one command — truffle unbox [box name]
. However, the Truffle box with webpack isn’t updated with the latest versions and includes an example application. Thus, I created this repo (the one linked in the instructions above).
该存储库只是Truffle Box的框架,它们是您可以在一个命令中获得的样板或示例应用程序– truffle unbox [box name]
。 但是,带有webpack的松露盒未使用最新版本进行更新,并包含示例应用程序。 因此,我创建了这个仓库 (上面的说明中链接的仓库)。
2.目录结构 (2. Directory Structure)
Your directory structure should include these:
您的目录结构应包括以下内容:
contracts/
— Folder holding all of the Contracts. DO NOT DELETEMigrations.sol
contracts/
—存放所有合同的文件夹。 不要删除Migrations.sol
migrations/
— Folder holding Migration files, which help you deploy your smart contracts into the Blockchain.migrations/
—保存迁移文件的文件夹,可帮助您将智能合约部署到区块链中。src/
— holds the HTML/CSS and Javascript files for the applicationsrc/
—存放应用程序HTML / CSS和Javascript文件truffle.js
— Truffle Configuration filetruffle.js
—松露配置文件build/
— You won’t see this folder until you compile your contracts. This folder holds the build artifacts so don’t modify any of these files! Build artifacts describe the function and architecture of your contract and give Truffle Contracts and web3 information on how to interact with your Smart Contract in the Blockchain.build/
—在编译合同之前不会看到此文件夹。 此文件夹包含构建工件,因此请勿修改任何这些文件! 构建工件描述了合约的功能和体系结构,并为松露合约和web3信息提供了有关如何与区块链中的智能合约进行交互的信息。
1.编写您的智能合约 (1. Write your Smart Contracts)
Enough with the setup and introduction. Let’s get into the code! First off, we’ll be writing our Smart Contract, which is written in Solidity (the other languages aren’t as popular). It may seem scary, but it’s not.
足够的设置和介绍。 让我们进入代码! 首先,我们将编写以Solidity编写的智能合约(其他语言不那么流行)。 它可能看起来很吓人,但事实并非如此。
For any application, you want your smart contracts to be as simple as possible, even stupidly simple. Remember that you have to pay for every computation/transaction you make, and your smart contracts will be on the Blockchain forever. So, you really want it to work perfectly––meaning, the more complex it is, the easier it is to make a mistake.
对于任何应用程序, 您都希望您的智能合约尽可能地简单,甚至非常简单。 请记住,您必须为所做的每次计算/交易付费,您的智能合约将永远存在于区块链中。 因此,您真的希望它完美地工作-这意味着它越复杂,就越容易出错。
Our contract will include:
我们的合同将包括:
State Variables — variables that hold values that are permanently stored on the Blockchain. We will use state variables to hold a list and number of Voters and Candidates.
状态变量 -持有永久存储在区块链中的值的变量。 我们将使用状态变量来保存选民和候选人的列表和数量。
Functions — Functions are the executables of smart contracts. They are what we will call to interact with the Blockchain, and they have different levels of visibility, internally and externally. Keep in mind that whenever you want to change the value/state of a variable, a transaction must occur — costing Ether. You can also make
calls
to the Blockchain, which won’t cost any Ether because the changes you made will be destroyed (more on this in Section 3 when we actually make thetransactions
andcalls
).函数 -函数是智能合约的可执行文件。 它们是我们与区块链进行交互所需要的,它们在内部和外部具有不同的可见性级别。 请记住,每当您要更改变量的值/状态时,都必须进行交易-花费以太坊。 您还可以
calls
区块链,这不会花费任何以太币,因为您所做的更改将被销毁(在我们实际进行transactions
和calls
时,将在第3节中对此进行详细介绍)。Events — Whenever an event is called, the value passed into the event will be logged in the transaction’s log. This allows Javascript callback functions or resolved promises to view the certain value you wanted to pass back after a transaction. This is because every time you make a transaction, a transaction log will be returned. We will use an event to log the ID of the newly created Candidate, which we’ll display (check the first bullet point of Section 3).
事件 -每当调用事件时,传递给事件的值将记录在事务日志中。 这允许Javascript回调函数或已解决的Promise查看事务后要传递回的特定值。 这是因为每次进行交易时,都会返回交易日志。 我们将使用一个事件来记录新创建的候选人的ID,我们将显示该ID(检查第3节的第一个项目符号)。
Struct Types — This is very similar to a C struct. Structs allow you to hold multiple variables, and are awesome for things with multiple attributes.
Candidates
will only have their name and party, but you can definitely add more attributes to them.结构类型 —与C结构非常相似。 结构允许您容纳多个变量,并且对于具有多个属性的事物非常有用。
Candidates
只有他们的名字和聚会,但是您绝对可以为他们添加更多属性。Mappings — Think of these like hash-maps or dictionaries, where it has a key-value pair. We will use two mappings.
映射 -像哈希映射或字典一样,它们具有键值对。 我们将使用两个映射。
There are a couple more types that aren’t listed here, but some of them are a little more complicated. These five encompass many of the structures a smart contract will generally use. These types are explained more in depth here.
这里没有列出更多类型,但是其中一些类型稍微复杂一些。 这五个包含智能合约通常会使用的许多结构。 这些类型将在此处更深入地说明。
For reference, here’s the Smart Contract’s code. Note that this file should be called Voting.sol
but I wanted the Github gist to have styling so I gave it a .js
extension. Like the rest of this guide, I will provide comments within the code that will explain what it is doing, and I’ll explain the big picture afterwards while pointing out certain caveats and logic.
作为参考,这是智能合约的代码。 请注意,该文件应名为Voting.sol
但我希望Github要点具有样式,因此我给它一个.js
扩展名。 与本指南的其余部分一样,我将在代码中提供注释,以解释其功能,然后在指出某些注意事项和逻辑的同时,对全局进行解释。
Basically, we have two Structs (types that hold multiple variables) that describe a Voter and a Candidate. With Structs, we are able to assign multiple properties to them, such as emails, address, and so on.
基本上,我们有两个结构(包含多个变量的类型)来描述选民和候选人。 使用Structs,我们可以为它们分配多个属性,例如电子邮件,地址等。
To keep track of Voters and Candidates, we put them into separate mappings where they are integer indexed. A Candidate or Voter’s index/key––lets call it ID — is the sole way for functions to access them.
为了跟踪选民和候选人,我们将它们放入单独的映射中,在该映射中对它们进行整数索引。 候选人或选民的索引/关键字-称为ID-是函数访问它们的唯一方法 。
We also keep track of the number of Voters and Candidates, which will help us index them. In addition, don’t forget about the event in line 8, which will log the candidate’s ID when it’s added. This event will be used by our interface, since we need to keep track of a candidate’s ID in order to vote for a candidate.
我们还将跟踪选民和候选人的数量,这将有助于我们对他们进行索引。 此外,请不要忘记第8行中的事件,该事件将在添加候选人时记录其ID。 此事件将由我们的界面使用,因为我们需要跟踪候选人的ID才能投票给候选人。
- I know, contrary to what I said earlier about making contracts super simple, I made this contract a little more complicated in comparison to what this application actually does. However, I did this so that it would be a lot easier for you guys to make edits and add features to this application afterward (more on that at the end). If you’d like to make an even simpler voting application, the smart contract could work in less than 15 lines of code.我知道,与我之前所说的使合同超级简单的说法相反,与该应用程序的实际操作相比,我使该合同更加复杂。 但是,我这样做是为了让你们以后进行编辑和向此应用程序添加功能会容易得多(最后更多内容)。 如果您想制作一个更简单的投票应用程序,则智能合约可以用少于15行的代码运行。
Note that the state variables
numCandidates
andnumVoters
are not declared public. By default, these variables have a visibility ofinternal
, which means that they can only be directly accessed by the current contract or derived contracts (don’t worry about that, we won’t be using it).请注意,状态变量
numCandidates
和numVoters
并未声明为公共。 默认情况下 ,这些变量具有internal
的可见性,这意味着它们只能由当前合同或派生合同直接访问(不必担心,我们不会使用它)。We are using
32bytes
for strings instead of using thestring
type. Our EVM has a word-size of 32 bytes, so it is “optimized” for dealing with data in chunks of 32 bytes. (Compilers, such as Solidity, have to do more work and generate more bytecode when data isn’t in chunks of 32 bytes, which effectively leads to higher gas cost.)我们使用
32bytes
作为字符串,而不是使用string
类型。 我们的EVM的字长为32字节 ,因此已“优化”以处理32字节的数据块。 (当数据不在32个字节的块中时,诸如Solidity之类的编译器必须做更多的工作并生成更多的字节码,这实际上导致更高的气体成本。)When a user votes, a new
Voter
struct is created and added to the mapping. In order to count the number of votes a certain candidate has, you must loop through all the Voters and count the number of votes. Candidates operate on the same behavior. Thus, these mappings will hold the history of all Candidates and Voters.当用户投票时,将创建一个新的
Voter
结构并将其添加到映射中。 为了计算某位候选人的票数,您必须遍历所有选民并计算票数。 候选人的行为相同。 因此,这些映射将保留所有候选人和选民的历史。
2.实例化web3和合同 (2. Instantiate web3 and contracts)
With our Smart Contract completed, we now need to run our test blockchain and deploy this contract onto the Blockchain. We’ll also need a way to talk to it, which will be via web3.js.
完成智能合约后,我们现在需要运行测试区块链并将此合约部署到区块链上。 我们还需要通过web3.js与之对话的方式。
Before we start our test blockchain, we must create a file called 2_deploy_contracts.js
inside the folder /contracts
that tells it to include your Voting Smart Contract when you migrate.
在开始测试2_deploy_contracts.js
链之前,我们必须在/contracts
文件夹中创建一个名为2_deploy_contracts.js
的文件,该文件告诉您在迁移时包括您的投票智能合约。
To start the development Ethereum blockchain, go to your command line and run:
要开始开发以太坊区块链,请转到命令行并运行:
truffle develop
This will live on your command line. Since Solidity is a compiled language, we must compile it to bytecode first for the EVM to execute.
这将出现在您的命令行中。 由于Solidity是一种编译语言,因此我们必须先将其编译为字节码,然后才能执行EVM。
compile
You should see a build/
folder inside your directory now. This folder holds the build artifacts, which are critical to the inner workings of Truffle, so don’t touch them!
您现在应该在目录中看到一个build/
文件夹。 此文件夹中包含构建工件,这对于Truffle的内部工作至关重要,因此请不要触摸它们!
Next, we must migrate the contract. Migrations is a Truffle script that helps you alter the state of your application’s contract as you develop. Remember that your contract is deployed to a certain address on the Blockchain, so whenever you make changes, your contract will be located at a different address. Migrations help you do this and also help you move data around.
接下来,我们必须迁移合同。 迁移是一种Truffle脚本,可帮助您在开发时更改应用程序合同的状态。 请记住,您的合同已部署到区块链上的某个地址,因此无论何时进行更改,您的合同都将位于其他地址。 迁移可以帮助您做到这一点,还可以帮助您移动数据。
migrate
Congratulations! Your smart contract is now on the Blockchain forever. Well, not really…. because truffle develop
refreshes every time you stop it.
恭喜你! 您的智能合约现在永远在区块链上。 好吧,不是真的。 因为truffle develop
每次停止都会刷新。
If you’d like to have a persisting blockchain, consider Ganache, which is also developed by Truffle. If you are using Ganache, you will not need to call truffle develop
. Instead, you will run truffle compile
and truffle migrate
. To understand what it really takes to deploy a contract without Truffle, check out this blog post.
如果您想拥有持久的区块链,请考虑Truffle开发的Ganache 。 如果您使用的是Ganache,则无需调用truffle develop
。 相反,您将运行truffle compile
和truffle migrate
。 要了解在没有Truffle的情况下部署合同真正需要什么,请查看此博客文章 。
Once we have deployed the smart contract to the Blockchain, we will have to setup a web3.0 instance with Javascript on the browser whenever the application starts. Thus, the next piece of code will be placed in the bottom of js/app.js
. Note that we are using web3.0 version 0.20.1.
将智能合约部署到区块链后,无论何时启动应用程序,我们都必须在浏览器上使用Javascript设置一个web3.0实例。 因此,下一段代码将放在js/app.js
的底部。 请注意,我们使用的是web3.0版本0.20.1。
You don’t really have to worry too much if you don’t understand this code. Just know that this will be run when the application starts and will check if there already is a web3 instance (Metamask) in your browser. If there isn’t, we’ll just create one that talks to localhost:9545
, which is the Truffle development blockchain.
如果您不了解此代码,则不必担心太多。 只需知道这将在应用程序启动时运行,并将检查您的浏览器中是否已存在Web3实例(Metamask)。 如果没有,我们将创建一个与localhost:9545
对话的localhost:9545
,该localhost:9545
是Truffle开发区块链。
If you’re using Ganache, you must change the port to 7545
. Once an instance is created, we will call the start
function (I’ll define it in the next section).
如果使用的是Ganache,则必须将端口更改为7545
。 创建实例后,我们将调用start
函数(我将在下一部分中对其进行定义)。
3.添加功能 (3. Add functionality)
The last thing we’ll need to do is to write the interface for the application. This involves the essentials for any web application––HTML, CSS, and Javascript (We’ve already written a little of the Javascript with creating a web3 instance). First, let’s create our HTML file.
我们需要做的最后一件事是为应用程序编写接口。 这涉及到任何Web应用程序的基本要素– HTML,CSS和Javascript(我们已经创建了一个web3实例,已经编写了一些Javascript)。 首先,让我们创建HTML文件。
This is a very simple page, with an input form for user ID, and buttons for Voting and Counting votes. When those buttons are clicked, they will call specific functions that vote, and will find the number of votes for the candidates.
这是一个非常简单的页面,其中包含用户ID的输入表单,以及用于投票和计数投票的按钮。 单击这些按钮时,它们将调用特定的投票功能,并找到候选人的投票数。
There are three important div elements though, with ids: candidate-box
, msg
, and vote-box
, which will hold checkboxes for each candidate, a message, and the number of votes, respectively. We also import JQuery, Bootstrap, and app.js
.
但是,有三个重要的div元素,其ID为: candidate-box
, msg
和vote-box
,将分别保留每个候选人的复选框,一条消息和一张投票数。 我们还导入JQuery,Bootstrap和app.js
Now, we just need to interact with the Contract and implement the functions for voting and counting the number of votes for each candidate. JQuery will manipulate the DOM, and we’ll be using Promises as we make transactions or calls to the Blockchain. Below is the code for app.js
.
现在,我们只需要与合同进行交互并实现投票功能并计算每个候选人的投票数即可。 jQuery将操纵DOM,并且在进行交易或调用区块链时将使用Promises。 以下是app.js
的代码。
Note that the code I provided in the previous step for creating a web3 instance is also here. First, we import the necessary libraries and webpack stuff, including web3 and Truffle Contracts. We will be using Truffle Contracts, which is built on top of web3 to interact with the Blockchain.
请注意,我在上一步中提供的用于创建web3实例的代码也在此处。 首先,我们导入必要的库和webpack内容,包括web3和Truffle Contracts 。 我们将使用基于Web3构建的Truffle Contracts与区块链进行交互。
To use it, we’ll grab the build artifacts that were automatically built when we compiled the voting smart contract and use them to create the Truffle Contract. Finally, we set up the functions in the global variable window
for starting the app, voting for a candidate, and finding the number of votes.
要使用它,我们将获取编译投票智能合约时自动生成的生成工件,并使用它们来创建松露合约。 最后,我们在全局变量window
设置函数,以启动应用程序,为候选人投票并找到投票数。
To actually interact with the Blockchain, we must create an instance of the Truffle Contract by using the deployed
function. This, in turn, will return a promise with the instance as the return value that you will use to call functions from the smart contract.
要与区块链进行实际交互,我们必须使用deployed
功能创建松露合约的实例。 反过来,这将返回一个带有实例的promise作为您将用来从智能合约调用函数的返回值。
There are two ways to interact with those functions: transactions and calls. A transaction is a write-operation, and it will be broadcast to the entire network and processed by miners (and thus, costs Ether). You must perform a transaction if you’re changing a state variable, since it will change the state of the blockchain.
与这些功能进行交互的方式有两种:交易和调用。 交易是一种写操作,它将被广播到整个网络并由矿工进行处理(因此,成本为以太币)。 如果要更改状态变量,则必须执行事务,因为它将更改区块链的状态。
A call is a read-operation, simulating a transaction but discarding the change in state. Thus, it will not cost Ether. This is great for calling getter functions (check out the four getter functions we wrote previously in our smart contract).
调用是读取操作,它模拟事务但丢弃状态更改。 因此,它不会花费以太。 这对于调用getter函数非常有用(查看我们先前在智能合约中编写的四个getter函数)。
To make a transaction with Truffle Contracts, you write instance.functionName(param1, param2)
, with instance
as the instance that was returned by the deployed
function (Check line 36 for an example). This transaction will return a promise with the transaction data as the return value. Thus, if you return a value in your smart contract function but you perform a transaction with that same function, it will not return that value.
要使用松露合约进行交易,请编写instance.functionName(param1, param2)
,并将instance
作为已deployed
函数返回的实例(请参阅第36行)。 该交易将以交易数据作为返回值返回承诺。 因此,如果您在智能合约函数中返回一个值,但是您使用相同的函数执行交易,则它将不会返回该值。
This is why we have an event that will log whatever you want it to write into the transaction data that will be returned. In the case of lines 36–37, we make a transaction to add a Candidate. When we resolve the promise, we have the transaction data in result
.
这就是为什么我们有一个事件,它将记录您想要写入的任何内容写入将返回的事务数据中。 在第36-37行的情况下,我们进行了交易以添加候选。 当我们解决的承诺,我们在交易数据result
。
To get the candidateID
that we logged with the event AddedCandidate()
(check the smart contract to see it 0), we must go through the logs and retrieve it like this: result.logs[0].args.candidateID
.
为了得到candidateID
我们记录与事件AddedCandidate()
检查智能合同,看看它0),我们必须通过日志和检索它像这样: result.logs[0].args.candidateID
。
To really see what’s going on, use the Chrome developer tools to print out the result
and look through its structure of result
.
要真正看到发生了什么事情,使用Chrome开发者工具,打印出的result
通过它的结构和外观result
。
To make a call, you will write instance.functionName.call(param1,param2)
. However, if a function has the keyword view
, then Truffle Contracts will automatically create a call and thus you don’t need to add the .call
.
要进行呼叫,您将编写instance.functionName.call(param1,param2)
。 但是,如果函数具有关键字view
,则Truffle Contracts将自动创建一个调用,因此您无需添加.call
。
This is why our getter functions have the view
keyword. Unlike making a transaction, the returned promise of a call will have a return value of whatever is returned by the smart contract function.
这就是为什么我们的getter函数具有view
关键字的原因。 与进行交易不同,返回的呼叫承诺将具有智能合约功能返回的返回值。
I will now explain the 3 functions briefly but this should be very familiar if you’ve built applications retrieving/changing data from a data store and manipulating the DOM accordingly. Think of the Blockchain as your database, and the Truffle Contracts as the API to get data from your database.
现在,我将简要解释这三个功能,但是如果您已构建了从数据存储中检索/更改数据并相应地操作DOM的应用程序,则应该非常熟悉这三个功能。 将区块链视为您的数据库,将松露合同视为从数据库中获取数据的API。
App.start() (App.start())
This function is called immediately after we create a web3 instance. To get Truffle Contracts to work, we must set the provider to the created web3 instance and set defaults (like which account you’re using and the amount of gas you want to pay to make a transaction).
创建一个web3实例后立即调用此函数。 为了使松露合约生效,我们必须将提供者设置为创建的web3实例并设置默认值(例如您正在使用的帐户以及要进行交易的天然气价格)。
Since we are in development mode, we can use any amount of gas and any account. During production, we would take the account provided by MetaMask and try to figure out the smallest amount of gas you could use, since it’s actually real money.
由于我们处于开发模式,因此我们可以使用任何数量的天然气和任何帐户。 在生产过程中,我们会考虑MetaMask提供的费用,并尝试找出您可以使用的最小量的天然气,因为它实际上是真钱。
With everything set up, we will now display the checkboxes for each candidate for the user to vote. To do this, we must create an instance of the contract and get the Candidate’s information. If there aren’t any candidates, we will create them. In order for a user to vote for a candidate, we must provide the ID of that certain candidate. Thus, we make each checkbox element have an id
(HTML element attribute) of the ID of the candidate. Additionally, we will add the number Of candidates to a global variable numOfCandidates
, which we will use in App.findNumOfVotes()
. JQuery is used to append each checkbox and its candidate name to .candidate-box
.
完成所有设置后,我们现在将显示每个候选人的复选框,供用户投票。 为此,我们必须创建合同的实例并获取候选人的信息。 如果没有任何候选人,我们将创建他们。 为了使用户投票给候选人,我们必须提供该特定候选人的ID。 因此,我们使每个复选框元素都具有候选ID的id
(HTML元素属性)。 此外,我们会将候选人数添加到全局变量numOfCandidates
,该变量将在App.findNumOfVotes()
。 jQuery用于将每个复选框及其候选名称附加到.candidate-box
。
App.vote() (App.vote())
This function will vote for a certain candidate based on which checkbox is clicked and its id
attribute.
此功能将根据单击哪个复选框及其id
属性来投票给某个候选人。
One, we will check whether the user has input their userID, which is their identification. If they didn’t, we display a message telling them to do so.
一,我们将检查用户是否输入了他们的用户ID,这是他们的身份。 如果没有,我们会显示一条消息,告诉他们这样做。
Two, we will check whether the user is voting for a candidate, checking if there is at least one checkbox that’s clicked. If none of the checkboxes were clicked, we will also display a message telling them to vote for a candidate. If one of the checkboxes is clicked, we will grab the id
attribute of that checkbox, which is also the linked candidate’s ID, and use that to vote for the candidate.
第二,我们将检查用户是否对候选人进行投票,检查是否至少单击了一个复选框。 如果未选中任何复选框,我们还将显示一条消息,告诉他们为候选人投票。 如果单击其中一个复选框,我们将获取该复选框的id
属性,该属性也是链接的候选人的ID,然后使用该属性为候选人投票。
Once the transaction has been completed, we will resolve the returned promise and display a “Voted” message.
交易完成后,我们将解决返回的承诺并显示“已投票”消息。
App.findNumOfVotes() (App.findNumOfVotes())
This last function will find the number of Votes for each candidate and display them. We will go through the candidates and call two smart contract functions, getCandidate
and totalVotes
. We will resolve those promises and create an HTML element for that certain candidate.
最后一个功能将找到每个候选人的投票数并显示出来。 我们将遍历候选人并调用两个智能合约函数getCandidate
和totalVotes
。 我们将兑现这些承诺,并为该特定候选人创建一个HTML元素。
Now, start the application and you’ll see it on http://localhost:8080/
!
现在,启动应用程序,您将在http://localhost:8080/
上看到它!
npm run dev
翻译自: https://www.freecodecamp.org/news/developing-an-ethereum-decentralized-voting-application-a99de24992d9/
以太坊去中心化
相关文章:

Intellij IDEA的下载和使用(针对学生的免费使用计划)
一、下载和使用授权(针对学生) 1、下载 可以在Intellij IDEA官网上下载需要的版本。下载地址:https://www.jetbrains.com/idea/ 2、学生免费试用 首先,你得现有你们学校的官方邮箱账户,例如XXXYYY.edu.cn 其次…

LPC1768基本输入输出GPIO使用
LPC1788通用IO口的控制包含了一些基本的组件,比如设置推挽输出,开漏输出,上拉电阻等,我们今天来看看. 首先使用GPIO要打开GPIO的系统时钟 LPC_SC->PCONP | (1<<15);//gpio 时钟 然后需要选择我们选定引脚的功能,有些引脚有多个功能,通过寄存器可以从中选择一个 之后是…

微信小程序发红包功能实现,附效果图加讲解。
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 需要做红包功能的可以找我,收费卖源码,也承接开发。此博文仅示例。 流程效果图: 图片1触发wx.sendBizRedPacket({})吊起图片2,点击开,出现图…

项目部署时网关怎么回事_使用Kubernetes部署聊天网关(或技术按预期运行时)...
项目部署时网关怎么回事by Richard Li理查德李(Richard Li) 使用Kubernetes部署聊天网关(或技术按预期运行时) (Using Kubernetes to deploy a chat gateway (or when technology works like it’s supposed to)) TL; DR (TL;DR) This is a story about what happens when clo…

如何用php实现分页效果
分页效果在网页中是常见的,可是怎样才能实现分页呢,今天做了两种方法来实现一下分页的效果 首先,我们需要准备在数据库里面准备一个表,并且插入数据,这些都是必需的前提工作了,不多说,如图所示&…

微信小程序在showToast中换行并且隐藏icon
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文: 实现代码: 注释:真机才有效果,开发工具展示icon属性无效 var a 11\r\n3wx.showToast({title: a,icon:none,duration: 5000})

node aws 内存溢出_如何使用Node.js和AWS快速创建无服务器RESTful API
node aws 内存溢出by Mark Hopson马克霍普森(Mark Hopson) 如何使用Node.js和AWS快速创建无服务器RESTful API (How to quickly create a serverless RESTful API with Node.js and AWS) In this beginner’s guide, we’ll briefly describe the “Serverless” software arc…

java学习之匿名内部类与包装类
匿名内部类: 所谓匿名内部类,顾名思义指的就是定义在类内部的匿名类,现有的spring框架开发以及java图形界面都经常用到匿名内部类。 下面来看一个代码: interface A{public void fun() ; } class B implements A{public void fun(…

【微信小程序】登录功能实现及讲解(获取用户唯一标识)
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文: 功能:登录实现并获取到用户唯一标识 官方文档地址:可以先看完我的文章再看官方地址 实现步骤:1.调用微信API wx.login()得到code 2.把得到的cod…

参考框架 系统 基准_带有基准的前端框架的真实比较(2018更新)
参考框架 系统 基准by Jacek Schae由Jacek Schae 带有基准的前端框架的真实比较(2018更新) (A Real-World Comparison of Front-End Frameworks with Benchmarks (2018 update)) This article is a refresh of A Real-World Comparison of Front-End Frameworks with Benchmar…

U盘重装MacOS-Sierra系统
Mac系统重新安装两种方法: 1、在线远程重装。 2、制作启动U盘进行重装。 理论上第一种比较简单,但是会比较耗时,实际操作中,由于网上下载的系统版本低于我现在MacOS的版本,导致无法安装,因此只能使用第二种…

this和that的区别和原理
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 正文: 本篇博文纯属个人见解,如有不妥,可以留言批评指正,谢谢。 var that this; this指的是当前的对象。 that是一个临时的变量,用于保存当…

linu逻辑分区动态调整大小
linu逻辑分区动态调整大小 注意: 这个动态调整的方法是有丢数据风险的,要确保调整的源分区没有使用或者使用率很低。源分区中如果有重要的文件最好先备份在centos 6.5上操作过lvdisplay 查看已有的分区的大小 lvdisplay ,选择要操作的逻辑分区&#…

多个敏捷团队同时做一个项目_您说您的团队很敏捷……但是这个词可能并不代表您的想法。...
多个敏捷团队同时做一个项目by Mark Shead由马克希德(Mark Shead) Many things get called Agile — especially by people who are selling something. But the Agile Manifesto makes it clear that it isn’t a methodology. It isn’t a specific way of doing software d…

Python IDLE theme
#转自 http://www.2cto.com/os/201507/418532.html #win10python3.5.2 #保护视力 .idlerc 目录下新建名为 config-highlight.cfg 文件,并加入如下内容 [tango] definition-foreground #fce94ferror-foreground #fa8072string-background #2e3436keyword-foregrou…

【转帖】SQLServer登录连接失败(error:40-无法打开到SQLServer的连接)的解决方案...
在与SQLServer建立连接时出现与网络相关的或特定与实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且SQL SERVER已配置允许远程链接.(provide:命名管道提供程序,error:40 -无法打开到SQL Server的连接)(Microsoft SQL Server,错误:2) 我刚刚在登录连接SQL Server …

js时间戳转换成日期格式
//时间戳转日期格式function timestampToTime(timestamp) {var date new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000Y date.getFullYear() -;M (date.getMonth() 1 < 10 ? 0 (date.getMonth() 1) : date.getMonth() 1)…

30岁找不到工作很绝望_计算机为绝望的新编码员工作方式的快速指南
30岁找不到工作很绝望by Danielle Ormshaw丹妮尔欧姆肖(Danielle Ormshaw) 计算机为绝望的新编码员工作方式的快速指南 (The quick guide to the way computers work for desperate new coders) The sole purpose of your computer is to send and receive information in the…

纯css3代码写下拉菜单效果
1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <meta name"viewport" content"widthdevice-width,initial-scale1;user-scaleno">6 <title>CSS3树形菜单</title…

webpack chunkFilename 非入口文件的命名规则 [转]
官网的文档只理解了filename是主入口的文件名,chunkFilename是非主入口的文件名 filename应该比较好理解,就是对应于entry里面生成出来的文件名。比如: {entry: {"index": "pages/index.jsx"},output: {filename: "…

对数组中的数字从小到大排序
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 var arr [{name:1,age:1},{name:2,age:4},{name:3,age:2} ];function compare(e){return function(a,b){var value1 a[e];var value2 b[e];return value1 - value2;} } console.log(arr.sort(compare…

自动售货机编程_Rosmaro中基于视觉自动机的编程简介
自动售货机编程by Łukasz Makuch通过ŁukaszMakuch Rosmaro中基于视觉自动机的编程简介 (An introduction to visual automata-based programming in Rosmaro) To do automata-based programming is to program with states and transitions. States correspond to different…

JAVA设计模式之命令模式
将请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化;对起那个请求进行排队或记录请求日志。 命令模式告诉我们可以为一个操作生成一个对象并给出它的一个execute(执行)方法。Command模式为系统架构带来效果: 实现请求一方&#…

vb.net与matlab的混合编程
首先,使用deploytool工具或者命令行将matlab的m文件编译成类,结果产生动态链接库.dll文件和一些c#代码的类. 第二步,将这些dll文件导入进去,并使用一些win32api函数,因为此m文件会产生figure窗口,这些api函数将此figure窗口嵌入到vb程序窗体里面. 代码: Imports SystemImports …

java web开发初学_2018年学习Web开发的绝对初学者指南
java web开发初学This post was originally published on Coder-Coder.com.该帖子最初发布在Coder-Coder.com上 。 If you’re a beginner coder, this guide is for you!如果您是初学者,那么本指南适合您! Here is what this guide covers:本指南涵盖…

PC机安装android apk | adb install -r
PC 下载 *****.apk 通过adb直接安装到android系统 转载于:https://www.cnblogs.com/galoishelley/p/4353423.html

微信小程序之apply和call ( 附示例代码和注释讲解) apply call bind
微信小程序开发交流qq群 173683895 相同点:作用是一样的,它们能劫持另外一个对象的方法,继承另外一个对象的属性; js中的call(), apply()和bind()是Function.prototype下的方法,都是用于改变函数运行时上下文&#…

(转)@ContextConfiguration注解说明
场景:学习spring实战中相关的单元测试 1 正常使用 ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件 1.1 单个文件 ContextConfiguration(locations"../applicationContext.xml") ContextConfiguration(classes Simple…

ios pusher使用_如何使用JavaScript和Pusher构建实时评论功能
ios pusher使用by Rahat Khanna通过拉哈特汉娜 如何使用JavaScript和Pusher构建实时评论功能 (How to build a Live Comment feature using JavaScript and Pusher) These days “Social” has become the buzzword and we all want our apps to be the center of these amazi…

OpenDigg前端开源项目月报201704
由OpenDigg 出品的前端开源项目月报第一期来啦。我们的前端开源月报集合了OpenDigg一个月来新收录的优质前端开源项目,方便前端开发人员便捷的找到自己需要的项目工具。 reactide React web应用开发的第一个专用IDE redux-offline 持久性Redux存储 react-loadable 用…