【体验贴】EOS_v2.0版官方教程

Getting Started

本次体验依据EOSIO官方教程Getting Started章节
体验了启动节点、管理钱包、创建账户、编写合约、编译部署合约、调用合约等功能
详情参看https://developers.eos.io/welcome/latest/getting-started/index/
不足之处,欢迎指正。

EOS是什么?

  1. 软件:EOS可以理解为对eos.io软件的简称。eos.io软件由block.one公司开发,构建了EOS区块链的底层技术架构;eos.io类似于区块链中的操作系统,开发者可以基于此工具快速构建DAPP。
  2. 通证: EOS可以指是一种通证(token),目前可以支持在EOS、BOS中进行交换,具有一定的价值。
  3. 公链:EOS也可以理解为采用DPOS共识机制的一种底层公链架构,其采用投票机制选择21个节点为主节点完成交易的打包。

本文我们尝试的EOS是指软件eos.io

一 免安装体验版

如果觉得本地安装比较麻烦,可以直接访问:

https://gitpod.io/#https://github.com/EOSIO/eosio-web-ide

Tips:初次访问需要配置环境,打开页面可能会慢些。
在线IDE页面

想要了解更多Web IDE的细节,可以访问

https://github.com/EOSIO/eosio-web-ide

(1)编译合约
先看下合约文件talk.cpp

#include <eosio/eosio.hpp>

// Message table
struct [[eosio::table("message"), eosio::contract("talk")]] message {
    
    
    uint64_t    id       = {
    
    }; // Non-0
    uint64_t    reply_to = {
    
    }; // Non-0 if this is a reply
    eosio::name user     = {
    
    };
    std::string content  = {
    
    };

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

using message_table = eosio::multi_index<
    "message"_n, message, eosio::indexed_by<"by.reply.to"_n, eosio::const_mem_fun<message, uint64_t, &message::get_reply_to>>>;

// The contract
class talk : eosio::contract {
    
    
  public:
    // Use contract's constructor
    using contract::contract;

