• solidty提升篇-智能协议-合约的所有权-gas-带参数的函数修饰符


    智能协议的永固性

    有几点以太坊上的 DApp 跟普通的应用程序有着天壤之别。

    把智能协议传上以太坊之后,它就变得不可更改, 这种永固性意味着你的代码永远不能被调整或更新。
    你编译的程序会一直,永久的,不可更改的,存在以太坊上。这就是 Solidity 代码的安全性如此重要的一个原因。如果你的智能协议有任何漏洞,即使你发现了也无法补救。你只能让你的用户们放弃这个智能协议,然后转移到一个新的修复后的合约上。

    外部依赖关系

    在引用外部关系的时候,不能硬编码,而要采用“函数”,以便于 DApp 的关键部分可以以参数形式修改。

    指定合约的“所有权”

    Ownable 合约基本都会这么干:

    合约创建,构造函数先行,将其 owner 设置为msg.sender(其部署者)

    为它加上一个修饰符 onlyOwner,它会限制陌生人的访问,将访问某些函数的权限锁定在 owner 上。

    允许将合约所有权转让给他人。

    构造函数:

    function Ownable()是一个 _ constructor_ (构造函数),构造函数不是必须的,它与合约同名,构造函数一生中唯一的一次执行,就是在合约最初被创建的时候。

    函数修饰符 onlyOwner-在禁止第三方修改我们的合约的同时,只允许自己去修改:

    modifier onlyOwner()。 修饰符跟函数很类似,不过是用来修饰其他已有函数用的, 在其他语句执行前,为它检查下先验条件。 在这个例子中,我们就可以写个修饰符 onlyOwner 检查下调用者,确保只有合约的主人才能运行本函数。
    函数修饰符看起来跟函数没什么不同,不过关键字modifier 告诉编译器,这是个modifier(修饰符),而不是个function(函数)。它不能像函数那样被直接调用,只能被添加到函数定义的末尾,用以改变函数的行为。

    /**
     * @dev 调用者不是‘主人’,就会抛出异常
     */
    modifier onlyOwner() {
      require(msg.sender == owner);
      _;
    }
    onlyOwner 函数修饰符是这么用的:
    
    contract MyContract is Ownable {
      event LaughManiacally(string laughter);
    
      //注意! `onlyOwner`上场 :
      function likeABoss() external onlyOwner {
        LaughManiacally("Muahahahaha");
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Gas

    一个 DApp 收取多少 gas 取决于功能逻辑的复杂程度,一次操作所需要花费的 gas 等于这个操作背后的所有运算花销的总和。
    注意:如果你使用侧链,倒是不一定需要付费,比如咱们在 Loom Network 上构建的 CryptoZombies 就免费。

    省 gas 的招数:结构封装 (Struct packing)

    当 uint 定义在一个 struct 中的时候,尽量使用最小的整数子类型以节约空间。 并且把同样类型的变量放一起(即在 struct 中将把变量按照类型依次放置),这样 Solidity 可以将存储空间最小化。例如,有两个 struct:

    uint c; uint32 a; uint32 b; 和 uint32 a; uint c; uint32 b;

    前者比后者需要的gas更少,因为前者把uint32放一起了。

    时间单位

    Solidity 使用自己的本地时间单位。
    变量 now 将返回当前的unix时间戳(自1970年1月1日以来经过的秒数)
    Solidity 还包含秒(seconds),分钟(minutes),小时(hours),天(days),周(weeks) 和 年(years) 等时间单位。它们都会转换成对应的秒数放入 uint 中。所以 1分钟 就是 60,1小时是 3600(60秒×60分钟),1天是86400(24小时×60分钟×60秒),以此类推。

    带参数的函数修饰符

    修饰符可以像函数一样接收参数,是“宿主”函数把参数传递给它的修饰符的。
    记住,修饰符的最后一行为 _;,表示修饰符调用结束后返回,并执行调用函数余下的部分。

    // 存储用户年龄的映射
    mapping (uint => uint) public age;
    
    // 限定用户年龄的修饰符
    modifier olderThan(uint _age, uint _userId) {
      require(age[_userId] >= _age);
      _;
    }
    
    // 必须年满16周岁才允许开车 (至少在美国是这样的).
    // 我们可以用如下参数调用`olderThan` 修饰符:
    function driveCar(uint _userId) public olderThan(16, _userId) {
      // 其余的程序逻辑
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    《Nature Medicine》:达摩院医疗AI攻克胰腺癌早筛难题,2万病例中发现31例漏诊
    SpringSecurity源码学习五:跨域与跨站请求伪造
    lock_icon_container LockIconContainer的显示
    【Django】model模型—字段关联关系:多对多
    ubuntu18安装caffe(CPU)
    海尔智家:科技优秀是一种习惯
    SpringCloud-01
    8、RedLock协议
    python使用requests实现发送带文件请求
    MySQL数据的基础语法
  • 原文地址:https://blog.csdn.net/weixin_52723971/article/details/125644424