Solidity 入门教程之 Owner 案例学习

在 remix 中有三个例子这是第2个 Owner 案例,看这篇之前,请先确定看过之前的2篇。

Owner 这个案例,主要是存储、检查、修改智能合约的以太坊地址。

源码如下

pragma solidity >=0.7.0 <0.8.0;

/**
@title Owner
@dev Set & change owner
*/
contract Owner {

  address private owner;

  // event for EVM logging
  event OwnerSet(address indexed oldOwner, address indexed newOwner);
  // modifier to check if caller is owner
  modifier isOwner() {
     // If the first argument of 'require' evaluates to 'false', execution terminates and all
     // changes to the state and to Ether balances are reverted.
     // This used to consume all gas in old EVM versions, but not anymore.
     // It is often a good idea to use 'require' to check if functions are called correctly.
     // As a second argument, you can also provide an explanation about what went wrong.
     require(msg.sender == owner, "Caller is not owner");
     _;
 }
  /**
  @dev Set contract deployer as owner
  */
  constructor() {
    owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
    emit OwnerSet(address(0), owner);
 }

  /**
  @dev Change owner
  @param newOwner address of new owner
  */
  function changeOwner(address newOwner) public isOwner {
    emit OwnerSet(owner, newOwner);
    owner = newOwner;
  }

  /**
  @dev Return owner address 
  @return address of owner
  */
   function getOwner() external view returns (address) {
     return owner;
   }
 } 

接下来开始分析

contract Owner 定义一个智能合约 Owner。

address private owner; 定义一个数据类型是 address、属性是 private 的变量。private 表示只能当前合约访问,继承合约也不能访问,跟我们接触其他语言一样。

address 是智能合约或用户的以太坊地址,这是一个以太坊的数据类型,像 stringuint 类型一样。

event OwnerSet(address indexed oldOwner, address indexed newOwner);

声明一个事件。事件是合约和区块链通讯的一种机制,前端应用可以监听某些事件。indexed 表示这个事件变量可以被搜索。会通过 emit 关键字触发事件。

modifier isOwner() {
     require(msg.sender == owner, "Caller is not owner");
     _;
 }

modifier 声明一个函数修饰器,这有点像 python 和 javascript 的修饰器。_; 是一个固定写法,表示被修饰的函数体内容。

msg.sender 是一个全局变量,表示当前调用者或者智能合约的 address。

require 检查条件不满足时抛出异常,并停止执行。

这段代码的意思就是声明一个函数器,用于检查发送者是否等于智能合约中的拥有者。

constructor() {
     owner = msg.sender;
     emit OwnerSet(address(0), owner);
 }

constructor 是构造函数,跟我们理解的 class 的构造函数一样。智能合约部署时执行。函数内设置 owner 的变量等于部署者的 address,并触发事件 OwnerSet

function changeOwner(address newOwner) public isOwner {
     emit OwnerSet(owner, newOwner);
     owner = newOwner;
 }

定义一个函数 changeOwner 修改智能合约的所有者,其中用到了刚才定义的修饰器 isOwner,这个写法跟 python 的@符号不一样。

function getOwner() external view returns (address) {
    return owner;
}

定义一个函数 getOwner 返回智能合约的所有者。这里用到了一个 external 属性,顾名思义这个函数只能在合约之外调用,但是不能被合约内的其他函数调用,这也是于 public 的不同之处。

总结一下

这个例子涉及到知识点有点多,privateexternal 限制条件,address 数字类型,msg.sender 全局变量,require 条件检测,事件,函数修饰器。

Leave a Reply

Your email address will not be published. Required fields are marked *