美文网首页
Solidity 事件、继承、全局变量

Solidity 事件、继承、全局变量

作者: 黄靠谱 | 来源:发表于2019-01-09 18:18 被阅读6次

Event

https://www.jianshu.com/p/a99375c4e003

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

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

  1. 特性
  • 区块链是打包一系列交易的区块组成的链条,每一个交易“收据”会包含0到多个日志记录,日志代表着智能合约所触发的事件。
  • 通过emit来调用一个事件
  • 存储合约数据,相比storage要便宜很多(storage存储的大概价格为:每32字节需要消耗20000Gas,而日志存储价格大概为每字节8Gas)
pragma solidity >=0.4.21 <0.6.0;

contract SimpleAuction {
    event HighestBidIncreased(address bidder, uint amount); // Event
    function bid() public payable {
        // ...
        emit HighestBidIncreased(msg.sender, msg.value); // Triggering event
    }
}
  • 在DAPP的应用中,有2种反馈方式:监听回调、持续阻塞式监听的方式。
var abi = /* abi as generated by the compiler */;
var ClientReceipt = web3.eth.contract(abi);
var clientReceipt = ClientReceipt.at("0x1234...ab67" /* address */);

var event = clientReceipt.Deposit();

// watch for changes
event.watch(function(error, result){
    // result contains non-indexed arguments and topics
    // given to the `Deposit` call.
    if (!error)
        console.log(result);
});


// Or pass a callback to start watching immediately
var event = clientReceipt.Deposit(function(error, result) {
    if (!error)
        console.log(result);
});

日志的查询

通过web.js 来进行监听查询
由于日志不可被任何合约访问,那么我们应该如何查找日志了。尽管solidity没有提供查询日志的api,但是监听日志时,提供了filter功能,通过filter我们就可以完成查询日志的需求。

var event = myContract.Transfer(object1, object2, callfunction);
  1. object1:json对象,添加indexed属性的参数值,这里需要填具体的值,例如上面的例子,我们可以过滤由指定地址发出的交易{'_from':'0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E'}

  2. object2:json对象,额外的filter参数,由solidit提供,可以指定的参数有:

  • fromBlock:数字或字符串,默认为latest,指定过滤的起始位置,值为块的编号
  • toBlock:数字或字符串,默认为latest,指定过滤的结束位置,值为块的编号
  • address:字符串,接收指定账户地址发出的event
  • topics:字符串数组,接收指定topic的event。如果是非匿名事件,其中一个topic就是事件签名:Transfer(address,address,uint),匿名事件是无法通过topic来过滤
  1. callfunction:回调函数function(error, result){...}
     // 只监听向0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E地址转账的事件
    var obj1 = {
        '_to': '0x84d939AD8034c3ce2A7D4D100b939d4523b9E46E',
    }

    // block过滤范围0-latest
    var obj2 = {
        'fromBlock': 0,
        'toBlock': 'latest'
    }

    var event = instance.Transfer(obj1, obj2)
    //监听和回调函数
    event.watch(function (error, result) {
        console.log('transfer log begin')
        console.log(JSON.stringify(result))
        console.log('transfer log end')
    })

多继承

  • 当一个合约从多个其它合约那里继承,在区块链上仅会创建一个合约,在父合约里的代码会复制来形成继承合约。
  • 派生合约可以访问父类合约里所有非私有成员,包括内部函数和状态变量。 但是这些不能通过this从外部访问。
contract named is owned, mortal {

}
  • 继承的时候,可以直接给父类构造函数赋值
pragma solidity ^0.4.0;
contract Base {
    uint x;
    function Base(uint _x) { x = _x; }
}

contract Derived is Base(7) {
    function Derived(uint _y) Base(_y * _y) {
    }
}

全局变量

区块和交易属性

  • block.blockhash(uint blockNumber) returns (bytes32):指定区块的区块哈希——仅可用于最新的 256 个区块且不包括当前区块;而 blocks 从 0.4.22 版本开始已经不推荐使用,由 blockhash(uint blockNumber) 代替
  • block.coinbase (address): 挖出当前区块的矿工地址
  • block.difficulty (uint): 当前区块难度
  • block.gaslimit (uint): 当前区块 gas 限额
  • block.number (uint): 当前区块号
  • block.timestamp (uint): 自 unix epoch 起始当前区块以秒计的时间戳
  • gasleft() returns (uint256):剩余的 gas
  • msg.data (bytes): 完整的 calldata
  • msg.gas (uint): 剩余 gas - 自 0.4.21 版本开始已经不推荐使用,由 gesleft() 代替
  • msg.sender (address): 消息发送者(当前调用)
  • msg.sig (bytes4): calldata 的前 4 字节(也就是函数标识符)
  • msg.value (uint): 随消息发送的 wei 的数量
  • now (uint): 目前区块时间戳(block.timestamp)
  • tx.gasprice (uint): 交易的 gas 价格
  • tx.origin (address): 交易发起者(完全的调用链)

相关文章

网友评论

      本文标题:Solidity 事件、继承、全局变量

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