EOS智能合约如何调试?

作者: 编程狂魔 | 来源:发表于2018-07-27 14:11 被阅读6次

    为了能够调试智能合约,需要配置本地节点。这个本地节点可以作为单独的私有链或公有链的扩展来运行。这个本地节点还需要运行在合约控制台选项上,或者通过命令行 加参数--contracts-console,或者通过config.ini设置contracts-console = true

    当第一次创建智能合约时,建议首先在私有链上测试和调试智能合约,因为你完全控制整个区块链。这使你可以拥有无限量的EOS币,并且可以随时重置区块链的状态。当它已经完全准备好,并打算正式上线时,可以通过将本地nodeos连接到公有testnet链(或官方测试链testnet)来完成对公有testnet链(或官方测试链testnet)的调试,这样就可以在本地nodeos中查看测试链的日志。

    理解了这个意思的话,对于下面的内容,就使用私有链进行调试。

    如果你没有配置好自己的本地nodeos,请参考eos开发环境安装。默认情况下,本地nodeos将只运行在私有链中,除非你修改配置文件config.ini以与公有testnet链(或官方测试链testnet)的节点连接,如这里中所述。

    方法

    调试智能合约的主要方法是Caveman Debugging,我们利用打印功能来检查变量的值并检查合约的流程。智能合约中的打印可以通过Print C API(C和C++)来完成。C++ APIC API的封装包,所以我们通常只使用C++ API

    打印

    Print C API支持的可以打印的数据类型如下:

    • prints:空终止字符数组(字符串)
    • prints_l:给定大小的任意字符数组(字符串)
    • printi:64位无符号整数
    • printi128:128位无符号整数
    • printd:双重编码为64位无符号整数
    • printn:编码为64位无符号整数的base32字符串
    • printhex:二进制数据及其大小给定为十六进制

    虽然Print C++ API通过重载print()函数来封装一些上面的C API,所以用户不需要确定自己使用的特定的print函数Print C++ API支持:

    • 空终止字符数组(字符串)
    • 整数(128位无符号,64位无符号,32位无符号,有符号,无符号)
    • 编码为64位无符号整数的Base32字符串
    • 具有print()的结构体类型

    例子

    让我们以一个新的合约作为示例进行调试。

    debug.hpp

    C++

    #include <eoslib/eos.hpp>
    #include <eoslib/db.hpp>
    
    namespace debug {
        struct foo {
            account_name from;
            account_name to;
            uint64_t amount;
            void print() const {
                eosio::print("Foo from ", eosio::name(from), " to ",eosio::name(to), " with amount ", amount, "\n");
            }
        };
    }
    

    debug.cpp

    C++

    #include <debug.hpp>
    
    extern "C" {
    
        void apply( uint64_t code, uint64_t action ) {
            if (code == N(debug)) {
                eosio::print("Code is debug\n");
                if (action == N(foo)) {
                     eosio::print("Action is foo\n");
                    debug::foo f = eosio::current_message<debug::foo>();
                    if (f.amount >= 100) {
                        eosio::print("Amount is larger or equal than 100\n");
                    } else {
                        eosio::print("Amount is smaller than 100\n");
                        eosio::print("Increase amount by 10\n");
                        f.amount += 10;
                        eosio::print(f);
                    }
                }
            }
        }
    } // extern "C"
    

    debug.hpp

    C++

    {
      "structs": [{
          "name": "foo",
          "base": "",
          "fields": {
            "from": "account_name",
            "to": "account_name",
            "amount": "uint64"
          }
        }
      ],
      "actions": [{
          "action_name": "foo",
          "type": "foo"
        }
      ]
    }
    

    让我们部署完成后发送一个消息给它。假设你已经创建了调试帐户并在钱包中有它的密钥。

    $ eosiocpp -o debug.wast debug.cpp
    $ cleos set contract debug debug.wast debug.abi
    $ cleos push message debug foo '{"from":"inita", "to":"initb", "amount":10}' --scope debug
    

    当你检查本地节点日志时,在发送上述消息后,将看到以下几行:

    Code is debug
    Action is foo
    Amount is smaller than 100
    Increase amount by 10
    Foo from inita to initb with amount 20
    

    在那里,可以确认你的消息将进入正确的控制流,并且正确地更新该值。你可能会看到上述消息至少2次,这是正常的,因为每个交易都在验证、块生成和区块链应用中用到。

    另:《EOS智能合约与DApp开发入门》教程已经上线,爱学习等不及的可以抓紧体验一下:

    EOS教程

    这个教程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用React和EOS的各知识点完成一个便签DApp的开发。

    如果大家是学习以太坊的可以看这些教程:

    • web3j教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
    • 以太坊教程,主要介绍智能合约与dapp应用开发,适合入门。
    • 以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
    • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
    • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。

    博客原文在:这里

    相关文章

      网友评论

        本文标题:EOS智能合约如何调试?

        本文链接:https://www.haomeiwen.com/subject/ezzwmftx.html