建议和反馈

请填写你的反馈内容

如何逐步构建完整的堆栈去中心化应用程序

2020-02-20 ·673次阅读 ·读完需要27分钟

今天,我将向您展示如何在以太坊区块链上构建第一个去中心化应用程序或dApp。我将向您展示如何编写您的第一个以太坊智能合约,我们将在两个候选人之间进行选举。我们将针对智能合约编写测试,将其部署到以太坊区块链,并开发允许帐户进行投票的客户端应用程序。我们还将研究关键概念,例如“什么是区块链?”,“什么是智能合约?”和“ dApp如何工作?”。


什么是区块链?

让我们用一个类比来理解什么是区块链及其运作方式。让我们看一个Web应用程序。

Web应用图

通常,当您与Web应用程序进行交互时,您将使用Web浏览器通过网络连接到中央服务器。该Web应用程序的所有代码均位于该中央服务器上,所有数据均位于中央数据库中。每当您与应用程序进行交易时,必须与Web上的该中央服务器进行通信。

如果要在网络上构建投票应用程序,则会遇到一些问题:

  1. 数据库上的数据可以更改:可以不止一次计数或完全删除。

  2. Web服务器上的源代码也可以随时更改。

我们不想在网络上构建我们的应用程序。我们希望将其构建在区块链上,任何连接到网络的人都可以参加选举。我们要确保计算他们的选票,并且只计算一次。因此,让我们看一下它是如何工作的。

区块链不是拥有网络,中央服务器和数据库,而是一个网络和一个数据库区块链是计算机的对等网络,称为节点,它们共享网络中的所有数据和代码。因此,如果您是连接到区块链的设备,那么您就是网络中的一个节点,并且您会与网络中的所有其他计算机节点通信。现在,您在区块链上拥有所有数据和代码的副本。没有更多的中央服务器。只是一堆在同一网络上互相通信的计算机。

以太坊区块链节点图

区块链中各节点之间共享的所有交易数据都取代了集中式数据库,而是包含在称为块的记录束中,这些记录束链接在一起以创建公共分类帐。该公共分类账代表区块链中的所有数据。公共分类账中的所有数据均通过加密哈希进行保护,并通过共识算法进行验证。网络上的节点参与以确保跨网络分布的所有数据副本都是相同的。这是我们在区块链上构建投票应用程序的一个非常重要的原因,因为我们要确保计数我们的投票,并且投票不会改变。

我们的应用程序的用户在区块链上投票会是什么样?好吧,对于初学者来说,用户需要一个带有钱包地址的账户,并带有一些以太坊的加密货币以太币。一旦他们连接到网络,他们将投票并支付一小笔交易费用,以将该交易写入区块链。该交易费称为“煤气”。每当进行表决时,网络上称为矿工的某些节点就会竞争以完成此事务。完成该交易的矿工将获得我们支付以投票的以太币。

回顾一下,当我投票时,我付出了汽油的价格进行投票,当我的投票被记录下来时,网络上的一台计算机就获得了我的以太费。反过来,我有信心永远正确记录我的投票。

因此,还需要注意的是,对区块链进行投票会使以太币付出代价,但仅看到候选人名单就不会了。这是因为从区块链读取数据是免费的,但写入数据却不是。

什么是智能合约?

这就是投票过程的工作方式,但是我们实际上如何编写应用程序代码?好吧,以太坊区块链允许我们使用称为智能合约的东西在区块链上使用以太坊虚拟机(EVM)执行代码。

智能合约是我们应用程序所有业务逻辑的生命。这是我们实际对应用程序的分散部分进行编码的地方。智能合约负责向区块链读取和写入数据以及执行业务逻辑。智能联系人以称为Solidity的编程语言编写,该语言看起来很像Javascript。它是一种功能强大的编程语言,它使我们能够执行Javascript能够执行的许多相同类型的事情,但是由于其用例,其行为会有所不同,正如我们将在本教程中看到的那样。

区块链上智能合约的功能与网络上的微服务非常相似。如果公共分类账代表了区块链的数据库层,那么智能合约就是所有与该数据进行交易的业务逻辑所在的地方。

另外,它们也称为智能合约,因为它们代表着契约或协议。就我们的dApp投票而言,这是一个协议,我的投票将被计入,其他选票仅被计算一次,并且获得最高票数的候选人实际上将赢得选举。

现在,让我们快速看一下正在构建的dApp的结构。

dApp图

我们将有一个用HTML,CSS和Javascript编写的传统前端客户端。无需与后端服务器对话,该客户端将连接到我们将安装的本地以太坊区块链。我们将使用Solidity编程语言在Election智能合约中编写有关dApp的所有业务逻辑。我们将将此智能合约部署到我们本地的Etherum区块链中,并允许帐户开始投票。

