• eosio.cdt发布带来的变化


    change of version 1.3.x+,EOSIO.CDT

    After eos version 1.3.x, generation of cdt tools, Smart Contracts has changed alot.
    Both source code and compilation.

    Compilation and application

    1. download and install cdt

    $ git clone --recursive https://github.com/eosio/eosio.cdt
    $ cd eosio.cdt
    $ ./build.sh
    $ sudo ./install.sh
    

    2. Building your first smart contract

    This will generate two files:old===>new

    eg:

    eosiocpp -g hello.abi hello.hpp
    eosiocpp -o heool.wast hello.cpp
    ===>
    eosio-cpp -abigen hello.cpp -o hello.wasm
    

    3. Original contract change to cdt contract need do somethings:

    • name replace account_name
    • symbol("EOS",4) replace S(4,EOS)
    • add #define N(X) name("X") to .hpp
    • ACTION replace void
    • [[eosio::action]] replace @abi action
    • struct [[eosio::table("testtabb")]] test_table2{} replace //@abi table testtabb
    • EOSIO_DISPATCH() replace EOSIO_ABI()

    Modules changes

    1. console Defines C++ wrapper to log/print text messages. More...

    e.g.

    print( "hello world, this is a number: ", 5 );
    print_f("Number of apples: %", 10);
    
    const char *s = "Hello World!";
    uint64_t unsigned_64_bit_int = 1e+18;
    uint128_t unsigned_128_bit_int (87654323456);
    uint64_t string_as_unsigned_64_bit = N(abcde);
    std::out << s << " " << unsigned_64_bit_int << " "  << unsigned_128_bit_int << " " << string_as_unsigned_64_bit;
    

    2. multiindex Defines EOSIO Multi Index Table

    e.g.

    #include <eosiolib/eosio.hpp>
    using namespace eosio;
    using namespace std;
    class addressbook: contract {
    struct address {
    uint64_t account_name;
    string first_name;
    string last_name;
    string street;
    string city;
    string state;
    uint64_t primary_key() const { return account_name; }
    };
    public:
    addressbook(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds) {}
    typedef eosio::multi_index< name("address"), address > address_index;
    void myaction() {
    address_index addresses(_self, _self.value); // code, scope
    }
    }
    EOSIO_DISPATCH( addressbook, (myaction) )
    

    3. inline actions delete currency.hpp

    /**
    * Send inline action
    *
    * @brief Send inline action
    * @param CONTRACT - The account this action is intended for
    * @param NAME - The name of the action
    * @param ... - The member of the action specified as ("action_member1_name", action_member1_value)("action_member2_name", action_member2_value)
    */
    #define SEND_INLINE_ACTION( CONTRACT, NAME, ... )
    INLINE_ACTION_SENDER(std::decay_t<decltype(CONTRACT)>, NAME)( (CONTRACT).get_self(),
    BOOST_PP_TUPLE_ENUM(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__)) );
    

    e.g.1:owner call owner function ,create inline option

    SEND_INLINE_ACTION(*this,transfer,{_self, N(active)},{_self,from,"1.0000 EOS","inline transfer"})
    

    e.g.2:contract B call contract A's hi function

    #include <eosiolib/eosio.hpp>
    using namespace eosio;
    CONTRACT A : public eosio::contract {
    public:
    using contract::contract;
    ACTION hi( name user );
    // accessor for external contracts to easily send inline actions to your contract
    using hi_action = action_wrapper<"hi"_n, &A::hi>;
    };
    ===>
    #include <A.hpp>
    using namespace eosio;
    CONTRACT send_inline : public eosio::contract {
    public:
    using contract::contract;
    ACTION test( name user, name inline_code ) {
    print_f( "Hello % from send_inline", user );
    // constructor takes two arguments (the code the contract is deployed on and the set of permissions)
    A::hi_action hi(inline_code, {_self, "active"_n});
    hi.send(user);
    }
    // accessor for external contracts to easily send inline actions to your contract
    using test_action = action_wrapper<"test"_n, &send_inline::test>;
    };
    

    4. others

    • delete eosio::vector,bytes replace to std::vector<>,std::vector

    Headers changes

    1.change eosiolib/types.hpp

    • delete account_name and replace to name (details later)
    • delete permission_name,table_name,scope_name,action_name
    • delete time,weight_type
    • change name public_key to capi_public_key,signature to capi_signature the same as capi_checksum256...

    2.add eosiolib/name.hpp

    • Added enum class eosio::name::raw which is implicitly converted from an eosio::name (used for template non-type parameters)
    struct name
    {
    public:
    enum class raw : uint64_t {};
    uint64_t value = 0;
    }
    
    • delete macro N(X) replace to "X"_n or name("X")
    #define N(X) name("X")
    #define V(X) N(X).value
    

    3.change eosiolib/contract.hpp

    • change constract function
    class contract {
    public:
    /**
    * Construct a new contract given the contract name
    * @brief Construct a new contract object.
    * @param n - The name of this contract
    */
    contract( account_name n ):_self(n){}
    /**
    * Get this contract name
    * @brief Get this contract name.
    * @return account_name - The name of this contract
    */
    inline account_name get_self()const { return _self; }
    
    protected:
    /**
    * The name of this contract
    * @brief The name of this contract.
    */
    account_name _self;
    };
    ==========================================================================>
    class contract {
    public:
    /**
    * Construct a new contract given the contract name
    * @brief Construct a new contract object.
    * @param receiver - The name of this contract
    * @param code - The code name of the action this contract is processing.
    * @param ds - The datastream used
    */
    contract( name receiver, name code, datastream<const char*> ds ):_self(receiver),_code(code),_ds(ds) {}
    /**
    * Get this contract name
    * @brief Get this contract name.
    * @return name - The name of this contract
    */
    inline name get_self()const { return _self; }
    /**
    * The code name of the action this contract is processing.
    * @brief The code name of the action this contract is processing.
    * @return name - The code name of the action this contract is processing.
    */
    inline name get_code()const { return _code; }
    /**
    * Get the datastream for this contract
    * @brief Get the datastream for this contract
    * @return datastream<const char*> - The datastream for this contract
    */
    inline datastream<const char*> get_datastream()const { return _ds; }
    protected:
    /**
    * The name of this contract
    * @brief The name of this contract.
    */
    name _self;
    /**
    * The code name of the action this contract is processing.
    * @brief The code name of the action this contract is processing.
    */
    name _code;
    /**
    * The datastream for this contract
    *@ The datastream for this contract
    */
    datastream<const char*> _ds = datastream<const char*>(nullptr, 0);
    };
    

    4.change eosiolib/eosio.hpp

    • Added ACTION macro which is simply a shortcut for [[eosio::action]] void.

    • Added TABLE macro which is simply a shortcut for struct [[eosio::table]].

    • Added CONTRACT macro which is simply a shortcut for class [[eosio::contract]].

    • e.g. abitest.cpp

    #include <eosiolib/eosio.hpp>
    #include <optional>
    
    using namespace eosio;
    
    typedef int type_def;
    
    namespace test {
    // mark this struct as an action
    struct [[ eosio::action ]] testa {
    void printddd() { print("testa"); }
    int fielda;
    float fieldb;
    capi_name name;
    };
    
    struct testb {
    float field;
    void printll() { print("testb"); }
    };
    
    // mark this struct as an action and specify the name explicitly
    struct [[ using eosio: action("testc"), contract("abitest") ]] test_c : testb {
    uint64_t num;
    };
    }
    
    CONTRACT abitest : public eosio::contract {
    public:
    using contract::contract;
    
    // mark this method as an action and specify the name explicity
    [[ eosio::action("testacta") ]]
    void testact_a( name user, const std::string& s, std::vector<int>& c, std::vector<std::string> sv ) {
    print( "Hello, ", name{user} );
    symbol sym("TEST", 4);
    }
    
    // mark this method as an action
    ACTION testactb( test::test_c input, type_def td, std::optional<int> cc, bool d ) {
    print(input.num);
    }
    
    // mark this struct as a table and allow multi_index typedefs to define the tables
    TABLE testtable {
    uint64_t owner;
    uint64_t third;
    uint64_t primary_key() const { return owner; }
    };
    
    // mark this struct as a table and allow multi_index typedefs to define the tables, and specify a primitive table (non multi_index) with an explicit name
    struct [[eosio::table("testtabb")]] test_table2 {
    uint64_t owner;
    uint64_t sec;
    uint64_t third;
    uint64_t primary_key() const { return owner; }
    };
    };
    
    typedef eosio::multi_index< "testtab"_n,  abitest::testtable > testtable_t;
    typedef eosio::multi_index< "testtaba"_n, abitest::testtable > testtable_a_t;
    typedef eosio::multi_index< "testtab2"_n, abitest::test_table2 > testtable2_t;
    
    #define EOSIO_DISPATCH_EX( TYPE, MEMBERS ) 
    extern "C"
    void apply(uint64_t, uint64_t, uint64_t){
    auto self = receiver; 
    if( action == "onerror"_n.value) { 
    /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ 
    eosio_assert(code == "eosio"_n.value, "onerror action's are only valid from the "eosio" system account"); 
    } 
    if( (code == self && action != "transfer"_n.value) || action == "onerror"_n.value || (code == "eosio.token"_n.value && action == "transfer"_n.value))  { 
    switch( action ) { 
    EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) 
    } 
    /* does not allow destructor of thiscontract to run: eosio_exit(0); */ 
    } 
    } 
    }
    EOSIO_DISPATCH_EX( abitest, (testactb) )
    

    5.eosiolib/dispatcher.hpp

    • Renamed the macro EOSIO_ABI to EOSIO_DISPATCH as this is more descriptive of what this macro actually does.
    • Modified the definition of EOSIO_DISPATCH to work with the new constructor for eosio::contrac
    • delete EOSIO_API and replace to EOSIO_DISPATCH_HELPER

    e.g.

    #define EOSIO_ABI_EX( TYPE, MEMBERS ) 
    extern "C" { 
    void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 
    auto self = receiver; 
    if( action == N(onerror)) { 
    /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ 
    eosio_assert(code == N(eosio), "onerror action's are only valid from the "eosio" system account"); 
    } 
    if( (code == self && action != N(transfer)) || action == N(onerror) || (code == N(eosio.token) && action == N(transfer)))  { 
    TYPE thiscontract( self ); 
    switch( action ) { 
    EOSIO_API( TYPE, MEMBERS ) 
    } 
    /* does not allow destructor of thiscontract to run: eosio_exit(0); */ 
    } 
    } 
    }
    EOSIO_ABI_EX( monster,(transfer))
    ==>
    
    #define EOSIO_DISPATCH_EX( TYPE, MEMBERS ) 
    extern "C" { 
    void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 
    auto self = receiver; 
    if( action == "onerror"_n.value) { 
    /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ 
    eosio_assert(code == "eosio"_n.value, "onerror action's are only valid from the "eosio" system account"); 
    } 
    if( (code == self && action != "transfer"_n.value) || action == "onerror"_n.value || (code == "eosio.token"_n.value && action == "transfer"_n.value))  { 
    switch( action ) { 
    EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) 
    } 
    /* does not allow destructor of thiscontract to run: eosio_exit(0); */ 
    } 
    } 
    }
    

    6.Removed eosiolib/core_symbol.hpp and change symbol.hpp

    • change contract function.Removed eosio::symbol_type struct and replaced with eosio::symbol class
    struct symbol_type {
    symbol_name value;
    };
    ==================================>
    class symbol_code {
    public:
    constexpr symbol_code() : value(0) {}
    constexpr explicit symbol_code( uint64_t raw )
    :value(raw)
    {}
    private:
    uint64_t value = 0;
    };
    
    • Removed the S macro. The symbol constructor should be used as a type safe replacement
    S(4,SYS)
    ===>
    symbol(symbol_code("SYS"), 4) = symbol("SYS", 4)
    
    安来根-EOS 开发社区
    ---
    ![](https://img2018.cnblogs.com/blog/1015273/201812/1015273-20181218201530501-1531824304.jpg)
  • 相关阅读:
    windows10环境运用SSH和SwitchySharp自由翱翔
    Windows10 Virtualization Technology虚拟化技术功能
    [转]docker 基本原理及快速入门
    通俗易懂介绍机器学习与深度学习的差别
    对于python setup.py install安装的包如何卸载
    在Ubuntu上安装boost库[转]
    word2vec相关资源
    ubuntu16.04 LTS Server 安装mysql phpmyadmin apache2 php5.6环境
    tmux配置与用法整理
    Oracle学习笔记:LOB大数据字段类型
  • 原文地址:https://www.cnblogs.com/anlg-dongxh/p/10139712.html
Copyright © 2020-2023  润新知