一起学智能合约之五函数和修改器

一起学智能合约之五函数和修改器

 

函数是所有的语言都离不开的。其实在上面的表达式里就简单的说明了函数的一些形式和用法,这里再整体说明一下。

Solidity的函数形式如下:

function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]

function 函数名(参数列表){调用修饰符}[函数属性][返回值列表]

看一个实例:

pragma solidity ^0.4.16;

 

contract C {

    function g(uint a) public pure returns (uint ret) { return f(); }

    function f() internal pure returns (uint ret) { return g(7) + f(); }

}

和上面的一对应就明白怎么回事了。现在主要介绍一下函数的高级用法:

  1. Solidity封装了两种函数的调用方式internal和external。

1)内部函数调用

当前合约中的函数可以直接(“从内部”)调用,也可以递归调用,就像下边这个荒谬的例子一样

pragma solidity ^0.4.16;

 

contract C {

    function g(uint a) public pure returns (uint ret) { return f(); }

    function f() internal pure returns (uint ret) { return g(7) + f(); }

}

 

这些函数调用在 EVM 中被解释为简单的跳转。这样做的效果就是当前内存不会被清除,也就是说,通过内部调用在函数之间传递内存引用是非常有效的。

2)外部函数调用

如果想要调用其他合约的函数,需要外部调用。对于一个外部调用,所有的函数参数都需要被复制到内存。虽然下面两个合约写到了一起,但和不写在一些,部署到链上的结果是一致的。

pragma solidity ^0.4.0;

 

contract InfoFeed {

    function info() public payable returns (uint ret) { return 42; }

}

 

contract Consumer {

    InfoFeed feed;

    function setFeed(address addr) public { feed = InfoFeed(addr); }

    function callFeed() public { feed.info.value(10).gas(800)(); }

}

 

说明:payable 修饰符要用于修饰 info,否则,.value() 选项将不可用。

external调用时,实际是向目标合约发送一个消息调用。消息中的函数定义部分是一个24字节大小的消息体,20字节为地址,4字节为函数签名2。如果被调函数所在合约不存在(也就是账户中不包含代码)或者被调用合约本身抛出异常或者 gas 用完等,函数调用会抛出异常。

3)this关键字

可以使用this关键字来强制以external方式的调用。注意,不可以在构造函数中通过 this 来调用函数,因为此时真实的合约实例还没有被创建。

4)具名调用和匿名函数参数

函数调用参数也可以按照任意顺序由名称给出,如果它们被包含在 {} 中, 如以下示例中所示。参数列表必须按名称与函数声明中的参数列表相符,但可以按任意顺序排列。

pragma solidity ^0.4.0;

 

contract C {

    function f(uint key, uint value) public {

        // ...

    }

 

    function g() public {

        // 具名参数

        f({value: 2, key: 3});

    }

}

5)函数重载

类似于大多数面向对象编程的语言,Solidity也是支持函数的重载的。

contract Simple {

    function func(uint num) public pure returns (uint count) {

        return  1;

    }

 

    function func(uint num, int id) public pure returns (uint count) {

        return 2;

    }

}

  1. Solidity为函数提供了四种可见性,external,public,internal,private。

1)external

external关键字表示合约函数调用的其它合约或者在交易中调用。在接收比较大的数组时性能可能会好一些。

2)public

函数默认声明为public。

这个没啥限制,想怎么访问就怎么访问,这其实相当于API。

3)internal

类似于protected,在本合约和继承合约中,只允许以internal的方式调用。

4)private

类似其它语言,只能在本合约中被访问(继承合约不可访问)。但是按照区块链的特性,其仍然可以被查看,只是不能被访问。

pragma solidity ^0.4.5;

 

contract Base{

    //指定私有

    function privateFun() private{}

 

    function callFun(){

        //内部调用

        privateFun();

    }

}

contract Simple is Base{

    //错误

    function callFun(){

        //privateFun();

    }

}

 

3、回退函数fallback

每个合约有且仅有一个没有名字的函数。函数没有参数和返回值。如果调用合约时,没有找到其它函数,即调用fallback函数。

另外,如果想对合约直接转帐(send()函数发送ether),那么这个回退函数也会执行。可以认为它是一个默认的接收函数。但为了安全起见,应该让此函数执行较少的动作。同时,限制此函数对gas的使用。(理论是2300gas)

所以在下列的操作中,都无法在fallback函数中执行,因为耗费的gas超过了2300。

1. 写入到存储(storage);

2. 创建一个合约;

3. 执行一个外部(external)函数调用,会花费非常多的gas;

4. 发送ether。

所以在部署合约前一定要进行安全测试,防止Gas超标,如果没有定义回退函数,那么向其发送以太坊,会引起异常并退回相应的以太坊(V0.4.0开始)。

pragma solidity ^0.4.0;

 

contract Simple{

  function(){

    //fallback function

  }

}

 

4、修改器modifier

函数修改器类似于SpringMVC的增强(前置增强,后置增强,环绕增强),其实说白了就是简单的代码重用技术,没有任何高深的知识。

修改器(Modifiers)可以用来改变一个函数的行为。比如用于在函数执行前检查某种前置条件。修改器是一种合约属性,可被继承,同时还可被派生的合约重写(override)。

下面是一个官网的防止重入的例子:

pragma solidity ^0.4.0;

contract Mutex {

    bool locked;

    modifier noReentrancy() {

        if (locked) throw;

        locked = true;

        _;

        locked = false;

    }

 

    /// This function is protected by a mutex, which means that

    /// reentrant calls from within msg.sender.call cannot call f again.

    /// The `return 7` statement assigns 7 to the return value but still

    /// executes the statement `locked = false` in the modifier.

    function f() noReentrancy returns (uint) {

        if (!msg.sender.call()) throw;

        return 7;

    }

}

