第三课就开始深入讲解solidity编程技巧了。

chapter1: 智能合约的不变性。

  合约一旦部署到以太坊后,就不可更改了,所以从一方面来说,智能合约代码的安全性是如此重要,因为一旦发现你的代码里存在漏洞,那么你只能放弃这个合约,告诉你的用户去另外一个新地址调用修复过的新合约。那么另一方面,如果你想调用某一个智能合约,尽管放心,它永远不会失效或者给出意料之外的结果。

  所以当我们调用了一个不再更新的合约地址时,该怎么办呢?solidity有一个解决办法,调用接口时不会直接声明合约的地址,而是用一个设置地址的函数代替,方便我们在未来修改地址。

  原调用方式:

  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
KittyInterface kittyContract = KittyInterface(ckAddress);

  新调用方式:

 KittyInterface kittyContract;

 function setKittyContractAddress(address _address) external{
kittyContract = KittyInterface(_address);
}

chapter2:Ownable Contracts

  上述代码中,setKittyContractAddress是external的,意味着任何一个外部用户都可以更改调用地址,所以存在安全漏洞,所以定义了一个合约的Ownable,即拥有合约者有调用该函数的特权。推荐了OpenZeppilin库,是一个主打安全和社区审查的智能合约库,Ownable合约即来自其中。可以去官网学习更多。

  这章里又涉及了几个新的概念:

  构造函数:函数名同合约名,在合约开始时自动调用,相当于一个初始化函数。

  函数修饰符:modifier functionName();在函数执行前检查约束条件。下一章节会详述更多细节。

  Ownable合约代码:

