汉中搬家公司费用联盟

[区块链研究实验室]终极端到端的EOS DAPP开发教程 - 第1部分

楼主:区块链研究实验室 时间:2022-05-13 14:39:14

在之前的教程中,我们学习了如何设置开发环境来构建EOS。我们启动了本地测试网络,部署了一个示例EOS智能合约并与之交互。您可以在我们的EOS区块链开发系列的第一个教程中找到所有内容。

我们要做的是一个小型的dApp,它会有玩家。每个玩家都可以玩游戏,并且可以从中获得硬币。随着硬币,他可以去市场购买物品,这会给他力量,能力,健康和/或水平。当然,Oasis合同是我们的主要合同工具。

我们需要的工具:

为了能够开发EOS dApps,您需要懂得使用C / C ++技术开发,因为这是用于EOS Smart Contracts的编程语言

  • C / C ++

  • IDE

  • 一个工作的本地测试网络节点


搭建环境

在编写我们的第一份合同之前,我们需要在开发过程中设置一些我们需要的参数。

步骤1 - 启动节点

# 默认情况下将合同的输出到控制台中:

# --contracts-console

nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --contracts-console


步骤2 - 创建钱包

它将存储我们在签署交易时使用的密钥

# 1. 钱包命名为"oasis"

cleos wallet create -n oasis

# 2. 生产2对密钥(使用该命令2次)

cleos create key

# 3.将生成的私钥导入钱包(您需要在最后指定钱包)

# {private_key_1} - 这是拥有者私钥

# {private_key_2} - 这是活动密钥

cleos wallet import {private_key_1} -n oasis
cleos wallet import {private_key_2} -n oasis

# 4. 将“eosio”帐户的私钥添加到您的钱包中

#注意:使用最新版本的EOSIO,私钥会自动添加到您的钱包中

cleos wallet import5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 -n oasis


步骤3 - 创建账号

EOS.IO智能合约在账户上运行。 因此,账户需要将交易转移或以其他方式推送至区块链。 让我们将我们的账户命名为“anorak”。


# 创建账号使用的公钥


cleos create account eosio anorak {public_OwnerKey} {public_ActiveKey}


#“eosio”是将创建新账户的账户的名称


#“anorak”是新账户的名称


项目'Oasis'

现在是开始开发我们的dApp的时候了!创建一个名为Oasis的项目文件夹,里面添加两个主要的子文件夹 - 合同和测试,再建四个子文件夹:玩家,游戏,市场和绿洲。

玩家智能合同

玩家将成为我们的第一个EOS智能合约。每个玩家将拥有用户名,等级,健康点,能量点数,余额,库存(全部物品)和能力。他将能够从市场购买物品,并将其添加到他的库存,生命值,能量点和/或能力中。为了获得硬币,他需要与Oasis的其他玩家一起玩游戏。

在Players文件夹中创建Players.hpp&Players.cpp文件

1. Player.hpp是包含由.cpp文件引用的变量,常量和函数的头文件。

2. Player.cpp文件是包含合同功能的源文件。

我们来深入看一下EOS合约的基本结构

Players.hpp

 #include <eosiolib/eosio.hpp>

#include <eosiolib/print.hpp>

#include <string>


注意:我们现在只需要在Players.hpp中添加包含,目前不会在其他合约中使用。

Players.cpp

在合同开始时,我们设置了我们要使用的所有包含。 在我们的例子中,Players.hpp已经导入它们,所以在我们的合同实现中只包含头文件就足够了。 将所有内容都包装在名称空间中是一种很好的做法,因为它与Oasis一起显示在这里。

如果你熟悉C ++,你可能知道为什么在类实现前我们有两个using子句。 对于其他人 - 当我们想从C ++的eosio命名空间中调用一个动作时,我们必须像这样调用它:eosio :: some_action(),以避免在动作名称前添加eosio :: everytime 在开始时使用名称空间eosio添加。

 #include "Players.hpp"

namespace Oasis {
  using namespace eosio;
  using std::string;

  class Players : public contract {
      using contract::contract;

      public:
          Players(account_name self):contract(self) {}

          //@abi action
          void add(const account_name account, string& username, uint64_t level) {

          }

          //@abi action
          void update(const account_name account) {

          }

          //@abi action
          void getplayer(const account_name account) {

          }

