zoukankan      html  css  js  c++  java
  • eos智能合约开发最佳实践

    安全问题

    1.可能的错误

    智能合约终止
    限制转账限额 限制速率
    有效途径来进行bug修复和提升

    2.谨慎发布智能合约

    对智能合约进行彻底的测试 并在任何新的攻击手法被发现后及时制止
    赏金计划和审计合约

    3.合约的简介
    确保智能合约逻辑简单
    确保合约和函数模块化

    4.保持更新
    在任何新发现的漏洞之前进行修复
    利用最新技术

    5.潜在特性
    可能会调用同名函数

    漏洞
    溢出漏洞

    typedef struct acnts {
    account_name name0;
    account_name name1;
    account_name name2;
    account_name name3;
    } account_names;

    void transfer(symbol_name symbol, account_name from, account_names to, uint64_t balance)
    {
    require_auth(from);
    account fromaccount;

    require_recipient(from);
    require_recipient(to.name0);
    require_recipient(to.name1);
    require_recipient(to.name2);
    require_recipient(to.name3);
    
    eosio_assert(is_balance_within_range(balance), "invalid balance");
    eosio_assert(balance > 0, "must transfer positive balance");
    
    uint64_t amount = balance * 4; //乘法溢出
    
    int itr = db_find_i64(_self, symbol, N(table), from);
    eosio_assert(itr >= 0, "Sub-- wrong name");
    db_get_i64(itr, &fromaccount, (account));
    eosio_assert(fromaccount.balance >= amount, "overdrawn balance");
    
    sub_balance(symbol, from, amount);
    
    add_balance(symbol, to.name0, balance);
    add_balance(symbol, to.name1, balance);
    add_balance(symbol, to.name2, balance);
    add_balance(symbol, to.name3, balance);
    

    }
    提示 使用assert进行检查 而不是把balance提出来进行运算

    权限校验
    严格判断入参函数和实际调用使得否一致

    void token::transfer( account_name from,
    account_name to,
    asset quantity,
    string memo )
    {
    eosio_assert( from != to, "cannot transfer to self" );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );
    
    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
    
    auto payer = has_auth( to ) ? to : from;
    
    sub_balance( from, quantity );
    add_balance( to, quantity, payer );
    

    }
    提示:检验资产转出账户和调用账户是否一致

    确保每一个action和code满足关联要求
    // extend from EOSIO_ABI

    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 || code == N(eosio.token) || action == N(onerror) ) {
    TYPE thiscontract( self );
    switch( action ) {
    EOSIO_API( TYPE, MEMBERS )
    }
    /
    does not allow destructor of thiscontract to run: eosio_exit(0); */
    }
    }
    }

    EOSIO_ABI_EX(eosio::charity, (hi)(transfer))

    提示:关键检查

    相关文章:
    eosbet被盗事件合约分析

    被盗合约 受攻击代码

    有问题的合约代码

    // extend from EOSIO_ABI, because we need to listen to incoming eosio.token transfers

    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 || code == N(eosio.token) || action == N(onerror) ) {
    TYPE thiscontract( self );
    switch( action ) {
    EOSIO_API( TYPE, MEMBERS )
    }
    /
    does not allow destructor of thiscontract to run: eosio_exit(0); */
    }
    }
    }

    问题原因:

    由于abi转发器允许下注而不将eos转移到合同中。

    修改措施:
    1.去掉错误判断
    2.过滤传入操作 只将eosio.token的行为传入合同

    提醒:
    更强大的代码测试
    至少两次审计
    资金监控

  • 相关阅读:
    10. Regular Expression Matching
    9. Palindrome Number (考虑负数的情况)
    8. String to Integer (整数的溢出)
    7. Reverse Integer (整数的溢出)
    LeetCode Minimum Size Subarray Sum
    LeetCode Course Schedule II
    Linux 文件缓存 (一)
    LeetCode Tries Prefix Tree
    Linux : lsof 命令
    LeetCode Binary Tree Right Side View
  • 原文地址:https://www.cnblogs.com/xiaocongcong888/p/9807150.html
Copyright © 2011-2022 走看看