    // Post a message
    [[eosio::action]] void post(uint64_t id, uint64_t reply_to, eosio::name user, const std::string& content) {
    
    
        message_table table{
    
    get_self(), 0};

        // Check user
        require_auth(user);

        // Check reply_to exists
        if (reply_to)
            table.get(reply_to);

        // Create an ID if user didn't specify one
        eosio::check(id < 1'000'000'000ull, "user-specified id is too big");
        if (!id)
            id = std::max(table.available_primary_key(), 1'000'000'000ull);

        // Record the message
        table.emplace(get_self(), [&](auto& message) {
    
    
            message.id       = id;
            message.reply_to = reply_to;
            message.user     = user;
            message.content  = content;
        });
    }
};

在IDE中新建终端,运行

eosio-cpp contract/talk.dpp

完成合约的编译,会在contract文件目录生成talk.abi与talk.wasm

#talk.abi内容
{
    
    
    "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ",
    "version": "eosio::abi/1.1",
    "types": [],
    "structs": [
        {
    
    
            "name": "message",
            "base": "",
            "fields": [
                {
    
    
                    "name": "id",
                    "type": "uint64"
                },
                {
    
    
                    "name": "reply_to",
                    "type": "uint64"
                },
                {
    
    
                    "name": "user",
                    "type": "name"
                },
                {
    
    
                    "name": "content",
                    "type": "string"
                }
            ]
        },
        {
    
    
            "name": "post",
            "base": "",
            "fields": [
                {
    
    
                    "name": "id",
                    "type": "uint64"
                },
                {
    
    
                    "name": "reply_to",
                    "type": "uint64"
                },
                {
    
    
                    "name": "user",
                    "type": "name"
                },
                {
    
    
                    "name": "content",
                    "type": "string"
                }
            ]
        }
    ],
    "actions": [
        {
    
    
            "name": "post",
            "type": "post",
            "ricardian_contract": ""
        }
    ],
    "tables": [
        {
    
    
            "name": "message",
            "type": "message",
            "index_type": "i64",
            "key_names": [],
            "key_types": []
        }
    ],
    "ricardian_clauses": [],
    "variants": []

talk.wasm为编译后的二进制文件,会在合约部署时分发至各节点。

(2)安装合约

cleos create account eosio talk EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos set code talk talk.wasm
cleos set abi talk talk.abi

***命令执行后无反应,放弃了!***

开玩笑的,如遇到创建账号无反应,请重启一下工作空间。因为创建账号需要存调用系统合约,请注意不能关闭出块进程(下图页面)
出块信息页
输出如下:

$ cleos create account eosio talk EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
executed transaction: f08fb469311c57c280e6ebcc0f038572ed230e28c070d48a60711b4183aabb92  200 bytes  282 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"talk","owner":{"threshold":1,"keys":[{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcV...
warning: transaction executed locally, but may not be confirmed by the network yet         ] 

$ cleos set code talk talk.wasm
Reading WASM from /workspace/eosio-web-ide/contract/talk.wasm...
Setting Code...
executed transaction: 4afac605a367ccf58dcf093463e881221bf910b29ad65b6ece4dfc85d695cc80  4024 bytes  736 us
#         eosio <= eosio::setcode               {"account":"talk","vmtype":0,"vmversion":0,"code":"0061736d0100000001a2011a6000006000017f60027f7f006...
warn  2020-09-01T04:32:52.185 cleos     main.cpp:495            warning: transaction executed locally, but may not be confirmed by the network yet

$ cleos set abi talk talk.abi
Setting ABI...
executed transaction: 941ddd90e63716f21f2568668dd967574b696b58c3ed189ede86b8e28d80da82  200 bytes  139 us
#         eosio <= eosio::setabi                {"account":"talk","abi":"0e656f73696f3a3a6162692f312e310002076d65737361676500040269640675696e7436340...
warn  2020-09-01T04:33:03.198 cleos     main.cpp:495            warning: transaction executed locally, but may not be confirmed by the network yet

warn:原因是交易刚上传至链上,尚未被其他节点确认。

(3)创建用户并调用合约

#创建用户bob、alice
cleos create account eosio bob EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos create account eosio jane EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
#调用talk合约中post动作
cleos push action talk post '[1000, 0, bob, "This is a new post"]' -p bob
cleos push action talk post '[2000, 0, jane, "This is my first post"]' -p jane
cleos push action talk post '[1001, 2000, bob, "Replying to your post"]' -p bob

(4)监听链上信息

cleos get table talk '' message

会反馈talk合约的链上信息:

{
    
    
  "rows": [{
    
    
      "id": 1000,
      "reply_to": 0,
      "user": "bob",
      "content": "This is a new post"
    },{
    
    
      "id": 1001,
      "reply_to": 2000,
      "user": "bob",
      "content": "Replying to your post"
    },{
    
    
      "id": 2000,
      "reply_to": 0,
      "user": "jane",
      "content": "This is my first post"
    }
  ],
  "more": false
}

(5)前端页面展示
IDE中已经用React实现了数据展示功能,输入:

gp preview $(gp url 8000)

弹出前端页面效果如下:
在这里插入图片描述
(6)构建并运行单元测试
返回上层目录,在eosio-web-ide目录下运行:

./build-tests

该命令会调用test文件夹下的所有.cpp文件,进行构建(build)操作。过程大概需要40秒,耐心等待。

将contract目录下产生的talk.wasm、talk.abi文件复制(或者移动)到tester所在目录。

运行:

./tester

正常运行时,显示

***No errors detected

如果感兴趣可以查看下talk_tests.cpp,该文件一次性实现了合约加载,创建用户,调用action,异常处理;

#include <boost/test/unit_test.hpp>
#include <eosio/chain/abi_serializer.hpp>
#include <eosio/chain/permission_object.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/testing/tester.hpp>

using namespace eosio;
using namespace eosio::chain;
using namespace eosio::testing;
using namespace fc;

BOOST_AUTO_TEST_SUITE(talk_tests)

BOOST_AUTO_TEST_CASE(post) try {
    
    
    tester t{
    
    setup_policy::none};

    // Load contract
    t.create_account(N(talk));
    t.set_code(N(talk), read_wasm("talk.wasm"));
    t.set_abi(N(talk), read_abi("talk.abi").data());
    t.produce_block();

    // Create users
    t.create_account(N(john));
    t.create_account(N(jane));

    // Test "post" action
    t.push_action(
        N(talk), N(post), N(john),
        mutable_variant_object //
        ("id", 1)              //
        ("reply_to", 0)        //
        ("user", "john")       //
        ("content", "post 1")  //
    );
    t.push_action(
        N(talk), N(post), N(jane),
        mutable_variant_object //
        ("id", 2)              //
        ("reply_to", 0)        //
        ("user", "jane")       //
        ("content", "post 2")  //
    );
    t.push_action(
        N(talk), N(post), N(john),
        mutable_variant_object       //
        ("id", 3)                    //
        ("reply_to", 2)              //
        ("user", "john")             //
        ("content", "post 3: reply") //
    );

    // Can't reply to non-existing message
    BOOST_CHECK_THROW(
        [&] {
    
    
            t.push_action(
                N(talk), N(post), N(john),
                mutable_variant_object       //
                ("id", 4)                    //
                ("reply_to", 99)             //
                ("user", "john")             //
                ("content", "post 3: reply") //
            );
        }(),
        fc::exception);
}
FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()

(7)重置链
删除已经存在的链并创建另外一个。首先进入用于出块的终端,按“ctrl+c”停止。
接着运行以下代码:

#删除现有链数据
rm -rf ~/eosio/chain
#初始化并启动新链
nodeos --config-dir ~/eosio/chain/config --data-dir ~/eosio/chain/data -e -p eosio --plugin eosio::chain_api_plugin --contracts-console

此时会发现会从0开始快速出块。

二 本地安装

环境准备

1.安装eosio

  • 二进制安装
#Mac OS
brew tap eosio/eosio
brew install eosio
#Ubuntu18.04
wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-18.04_amd64.deb
sudo apt install ./eosio_2.0.0-1-ubuntu-18.04_amd64.deb
#Ubuntu16.04
wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio_2.0.0-1-ubuntu-16.04_amd64.deb
sudo apt install ./eosio_2.0.0-1-ubuntu-16.04_amd64.deb
#CentOS
wget https://github.com/EOSIO/eos/releases/download/v2.0.0/eosio-2.0.0-1.el7.x86_64.rpm
sudo yum install ./eosio-2.0.0-1.el7.x86_64.rpm
  • 源码安装
    因为用的Ubuntu20.04,目前并没有可以支持的二进制文件,尝试采用源码安装方式(最后证明也不行,构建时不支持)。
    (1)从github获取EOSIO源代码【下载较慢,建议休息时间下载】
    官网推荐新建eosio文件夹
mkdir -p ~/eosio && cd ~/eosio
git clone --recursive https://github.com/EOSIO/eos

(2)更新子模块

cd eosio/eos
git submodule update --init --recursive

(3)获取变更信息

[git checkout <branch>]  (optional)
git pull --recurse-submodules

2.安装CDT

CDT :Contract Dev. Toolkit合约开发工具包
ubuntu18.08安装方式:

wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.6.3/eosio.cdt_1.6.3-1-ubuntu-18.04_amd64.deb
sudo apt install ./eosio.cdt_1.6.3-1-ubuntu-18.04_amd64.deb

3.使用钱包

钱包:公私钥对的存储库

(1)创建钱包

–file 选项可以避免钱包密码出现在终端(实际生产)
–to-console 创建默认钱包,页面显示密码(测试阶段)

$cleos wallet create --to-console

(2)开启钱包
默认情况下创建的钱包是关闭状态

#打开钱包
cleos wallet open
#返回钱包列表
cleos wallet list

如果运行正确,输出:

Wallets:
[
  "default"
]

(3)解锁钱包

cleos wallet unlock

解锁成功后,会输出:

Wallets:
[
  "default *"
]

(4)导入私钥到钱包

#生成私钥
cleos wallet creat_key

(5)导入开发密钥

每条EOSIO链都有默认的系统用户“eosio”,该账户通过加载用于指定管理和链共识的系统合约来启动链。每条新建的EOS链 拥有一个相同的开发密钥。

cleos wallet import
#提示输入私钥时输入:
5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

4.启动keosd & nodeos

#启动keosd
keosd &
#启动nodeos
nodeos -e -p eosio \
--plugin eosio::producer_plugin \
--plugin eosio::producer_api_plugin \
--plugin eosio::chain_api_plugin \
--plugin eosio::http_plugin \
--plugin eosio::history_plugin \
--plugin eosio::history_api_plugin \
--filter-on="*" \
--access-control-allow-origin='*' \
--contracts-console \
--http-validate-host=false \
--verbose-http-errors >> nodeos.log 2>&1 &

启动成功后,进行必要的检查:

#检查节点是否正常出块
tail -f nodeos.log
#检查电子钱包,输出为Wallets:[]
cleos wallet list
#检查Nodeos端
#可以直接浏览器打开http://localhost:8888/v1/chain/get_info
#或者:
curl http://localhost:8888/v1/chain/get_info

5.创建测试账号
测试过程包括:

  • 用户账号:bob、alice
  • 默认账户:eosio
  • 合约账户
#创建用户账号
cleos create account eosio bob YOUR_PUBLIC_KEY
cleos create account eosio alice YOUR_PUBLIC_KEY
#检查公钥--用户的关联
#注意:用户名(alice)是所有权的唯一标识,绑定的公钥变更 不会改变账户的所有权
#eosio授权机制比较特殊:owner密钥保持冷存储,当active被盗用时可以通过owner重获控制权。
cleos get account alice

合约开发

1.合约部署
(1)创建合约
contract目录中创建hello目录,新建hello.cpp

#include <eosio/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] hello : public contract {
    
    
  public:
      using contract::contract;

      [[eosio::action]]
      void hi( name user ) {
    
    
         print( "Hello, ", user);
      }
};

(2)编译合约

eosio-cpp hello.cpp -o hello.wasm

(3)部署合约

#查看钱包内密钥
cleos wallet keys
#创建合约账户
cleos create account eosio hello YOUR_PUBLIC_KEY -p eosio@active
#部署合约
cleos set contract hello **CONTRACTS_DIR**/hello -p hello@active

(4)执行合约

#调用action
cleos push action hello hi '["bob"]' -p bob@active
#切换用户调用
cleos push action hello hi '["bob"]' -p alice@active

2.其他

猜你喜欢

转载自blog.csdn.net/weixin_43347204/article/details/108334280