以太坊 - 快速指南

以太坊 - 简介

比特币的巨大成功引起了许多人创建自己货币的兴趣。考虑到比特币(一种数字货币)提供的优势,人们希望在自己的应用程序中使用区块链的概念。人们希望从物理合约转移到智能数字合约,这样可以自动解决诸如否认、透明度、安全性等几个问题。这一努力的成果导致了以太坊的创建 - 一个用于创建支持智能合约的分布式区块链应用程序的流行平台。

在本教程中,您将学习如何在以太坊平台上创建分布式应用程序 (DAPP)。更具体地说,您将学习如何编写合约、在本地区块链上测试它以及最终将其部署到外部区块链上以进行深度测试和商业用途。您将使用 Solidity(一种面向对象的合约开发语言)。您还将使用 Remix(一种用于开发和测试合约的开源 IDE)。要在外部区块链上部署经过测试的合约,您将使用 Ganache。要与合约交互,您将需要一个客户端应用程序。我们将使用 MyEtherWallet 为每个这样的客户端创建一个钱包。合约创建者将发布合约。任何其他客户端都将使用合约提供的接口查看联系人值,并向创建者发送一些钱以执行合约的一部分。

那么让我们从编写合约开始吧。

以太坊 - 智能合约

有几种工具可用于开发和测试合约。以太坊官方网站本身提供了最简单的工具之一。该工具名为Remix,我们将使用它进行合约开发。

Remix 用于合约开发

在浏览器中输入以下 URL 打开 Remix IDE。

https://remix.ethereum.org

将出现以下屏幕。

合约开发

在中心窗口中,您将看到一些默认代码,这是 Solidity 代码示例。您将在此代码编辑器中输入合约代码。您的代码可能会自动编译。成功编译代码后,您将能够在同一 IDE 中运行代码。执行合约方法时,结果将显示在同一个 IDE 窗口中。有一些工具可以调试代码并对您的项目进行单元测试。这些可以在右上角的菜单栏中看到,如下面的 IDE 屏幕截图所示。您很快就会使用这些选项。

Remix options

您现在将开始编写合约。

以太坊 - Solidity 用于合约编写

Solidity 是一种面向对象的语言,专门为合约编写而开发。它是一种高级语言,继承了 C++、Python 和 JavaScript 的特性。 Solidity 编译器将您的源代码编译为在以太坊虚拟机 (EVM) 上运行的字节码。

为了快速了解 Solidity 语法,请查看 IDE 中的示例代码。