5、总结

从上面的分析来看,Solidity的函数并没有什么高深的知识,只要是掌握其它语言,学习这个应该是很简单的,不过需要注意的是,要把一些细节吃透,防止出现异常。现在黑客越来越生猛,一不小心,就被割韭菜了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以太坊是一个平台,它上面提供各种模块让用户来搭建应用,如果将搭建应用比作造房子,那么以太坊就提供了墙面、屋顶、地板等模块,用户只需像搭积木一样把房子搭起来,因此在以太坊上建立应用的成本和速度都大大改善。具体来说,以太坊通过一套图灵完备的脚本语言(Ethereum Virtual Machinecode,简称EVM语言)来建立应用,它类似于汇编语言。我们知道,直接用汇编语言编程是非常痛苦的,但以太坊里的编程并不需要直接使用EVM语言,而是类似C语言、Python、Lisp等高级语言,再通过编译器转成EVM语言。上面所说的平台之上的应用,其实就是合约,这是以太坊的核心。合约是一个活在以太坊系统里的自动代理人,他有一个自己的以太币地址,当用户向合约的地址里发送一笔交易后,该合约就被激活,然后根据交易中的额外信息,合约会运行自身的代码,最后返回一个结果,这个结果可能是从合约的地址发出另外一笔交易。需要指出的是,以太坊中的交易,不单只是发送以太币而已,它还可以嵌入相当多的额外信息。如果一笔交易是发送给合约的,那么这些信息就非常重要,因为合约将根据这些信息来完成自身的业务逻辑。合约所能提供的业务,几乎是无穷无尽的,它的边界就是你的想象力,因为图灵完备的语言提供了完整的自由度,让用户搭建各种应用。白皮书举了几个例子,如储蓄账户、用户自定义的子货币等。 2013年年末,以太坊创始人Vitalik Buterin发布了以太坊初版白皮书,启动了项目。2014年7月24日起,以太坊进行了为期42天的以太币预售。2016年初,以太坊的技术得到市场认可,价格开始暴涨,吸引了大量开发者以外的人进入以太坊的世界。中国三大比特币交易所之二的火币网及OKCoin币行都于2017年5月31日正式上线以太坊。 [1] 自从进入2016年以来,那些密切关注数字货币产业的人都急切地观察着第二代加密货币平台以太坊的发展动向。作为一种比较新的利用比特币技术的开发项目,以太坊致力于实施全球去中心化且无所有权的的数字技术计算机来执行点对点合约。简单来说就是,以太坊是一个你无法关闭的世界计算机。加密架构与图灵完整性的创新型结合可以促进大量的新产业的出现。反过来,传统行业的创新压力越来越大,甚至面临淘汰的风险。比特币网络事实上是一套分布式的数据库,而以太坊则更进一步,她可以看作是一台分布式的计算机:区块链是计算机的ROM,合约是程序,而以太坊的矿工们则负责计算,担任CPU的角色。这台计算机不是、也不可能是免费使用的,不然任何人都可以往里面存储各种垃圾信息和执行各种鸡毛蒜皮的计算,使用它至少需要支付计算费和存储费,当然还有其它一些费用。最为知名的是2017年初以摩根大通、芝加哥交易所集团、纽约梅隆银行、汤森路透、微软、英特尔、埃森哲等20多家全球top金融机构和科技公司成立的企业以太坊联盟。而以太坊催生的加密货币以太币近期又成了继比特币之后受追捧的资产。  智能合约的潜在应用很多。彭博社商业周刊称它是“所有人共享但无法篡改的软件”。更高级的软件有可能用以太坊创建网络商店。区块链程序以太坊可以用来创建去中心化的程序、自治组织和智能合约,据纽约时报的报导,在2016年5月已经有数十个可用的程序。预期的应用目标涵盖金融、物联网、农田到餐桌(farm-to-table)、智能电网、体育,菠菜等。去中心化自治组织有潜力让许多原本无法运行或成本过高的营运模型成为可能。较知名的应用有:去中心化创业投资:The DAO用以太币资金创立,目标是为商企业和非营利机构创建新的去中心化营业模式、The Rudimental让独立艺术家在区块链上进行群众募资。社会经济平台:Backfeed。去中心化预测市场:Augur。物联网:Ethcore(一间以太坊公司)研发的客户端、Chronicled(一间区块链公司)发表了以太坊区块链的实物资产验证平台;芯片公司、物理IP创建者和生产者可以用植入的蓝牙或近场通信进行验证。Slock.It开发的智能锁可以在付费后自动打开,让用户在付费后可以帮电动车充电、或是打开租屋的房门。虚拟宝物交易平台:FreeMyVunk。版权授权:Ujo Music平台让创作人用智能合约发布音乐,消费者可以直接付费给创作人。伊莫珍·希普用此平台发布了一首单曲。智能电网:TransActive Grid让用户可以和邻居买卖能源。去中心化期权市场:Etheropt。钉住汇率的代币:DigixDAO提供与黄金挂钩的代币,在2016年四月正式营运。Decentralized Capital提供和各种货币挂钩的代币。移动支付:Everex让外劳汇款回家乡。客户端软件以太坊的两个主要的客户端软件是Geth和Parity。企业软件企业软件公司也正测试用以太坊作为各种用途。已知有兴趣的公司包括微软、IBM、摩根大通。德勤和ConsenSys在2016年

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值