现在我们已经了解了什么是区块链及其工作原理。我们已经知道了为什么要在区块链而不是当前的网络上构建投票dApp。而且我们已经看到,我们希望通过编写将部署到以太坊区块链的智能合约来对dApp进行编码。现在,让我们开始编程吧!

我们将要建设的

这是我们将要构建的投票dApp的演示。

dApp演示

我们将构建一个客户端应用程序,该应用程序将与区块链上的智能合约进行对话。该客户端应用程序将具有一个候选人表,其中列出了每个候选人的ID,姓名和投票数。它将有一个表格,我们可以在其中为所需的候选人投票。它还在“您的帐户”下显示了我们已连接到区块链的帐户。

安装依赖项

本教程此部分随附的视频片段始于8:53

为了构建dApp,我们首先需要一些依赖项。

节点程序包管理器(NPM)

我们需要的第一个依赖项是Node.js附带的Node Package Manager或NPM。通过转到终端并输入以下命令,可以查看是否已安装节点:

$ node -v

松露框架

下一个依赖项是Truffle框架,它使我们能够在以太坊区块链上构建去中心化应用程序。它提供了一套工具,使我们能够使用Solidity编程语言编写智能联系人。它还使我们能够测试智能合约并将其部署到区块链。它还为我们提供了开发客户端应用程序的地方。

您可以在命令行中使用NPM安装Truffle,如下所示:

$ npm install -g truffle

伽纳彻

下一个依赖项是Ganache(本地内存区块链)。您可以通过从Truffle Framework网站下载来安装Ganache 它将为我们提供10个外部账户,这些账户的地址在我们本地的以太坊区块链上。每个帐户都预装有100个假以太币。

元掩码

下一个依赖项是Google ChromeMetamask扩展为了使用区块链,我们必须连接到区块链(记住,我说过区块链一个网络)。为了使用以太坊区块链,我们必须安装一个特殊的浏览器扩展。那就是元掩码的来源。我们将能够使用我们的个人帐户连接到我们本地的以太坊区块链,并与我们的智能合约进行交互。

在本教程中,我们将使用Metamask chrome扩展程序,因此,如果您还没有安装google chrome浏览器,则还需要安装它。要安装Metamask,请在Google Chrome网络商店中搜索Metamask Chrome插件。安装后,请确保已在扩展列表中将其选中。安装Chrome浏览器后,您会在右上角看到fox图标。如果遇到问题,请参考视频演练!

语法高亮

依赖关系是可选的,但建议使用。我建议为Solidity编程语言安装语法突出显示大多数文本编辑器和IDE都没有开箱即用地突出显示Solidity的语法,因此您必须安装一个软件包来支持此功能。我正在使用Sublime Text,并且下载了“ Ethereum”包,该Solidity提供了出色的语法突出显示。

烟雾测试-步骤1

该教程的此部分随附的视频片段始于11:40您可以在此处下载本部分教程的代码如果遇到困难,可以随意将它们用作参考点!

现在我们已经安装了依赖项,让我们开始构建dApp!

首先,找到在哪里下载Ganache,然后打开它。现在,Ganache已启动,您已经在运行本地区块链。

打开Ganache区块链客户端

Ganache给了我们10个帐户,其中预装有100个虚假的以太币(在以太坊主网络上这不值钱)。每个帐户都有一个唯一的地址和一个私钥。每个帐户地址将作为我们选举中每个选民的唯一标识符。

现在,让我们在命令行中为dApp创建一个项目目录,如下所示:

$ mkdir election$ cd election

现在我们进入了项目,可以使用Truffle box快速启动并运行在本教程我们将使用“ 宠物店”框在项目目录中,从命令行安装pet shop框,如下所示:

$ truffle unbox pet-shop

让我们看看宠物店盒子给我们带来了什么:

项目目录
    • 合同目录:这是所有智能联系人所在的位置。我们已经有一个迁移合同,可以处理向区块链的迁移。

    • migrations目录:这是所有迁移文件所在的位置。这些迁移类似于其他Web开发框架,这些框架要求迁移才能更改数据库状态。每当我们将智能合约部署到区块链时,我们都会更新区块链的状态,因此需要进行迁移。

    • node_modules目录:这是我们所有Node依赖项的宿主

    • src目录:这是我们将开发客户端应用程序的位置。

    • 测试目录:这是我们为智能合约编写测试的地方。

    • truffle.js文件:这是我们的Truffle项目的主要配置文件

现在让我们开始编写我们的智能合约!该智能合约将包含我们dApp的所有业务逻辑。它将负责读写以太坊区块链。这将使我们能够列出将参加选举的候选人,并跟踪所有选票和选民。它还将管辖所有选举规则,例如强制执行帐户只能投票一次。从项目的根目录开始,像下面这样在合同目录中创建一个新的合同文件:

