美文网首页区块链大学区块链研习社区块链实战
智能合约Solidity教程-事件和日志(一)

智能合约Solidity教程-事件和日志(一)

作者: JouyPub | 来源:发表于2018-11-14 12:40 被阅读2次

    简述:事件是以太坊提供的基本功能,用来将数据记录成日志,保存在区块链上,同时事件也可用于用于和外部交互,例如和前端的交互、异步调用等作用。solidity中,事件是指操作触发的行为,而日志则是触发事件后,将数据记录在区块链上形成日志。

    本文主要介绍以下几点:

    • 什么是事件event、日志log
    • 事件event如何定义、如何触发
    • 事件event有什么作用

    什么是事件event、日志log

    事件event是以太坊提供的基本功能,用于将数据记录成日志保存到区块链上,用户可以自定义需要记录的数据,以及topic和索引;日志是指事件保存在区块链上的数据。事件强调操作行为,日志强调存储内容,两者是完全不同的概念。

    事件event如何定义、如何触发

    solidity中,使用关键字event来定义事件,其中参数列表就是需要保存到区块链上的数据,其中最多可以有三个参数被描述成indexed,表示该参数可以被索引,添加indexed的参数本身不会保存,但是可以通过参数值来检索。

    以下内容是使用truffle unbox webpack命令生成的项目中已有的合约代码

    contract MetaCoin {
        mapping (address => uint) balances;
    
        // 定义事件
        event Transfer(address indexed _from, address indexed _to, uint256 _value);
    
        constructor() public {
            balances[tx.origin] = 10000;
        }
    
        function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
            if (balances[msg.sender] < amount) return false;
            balances[msg.sender] -= amount;
            balances[receiver] += amount;
            // 触发事件
            emit Transfer(msg.sender, receiver, amount);
            return true;
        }
    
        function getBalanceInEth(address addr) public view returns(uint){
            return ConvertLib.convert(getBalance(addr),2);
        }
    
        function getBalance(address addr) public view returns(uint) {
            return balances[addr];
        }
    }
    

    事件event有什么作用

    事件Event的作用的可以总结为以下几点:

    • 异步获取执行结果
    • 和前端交互
    • 存储合约数据,相比storage要便宜很多(storage存储的大概价格为:每32字节需要消耗20000Gas,而日志存储价格大概为每字节8Gas)

    以和前端交互为例,在web3.js中,我们可以通过监听event来做到及时更新前端显示。在项目index.js文件中的start方法内,新增以下内容

    MetaCoin.deployed().then(function (instance) {
        var event = instance.Transfer(function (error, result) {
            console.log('transfer log begin...')
            console.log(error)
            console.log(JSON.stringify(result))
            for (let key in result) {
                console.log(key + ': ' + result[key])
            }
    
            console.log(result['args'])
            for (let i in result['args']) {
                console.log(i + ': ' + result['args'][i])
            }
            console.log('transfer log end')
        })
        }).then(function (value) {
            console.log(value)
        }).catch(function (e) {
            console.log(e)
        })
    

    在页面上点击send MetaCoin后,可以在浏览器的控制台中看到事件的日志输出,其中event中的三个参数值都包含在在result['args'],具体event相关内容如下:

    {
        "logIndex":0,
        "transactionIndex":0,
        "transactionHash":"0xecff3eac67a457f4cad2044735a45634d8b67a786a2c0a90f73a12665dd22dab",
        "blockHash":"0xc9ec321f9dc4e8f447955540980061a3520895b8d8caf940024f390e59fa9d64",
        "blockNumber":31,
        "address":"0x1cf0326180aca92c4d3cb30b16dec88cfe4854d3",
        "type":"mined",
        "event":"Transfer",
        "args":{
            "_from":"0x75441ac9a1d2daaa5638beae207546c8d14a7f6d",
            "_to":"0x6cc022fae89414146b2a2646ca5143e23da5b7e7",
            "_value":"10"
        }
    }
    
    欢迎订阅「K叔区块链」 - 专注于区块链技术学习
    博客地址:http://www.jouypub.com

    相关文章

      网友评论

        本文标题:智能合约Solidity教程-事件和日志(一)

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