区块链智能合约重点讲解

一、solidity中的特殊变量

solidity中有一些特殊变量,不需要定义即可以使用,其实是EVM中的内置变量,对应的映射如下所示:

  • block.blockhash(uint blockNumber) returns (bytes32): hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by blockhash(uint blockNumber).
  • block.coinbase (address): current block miner’s address
  • block.difficulty (uint): current block difficulty
  • block.gaslimit (uint): current block gaslimit
  • block.number (uint): current block number
  • block.timestamp (uint): current block timestamp as seconds since unix epoch
  • gasleft() returns (uint256): remaining gas
  • msg.data (bytes): complete calldata
  • msg.gas (uint): remaining gas - deprecated in version 0.4.21 and to be replaced by gasleft()
  • msg.sender (address): sender of the message (current call)
  • msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)
  • msg.value (uint): number of wei sent with the message
  • now (uint): current block timestamp (alias for block.timestamp)
  • tx.gasprice (uint): gas price of the transaction
  • tx.origin (address): sender of the transaction (full call chain)

二、solidity中的函数修饰符

Solidity 0.4.16 引入了 view 和 constant 修饰符,用来描述函数的属性,除了这几个,还有internal、external、private、public、payable。

  • private: 私有函数。内部访问,外部无法访问,子类无法继承。
  • public: 公共函数。内部正常访问,外部正常访问, 子类可继承。
  • internal: 内部函数。内部访问,外部无法访问,子类可以继承。
  • external: 外部函数。内部不能访问, 外部正常访问, 子类可继承。

    • view: 没有改变state的函数声明为view
      note:
      constant on functions used to be an alias to view, but this was dropped in version 0.5.0.
      Getter methods are marked views

    • pure: 即不读state也不改变state

pragma solidity ^0.4.19;

contract Test {
    uint id = 0;

    function get_id() public pure returns(uint) {
        return id;
    }
}

这里的pure函数读取id,id存在于state中,sol compiler会报error,改成constant或者view即可通过。

test.sol:7:16: Error: Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".
        return id;
  • payable: 专用于接收value,修改smart contract账户的balance。

三、smart contract对Ether的处理

标记有payable的函数才能对msg.value进行处理,但是这其实并不是由solidity本身决定的,而是通过vm和solidity一起作用的。正如parity中实现,在params.value != 0 的时候,call一个非payable的函数或者create contract的时候,evm返回revert。如果vm不返回revert,那么kernel在启动vm之前由于已经将value转到params.address中,这笔钱就花冤枉了。在call一个payable函数的时候,如果没有其他错误,返回EvmSuccess。

note: 网上有说在call一个deposit payable函数的时候,已经将value转到了合约账户中,这个动作就是在kernel中完成的。所以通过deposit函数能拿到(address(this).balance)合约账户更新后的balance

这是我的一个测试用例:

pragma solidity ^0.4.15;

contract Test {
    uint id = 99;

    function get_id() public constant returns(uint) {
        return id;
    }

    function get_money() public constant returns(uint) {
        return address(this).balance;
    }
}
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页