Ethereum 简明教程

Ethereum - Quick Guide

Ethereum - Introduction

比特币的巨大成功引起了一些人的兴趣,让他们创建自己的货币。鉴于比特币提供的数字货币的优势,人们希望在自己的应用程序中使用 Blockchain 的概念。人们希望摆脱物理 contract,转向智能数字 contract,其中拒绝、透明度、安全性等几个问题会自动得到解决。这一努力的结果是创建了 Ethereum,一个用于创建支持智能合约的分布式 Blockchain 应用程序的流行平台。

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

因此,让我们首先编写 contract。

Ethereum - Smart Contracts

有若干工具可用于开发和测试 contract。最简单的工具之一位于官方的 Ethereum 网站上。该工具称为 Remix ,我们将使用此工具进行 contract 开发。

Remix for Contract Development

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

将显示以下屏幕。

contract development

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

remix options

您现在将开始编写您的合约。

Ethereum - Solidity for Contract Writing

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 的完整语法超出了本教程的范围。

Ethereum - Developing 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;
   }
}

Ethereum - Compiling the Contract

一旦写好完整的合约代码,在该 IDE 中编译它就是小菜一碟。只需单击 IDE 中的 Autocompile 复选框,如下面的屏幕截图所示−

autocompile checkbox

或者,您可以通过单击标题为 “Start to compile” 的按钮来编译合约。

start to compile

如果有任何拼写错误,请在代码窗口中更正它。确保代码完全编译且没有错误。现在,您已准备就绪部署合约。

Ethereum - Deploying the Contract

在本章中,我们将学习如何在 Ethereum 上部署 contract。点击 Run 菜单选项以部署 contract。将出现以下屏幕。

deploy contract

contract 名称显示在突出显示的列表框中。在其下方,您会注意到 Deploy 按钮,单击以部署 contract。该 contract 将部署在 Remix 内置 Blockchain 上。您可以在屏幕底部看到已部署的 contract。您可以在下方屏幕截图的突出显示部分中看到这一点。

deploy highlighted portion

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

Ethereum - Interacting with the Contract

单击已部署的合同后,您将看到合同提供的各种公共方法。这在下面的屏幕截图中显示。

deploy public methods

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

Sending Money

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

sending money

Examining Contract Value

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

examining contract value

合同 value 现在已减少到 900。

Examining Collected Amount

在本节中,我们将检查到目前为止在此合同中收集的金额。为此,请单击 getAmount 按钮。以下屏幕将会出现。

examining collected amount

amount 字段值由 0 变成了 100。

尝试一些 send 操作,并检查 contract valueamount 字段,以断定已部署的 contract 按预期执行。

Ethereum - Limitations of Remix

到目前为止,您使用的 Remix IDE 足以用于您的合约的开发和初始测试。对于实际合约,您需要针对各种参数测试您的功能。Remix 无法创建真实的(非测试)用户账户,以在其之间转账。您无法控制 Remix 创建的区块链配置。您甚至无法监视交易执行。

Remix 错过了多项高级操作。因此,我们需要将合约部署到一个提供所有这些功能的更复杂的区块链上。您将在我们随后的章节中学习到其中一个名为 Ganache 的区块链。

Ethereum - Ganache for Blockchain

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

Downloading Ganache

您可以从以下 URL 下载 Ganache −

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

downloading ganache

当您点击下载按钮时,它将开始下载适合 Mac 安装的 DMG 文件。

Installing Ganache

在下载文件夹中找到 “Ganache-2.0.0.dmg” 并双击以安装 Ganache。安装成功后,将出现以下界面 −

installing ganache

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

如果您使用其他操作系统,按照说明进行安装。

Starting Ganache

现在,在应用程序文件夹中找到 Ganache 并双击图标启动 Ganache。

Ganache Desktop

Ganache 启动后,将出现以下 Ganache 界面 −

ganache desktop

点击快速启动以启动 Ganache。您将看到以下 Ganache 控制台 −

quickstart

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

现在,我们将简要了解几个与我们立即相关的重要 Ganache 界面。

Ethereum - Ganache Server Settings

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

ganache settings

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

server settings

在此处,您将能够设置 Ganache 服务器的服务器地址和端口号。暂时将其保留为其默认值。网络 ID 是 Ganache 服务器的内部区块链标识符;将其保留为其默认值。 Automine 按钮处于 ON 状态,表示将立即处理交易。如果您将其关闭,它将要求您输入秒数,然后会进行挖矿。

Account and Keys

当您单击 Accounts & Keys 菜单选项时,您将看到以下屏幕−

account and keys

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

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

Ethereum - A Quick Walkthrough

接下来,我们简单了解一下 Ganache 桌面端有哪些功能。在桌面上方,我们有多个菜单选项,其中一些与我们直接相关。菜单栏在以下屏幕截图中突出显示了 −

ganache menu options

单击 TRANSACTIONS 菜单,它会显示到目前为止执行的所有事务。你很快就会执行事务。现在,返回上方的屏幕,不时检查事务。典型的事务屏幕如下图所示 −

ganache transactions

同样,当你单击 BLOCKS 菜单时,你将看到各种已开采的区块。请考虑以下屏幕截图,了解“区块”菜单的外观 −

ganache blocks

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

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

Ethereum - MyEtherWallet

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

从以下 URL 下载 MyEtherWallet 软件 −

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

myetherwallet

Ethereum - Creating Wallet

在本章中,我们将学习如何创建以太坊钱包。要创建一个新钱包,请输入你选择的密码,然后单击“ Create New Wallet ”按钮。当你这样做时,将创建一个钱包。数字钱包本质上是生成一对公钥/私钥,你需要将它们存储在安全的地方。钱包创建后的结果如下图所示 −

