以太坊宠物店搭建教程

设置开发环境

在我们开始之前,有一些技术要求。请安装以下内容:

一旦我们安装了这些,我们只需要一个命令来安装Truffle:

npm install -g truffle

要验证Truffle是否已正确安装,请truffle version在终端上键入。如果发现错误,请确保将npm模块添加到路径中。

我们还将使用Ganache,一个用于以太坊开发的个人区块链,您可以使用它来部署合同,开发应用程序和运行测试。您可以通过导航到http://truffleframework.com/ganache并单击“下载”按钮来下载Ganache 。

 

Truffle在当前目录中初始化,因此首先在您选择的开发文件夹中创建一个目录,然后在其中移动。

mkdir pet-shop-tutorial 

cd pet-shop-tutor

mkdir pet-shop-tutorial 
cd pet-shop-tutorial

al

truffle unbox命令解压缩此松露盒。

truffle unbox命令解压缩此松露盒。
truffle unbox pet-shop

truffle unbox pet-shop

目录结构

默认的Truffle目录结构包含以下内容:

  • contracts/:包含我们的智能合约的Solidity源文件。这里有一个重要的合同Migrations.sol,我们将在后面讨论。
  • migrations/:Truffle使用迁移系统来处理智能合约部署。迁移是一种额外的特殊智能合约,可以跟踪变化。
  • test/:包含我们的智能合约的JavaScript和Solidity测试
  • truffle.js:松露配置文件

pet-shop松露盒有额外的文件和文件夹,但我们不会担心这些,只是还没有。

 

写出智能合约

我们将通过编写充当后端逻辑和存储的智能合约来启动我们的dapp。

1创建一个名为一个新的文件Adoption.solcontracts/目录中。

2将以下内容添加到文件中:

pragma solidity ^0.4.17; 

contract Adoption {

 }

需要注意的事项:

  • 合同顶部注明了所需的最低Solidity版本:pragma solidity ^0.4.17;。该pragma命令表示“ 只有编译器关心的附加信息 ”,而插入符号(^)表示“ 指示的版本或更高 ”。
  • 与JavaScript或PHP一样,语句以分号结束。

变量设置

Solidity是一种静态类型语言,意味着必须定义字符串,整数和数组等数据类型。Solidity有一种称为地址的独特类型。地址是以太坊地址,存储为20字节值。以太坊区块链上的每个账户和智能合约都有一个地址,可以通过该地址发送和接收以太网。