      private:

          //@abi table player i64
          struct player {
              uint64_t account_name;
              string username;
              uint64_t level;
              uint64_t health_points = 1000;
              uint64_t energy_points = 1000;

              uint64_t primary_key() const { return account_name; }

              EOSLIB_SERIALIZE(player, (account_name)(username)(level)(health_points)(energy_points))
          };

          typedef multi_index playerIndex;
  };

  EOSIO_ABI(Players, (add)(update)(getplayer))
}


Players类继承“合约”智能合约并使用其构造函数(使用contract :: contract)

在开发EOS dApp时,您应该了解的一件重要事情是,智能合约以操作和共享内存数据库访问的形式相互通信。一个合同可以读取另一个合同数据库的状态,只要它包含在具有异步的事务的读取范围内。这可以通过使用两种通信模式之一来实现 - 内联或延迟。您可以将它们视为同步和异步;

EOS.IO文档:

内联 - 内联保证与当前交易一起执行或展开;无论成功或失败,都不会通知任何通知。内联与原始交易具有相同的范围和权限

延期 - 延期将在稍后由发行人自行决定;可以传达通信结果或者可以简单地超时。延期可以延伸到不同的范围,并承担发送它们的合同的权力。

在我们合同的类体中,有两种类型的访问修饰符 - public和private。在公共部分是构造函数和所有动作。一个动作表示智能合约中的单个操作。在我们的合同中,我们添加,更新和getplayer。我们稍后会看看他们。同时,您应该已经注意到,在每次操作之前,我们都有“// @ abi action”。它是eosiocpp脚本的指示标志,它将为我们的智能合约生成.abi文件。

在隐私部分,我们保留的所有内容不希望外部玩家合同访问。这里我们正在初始化multi_index。这是什么,为什么我们需要它?

 //@abi table player i64
struct player {
uint64_t account_name;
string username;
uint64_t level;
uint64_t health_points = 1000;
uint64_t energy_points = 1000;

uint64_t primary_key() const { return username; }

EOSLIB_SERIALIZE(player, (account_name)(username)(level)(health_points)(energy_points))
};

typedef multi_index playerIndex;

正如我们所说的,一个行动代表了智能合约中的单一操作。每个行动都在其自己的环境中运作,称为行动环境。上下文提供了执行该操作所需的几件事情。其中一件事是行动的工作记忆。这是行动维持其工作状态的地方。在处理动作之前,EOSIO为动作建立一个干净的工作记忆。在新操作的上下文中执行另一个操作时可能已设置的变量不可用。在行动中传递状态的唯一方法是将其持久存储并从EOSIO数据库中检索。

这可以通过多索引来实现,它允许我们读取和修改EOSIO数据库中的持久状态。

在我们的合同中,我们已经为多索引表声明了一个名为player的对象模板。需要注意的是,当我们为表格创建模板时,我们还需要添加primary_key。我们使用account_name,因为我们希望每个账户有一个玩家

我们还为eosiocpp脚本提供了一个指示标志 - “// @ abi桌面播放器i64”。我们说我们表的名字是玩家,而使用的索引类型是i64。

一旦对象准备就绪,我们需要使用以下模板键入我们的多索引:

 

// typedef multi_index multi_index_name;

typedef multi_index playerIndex;


您可能想知道EOSLIB_SERIALIZE和EOSIO_ABI是什么。


EOSLIB_SERIALIZE(player, (account_name)(username)(level)(health_points)(energy_points))


EOSIO_ABI(Players, (add)(update)(health)(energy)(getplayer))

注:代码部分可滑动

这些是C ++宏。 EOSIO_ABI封装了apply方法的逻辑。 apply为动作处理程序,它监听所有传入的动作并根据函数中的规范作出反应。 宏的结构非常简单。 第一个参数是类型(当前类的名称),下一个参数是下面示例中列出的所有操作


// EOSIO_ABI(class_name, (action_1)(action_2)(action_3)...(action_n))


EOSLIB_SERIALIZE宏提供序列化和反序列化方法,以便可以在合约和nodeos系统之间来回传递操作。


// EOSLIB_SERIALIZE(struct_name, (property_1)(property_2)(property_3)...(property_n))







朋友 图片 表情 草稿箱
请遵守社区公约言论规则,不得违反国家法律法规