主页 > imtoken不让安装 > 【精品】以太坊DApp开发入门-区块链投票系统视频教程
【精品】以太坊DApp开发入门-区块链投票系统视频教程
本视频课程面向初学者。 介绍了什么是区块链,什么是智能合约。 它涵盖了与以太坊开发相关的基本概念。 Gregory(Dapp大学创始人,专注于在以太坊区块链上构建DApp应用。教程。Gregory的以太坊课程在youtube上订阅人数超过5000人,所有课程观看人数超过10万人,深受区块链技术开发者喜爱用户方完整的去中心化应用——区块链投票系统。
课程介绍
本视频课程面向初学者。 介绍了什么是区块链,什么是智能合约。 它涵盖了与以太坊开发相关的基本概念。 Gregory 将教您如何构建一个完整的基于以太坊的去中心化应用程序。 - 区块链投票系统。
通过本课程的学习,您将掌握:
1. 以太坊区块链开发基础知识
2. 开发部署以太坊合约所需的软件环境
3. 使用高级语言(solidity)编写以太坊智能合约
4. 使用NodeJS编译、部署和交互合约
5.使用Truffle框架开发分布式应用
6.使用控制台或网页与合约进行交互
课程内容
什么是区块链?
让我们用一个比喻来理解什么是区块链,它是如何运作的? 让我们先看看网络应用程序。
当我们与 Web 应用程序交互时,您使用 Web 浏览器连接到我们的应用程序中心服务器。 所有 Web 应用程序都基于中央服务器,所有数据都存储在中央数据库中。 任何时候在应用程序上进行交易,都需要与网络中央服务器进行通信。
如果我们在web应用上进行选举投票,我们在进行选举投票时会遇到以下问题:
1.数据库中的数据可能会被更改:或重复投票:或所有投票数据可能会被删除。
2. Web 服务器上的源代码可能随时更改。
我们不愿意在网络上创建应用程序。 我们更愿意在每个人都可以连接的区块链上创建它,以确保每个人投票一次且不可篡改。 让我们看看它是如何在区块链上实现的。
区块链不是中央服务器和数据库以太坊 app,而是网络和数据库。 区块链是一个点对点的计算机网络,称为节点,共享网络中的所有数据和代码。 所以如果你是一个连接到区块链的设备,你就是网络中的一个节点,你可以和网络中的所有其他计算机节点对话。 您还拥有区块链上所有数据和代码的副本。 区块链上没有中央服务器,只有同一属性下不同设备之间的点对点通信。
区块链取代了集中式数据库。 所有交易都在区块链上,所有包含的记录都称为区块。 所有相连的区块称为区块链,区块链之间创建公共账本,代表区块链中的所有数据。
公共分类账中的所有数据均受加密哈希密码保护,并由共识算法验证。 网络上节点的参与确保了分散在网络中的所有数据副本都是相同的。 这就是我们在区块链上构建投票应用程序的原因,因为我们想确保我们的选票被计算在内并且没有被篡改。
如果我们的投票应用程序是在区块链上实现的呢?
对于新用户,新用户需要一个有钱包地址和ETH的账户。 ETH 是以太坊的加密货币。 一旦连接到区块链网络,投票就会消耗区块链上的一些 ETH。
这些交易费用被称为“gas”。 当投票开始时,网络上帮助完成交易的矿工将获得 ETH 作为交易费用。 我的投票记录将永远被记录下来。
记住一件事:投票是一种交易,交易会消耗ETH,但读取数据是免费的。
什么是智能合约?
智能合约是在以太坊虚拟机 (EVM) 上执行我们的代码的过程。
智能合约的编程语言是 Solidity,有点像 Javascript,但又有一点不同。 Solidity 编程语言可以实现我们所有的业务交易逻辑。
如果公共账本代表网页数据库,那么智能合约就是实现所有业务逻辑交易的地方。
现在让我们快速浏览一下我们构建的 DApp 的结构。
传统的前端应用程序使用 HTML、CSS 和 Javascript。 语言。
代替传统的前端应用程序的是后端服务器,客户端安装并连接到本地以太坊区块链以使用 Solidity 语言编译去中心化选举。 将智能合约部署到本地区块链进行投票。
让我们来看看区块链是如何工作的,以及为什么我们应该用它来取代目前的中心化应用。
我们要创造什么?
我们将构建一个客户端应用程序以太坊 app,与我们在区块链上的智能合约进行对话。 此客户端应用程序将有一个候选人列表,列出每个候选人的 ID、姓名和票数。 它将有一个表格,我们可以在其中为我们想要的候选人投票。 它还显示了我们在“您的帐户”下连接到区块链的帐户。
安装依赖项
在创建 DApp 之前,您首先需要安装依赖项。
节点包管理器 (NPM)
我们需要的第一个依赖项是 Node.js 附带的节点包管理器或 NPM。 您可以通过转到终端并键入以下内容来查看您的节点是否已安装:
$节点-v
松露框架
接下来的依赖是Truffle框架,它允许我们在以太坊区块链上创建分布式应用,提供了一套用solidity编译的智能合约工具,也可以帮助我们测试智能合约。 部署区块链,也为我们开发客户端应用提供了场所。 在命令行中像这样安装 truffle 和 NPM:
$ npm 安装-g 松露
伽纳彻
下一个依赖项是本地内存区块链 Ganache。 您还可以从 Truffle Framework 网站下载并安装 Ganache。 它将提供以太坊外部账户,每个账户有 100 个假 ETH 及其钱包地址。
Metamask 谷歌扩展
我们下一个要安装的依赖项是:Metamask Google Extensions。 Metamask 帮助我们通过个人账户与本地区块链网络进行交互。 在开始之前,请记住安装 Metamask Google 扩展。
语法高亮
下一个依赖是语法高亮,很多编辑器和 IED 没有语法高亮,我建议在 solidity 编程时安装语法高亮。 所以你需要安装这样一个子包。 在本教程中,我使用 Sublime Text。 我已经在“Ethereum”包中下载了这个语法高亮显示。
烟雾测试 - 第 1 步
好了,现在我们所有的依赖都安装好了,让我们开始创建我们的 DApp。
首先,下载 Ganache 并将其打开以确保您的本地区块链正常运行。
Ganache 给了我们 10 个账户,每个账户有 100 个假 ETH。
每个帐户都有一个唯一的地址和一个私钥。 每个帐户地址都将作为我们选举中每个选民的唯一标识符。 现在让我们创建一个 Dapp 项目目录:
$ mkdir 选举
$ cd 选举
现在我们进入了项目,Truffle box 使它变得更快。 在本教程中,我们使用 PET Shop 盒子。 在您的项目目录中,通过命令栏安装宠物店盒子,如下所示:
$松露拆箱宠物店
看看宠物店盒子给我们带来了什么:
· 合同目录:这是所有智能联系人所在的地方。 我们已经有一个迁移合约来处理我们向区块链的迁移。
这就是智能合约的用武之地。在区块链上,我们已经有了处理迁移的迁移合约。
迁移目录:这是所有迁移文件所在的位置。 在区块链上更新区块链状态时需要迁移。 就像web开发框架中需要迁移来更新数据状态一样。
· node_modules 目录:这是所有节点依赖项的主目录。
src 目录:这是我们开发客户端应用程序的地方。
测试目录:这是我们为智能合约编写测试的地方。
truffle.js 文件:这是 Truffle 项目的主要配置文件。
让我们在合约目录中创建一个新合约:
$触摸合同/Election.sol
我们首先创建一个“冒烟测试”,以确保我们已正确设置项目并将合约成功部署到区块链。 打开文件并从以下代码开始:
编译指示可靠性 0.4.2;
合同选举{
// 读/写候选
字符串公共候选人;
//构造函数
函数选举()公共{
candidate = "候选人1";
}
}
现在我们已经为我们的智能合约创建了基础,让我们看看我们是否可以将它部署到区块链上。 因此,我们需要在迁移目录中创建一个新文件。 在您的项目根目录中,通过命令行创建一个新文件,如下所示:
$ touch migrations/2_deploy_contracts.js
请注意,我们用数字对 migrations 目录中的所有文件进行编号,以便 Truffle 知道执行它们的顺序。 让我们为这样一个新的迁移部署创建一个合约:
var 选举 = 人工制品。 require("./Election.sol");
模块。 出口=功能(部署){
deployer.deploy(选举);
};
首先,我们需要创建合约并将其分配给一个名为“Election”的变量。 接下来,我们将它添加到已部署合约的清单中,以确保它在我们运行迁移时得到部署。 现在让我们像这样从命令行运行迁移
$松露迁移:
现在我们已经成功将我们的智能合约迁移到本地以太坊区块链,让我们打开控制台与智能合约进行交互。 您可以像这样从命令栏打开松露控制器:
$松露控制台
现在我们在控制台中,让我们看一下我们部署的智能合约的一个实例,看看我们是否可以从合约中读取候选人的姓名。 从控制台运行此代码:
选举。 部署()。 然后(函数(实例){应用程序=实例})
这里选的是我们在迁移文件中创建的变量名。 我们在此示例合约中检索一个 deployed() 函数,将其分配给 promise 的回调函数中的 app 变量。 现在我们可以像这样读取候选变量的值:
应用程序。 候选人()
// => '候选人 1'
恭喜! 您刚刚编写了第一个智能合约,将其部署到区块链,并检索了一些数据。
第 2 步:候选人名单。
我们需要一种方法来存储多个候选人,并存储每个候选人的多个属性。 我们想跟踪候选人的身份、姓名和投票数。 以下是我们将如何模拟候选人:
合同选举{
// 为候选人建模
结构候选人{
单位编号;
字符串名称;
uint 投票数;
}
//...
}
我们使用 Solidity Struct 为候选人建模,Solidity 允许我们创建自己的结构类型,就像我们在这里为候选人所做的那样。 我们指定此结构具有无符号整数类型的 ID、字符串类型的名称和无符号整数类型的 voteCount。 简单地声明这个结构实际上不会给我们一个候选人。 我们需要在将其写入存储之前将其实例化并将其分配给变量。
接下来我们需要的是一个存储候选人的地方。 我们需要一个地方来存储我们刚刚创建的一种结构类型。 我们可以使用 Solidity 映射来做到这一点。 Solidity 中的映射类似于关联数组或哈希,它们关联键值对。 我们可以像这样创建这个映射:
合同选举{
// 为候选人建模
结构候选人{
单位编号;
字符串名称;
uint 投票数;
}
// 读/写候选
映射(uint => Candidate)公共候选人;
//...
}
在这种情况下,映射的键是一个无符号整数,值是我们刚刚定义的 Candidate 结构类型。 这基本上为我们提供了每个候选人的基于 id 的查找。 由于这个映射被分配给一个状态变量,每当我们为它分配一个新的键值对时,我们就将数据写入区块链。 接下来,我们将该地图的可见性设置为 public 以获取 getter 函数,就像我们在冒烟测试中对候选名称所做的那样。
接下来,我们通过计数器缓存状态变量跟踪选举中有多少候选人,如下所示:
合同选举{
// 为候选人建模
结构候选人{
单位编号;
字符串名称;
uint 投票数;
}
// 读/写候选
映射(uint => Candidate)公共候选人;
// 存储候选数
uint public candidatesCount;
//...
}
在 Solidity 中,无法确定地图的大小,也无法对其进行迭代。 这是因为地图中任何尚未分配值的键都会返回默认值(在本例中为空候选)。 例如,如果我们在这次选举中只有 2 个候选人,并且我们尝试查找候选人 #99,映射将返回一个空的候选人结构。这种行为使得无法知道有多少候选人存在,所以我们必须使用计数器缓存
接下来,我们创建一个函数,将候选人添加到我们创建的地图中:
合同选举{
//...
函数 addCandidate (string_name) private {
候选人数++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
}
我们已经声明了函数 addCandidate,它接受一个代表候选人姓名的字符串类型的参数。 在函数内部,我们递增候选计数器缓存以指示添加了新候选。 然后我们使用新的候选结构更新地图,使用当前候选计数作为键。 此 Candidate 结构初始化为 0,其中包含当前候选人计数中的候选人 ID、函数参数中的名称以及初始投票计数。 请注意,此函数的可见性是私有的,因为我们只想在合约中调用它。
现在,我们可以通过在构造函数中两次调用“addCandidate”函数来添加两个候选人,如下所示:
合同选举{
//...
函数选举()公共{
addCandidate("候选人1");
addCandidate("候选人2");
}
//...
}
当我们将合约部署到区块链时将执行此迁移,并且将有两名候选人参加我们的选举。 此时,您的完整合约代码应如下所示:
pragma solidity ^0.4.2;
合同选举{
// 为候选人建模
结构候选人{
单位编号;
字符串名称;
uint 投票数;
}
// 读/写候选人
映射(uint => Candidate)公共候选人;
// 存储候选数
uint public candidatesCount;
函数选举()公共{
addCandidate("候选人1");
addCandidate("候选人2");
}
函数 addCandidate (string_name) private {
候选人数++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
}
现在让我们像这样迁移我们的合同:
$松露迁移--重置
现在尝试在控制台内与候选人互动。
现在让我们编写一些测试来确保我们的智能合约被正确初始化。 首先,让我解释一下为什么测试在开发智能合约时如此重要。
测试
现在让我们写一些测试。 确保首先运行 Ganache。 然后,从项目根目录中的命令行创建一个新的测试文件,如下所示:
$ 触摸测试/election.js
我们将使用 Mocha 测试框架和 Chai 断言库在这个文件中用 Javascript 编写我们所有的测试。 这些与 Truffle 框架捆绑在一起。 我们将用 Javascript 编写所有这些测试,以模拟客户端与我们的智能合约的交互,就像我们在控制台中所做的那样。 这是测试的所有代码:
var 选举 = 人工制品。 require("./Election.sol");
合同(“选举”,功能(账户){
变种选举实例;
it("用两个候选人初始化", function() {
回归选举。 部署()。 然后(函数(实例){
返回实例。 候选人计数();
}).then(函数(计数){
断言。 等于(计数,2);
});
});
it("它用正确的值初始化候选人", function() {
回归选举。 部署()。 然后(函数(实例){
选举实例=实例;
返回选举实例。 候选人(1);
}).then(函数(候选人){
assert.equal(candidate[0], 1, "包含正确的 id");
assert.equal(candidate[1], "Candidate 1", "contains the correct name");
assert.equal(candidate[2], 0, "包含正确的票数");
返回选举实例。 候选人(2);
}).then(函数(候选人){
assert.equal(candidate[0], 2, "包含正确的 id");
assert.equal(candidate[1], "Candidate 2", "contains the correct name");
assert.equal(candidate[2], 0, "包含正确的票数");
});
});
});
第一个测试通过检查候选人数是否等于 2 来检查合约是否使用正确的候选人数进行了初始化。
下一次考试将检查每位候选人在选举中的价值,确保每位候选人都拥有正确的身份证件、姓名和票数。
现在让我们像这样从命令行运行测试:
$松露测试
看,编译通过了。
关注蜜蜂区块链学院,这里有最新最全的区块链学习课程和资料。
课程合作联系邮箱:bd@51bitbee.com