• eos 智能合约开发体验


    eos编译安装

    ERROR: Could not find a package configuration file provided by "LLVM" (requested version 4.0) with any of the following names
    需要执行以下命令(检查一下你有没有这个目录,没有的话搜索一下)
    export LLVM_DIR=/usr/local/Cellar/llvm@4/4.0.1/lib/cmake
    
    cleos/localize.hpp:7:10: fatal error: 'libintl.h' file not found
    
    brew reinstall gettext
    brew unlink gettext && brew link gettext --force
    
    eos/build/programs/nodeos/config.hpp:13:33: error: invalid suffix 'x' on integer constant
    
    重新下载tag dawn4版本进行编译通过
    
    EOS.IO has been successfully built. 0:0:10
    
        To verify your installation run the following commands:
    
        /usr/local/bin/mongod -f /usr/local/etc/mongod.conf &
        cd /opt/eos/build; make test
    
        For more information:
        EOS.IO website: https://eos.io
        EOS.IO Telegram channel @ https://t.me/EOSProject
        EOS.IO resources: https://eos.io/resources/
        EOS.IO wiki: https://github.com/EOSIO/eos/wiki
    
    cd build
    sudo make install
    

    eos 特性

    数据存储

    eos数据库使用指南 参照 Boost Multi-Index Containers容器进行理解
    【系列】EOS智能合约开发31 - 使用数据库的智能合约实例
    【系列】EOS智能合约开发32 - 详解Multi-Index(上)
    【系列】EOS智能合约开发33 - 详解Multi-Index(下)
    【系列】EOS智能合约开发34 - EOS开发命令阶段性总结
    系列文章

    eos投票智能合约开发

    创建合约eosiocpp -n ballot

    // ballot.hpp
    
    /**
     *  @file
     *  @copyright defined in eos/LICENSE.txt
     */
    #include <eosiolib/eosio.hpp>
    #include <string>
    
    using namespace eosio;
    using std::string;
    
    class Ballot : public eosio::contract
    {
    public:
      using contract::contract;
      Ballot(account_name self) : contract(self) {}
    
      // 投票发起人接口
      void addposposal(string posposal_name);                      // 初始化投票提案
      void addvoter(account_name voter_name, uint64_t weight = 1); // 初始化投票人
      // 普通选民接口
      void delegate(account_name voter, account_name delegate_to); // 委托投票(跟随投票)
      void vote(account_name voter, string proposal);              // 投票给某个提议
      void winproposal();                                          // 返回投票数最多的提议
      void allproposal();                                          // 返回全部提案投票状态
    
    private:
      // 定义投票人
      struct voter
      {
        account_name account;      // 投票人
        uint64_t weight;           // 权重
        bool voted;                // 如果值为true,代表这个投票人已经投过票
        uint64_t delegate_account; // 委托投票人地址
        string pos_name;           // 投票提案名
    
        uint64_t primary_key() const { return account; }
    
        EOSLIB_SERIALIZE(voter, (account)(weight)(voted)(delegate_account)(pos_name));
      };
      // 提案的数据结构
      struct posposal
      {
        string name;        // 提案的名称
        uint64_t voteCount; // 提议接受的投票数
    
        uint64_t primary_key() const { return eosio::string_to_name(name.c_str()); }
    
        EOSLIB_SERIALIZE(posposal, (name)(voteCount));
      };
    
      typedef eosio::multi_index<N(voter), voter> voter_index;
      typedef eosio::multi_index<N(posposal), posposal> posposal_index;
    };
    
    // ballot.cpp
    
    #include <eosiolib/eosio.hpp>
    #include "ballot.hpp"
    
    using namespace eosio;
    
    // 投票发起人接口
    void Ballot::addposposal(string posposal_name) // 初始化投票提案
    {
      require_auth(_self);
    
      posposal_index posposals(_self, _self);
      auto it = posposals.find(eosio::string_to_name(posposal_name.c_str()));
      eosio_assert(it == posposals.end(), "posposal exist");
    
      posposals.emplace(_self, [&](auto &a) {
        a.name = posposal_name;
        a.voteCount = 0;
      });
    }
    void Ballot::addvoter(account_name voter_name, uint64_t weight /* =1 */) // 初始化投票人
    {
      require_auth(_self);
      eosio_assert(weight > 0, "must positive weight");
    
      voter_index voters(_self, _self);
      auto it = voters.find(voter_name);
    
      eosio_assert(it == voters.end(), "voter exist");
      voters.emplace(_self, [&](auto &a) {
        a.account = voter_name;
        a.weight = weight;
        a.voted = false;
        a.delegate_account = 0;
        a.pos_name = "";
      });
    }
    // 普通选民接口
    void Ballot::delegate(account_name voter, account_name delegate_to) // 委托投票(跟随投票)
    {
      require_auth(voter);
    
      voter_index voters(_self, _self);
      auto vit = voters.find(voter);
      eosio_assert(vit->voted == false, "is voted");
      eosio_assert(vit != voters.end(), "voter not exist");
      auto it = voters.find(delegate_to);
      eosio_assert(it != voters.end(), "delegate_to not exist");
    
      while (it != voters.end() && it->delegate_account != 0 && it->delegate_account != voter)
        it = voters.find(it->delegate_account);
    
      eosio_assert(it != voters.end(), "delegate obj not exist");
      eosio_assert(it->account != voter, "not delegate self");
    
      if (it->voted)
      {
        vote(voter, it->pos_name);
      }
      else
      {
        voters.modify(it, _self, [&](auto &a) {
          a.weight += vit->weight;
        });
        voters.modify(vit, _self, [&](auto &a) {
          a.voted = true;
        });
      }
    }
    void Ballot::vote(account_name voter, string proposal) // 投票给某个提议
    {
      require_auth(voter);
      posposal_index posposals(_self, _self);
      auto it = posposals.find(eosio::string_to_name(proposal.c_str()));
      eosio_assert(it != posposals.end(), "posposal not exist");
    
      voter_index voters(_self, _self);
      auto vit = voters.find(voter);
      eosio_assert(vit->voted == false, "is voted");
      eosio_assert(vit != voters.end(), "voter not exist");
    
      voters.modify(vit, _self, [&](auto &a) {
        a.voted = true;
        a.pos_name = proposal;
      });
    
      posposals.modify(it, _self, [&](auto &a) {
        a.voteCount += vit->weight;
      });
    }
    void Ballot::winproposal() // 返回投票数最多的提议
    {
      posposal_index posposals(_self, _self);
      auto win = posposal();
      uint64_t max = 0;
      for (auto it : posposals)
      {
        if (it.voteCount > max)
        {
          max = it.voteCount;
          win = it;
        }
      }
      if (max > 0)
      {
        eosio::print("win posposal is: ", win.name.c_str(), "vote count", win.voteCount, "
    ");
      }
      else
      {
        eosio::print("not vote", "
    ");
      }
    }
    void Ballot::allproposal() // 返回全部提案投票状态
    {
      posposal_index posposals(_self, _self);
      uint64_t idx = 0;
      for (auto it : posposals)
      {
        eosio::print(" posposal ", idx, ":", it.name.c_str(), "vote count", it.voteCount, "
    ");
      }
    }
    
    EOSIO_ABI(Ballot, (addposposal)(addvoter)(delegate)(vote)(winproposal)(allproposal))
    
    

    eosiocpp -o ballot.wast ballot.cpp
    eosiocpp -g ballot.abi ballot.cpp

    eos投票智能合约部署测试

    1.创建
    2.生成公私钥

    cleos create key
    Private key: 5JMiZ1VyByUsHuRR9homayUFKM6buMLzyBeJ6p5ToMEn5N27p1B
    Public key: EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    

    3.创建钱包

    cleos wallet create -n gxk
    Creating wallet: gxk
    Save password to use in the future to unlock this wallet.
    Without password imported keys will not be retrievable.
    "PW5HsWtVxz3kBQKeTGvNL448p2cD1P9ghQAM6MYjWysfsLZApx3n2"
    

    4.创建多个账户

    cleos create account eosio acc1 EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    
    cleos create account eosio acc2 EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    
    cleos create account eosio acc3 EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    
    cleos create account eosio acc4 EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    
    cleos create account eosio acc5 EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    
    cleos create account eosio accballot EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak  EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    

    5.查看账户

    # cleos get accounts EOS8PPs1yQ4bkBDMAzGGNigPWmKLNBV6FULFq8TmcNFP9Pv5Jgvak
    {
      "account_names": [
        "acc1",
        "acc2",
        "acc3",
        "acc4",
        "acc5",
        "accballot"
      ]
    }
    

    6.部署智能合约

    # cleos set contract accballot   /opt/eos/contracts/ballot
    Reading WAST/WASM from /opt/eos/contracts/ballot/ballot.wast...
    Using already assembled WASM...
    Publishing contract...
    executed transaction: c01fc59198803da7206a94751d6913500b1a06d2a36fb643bc136e0e94344898  7872 bytes  5781 us
    #         eosio <= eosio::setcode               {"account":"accballot","vmtype":0,"vmversion":0,"code":"0061736d01000000017a1460027f7f0060037f7e7e00...
    #         eosio <= eosio::setabi                {"account":"accballot","abi":{"types":[],"structs":[{"name":"addposposal","base":"","fields":[{"name...
    warning: transaction executed locally, but may not be confirmed by the network yet
    
    #cleos get code accballot
    code hash: adaa3df4b876295a8eb185edf9668f110d83d8af03dce0ccdc6ae9503967fd00
    

    7.调用合约,创建投票

    #cleos push action accballot addposposal '["baidu"]' -p accballot
    executed transaction: f0b54c41b0418d7785dd37f0db30099e50b6a6426ed10b3741ff22d7c143285a  104 bytes  11014 us   accballot <= accballot::addposposal       {"posposal_name":"baidu"}
    warning: transaction executed locally, but may not be confirmed by the network yet
    
    #cleos push action accballot addposposal '["alibaba"]' -p accballot
    #cleos push action accballot addposposal '["163"]' -p accballot
    #cleos push action accballot addposposal '["360"]' -p accballot
    #cleos push action accballot addposposal '["qq"]' -p accballot
    #cleos push action accballot addposposal '["yy"]' -p accballot
    
    // 返回投票状态
    #cleos push action accballot allproposal '[]' -p acc1
    executed transaction: 672fc91ea96bd9509850162dd1866eb4a625afd844e488883129df648ea26202  96 bytes  1063 us
          accballot <= accballot::allproposal       {}
    >>  posposal 0:163vote count0
    
    
    // 查询投票结果:当前未进行过投票
    #cleos push action accballot winproposal '[]' -p acc1
    executed transaction: e37d6ea6577055bfe33a053c29cf369b7c2702550078af99627f1fea9fa92620  96 bytes  1086 us
          accballot <= accballot::winproposal       {}
    >> not vote
    
    
    

    添加投票人

    #cleos push action accballot addvoter '["acc1",1]' -p accballot
    #cleos push action accballot addvoter '["acc2",1]' -p accballot
    #cleos push action accballot addvoter '["acc3",1]' -p accballot
    #cleos push action accballot addvoter '["acc4",1]' -p accballot
    #cleos push action accballot addvoter '["acc5",1]' -p accballot
    executed transaction: 954165ee5be714b7ef31a3183cbda179b69d8c2ea159c4447ee2ed0c4283c2d8  112 bytes  468 us
          accballot <= accballot::addvoter          {"voter_name":"acc5","weight":1}
    warning: transaction executed locally, but may not be confirmed by the network yet
    

    8.进行投票操作

    #cleos push action accballot vote '["acc1","qq"]' -p acc1
    #cleos push action accballot vote '["acc2","qq"]' -p acc2
    #cleos push action accballot vote '["acc3","163"]' -p acc3
    #cleos push action accballot vote '["acc4","qq"]' -p acc4
    #cleos push action accballot delegate '["acc5","acc3"]' -p acc5
    

    9.查看票数最多的获胜结果

    cleos push action accballot winproposal '[]' -p acc1
    executed transaction: a30ce81cfc3bb5eaf51e8dbbe8ff88723af3f46f1ba8c69c434aa95917aecf81  96 bytes  941 us
          accballot <= accballot::winproposal       {}
    >> win posposal is: qqvote count3
    

    10.全部投票状态

    148655ms thread-0   apply_context.cpp:29          print_debug          ]
    [(accballot,allproposal)->accballot]: CONSOLE OUTPUT BEGIN =====================
     posposal 0:163vote count2
     posposal 0:360vote count0
     posposal 0:alibabavote count0
     posposal 0:baiduvote count0
     posposal 0:qqvote count3
     posposal 0:yyvote count0
    
    [(accballot,allproposal)->accballot]: CONSOLE OUTPUT END   =====================
    

    注意避坑

    • 函数名不支持大写字母,不支持下划线,不能超过12个字符长度
    • 结构体名不要使用大写,持久化的数据表操作会受影响(类名大写暂未碰到问题)
  • 相关阅读:
    php解析XML的两种方法
    Windows下xampp搭配php环境以及mysql的设置和php连接Mysql数据库
    管道
    Ubuntu文件系统
    Ubuntu如何使用Vscode写C++代码
    Ubuntu如何百度云盘下载
    Debug程序的使用
    寄存器
    汇编指令
    汇编第二章_寄存器
  • 原文地址:https://www.cnblogs.com/Jogging/p/ballot.html
Copyright © 2020-2023  润新知