EOS智能合約授權限制和數據存儲

EOS智能合約授權限制和數據存儲

image

在EOS合約中,調用合約需要來自賬戶的授權,同時還要指定需要調用的動作。當然,有的合約並不是所有賬戶都可以調用的,這就需要用到授權限制。接下來我們就來看看如何限制合約的授權賬戶。

合約案例

爲了更好的演示,寫了一個下課和喫飯的智能合約小例子。這個合約有兩個動作,下課和喫飯。教師賬戶可以調用下課動作,學生賬戶可以調用喫飯動作。教師調用下課動作後,學生才能調用喫飯動作。接下來我們來看代碼:

teacher.hpp

頭文件teacher.hpp定義了兩個動作,over是class over 下課動作,eat是喫飯動作。

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>

using namespace eosio;

class teacher_stu : public eosio::contract{

    using contract::contract;
  public:
    teacher_stu( account_name self ) :
        contract( self ) {}

    void over(account_name teacher);

    void eat(account_name student);

  private:
    static uint64_t id;

    // @abi table
    struct mshare {
      uint64_t id;
      uint64_t start = 0;

      uint64_t primary_key() const { return id; }
    };

    typedef multi_index<N(mshare), mshare> mshares;

};

EOSIO_ABI( teacher_stu, (over)(eat))

teacher.cpp

teacher.cpp中主要是over和eat動作的實現。

#include "teacher.hpp"

uint64_t teacher_stu::id = 1;
uint64_t start = 0;

void teacher_stu::over(account_name teacher) {
  require_auth(teacher);
  print("teache:Class over!");

  mshares mshare_table(_self, _self);

  start = 1;//存儲動作調用狀態
  mshare_table.emplace( teacher, [&]( auto& mshare ) {
    mshare.id = id;
    mshare.start = start;
  });
}

void teacher_stu::eat(account_name student) {
  require_auth(student);
  mshares mshare_table(_self, _self);
  auto it = mshare_table.find( id );
  if (it->start == 1) {
    print("student:Class over, go to eat!");
    mshare_table.erase( it );
  }
  else
    print("teacher:Class time, you can't eat");
}

仔細觀察這段代碼就會發現,over和eat動作中都有個”require_auth()”語句。在over動作中,”requir_auth(teacher)”的作用是限制只有”teacher”賬戶纔可以調用over動作。在eat動作中則是限制只有”student”賬戶纔可調用eat動作。

合約數據存儲

此合約設計爲下課後纔可以喫飯,所以當教師賬戶調用合約的over動作後,需要存儲一個合約調用狀態值。EOS合約的數據存儲需要用數據庫,把數據存到一張表中,這是令人很難受的。

teacher.hpp

在teacher.hpp中創建一個結構體。下段代碼中的”//@abi table”註釋非常重要,必須要寫的,如果不寫數據將無法存儲。

    static uint64_t id;

    // @abi table
    struct mshare {
      uint64_t id;
      uint64_t start = 0;

      uint64_t primary_key() const { return id; }
    };

    typedef multi_index<N(mshare), mshare> mshares;

DAWN 3.0 使用eosio::multi_index作爲容器,我們可以使用emplace來插入數據,使用modify來修改數據,使用erase刪除數據。

teacher.cpp

  mshares mshare_table(_self, _self);

  start = 1;
  mshare_table.emplace( teacher, [&]( auto& mshare ) {
    mshare.id = id;
    mshare.start = start;
  });

在over動作中創建數據,學生調用eat動作後再修改或刪除數據即可

  mshares mshare_table(_self, _self);
  auto it = mshare_table.find( id );
  if (it->start == 1) {
    print("student:Class over, go to eat!");
    mshare_table.erase( it );
  }

合約調用效果展示

  • 授權限制
$ cleos push action class over '{"teacher":"teacher","student":"student"}' -p student
Error 3030001: missing required authority
Ensure that you have the related authority inside your transaction!;
If you are currently using 'cleos push action' command, try to add the relevant authority using -p option.
Error Details:
missing authority of teacher
  • 學生沒下課就喫飯
$ cleos push action class eat '{"teacher":"teacher","student":"student"}' -p student
executed transaction: 02918b223230cb9ea1fd383e0499ea22d22ced8f2108db3233bdfd51c06f3b37  232 bytes  102400 cycles
#         class <= class::eat                   {"student":"student"}
>> teacher:Class time, you can't eat
  • 正常下課喫飯
$ cleos push action class over '{"teacher":"teacher","student":"student"}' -p teacher
executed transaction: a96520fa28c8412e0998080126734337507811638ecf6b939e904818a4892e35  232 bytes  103424 cycles
#         class <= class::over                  {"teacher":"teacher"}
>> teache:Class over!
$ cleos push action class eat '{"teacher":"teacher","student":"student"}' -p student
executed transaction: 2955a693b626c539d20da9d4f5d41a6b53bb8ca2b2651b63cf4a67012fb3dd7e  232 bytes  103424 cycles
#         class <= class::eat                   {"student":"student"}
>> student:Class over, go to eat!
  • 查看錶中數據
$ cleos get table class class mshare
{
  "rows": [{
      "id": 1,
      "start": 1
    }
  ],
  "more": false
}

整個合約寫下來調通也是費了我很多腦細胞,數據存儲也比較坑爹啊。現在把我的一點經驗分享出來,希望大家在學習EOS的路上少踩一些坑。

知識星球二維碼380.png
歡迎添加微信(id:pdj107)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章