/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
} /**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
} /**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}

  使用时把代码复制到Ownable.sol然后继承即可。

chapter3:函数修饰符

  继承可连续继承,modifier不可和function一样直接调用,调用方法见上文onlyOwner例。调用函数时先执行修饰符函数,当执行到modifier里的_;时,跳出继续执行原函数。

**当然这也带来一个安全隐患,开发者可以给智能合约留下一个只有自己可以操作的后门。导致以太坊上Dapp并不完全是绝对的去中心化的,所以一定要阅读并理解代码,防止恶意植入后门。作为开发者,既留下修改bug的权限,又能让用户完全放心,是一个微妙的平衡,也许以后会有新技术出现完全杜绝这种情况发生。

chapter4:gas

  相当于执行函数时需要的能源。执行一次语句消耗多少gas取决于语句的复杂度,即需要多少计算资源去完成这段语句,比如写入storage比两个整数相加消耗的gas多得多。所以,Dapp的代码优化相当重要。

  为什么要使用gas?这段写的特别好,摘抄下来:

  以太坊相当于一个巨大、缓慢、又极度安全的计算机,每当有一个函数运行时,以太坊中每一个节点都会运行该函数以验证结果。以此保证以太坊的去中心化、数据不可篡改和抗监视。为了防止有人通过死循环阻塞网络,或者非常密集的运算大量占用网络资源,以太坊让这些交易需要付出代价,

  但是侧链不一定需要这样,所以一些极为复杂的应用可以应用在使用不同共识算法的侧链上。

  用更小的存储单位,比如uint换成uint32不会减少gas消耗,但有一个例外:在struct里使用,solidity会打包存储消耗更少的storage,从而消耗较少gas。同时将相同类型变量聚在一起,比如uint a,uint 32 b, uint 32 c会比uint32 b, uint a, uint32 c消耗的存储空间小。

chapter5:time units

  变量now返回值是当前最后区块的时间戳(从1970.1.1到现在的秒数),是一个256位uint。Unix时间变量基本都是存储在32位整数变量里的,所以如果想要你的dapp运行时间超过这个存储范围,需要改为64或更高位存储。

solidity还提供了例如seconds,minutes,hours,days,weeks等时间常量,都是换算成秒的整数。

chapter6:结构体可以以存储指针形式作为参数传入internal或private函数。遵循这种语法:

function _doStuff(Zombie storage _zombie) internal {
// do stuff with _zombie
}

chapter7:Public函数和安全

  检视public且没有加modifier的函数,看是否存在被其他用户滥用所导致的安全漏洞。

chapter8:更多关于函数修饰符

  modifier作为函数修饰符时也可以传递参数,格式和函数调用一样。

// A mapping to store a user's age:
mapping (uint => uint) public age; // Modifier that requires this user to be older than a certain age:
modifier olderThan(uint _age, uint _userId) {
require(age[_userId] >= _age);
_;
} // Must be older than 16 to drive a car (in the US, at least).
// We can call the `olderThan` modifier with arguments like so:
function driveCar(uint _userId) public olderThan(16, _userId) {
// Some function logic
}

chapter9:利用modifier完成一些新功能

chapter10:利用view减少gas消耗

  view修饰的函数调用时不消耗gas,因为调用view前缀函数并不会对区块链造成任何更改,一个注意点,只有当外部调用时才不消耗gas,被内部非view函数调用还是会消耗gas。

chapter11:storage存储是昂贵的

  尤其是写入。可以用memory数组代替,在当前版本里,memory数组必须在定义时声明数组大小。

chapter12:for循环

  在需要修改storage的时候,有时候for循环遍历view函数并储存可以减少消耗gas。语法类似js。

  

  

  

CryptoZombies学习笔记——Lesson3的更多相关文章

  1. CryptoZombies学习笔记——Lesson1

    CryptoZombies是一个学习以太坊开发的平台,我将在这里记录学习过程中的一些笔记. 课程网址:cryptozombies.io 首先是第一课——Lesson1:Making the Zombi ...

  2. CryptoZombies学习笔记——Lesson5

    chapter1:token代币 简而言之,通证就是支持交易的包含一系列规范的函数接口的一个智能合约,发币可以用ERC20标准,但是像僵尸这种非同质化代币,需要用ERC721标准 chapter2:e ...

  3. CryptoZombies学习笔记——Lesson2

    第二课是僵尸猎食,将把app变得更像一个游戏,添加多人模式,建立更多创造僵尸的方法. chapter1 依然是简介 chapter2:映射和地址 映射相当于一个索引,指向不同地址,不同地址存储的数据不 ...

  4. CryptoZombies学习笔记——Lesson4

    第四课主要介绍payable函数相关. chapter1: payable修饰函数 以太坊允许同时调用函数和eth转账.msg.value显示发送到合约的以太币数,ether是内置整型数.如果函数没有 ...

  5. 孙鑫视频VC++深入详解学习笔记

    孙鑫视频VC++深入详解学习笔记 VC++深入详解学习笔记 Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Le ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  8. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  9. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

随机推荐

  1. IOC-AutoFac

    学习过程中参考博客: AutoFac文档:http://www.cnblogs.com/wolegequ/archive/2012/06/09/2543487.html AutoFac使用方法总结:P ...

  2. oracle查询相关注意点

    单表查询: .or 和 and 混合使用 需求:查询业主名称包含'刘'或门牌号包含'5'的,并且地址编号为3的记录 and 的权限优先于 or 所以需要在or的两边添加() 2. 范围查询 除了传统的 ...

  3. Asp.net 中 OnClientClick 与 OnClick 的区别

    OnClientClick 是客户端事件处理方法,一般采用JavaScript来进行处理,也就是直接在IE端运行,一点击就运行. OnClick 是服务器端事件处理方法,在服务器端也就是IIS中运行, ...

  4. 红帽RHEL6.8离线环境下升级到RHEL7.3

    Red Hat Enterprise Linux 7 (RHEL 7) 是第一个支持从前一个 RHEL 主发行版本(RHEL 6)进行原位(in-place)升级的 RHEL 主版本.原位升级(in- ...

  5. 解决微信小程序安卓手机访问不到图片,无法显示图片

    关于微信小程序不显示图片 通病可能有以下几个可能性: 非本地图片:确定图片资源存在,copy 图片url再浏览器打开,确定图片资源存在且能正常访问 本地图片:确定相对路径或者绝对路径正确 微信小程序图 ...

  6. 初识Pentaho(一)

    学习一门语言或工具,首先得知道该工具的用途是什么.Pentaho 的官方定义是一个集数据集成和数据分析于一体的平台.这样的解释还是有点模糊.还是看其有哪些特点吧:  ☐可以进行数据集成.谈到数据集成这 ...

  7. PAT A1060 (Advanced Level) Practice

    If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered ...

  8. vuejs中的生命周期

    vue中生命周期分为初始化,跟新状态,销毁三个阶段 1.初始化阶段:beforeCreated,created,beforeMount,mounted 2.跟新状态:beforeUpdate,upda ...

  9. Java设计模式(5)——创建型模式之建造者模式(Builder)

    一.概述 概念 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.(与工厂类不同的是它用于创建复合对象) UML图   主要角色 抽象建造者(Builder)——规范建造方法与结果 ...

  10. PHP.52-TP框架商城应用实例-前台4-商品详情页-面包屑导航、AJAX浏览历史

    面包屑导航  思路:根据商品的主分类向上取出所有上级分类即可 1.在分类模型中增加取出所有上级分类的方法 /********** [面包屑导航]取出一个分类所有上级分类 **********/ pub ...