之后的下一行添加以下变量contract Adoption {

address[16] public adopters;

  •  

我们定义了一个变量:adopters。这是以太坊地址的数组。数组包含一种类型,可以具有固定或可变长度。在这种情况下,类型是address和长度是16

你也会注意到adopters是公开的。公共变量具有自动getter方法,但在数组的情况下,需要一个键,并且只返回一个值。稍后,我们将编写一个函数来返回整个数组,以便在我们的UI中使用。

 

你的第一个功能:采用宠物

1在我们上面设置的变量声明之后,将以下函数添加到智能合约中。

// Adopting a pet 

function adopt(uint petId) public returns (uint)  { 

require(petId >= 0 && petId <= 15); 

adopters[petId] = msg.sender;  

return petId; 

}

需要注意的事项:

 

在Solidity中,必须指定函数参数和输出的类型。在这种情况下,我们将接受一个petId(整数)并返回一个整数。

 

我们正在检查以确保petId在我们的adopters阵列范围内。Solidity中的数组从0开始索引,因此ID值必须介于0到15之间。我们使用该require()语句确保ID在范围内。

 

如果ID在范围内,我们然后添加调用我们的adopters数组的地址。调用此函数的人或智能合约的地址表示为msg.sender

 

最后,我们将petId提供的内容作为确认返回。

 

 

 

 

您的第二个功能:检索采用者

如上所述,数组getter仅从给定键返回单个值。我们的UI需要更新所有宠物采用状态,但进行16次API调用并不理想。所以我们下一步是编写一个函数来返回整个数组。

1我们上面添加的getAdopters()函数之后,将以下函数添加到智能合约中adopt()

// Retrieving the adopters 

function getAdopters() public view returns (address[16]) {

 return adopters;

 }

既然adopters已经宣布,我们可以简单地归还它。请务必将返回类型(在本例中为类型adopters)指定为address[16]

 

编译和迁移智能合约

现在我们已经编写了智能合约,接下来的步骤是编译和迁移它。

Truffle有一个内置的开发者控制台,我们称之为Truffle Develop,它生成一个开发区块链,我们可以使用它来测试部署合同。它还能够直接从控制台运行Truffle命令。在本教程中,我们将使用Truffle Develop来执行我们合同中的大部分操作。

Solidity是一种编译语言,这意味着我们需要将我们的Solidity编译为字节码,以便执行以太坊虚拟机(EVM)。可以把它想象成将人类可读的Solidity翻译成EVM理解的东西。

1在终端中,确保您位于包含dapp的目录的根目录中并键入:

truffle compile
您应该看到类似于以下内容的输出:
Compiling ./contracts/Migrations.sol... 
Compiling ./contracts/Adoption.sol... 
Writing artifacts to ./build/contracts

移民

现在我们已经成功编译了合同,是时候将它们迁移到区块链了!

迁移是一种部署脚本,用于更改应用程序合同的状态,将其从一个状态移动到另一个状态。对于第一次迁移,您可能只是部署新代码,但随着时间的推移,其他迁移可能会移动数据或用新代码替换合同。

您将在migrations/目录中看到一个JavaScript文件:1_initial_migration.js。这会处理部署Migrations.sol合同以观察后续智能合约迁移,并确保我们不会在未来双重迁移未更改的合同。

现在我们准备创建自己的迁移脚本了。

创建一个名为一个新的文件2_deploy_contracts.jsmigrations/目录中。

将以下内容添加到2_deploy_contracts.js文件中:

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

在我们将合同迁移到区块链之前,我们需要运行区块链。对于本教程,我们将使用Ganache,一个用于以太坊开发的个人区块链,您可以使用它来部署合同,开发应用程序和运行测试。如果您还没有,请下载Ganache并双击该图标以启动该应用程序。这将生成在端口7545上本地运行的区块链。

回到我们的终端,将合同迁移到区块链。

truffle migrate

truffle migrate
您应该看到类似于以下内容的输出:
Using network 'development'. 
Running migration: 1_initial_migration.js Deploying Migrations... ... 0xcc1a5aea7c0a8257ba3ae366b83af2d257d73a5772e84393b0576065bf24aedf Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0 Saving successful migration to network... ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956 

您可以按顺序查看正在执行的迁移,然后是每个已部署合同的区块链地址。

在Ganache中,请注意区块链的状态已发生变化。现在,区块链显示了当前的块,0现在是4。此外,虽然第一个帐户最初有100个以太,但由于迁移的交易成本,它现在更低。我们稍后会详细讨论交易成本。

 

迁移后的Ganache

您现在已经编写了第一份智能合约,并将其部署到本地运行的区块链中。现在是时候与我们的智能合约进行互动,以确保它能够满足我们的需求。

测试智能合约

Truffle在智能合约测试方面非常灵活,因为测试可以用JavaScript或Solidity编写。在本教程中,我们将在Solidity中编写测试。

创建一个名为一个新的文件TestAdoption.soltest/目录中。

将以下内容添加到TestAdoption.sol文件中:

pragma solidity ^0.4.17; import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import "../contracts/Adoption.sol"; contract TestAdoption { Adoption adoption = Adoption(DeployedAddresses.Adoption()); }

我们用3个进口开始合同:

  • Assert.sol:给我们在测试中使用的各种断言。在测试中,断言检查诸如平等,不平等或空虚之类的事情,以便从我们的测试中返回通过/失败以下是Truffle附带的断言的完整列表
  • DeployedAddresses.sol:运行测试时,Truffle会将正在测试的合同的新实例部署到区块链。这个智能合约获得已部署合同的地址。
  • Adoption.sol:我们想要测试的智能合约。
  • 注意:前两个导入是指全局Truffle文件,而不是truffle目录。您不应该在truffle目录中看到test/目录。

    然后我们定义一个合约范围的变量,其中包含要测试的DeployedAddresses智能合约,调用智能合约来获取其地址。

    测试adopt()函数

    要测试该adopt()功能,请记住,一旦成功,它将返回给定的petId。通过比较adopt()我们传入的ID 的返回值,我们可以确保返回一个ID并且它是正确的。

    TestAdoption.sol声明后,在智能合约中添加以下功能Adoption

     

    // Testing the adopt() function function testUserCanAdoptPet() public { uint returnedId = adoption.adopt(8); uint expected = 8; Assert.equal(returnedId, expected, "Adoption of pet ID 8 should be recorded."); }

     

    需要注意的事项:

  • 我们将之前声明的智能合约称为ID 8
  • 然后我们也声明了预期值8
  • 最后,我们传递实际值,期望值和失败消息(如果测试未通过则将其打印到控制台)Assert.equal()

    测试单个宠物主人的检索

    记住上面公共变量有自动getter方法,我们可以检索上面的采用测试存储的地址。存储的数据将在我们的测试期间持续存在,因此我们对8上面的pet的采用可以通过其他测试来检索。

    在以前添加的函数下面添加此函数TestAdoption.sol

    // Testing retrieval of a single pet's owner function testGetAdopterAddressByPetId() public { // Expected owner is this contract address expected = this; address adopter = adoption.adopters(8); Assert.equal(adopter, expected, "Owner of pet ID 8 should be recorded."); }

    由于TestAdoption合约将发送交易,我们将预期值设置为此是一个获得当前合约地址的合约范围变量。从那里我们就像上面所说的那样断言平等。

    测试所有宠物主人的检索

    由于数组只能在给定单个键的情况下返回单个值,因此我们为整个数组创建自己的getter。

    在以前添加的函数下面添加此函数TestAdoption.sol

    // Testing retrieval of all pet owners function testGetAdopterAddressByPetIdInArray() public {

     // Expected owner is this contract 

    address expected = this; 

    // Store adopters in memory rather than contract's storage 

    address[16] memory adopters = adoption.getAdopters(); Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded."); 

    }

    请注意内存属性adopters。memory属性告诉Solidity将值临时存储在内存中,而不是将其保存到合同的存储中。由于adopters是一个数组,我们从第一次采用测试我们知道采用pet 8,我们将测试合同地址与8数组中的位置进行比较。

  •  

     

    运行测试

    回到终端,运行测试

    运行测试
    回到终端,运行测试:
    truffle test
    如果所有测试都通过,您将看到与此类似的控制台输出:
    Using network 'development'. Compiling ./contracts/Adoption.sol... Compiling ./test/TestAdoption.sol... Compiling truffle/Assert.sol... Compiling truffle/DeployedAddresses.sol... TestAdoption ✓ testUserCanAdoptPet (91ms) ✓ testGetAdopterAddressByPetId (70ms) ✓ testGetAdopterAddressByPetIdInArray (89ms) 3 passing (670ms)

     

创建用户界面以与智能合约进行交互<下一章>

猜你喜欢

转载自blog.csdn.net/AVGworkld/article/details/81708522