详述Solidity数据类型之一:值类型

踩便便的小菇凉
踩便便的小菇凉 2018-05-17 10:37
2 32309
作者:梁雁明
著权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
<p>类型
Solidity是一种静态类型语言,也就意味着,每一种变量的类型(状态或局部变量)需要在编译期间被确定。Solidity提供了一些基本数据类型,可以用于构建复杂类型。
补充说明,数据类型可以在包括操作符的表达式中相互转化,详情见:Order of Precedence of Operators。
<p>值类型
因为这些类型的变量总是通过值传递,所以以下类型被称为值类型,也就是说,在函数参数或者是赋值操作时,他们都会被复制。
<p>Booleans
bool:可取值常量是 true 和 false.
操作符:
<p>·       ! (逻辑非)
<p>·       &amp;&amp; (逻辑且, "and")
<p>·       || (逻辑或, "or")
<p>·       == (等于)
<p>·       != (不等于)
|| 和&amp;&amp; 操作适应于短路规则,也就是说在表达式 f(x) || g(y)中,如果 f(x) 是 true, g(y) 不会再执行运算,即使有其它影响。
<p>Integers
int / uint:范围不同的有符号和无符号整形类型。以 8 为步长从uint8 到 uint256 的关键字(unsigned of 8 up to 256 bits) ,int8 到 int256与此类似. uint 和int 分别是uint256和 int256的别名.
操作:
<p>·       比较运算: &lt;=, &lt;, ==, !=, &gt;=, &gt; (返回 bool结果)
<p>·       位操作: &amp;, |, ^ (与 或 非), ~ (非)
<p>·       算术运算: +, -, 一元-, 一元+, *, /, % (取余), ** (求幂), &lt;&lt; (左位移), &gt;&gt; (右位移)
除法操作往往会对产生数字片断(除法被编译成EVM里的 DIV 操作码),但如果常量数据的话,是不会进行截取的,例如5/2不等于2, 而是等于 2.5。
<p>
被0除或者以0取余都会导致异常。                                  
位移操作的结果类型是左操作数的类型。表达式 x &lt;&lt; y 等于 x * 2**y, x &gt;&gt; y 等于 x / 2**y.也就意味着,对负数进行位移会导致越位. 且负数位移会导致运行时异常。
<b>警告
对有符号的负数进行右位移操作的结果与其它编程语言是不同的。在Solidity中,右位移操作会映射成除法,所以被位移的数值会渐渐转化为0。在其它编程语言中,负数的右移位操作与以四舍五入式的除法很类似(趋向于负无穷大)。
<p>固定点位数字
<b>警告
固定点位数字还没有被Solidity完全支持,固定点位数字可以被声明,但是不能被分配,也不能被指向到。
fixed / ufixed: 有符号和无符号不同范围的固定点数数字,关键字ufixedMxN与 fixedMxN, 其中M 代表类型的整数有效位数,N 代表了小数有效位数. M必须能够被8整数而且范围从8到256位. N的范围必须是从0到80,包括80. ufixed 和fixed 分别是 ufixed128x19 和fixed128x19的别名.
操作:
<p>·       比较运算: &lt;=, &lt;, ==, !=, &gt;=, &gt; (evaluate to bool)
<p>·       算术运算: +, -, 一元-, 一元+, *, /, % (取余)
<b>注解
浮点类型(float 和double在很多语言中,更加精准的IEEE 754标准数字)与固定点数数字的最主要不同在于:整数位与小数位部分的位数在前者更加灵活,而在后者是严格定义的。通常来说,在浮点数中,几乎全部的空间被用来表示数值,然而只有少数bit用来表示小数点位。
<p>地址
address: 20字节(160位)值(以太坊地址的大小).地址类型也有一些成员变量,地址是所有智能合约的服务基础。
操作:
<p>·       &lt;=, &lt;, ==, !=, &gt;= and &gt;
<b>注解
从智能合约0.5.0版本之后,没有地址类型address, 却仍可以被显示转化成地址类型。
<p>地址的成员变量
<p>·       balance 和transfer
For a quick reference, see Address Related.
可以通过属性balance 去查询该地址上的余额信息,也可以通过使用 transfer 方法发送Ether到Address地址上:
<b>注解
如果x是一个合约地址, 它的代码(更明确一些: 它的回滚方法, 如果具有此方法) 会和transfer 方法一起被调用(这是EVM的特性且不能被阻止). 如果执行过程gas用光或因其它问题出错,Ether转账操作会恢复初始状态,当前合约会以抛出异常的方式结束执行。
<p>·       send
send方法是与transfer功能相似。如果执行失败,当前合约同样以异常方式结束执行,但send 方法会返回 false
<b>警告
在使用send方法时会有一些危险: 如果堆栈调用深度达到1024时,转账会失败,(实施者往往可以强制实现此过程),或当接受者gas用光时,也会导致转账失败.所以为了安全进行Ether转账, 请多检查send方法的返回值, 使用transfer方法也许会更好: 使用一种可以让接收者可以返还Ether的模式。
<p>·       call, callcode 和delegatecall
而且,为了使智能合约交互不依附于ABI(应用程序二进制接口),方法call 被提供,以包含任意类型、任意长度的参数,这此参数被整合在32个字节的空间中并被整合连接起来。当第一个参数被准确的编码为4字节时,会导致异常,在这种情况下,不会允许使用签名功能。
call 方法返回boolean,用以区别被调用的功能是以(true) 执行成功结束或者是以EVM 异常(false)结束运行. 直接访问实际的返回数据是不可能的(如果这样的话,我们需要提前知道其编码和大小).
可以通过调用.gas() 方法来调整gas供应:
同样地, 以太币的数量也可以被调整:
最后,以上两种调整方法可以进行合并,其中顺序并不重要:
<b>注解
仍然不能在负载的方法上使用gas或value的修改方法。
引入工作区的概念,是为了以处理gas和value特殊情况,以重新检查他们是否存在于重载节点。
<p>
相同地, 也可以使用delegatecall方法:区别是,只有给定地址的代码会被使用,而其它方面(storage, balance, ...)会从当前合约中去除. delegatecall 的目的是调用存储在另一个合约中的库代码. 使用者必须确保两合约的存储布局合理以便delegatecall方法可被使用。在homestead之前, 只有名叫callcode 的限制版本是可用的,并不提供可以访问到原始msg.sender 和msg.value.
所有 call, delegatecall 和callcode 这三个功能,都是low-level的方法,当打破Solidity的类型安全时,它们作为一种最终手段被调用(怎么听起来有点悲壮)。
.gas() 是所有的三个方法中都是有效的, 然而 .value()在 delegatecall中是不被支持的。
<b>注解
所有合约都继承地址成员,所以可以通过this.balance
2条回应 最新 最早
石聪
沙发# 石聪 2018-05-17 10:51
当今快速演变的区块链经济的世界里创造一个供企业家和技术开发者交流的平台,共同去发掘新的商业模式,发掘尚未被大众认识到的机会。
同林鸟
板凳# 同林鸟 2018-05-17 11:07
期待区块链发展出人类大协作的完美创业形态!
游客
登录后才可以回帖,登录 或者 注册