$ touch contracts/Election.sol

让我们首先创建一个“烟雾测试”,以确保我们已经正确设置了项目,并且可以成功地将合同部署到区块链中。打开文件并从以下代码开始:

pragma solidity 0.4.2;contract Election {
    // Read/write candidate
    string public candidate;
    // Constructor
    function Election () public {
        candidate = "Candidate 1";
    }}

让我解释一下这段代码。我们首先用pragma solidity语句声明solidity版本接下来,我们使用“ contract”关键字声明智能合约,后跟合约名称。接下来,我们声明一个状态变量,该变量将存储候选名称的值。状态变量允许我们将数据写入区块链。我们已经声明该变量为字符串,并将其可见性设置为public因为它是公开的,所以坚固性将为我们提供免费的吸气剂功能,使我们能够在合同之外获得该价值。我们稍后会在控制台中看到效果!

然后,我们创建一个构造函数,该函数将在我们将智能合约部署到区块链时被调用。在这里,我们将设置候选状态变量的值,该值将在迁移时存储到区块链中。请注意,构造函数的名称与智能合约的名称相同。这就是Solidity知道该函数是构造函数的方式。

现在我们已经创建了智能合约的基础,让我们看看是否可以将其部署到区块链上。为此,我们需要在migrations目录中创建一个新文件。在您的项目根目录中,从命令行创建一个新文件,如下所示:

$ touch migrations/2_deploy_contracts.js

注意,我们在迁移目录中的所有文件都用数字编号,以便Truffle知道执行它们的顺序。让我们创建一个新的迁移来部署合同,如下所示:

var Election = artifacts.require("./Election.sol");module.exports = function(deployer) {
  deployer.deploy(Election);};

首先,我们需要创建的合同,并将其分配给一个名为“ Election”的变量。接下来,我们将其添加到已部署合同的清单中,以确保在运行迁移时将其部署。现在,让我们从命令行运行迁移,如下所示:

$ truffle migrate

现在我们已成功将智能合约迁移到本地以太坊区块链,让我们打开控制台以与智能合约进行交互。您可以从命令行打开松露控制台,如下所示:

$ truffle console

现在我们在控制台中,让我们获取已部署智能合约的实例,看看是否可以从合约中读取候选人的姓名。在控制台中,运行以下代码:

Election.deployed().then(function(instance) { app = instance })

Election是我们在迁移文件中创建的变量的名称。我们使用该deployed()函数检索了合同的已部署实例,并将其分配给apppromise的回调函数中变量。刚开始时这可能看起来有些混乱,但是您可以参考21:50的视频中的控制台演示以获取进一步的说明。

现在我们可以像这样读取候选变量的值:

app.candidate()// => 'Candidate 1'

恭喜你!您刚刚编写了第一个智能合约,将其部署到区块链,并检索了其中的一些数据。

列出候选人-步骤2

本教程此部分随附的视频片段始于27:11您可以在此处下载本部分教程的代码如果遇到困难,可以随意将它们用作参考点!

现在一切都已正确设置,让我们继续列出要参加选举的候选人,以建立智能联系。我们需要一种存储多个候选者的方法,并存储有关每个候选者的多个属性。我们要跟踪候选人的ID,姓名和投票数。这是我们如何对候选人建模:

contract Election {    // Model a Candidate
    struct Candidate {        uint id;        string name;        uint voteCount;
    }
    // ...}

我们已经使用Solidity Struct对候选人进行了建模坚固性使我们能够创建自己的结构类型,就像在这里为候选人所做的那样。我们指定此结构的ID为无符号整数类型,字符串类型的名称和无符号整数类型的表决数。简单地声明这个结构实际上不会给我们候选人。我们需要实例化并将其分配给变量,然后才能将其写入存储。

接下来,我们需要一个存储候选人的地方。我们需要一个地方来存储我们刚刚创建的一种结构类型。我们可以通过Solidity映射来做到这一点Solidity中的映射类似于关联键值对的关联数组或哈希。我们可以这样创建此映射:

contract Election {    // Model a Candidate
    struct Candidate {        uint id;        string name;        uint voteCount;
    }
    // Read/write Candidates
    mapping(uint => Candidate) public candidates;
    // ...}

在这种情况下,映射的键是一个无符号整数,值是我们刚刚定义的候选结构类型。从本质上讲,这使我们可以针对每个候选人进行基于ID的查找。由于此映射已分配给状态变量,因此,只要我们为其分配新的键值对,便会将数据写入区块链。接下来,我们将此映射的可见性设置public为以获得吸气功能,就像我们在烟雾测试中对候选名称所做的一样。

接下来,我们使用计数器缓存状态变量来跟踪选举中存在多少个候选者,如下所示:

contract Election {    // Model a Candidate
    struct Candidate {        uint id;        string name;        uint voteCount;
    }
    // Read/write Candidates
    mapping(uint => Candidate) public candidates;
    // Store Candidates Count
    uint public candidatesCount;
    // ...}

在Solidity中,也无法确定映射的大小,也无法对其进行迭代。这是因为映射中任何尚未分配值的键都将返回默认值(在这种情况下为空候选)。例如,如果在这次选举中我们只有2个候选人,而我们尝试查找候选人#99,则映射将返回一个空的候选人结构。此行为使得无法知道有多少候选对象,因此我们必须使用计数器缓存。

接下来,让我们创建一个函数,将候选者添加到我们创建的映射中,如下所示:

contract Election {    // ...
    function addCandidate (string _name) private {
        candidatesCount ++;
        candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
    }}

我们已经声明该函数addCandidate采用一个字符串类型的参数,该参数表示候选人的姓名。在函数内部,我们增加候选计数器缓存以表示已添加新的候选。然后,使用当前候选计数作为键,使用新的候选结构更新映射。使用从当前候选计数中获得的候选ID,从函数参数中获得的名称以及初始投票计数为0初始化此候选结构。请注意,此函数的可见性是私有的,因为我们只想在合同内部调用它。

现在,我们可以通过在构造函数内部两次调用“ addCandidate”函数来向选举中添加两个候选者,如下所示:

contract Election {    // ...
    function Election () public {
        addCandidate("Candidate 1");
        addCandidate("Candidate 2");
    }
    // ...}

当我们将合同部署到区块链时,将执行此迁移,并在选举中填充两名候选人。此时,您的完整合同代码应如下所示:

pragma solidity ^0.4.2;contract Election {
    // Model a Candidate
    struct Candidate {        uint id;        string name;        uint voteCount;
    }
    // Read/write candidates
    mapping(uint => Candidate) public candidates;
    // Store Candidates Count
    uint public candidatesCount;
    function Election () public {
        addCandidate("Candidate 1");
        addCandidate("Candidate 2");
    }
    function addCandidate (string _name) private {
        candidatesCount ++;
        candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
    }}

现在,让我们像这样迁移我们的合同:

$ truffle migrate --reset

现在尝试与控制台中的候选者进行交互。我在视频37:31上演示此内容时,您可以跟着我我会把它留给您作为练习。

评论(0)问答(0)
请先登录或注册

请先登陆或注册

相关推荐

幸运飞艇五码计算方法+方法群6139371

幸运飞艇五码计算方法+方法群6139371......
笑里斩情仇 · 2020-04-01
21阅读 · 0赞赏 · 0问答

幸运飞艇实战个人技巧+方法群6139371

 幸运飞艇实战个人技巧+方法群6139371......
笑里斩情仇 · 2020-04-01
20阅读 · 0赞赏 · 0问答

BPassword介绍

BPassword介绍    BPassword的由来,现阶段各个app都需要账号密码,都使用同一个账号密码又不太安全,不同的账号密码就会导致账号密码太多难以记......
李万胜 · 2020-03-31
702阅读 · 0赞赏 · 0问答

BPassword测试版简单实用教程

BPassword简单使用教程1.测试app下载,访问链接https://testflight.apple.com/join/co4IQ0Rc 执行第一步,下载完TestFlight,执行第......
李万胜 · 2020-03-31
1438阅读 · 0赞赏 · 0问答

注册即送矿机,可挖矿的区块链社交游戏

星际时代是什么?星际时代是基于区块链,以"挖矿"为核心的一款社交类游戏。通过购买矿机的方式来进行挖矿。通过挖矿的行为,可以获得HDAG的奖励。获得的HDAG可以进行交易或用于钱包中......
moonlight · 2020-03-27
580阅读 · 0赞赏 · 0问答

星际时代矿机,一款不需要电费和运维的矿机、注册就送矿机,你心动了吗?

[![](https://www.liankexing.com/Public/Uploads/2020-03-27/5e7d565f999ec.png)](http://harmonydag.com)......
moonlight · 2020-03-27
653阅读 · 0赞赏 · 0问答

2268

LK币

21

粉丝

82

笔记

感谢"论坛咸鸟"

这篇精彩的笔记,目前已经帮助

  • 0
  • 0
  • 6
  • 7
  • 3
喜欢0
链客社群 加入

微博进入

商务合作>

广告投放>

公司名称:北京链客行科技有限公司

联系方式:010-67707199

ICP备案号:京ICP备18032136号

Copyright:链客区块链技术问答社区 版权所有

感谢您的提问,问题被社区永久收入以便新人查看。一定要记得采纳最佳答案哦!加油!

感谢您的善举,每一次解答会成为新人的灯塔,回答被采纳后获得20算力和相应的LK币奖励

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!