编写有数据存储的智能合约

如何存储数据

EOS通过table的概念来存储智能合约运行中所需的数据。

数据储存在区块链上。

部署到区块链后,如果有数据存储,修改wasm编码后,会产生原始储存数据不可读的问题

我们看下官方例子tic_tac_toe

其中

hpp+cpp文件,主要实现了数据结构定义、业务逻辑、权限控制、数据存储

abi文件,定义了合约的types、structs、actions、tables和ricardian_clauses

hpp文件

#include <eosiolib/eosio.hpp>

/**
 *  圆叉旗:
 *  在一个3*3的棋盘里,一人用x(先手host),一人用o(后手challenger),先连成三点一线的获胜。
 *  棋盘如下所示:
 *
 *  (0,0)坐标表示左上角
 *  (2,2)坐标表示右下角
 *
 *                 (0,2)
 *  (0,0) -  |  o  |  x            - = 空
 *        -  |  x  |  -            x = 先手
 *  (2,0) x  |  o  |  o            o = 后手
 * 
 *  为了让存储变得简单,在本例中我们用一个9个长度的数组,表示上面3*3的矩阵
 *  比如,上面的棋盘存储后就是,[0, 2, 1, 0, 1, 0, 1, 2, 2]
 *  
 *  另外,为了让智能合约变的简单,我们对每两对用户A和B,只允许开启两个旗局,一个是A为先手,一个是B为先手
 *  数据存储在先手账户中,并用后手作为key
 * 
 *  create创建游戏
 *  restart重开游戏
 *  close关闭游戏
 *  move下棋,先手后手交替进行
 */

namespace neo_tictactoe {
   //游戏开启账户,先手
   static const account_name games_account = N(games);
   //合约账户
   static const account_name code_account = N(tic.tac.toe);

   /**
    * @brief 用于保存棋盘信息的结构
    */
   static const uint32_t board_len = 9;
   struct game {
      game() { initialize_board(); }

      game(account_name challenger, account_name host):challenger(challenger), host(host), turn(host) {
         initialize_board();
      }

      account_name     challenger; //后手
      account_name     host; //先手
      account_name     turn; // 谁的回合
      account_name     winner = N(none); // 谁赢了 none/ draw/ host/ challenger
      uint8_t          board[board_len]; // 棋盘信息

      // 初始化游戏
      void initialize_board() {
         for (uint8_t i = 0; i < board_len ; i++) {
            board[i] = 0;
         }
      }

      // 重置游戏
      void reset_game() {
         initialize_board();
         turn = host;
         winner = N(none);
      }

      auto primary_key() const { return challenger; }

      EOSLIB_SERIALIZE( game, (challenger)(host)(turn)(winner)(board) )
   };

   /**
    * @brief 新建游戏
    */
   struct create {
      account_name   challenger;
      account_name   host;

      EOSLIB_SERIALIZE( create, (challenger)(host) )
   };

   /**
    * @brief 重置游戏
    */
   struct restart {
      account_name   challenger;
      account_name   host;
      account_name   by; // the account who wants to restart the game

      EOSLIB_SERIALIZE( restart, (challenger)(host)(by) )
   };

   /**
    * @brief 关闭游戏
    */
   struct close {
      account_name   challenger;
      account_name   host;

      EOSLIB_SERIALIZE( close, (challenger)(host) )
   };

   /**
    * @brief 下棋坐标
    */
   struct movement {
      uint32_t    row;
      uint32_t    column;

      EOSLIB_SERIALIZE( movement, (row)(column) )
   };

   /**
    * @brief 下棋
    */
   struct move {
      account_name   challenger;
      account_name   host;
      account_name   by; // the account who wants to make the move
      movement       mvt;

      EOSLIB_SERIALIZE( move, (challenger)(host)(by)(mvt) )
   };

   /**
    * @brief 新建表,保存账号和游戏信息
    */
   typedef eosio::multi_index< games_account, game> games;
}

cpp文件

abi文件

编译并加载合约

执行合约

查看数据

最后更新于