create new wallet

单击 “Download Keystore File (UTC / JSON)” 按钮以保存生成的密钥。现在,单击 “I understand. Continue” 按钮。你的私钥将出现在屏幕上,如下图所示 −

download keystore

单击 “Print Paper Wallet” 按钮以保留钱包私钥的物理记录。以后解锁钱包时需要使用它。你将看到以下屏幕。不要丢弃此输出。

print paper wallet

要解锁钱包,请单击 “Save Your Address” 按钮。你将看到以下屏幕。

unlock your wallet

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

Attaching Wallet to Ganache Blockchain

您现在已经创建了一个钱包;此钱包是到 Blockchain 的客户端界面。我们将把钱包连接到您在前面的课程中已启动的 Ganache Blockchain。若要执行此操作,请单击 Network 下拉框,如下面的屏幕截图所示 −

network dropdown

转到列表底部。您将看到 “Add Custom Network / Node” 的选项。选择此项。

现在,将出现一个屏幕,要求输入 Ganache 服务器地址和它正在侦听的端口。

add custom network

输入您的 Ganache 服务器详细信息 – http://127.0.0.1 和端口: 8545 。这些将是您在 Ganache 服务器设置中设置的值。为此节点指定您选择的 name 。单击 “Save & Use Custom Node” 按钮。您将在屏幕底部看到连接的消息。此时,您的钱包已成功连接到 Ganache Blockchain。

您现在已准备好在此连接的 Blockchain 上部署 contract。

Ethereum - Deploying Contract

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

select contracts menu

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

转到 Remix IDE 界面,您先前键入的合约应在代码窗口中。如果没有,请在代码窗口中重新键入合约。点击字节码按钮,如下面屏幕截图所示 −

remix ide screen

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

remix bytecode

object 标记的值包含所需的字节码。小心复制此字节码,确保不复制带引号的内容。字节码非常长,因此请确保一直复制到最后一个字节。现在,将此字节码粘贴到 Deploy Contract 界面中,如下所示 −

desired bytecode

Gas Limit 字段将自动设置。

在 Gas 限制字段下方,你会找到用于访问钱包的选择。

accessing wallet

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

first account

你会看到用户帐户 # 1 的私钥,如下图所示。

first account private key

复制此私钥,并将其粘贴到“粘贴你的私钥”部分,如下图所示。

paste your private key

你将在屏幕底部看到 “Unlock” 按钮。解锁后,屏幕底部会显示“成功”消息。此时,你的钱包已连接到 Ganache 区块链的帐户 # 1。

现在,你可以为合约签名并部署它了。点击 “Sign Transaction” 按钮,如下图所示。

sign transaction

对交易签名会生成并显示 RawSigned 交易。点击 “Deploy Contract” 按钮在 Ganache 区块链上部署合约。记住,合约由 Ganache 区块链的帐户 # 1 用户部署。因此,帐户 # 1 用户成为合约创建者。在部署合约之前,系统会要求你确认交易,因为如果你要在公共的真实以太坊区块链上部署此合约,它可能会耗费一些真金白银。不必担心,对于正在你的本地机器上运行的当前私有区块链,无需支付真金白银。点击 Make transaction 按钮,如下图所示。

private blockchain running

检查 Ganache 控制台;你会看到帐户 # 1 中的 ETH 余额已减少,如下图所示。

ganache console

现在,点击 TRANSACTIONS 菜单,如下图所示。

ganache transactions screenshot

你会看到交易详情。

ganache transactions details

在此屏幕上,你会找到合约的发布地址。地址在上图中做了标记。你将公开分发此地址,以让其他人知道你的合约可在指定的地址上,他们可以连接到该地址,并执行合约方法(例如向你 - 合约创建者 - 发送钱)。复制此合约地址以供参考,因为在下一步中你将需要它。

Ethereum - Interacting with Deployed Contract

现在,您已准备好与已部署的合约交互。回到 MyEtherWallet 桌面,然后单击“与合约交互”标签,如下图所示 −

interact with contract

将您先前复制的合约地址粘贴到 “Contract Address” 字段中。您还需要将 “ABI / JSON Interface” 合约粘贴到上述屏幕上。

要获取 ABI ,请转到 Remix 窗口,然后单击 ABI 按钮,如下图所示。

abi button

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 的合约创建者汇款。

Ethereum - Creating Contract Users

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

单击 contracts 菜单,并选择 “Interact with Contract” 选项,就像前面一样。请注意,这个新用户将仅与已发布的合约进行交互,而不会部署自己的合约。请指定你在前面使用过的合约地址和 ABI。

interact with contract address

现在,单击 Access 按钮并调用 *send *方法。当被询问时,输入一些值,例如发送 100 ETH。提交交易。提交后,将出现以下屏幕。

interact with contract access

要将这个新客户端附加到我们的 Ganache 区块链,请转到 Ganache 控制台。单击账户 #2 的密钥图标,如下图所示 −

ganache console screenshot

你将获得账户 #2 的私钥。

ganache console private key

复制收到的密钥并在新创建的钱包中使用它,如下所示 −

newly created wallet

单击 Unlock 按钮以附加钱包。

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

wallet successfully unlocked

通过单击 “Generate Transaction” 按钮生成事务。

generate transaction

Make 交易并等待一段时间,以便其在区块链中生效。现在,执行 “getAmount” ,则现在应显示 200 的金额。

get amount

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

get balance

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

examine transaction

Ethereum - Summary

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

What is Next?

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