pragma solidity >=0.4.22 <0.6.0;
contract Ballot {

第一行是编译器的指令。第二行开始定义合约。在合约中,您可以声明变量,例如 −

address chairperson;

您还可以定义结构,例如 Proposal,并创建这些结构项的数组。在代码窗口中检查这一点。

然后,您可以定义一个构造函数,在实例化合约时调用该构造函数。

constructor(uint8 _numProposals) public {

在构造函数之后,您将定义几个方法,这些方法是合约方法。在示例合约中,giveRightToVote 就是这样一种方法,其语法如下 −

function giveRightToVote(address toVoter) public {

public 关键字使此方法可由任何有权访问合约的客户端公开调用。

同样,示例合约还定义了另外三种方法,分别称为 delegate、votewinningProposal。检查这些方法,以了解 Solidity 语法。这些是编写您自己的合约的先决条件。解释 Solidity 的完整语法超出了本教程的范围。

以太坊 - 开发 MyContract

我们将合约命名为 MyContract,如下所示 −

contract MyContract {

我们将声明两个变量,如下所示 −

uint amount;
uint value;

变量 amount 将保存合约执行者发送给合约创建者的累计资金。value 字段将保存合约值。当执行者执行合约时,value 字段将被修改以反映平衡的合约值。

在合约构造函数中,我们设置这两个变量的值。

constructor (uint initialAmount, uint initialValue) public {
   amount = 0;
   value = 1000;
}

由于最初在合约上收取的金额为零,我们将 amount 字段设置为 0。我们将合约 value 设置为某个任意数字,在本例中为 1000。合约创建者决定此值。

为了检查在任何给定时间点收取的金额,我们提供了一种名为 getAmount 的公共合约方法,定义如下 −

function getAmount() public view returns(uint) {
    return amount;
}

为了在任何给定时间点获取平衡的合约价值,我们定义 getBalance 方法如下 −

function getBalance() public view returns(uint) {
    return value;
}

最后,我们编写一个合约方法(Send)。它允许客户端向合约创建者发送一些钱 −

function send(uint newDeposit) public {
    value = value - newDeposit;
    amount = amount + newDeposit;
}

执行send方法将修改合约的valueamount字段。

完整的合约代码如下 −

contract MyContract {
   uint amount;
   uint value;

   constructor (uint initialAmount, uint initialValue) public {
      amount = 0;
      value = 1000;
   }
   function getBalance() public view returns(uint) {
      return value;
   }
   function getAmount() public view returns(uint) {
      return amount;
   }
   function send(uint newDeposit) public {
      value = value - newDeposit;
      amount = amount + newDeposit;
   }
}

以太坊 - 编译合约

编写完整的合约代码后,在此 IDE 中编译它就很简单了。只需单击 IDE 中的 自动编译 复选框,如下面的屏幕截图所示 −

自动编译复选框

或者,您可以通过单击标题为 "开始编译" 的按钮来编译合约。

开始编译

如果有任何拼写错误,请在代码窗口中进行修复。确保代码完全编译且无错误。现在,您已准备好部署合约。

以太坊 - 部署合约

在本章中,我们将学习如何在以太坊上部署合约。单击"运行"菜单选项以部署合约。将出现以下屏幕。

部署合约

合约名称显示在突出显示的列表框中。在此之下,您将看到部署按钮,单击它即可部署合约。合约将部署在 Remix 内置区块链上。您将能够在屏幕底部看到已部署的合约。您可以在以下屏幕截图的突出显示部分中看到这一点。

部署突出显示部分

请注意,此突出显示区域中存在三个方法名称。接下来,您将通过执行合约方法与合约进行交互。

以太坊 - 与合约交互

单击已部署的合约时,您将看到合约提供的各种公共方法。如以下屏幕截图所示。

部署公共方法

第一个方法 send 前面有一个编辑框。在这里,您将输入合约方法所需的参数。其他两种方法不接受任何参数。

发送资金

现在,在合约窗口中显示的 send 函数前面输入一些金额,例如 100。单击 send 按钮。这将执行合约 send 方法,减少合约 value 字段的值并增加 amount 字段的值。

发送资金

检查合约价值

之前的 send money 操作已将合约价值减少了 100。现在您可以通过调用合约的 getBalance 方法来检查这一点。单击 getBalance 按钮后,您将看到输出,如下面的屏幕截图所示 −

检查合约价值

合约价值现在已减少到 900。

检查已收集金额

在本节中,我们将检查迄今为止此合约收集的金额。为此,请单击 getAmount 按钮。将显示以下屏幕。

检查收集到的金额

amount 字段值已从 0 更改为 100。

尝试几个 send 操作并检查合约 valueamount 字段,以得出已部署合约是否按预期执行的结论。

以太坊 - Remix 的局限性

您目前使用的 Remix IDE 足以用于合约的开发和初步测试。对于实际合约,您需要针对各种参数测试您的功能。Remix 无法创建真实(非测试)用户帐户来在它们之间转移资金。您无法控制 Remix 创建的区块链的配置。您甚至无法监控交易的执行情况。

Remix 错过了几个高级操作。因此,我们需要在提供所有这些功能的更复杂的区块链上部署我们的合约。Ganache 就是这样一个区块链,您将在后续章节中了解它。

以太坊 - 用于区块链的 Ganache

Ganache 用于设置个人以太坊区块链以测试您的 Solidity 合约。与 Remix 相比,它提供了更多功能。当您使用 Ganache 时,您将了解这些功能。在开始使用 Ganache 之前,您必须先在本地机器上下载并安装区块链。

下载 Ganache

您可以从以下 URL 下载 Ganache −

https://truffleframework.com/ganache

Ganache 适用于多个平台。我们在 Mac 上开发并测试了整个教程。因此,下面的屏幕截图将显示 Mac 安装。当您打开上面给出的安装 URL 时,它会自动检测您机器的操作系统并将您引导至适当的二进制安装。下面的屏幕截图显示了 Mac 安装。

下载 Ganache

单击"下载"按钮时,它将开始下载用于 Mac 安装的 DMG 文件。

安装 Ganache

在下载文件夹中找到"Ganache-2.0.0.dmg",然后双击它以安装 Ganache。安装成功后,将出现以下屏幕 −

安装 Ganache

将 Ganache 图标拖到应用程序文件夹。现在,Ganache 可作为 Mac 上的应用程序使用。

如果您使用的是其他操作系统,请按照提供的说明成功安装。

启动 Ganache

现在在您的应用程序文件夹中找到 Ganache,然后双击其图标以启动 Ganache。

Ganache 桌面

当 Ganache 启动时,Ganache 屏幕将显示如下图所示 −

Ganache 桌面

单击 QUICKSTART 以启动 Ganache。您将看到如下所示的 Ganache 控制台 −

QUICKSTART

上图的控制台显示了两个用户帐户,余额为 100 ETH(以太币 - 以太坊平台上的交易货币)。它还显示每个帐户的交易计数为零。由于用户到目前为止尚未执行任何交易,因此该计数显然为零。

现在我们将概览与我们直接相关的几个重要的 Ganache 屏幕。

以太坊 - Ganache 服务器设置

单击屏幕右上角的设置图标,如下面的屏幕截图所示 −

Ganache 设置

服务器设置屏幕将如下所示 −

服务器设置

在这里,您将能够设置 Ganache 服务器的服务器地址和端口号的值。暂时将这些保留为默认值。网络 ID 是 Ganache 服务器的内部区块链标识符;将其保留为默认值。自动挖矿按钮处于开启状态,表示交易将立即处理。如果您关闭此功能,它会要求您输入挖矿块的时间(以秒为单位)。

帐户和密钥

当您单击帐户和密钥菜单选项时,您将看到以下屏幕 −

帐户和密钥

在这里,您可以设置每个帐户的默认余额。默认值为 100。这现在解释了为什么您在桌面屏幕截图中看到每个帐户显示 100 ETH。您还可以在此屏幕上设置帐户数量。此屏幕截图中显示的值为 2,这就是桌面仅显示两个帐户的原因。

现在,我们将使用这两个设置的屏幕进行操作;了解这两个设置如何工作就足够了。通过单击屏幕右侧的重新启动按钮重新启动服务器。您现在将返回到桌面屏幕。尝试在上述两个字段中输入不同的值,重新启动服务器并查看其效果。

以太坊 - 快速演练

现在我们将简要了解 Ganache 桌面上可用的内容。在桌面上,顶部有几个菜单选项,其中一些与我们直接相关。菜单栏在下面的屏幕截图中突出显示 −

Ganache 菜单选项

单击 TRANSACTIONS 菜单会显示迄今为止执行的所有交易。您很快就会执行交易。现在,返回上面的屏幕并时不时检查交易。典型的交易屏幕如下所示 −

Ganache TRANSACTIONS

同样,当您单击 BLOCKS 菜单时,您将看到各种挖掘的区块。请考虑以下屏幕截图以了解 BLOCKS 菜单的外观 −

Ganache Blocks

单击 LOGS 菜单。它将为您打开系统日志。在这里,您可以检查在以太坊区块链上执行的各种操作。

现在,您已经了解了如何使用 Ganache 设置私有以太坊区块链,现在您将创建一些使用此区块链的客户端。

以太坊 - MyEtherWallet

对于客户端应用程序,您将使用 MyEtherWallet

从以下 URL 下载 MyEtherWallet 软件 −

https://github.com/kvhnuke/etherwallet/releases/tag/v3.21.06

如果需要,解压下载的文件并打开 index.html。您将看到以下用于创建新钱包的界面。

MyEtherWallet

以太坊 - 创建钱包

在本章中,我们将学习如何创建以太坊钱包。要创建新钱包,请输入您选择的密码,然后单击"创建新钱包"按钮。当您这样做时,将创建一个钱包。数字钱包本质上是生成您需要存储在安全地方的公钥/私钥对。钱包创建后会出现以下屏幕 −

创建新钱包

单击"下载密钥库文件 (UTC / JSON)"按钮保存生成的密钥。现在,单击"我明白。继续"按钮。您的私钥将出现在屏幕上,如下面的屏幕截图所示 −

下载密钥库

单击"打印纸钱包"按钮以保留钱包私钥的物理记录。稍后您将需要它来解锁钱包。您将看到以下屏幕。不要丢失此输出。

打印纸钱包

要解锁您的钱包,请点击"保存您的地址"按钮。您将看到以下屏幕。

解锁您的钱包

可以使用上图突出显示的私钥选项解锁钱包。从上一个屏幕截图中剪切并粘贴私钥,然后单击"解锁"按钮。您的钱包将被解锁,您将看到屏幕底部出现一条消息。由于钱包目前不包含任何内容,因此解锁钱包对我们来说目前并没有太大用处。

将钱包附加到 Ganache 区块链

您现在已经创建了一个钱包;这个钱包是区块链的客户端界面。我们将把钱包附加到您在之前的课程中启动的 Ganache 区块链。为此,请单击网络下拉框,如下面的屏幕截图所示 −

网络下拉框

转到列表底部。您将看到"添加自定义网络/节点"的选项。选择此项。

现在,将出现一个屏幕,询问 Ganache 服务器地址和它正在监听的端口。

添加自定义网络

输入您的 Ganache 服务器详细信息 - http://127.0.0.1 和端口:8545。这些将是您在 Ganache 服务器设置中设置的值。为此节点提供您选择的名称。单击"保存并使用自定义节点"按钮。您将在屏幕底部看到连接消息。此时,您的钱包已成功连接到 Ganache 区块链。

您现在可以在此连接的区块链上部署合约了。

以太坊 - 部署合约

要部署合约,请选择 合约 菜单选项,如下面的屏幕截图所示 −

选择合约菜单

您需要在此屏幕上输入合约的字节码。请记住,当您编译 Solidity 合约代码时,它会生成一个在 EVM 上运行的字节码。您现在需要从 Remix IDE 获取此字节码。

转到 Remix IDE 屏幕,您之前输入的合约应该在代码窗口中。如果没有,请在代码窗口中重新输入合约。单击字节码按钮,如以下屏幕截图所示 −

Remix IDE Screen

编译源的字节码将与其他一些信息一起复制到剪贴板。将复制的代码粘贴到您最喜欢的文本编辑器中。以下是文本编辑器的屏幕截图 −

Remix bytecode

object 标签的值包含所需的字节码。小心复制此代码,确保不要复制括起来的引号。字节码非常长,因此请确保复制直到最后一个字节(包括它)。现在,将此字节码粘贴到 Deploy Contract 屏幕中,如下所示 −

Desired Bytecode

Gas Limit 字段已自动设置。

在 Gas Limit 字段下方,您将找到用于访问钱包的选项。

访问钱包

现在,使用将部署此合约的 Ganache 帐户的私钥访问钱包。要获取此私钥,请返回 Ganache 窗口。点击第一个帐户的钥匙图标,如下所示 −

第一个帐户

您将看到用户帐户 # 1 的私钥,如下图所示 −

第一个帐户私钥

复制此私钥并将其粘贴到"粘贴您的私钥"部分,如下所示 −

粘贴您的私钥

您将在屏幕底部看到"解锁"按钮。解锁后,屏幕底部会出现"成功"消息。此时,您的钱包已附加到 Ganache 区块链的 1 号账户。

现在,您已准备好签署和部署合约。单击"签署交易"按钮,如下面的屏幕截图所示 −

签署交易

签署交易会生成并显示原始已签署交易。单击"部署合约"按钮在 Ganache 区块链上部署合约。请记住,合约是由 Ganache 区块链的 1 号账户用户部署的。因此,1 号账户用户成为合约创建者。在部署合约之前,系统会要求您确认交易,因为如果您要在公共的真实以太坊区块链上部署此合约,则可能会花费一些真金白银。不用担心,对于您本地机器上运行的当前私有区块链,不涉及真金白银。单击进行交易按钮,如下面的屏幕截图所示 −

运行中的私有区块链

检查 Ganache 控制台;您将看到账户 #1 中的 ETH 余额已减少,如以下屏幕截图所示 −

Ganache console

现在,单击 TRANSACTIONS 菜单,如以下屏幕截图所示 −

Ganache Transactions Screenshot

您将看到交易详情。

Ganache Transactions Details

在此屏幕上,您将找到合约的已发布地址。该地址已在上面的屏幕截图中标记。您将公开分发此地址,以便让其他人知道您的合约在此指定地址可用,他们可以连接到该地址并执行合约方法,例如向您(合约创建者)汇款。复制此合约地址以供自己参考,因为您将在下一步中需要它。

以太坊 - 与已部署合约交互

现在,您已准备好与已部署的合约进行交互。返回 MyEtherWallet 桌面并单击"与合约交互"选项卡,如下面的屏幕截图所示 −

与合约交互

将您之前复制的合约地址粘贴到"合约地址"字段中。您还需要将合约的"ABI / JSON 接口"粘贴到上述屏幕上。

要获取ABI,请转到Remix窗口并单击ABI按钮,如下面的屏幕截图所示。

ABI 按钮

ABI / JSON 接口将被复制到剪贴板。将其粘贴到您最喜欢的编辑器中以检查生成的接口,如下所示 −

ABI / JSON Interface
[
   {
      "constant": false,
      "inputs": [
         {
            "name": "newDeposit",
            "type": "uint256"
         }
      ],
      "name": "send",
      "outputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "function"
   },
   {
      "inputs": [
         {
            "name": "initialAmount",
            "type": "uint256"
         },
         {
            "name": "initialValue",
            "type": "uint256"
         }
      ],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "constructor"
   },
   {
      "constant": true,
      "inputs": [],
      "name": "getAmount",
      "outputs": [
         {
            "name": "",
            "type": "uint256"
         }
      ],
      "payable": false,
      "stateMutability": "view",
      "type": "function"
   },
   {
      "constant": true,
      "inputs": [],
      "name": "getBalance",
      "outputs": [
         {
            "name": "",
            "type": "uint256"
         }
      ],
      "payable": false,
      "stateMutability": "view",
      "type": "function"
   }
]

将此 JSON 粘贴到 MyEtherWallet 界面后,您会注意到 JSON 界面下方的 ACCESS 按钮现已激活,如下所示 −

My Ether Wallet

单击 Access 按钮以访问合约。

单击 Access 按钮后,合约地址和功能选择下拉菜单将出现在屏幕上,就像在 Remix 编辑器中一样。这显示在下面的屏幕截图中 −

Access button

您可以像 Remix 部署一样检查合约的各种功能。请注意,该联系人现在已部署在外部 Ganache 区块链上。检查 getAmount 函数;您将获得金额值为零,并且 getBalance 将显示余额 1000。

现在尝试发送一些钱。它将向您显示一个 textedit 控件以输入金额。当您编写合同时,将使用一些"gas",并且会要求您在将其写入区块链之前确认交易。交易将在短时间内执行,具体取决于您在 Ganache 服务器上设置的挖掘时间。此后,您可以重新检查合同的 valueamount 字段,以验证这些字段确实已被修改。

您现在可以检查 Ganache 桌面以查看迄今为止执行的交易。示例输出如下所示 −

sample output

到目前为止,您既是合约创建者,又是合约执行者。这没有多大意义,因为您希望其他人使用您的合约。为此,我们将为我们的 Ganache 区块链创建另一个客户端,并从新创建的帐户 #2 向帐户 #1 的合约创建者发送一些钱。

以太坊 - 创建合约用户

在本章中,我们将学习如何在以太坊上创建合约用户。要为我们发布的合约创建用户,我们将创建另一个 MyEtherWallet 客户端,该客户端附加到您在前面的步骤中使用的相同 Ganache 区块链。转到 MyEtherWallet 屏幕并创建一个新钱包。

单击 合约 菜单并选择 "与合约交互" 选项,如前例所示。请注意,此新用户将仅与已发布的合约交互,而不是部署自己的合约。指定您在前例中使用的合约地址和 ABI。

与合约地址交互

现在,单击 访问 按钮并调用 发送 方法。当系统询问时,输入要发送的值,例如 100 ETH。提交交易。提交后,将出现以下屏幕。

Interact with Contract Access

要将此新客户端附加到我们的 Ganache 区块链,请转到 Ganache 控制台。单击帐户 #2 的钥匙图标,如以下屏幕截图所示 −

Ganache 控制台屏幕截图

您将获得帐户 #2 的私钥。

Ganache 控制台私钥

复制您收到的密钥并将其用于您新创建的钱包中,如下所示 −

新创建的钱包

单击解锁按钮以附加钱包。

成功解锁钱包后,写入所需的发送交易。

钱包已成功解锁

单击"生成交易"按钮生成交易。

生成交易

进行交易并等待一段时间以使其反映在区块链中。现在,执行"getAmount",显示的金额现在应为 200。

Generate get Amount

执行"getBalance"value 字段现在应为 800。

Generate get Balance

检查交易日志以查看不同用户执行的各种交易。

检查交易

以太坊 - 摘要

您学习了如何在 Solidity 中编写自己的数字合约。您在 Remix IDE 中开发并测试了合约接口。为了进一步进行多用户测试,您在 Ganache 区块链上部署了此合约。在 Ganache 上,您创建了两个用户帐户。第一个帐户用于发布合约。第二个帐户用于使用合约。

下一步是什么?

您在整个过程中使用的 Ganache 区块链是私有的,并且位于您的机器本地。一旦您对合约的功能完全满意,您就可以继续在真实的以太坊区块链上发布它。但是,这样做需要您花费真钱。在演示应用程序中,我们为 Ganache 中的每个用户帐户默认使用 1000 ETH。当您在真实的区块链上部署合约时,您必须通过将自己国家的货币转换为 ETH 来购买 ETH。这种货币将存储在您的钱包中,您可以按照自己的方式使用它。