div#pop_ad { opacity: 0; }
AD
首页 > 数字货币 > 正文

「链块技术39期」以太坊智能合约语言(四):Solidity函数(下)

[2021-01-29 08:10:54] 来源: 编辑:wangjia 点击量:
评论 点击收藏
导读: 原文链接 http://www.liankuai.tech/public/technology/80.html区块链技术教程——智能合约,本文主要讲解了区块链开发技术——以太坊智能合约语言Solid
原文链接 http://www.liankuai.tech/public/technology/80.html

区块链技术教程——智能合约,本文主要讲解了区块链开发技术——以太坊智能合约语言Solidity 函数的种类。

十一、 函数的输入参数与输出参数
Solidity函数的输入参数的数量是可选的,也可以有任意数量的返回参数。

入参(Input Parameter)与变量的定义方式一致,稍微不同的是,不会用到的参数可以省略变量名称。一种可接受两个整型参数的函数如下:
pragma solidity ^0.4.0;contract Simple { function taker(uint _a, uint) { // do something with _a. }}

出参(Output Paramets)在returns关键字后定义,语法类似变量的定义方式。返回结果的数量需要与定义的一致。如果给定了参数名,则函数可以不适用return关键字返回,如果没有给定参数名则需要函数体重使用return关键字按照顺序返回。
pragma solidity ^0.4.24;contract Simple { //return sum and product function arithmetics(uint _a, uint _b) returns (uint o_sum, uint o_product) { o_sum = _a + _b; o_product = _a * _b; }}pragma solidity ^0.4.24;contract Simple { //return sum and product function arithmetics(uint _a, uint _b) pure returns (uint , uint ) { return(_a + _b,_a * _b); }}

十二、访问函数
编译器为自动为所有的public的状态变量创建访问函数。下面的合约例子中,编译器会生成一个名叫data的无参,返回值是uint的类型的值data。状态变量的初始化可以在定义时完成。
pragma solidity ^0.4.0;contract C{ uint public c = 10;}contract D{ C c = new C(); function getDataUsingAccessor() returns (uint){ return c.c(); }}

访问函数有外部(external)可见性。如果通过内部(internal)的方式访问,比如直接访问,你可以直接把它当一个变量进行使用,但如果使用外部(external)的方式来访问,如通过this.,那么它必须通过函数的方式来调用。
pragma solidity ^0.4.0;contract C{ uint public c = 10; function accessInternal() returns (uint){ return c; } function accessExternal() returns (uint){ return this.c(); }}

十三、抽象函数
是没有函数体的的函数。如下:
pragma solidity ^0.4.0;contract Feline { function utterance() returns (bytes32);}

这样的合约不能通过编译,即使合约内也包含一些正常的函数。但它们可以做为基合约被继承。
pragma solidity ^0.4.0;contract Feline { function utterance() returns (bytes32); function getContractName() returns (string){ return "Feline"; }}contract Cat is Feline { function utterance() returns (bytes32) { return "miaow"; }}

如果一个合约从一个抽象合约里继承,但却没实现所有函数,那么它也是一个抽象合约。

十四、数学和加密函数
以下函数式solidity自带的函数

asser(bool condition):

如果条件不满足,抛出异常。

addmod(uint x, uint y, uint k) returns (uint):

计算(x + y) % k。加法支持任意的精度。但不超过(wrap around?)2**256。

mulmod(uint x, uint y, uint k) returns (uint):

计算(x * y) % k。乘法支持任意精度,但不超过(wrap around?)2**256。

keccak256(...) returns (bytes32):

使用以太坊的(Keccak-256)计算HASH值。紧密打包。

sha3(...) returns (bytes32):

等同于keccak256()。紧密打包。

sha256(...) returns (bytes32):

使用SHA-256计算HASH值。紧密打包。

ripemd160(...) returns (bytes20):

使用RIPEMD-160计算HASH值。紧密打包。

ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address):

通过签名信息恢复非对称加密算法公匙地址。如果出错会返回0,例如:
function verify(bytes32 hash, uint8 v, bytes32 r, bytes32 s) constant returns(bool) { bytes memory prefix = "\\x19Ethereum Signed Message:\n32"; bytes32 prefixedHash = keccak256(prefix, hash); return ecrecover(prefixedHash, v, r, s) == (Your Address);}

revert():

取消执行,并回撤状态变化。

需要注意的是参数是“紧密打包(tightly packed)”的,意思是说参数不会补位,就直接连接在一起的。下面来看一个例子:
keccak256("ab", "c")keccak256("abc")//hexkeccak256(0x616263)keccak256(6382179)//asciikeccak256(97, 98, 99)

上述例子中,三种表达方式都是一致的。

如果需要补位,需要明确的类型转换,如keccak256("\\x00\\x12")等同于keccak256(uint16(0x12))

需要注意的是字面量会用,尽可能小的空间来存储它们。比如,keccak256(0) == keccak256(uint8(0)),keccak256(0x12345678) == keccak256(uint32(0x12345678))

注意:

在私链(private blockchain)上运行sha256,ripemd160或ecrecover可能会出现Out-Of-Gas报错。因为它们实现了一种预编译的机制,但合约要在收到第一个消息后才会存在。向一个不存在的合约发送消息,非常昂贵,所以才会导致Out-Of-Gas的问题。一种解决办法是每个在你真正使用它们前,先发送1 wei到这些合约上来完成初始化。在官方和测试链上没有这个问题。

-END-


「链块技术39期」以太坊智能合约语言(四):Solidity函数(下)


附上链块学院网课学习平台链接:http://wk.liankuai.tech/

助教卫星:lkxy007


添加新手交流群:币种分析、每日早晚盘分析

添加助理微信,一对一亲自指导:YoYo8abc

查看更多:

为您推荐