目录

  Solidity 是一种静态语言类型,在编译前都要指定每个变量的类型。Solidity 提供了几种基本类型,通过几种基本类型的组合,可以组合成复杂类型。

  网络上有很多翻译后的关于 Solidity 类型介绍的文章,这里就不多介绍,只是着重介绍后面实例中会使用到的一些类型。

  上一章节中,我们讲了 使用 Browser-solidity 在 Go-Ethereum1.7.2 上进行简单的智能合约部署,本文中后面的实例,都可以在 Browser-solidity 中进行测试。

  

1、数组

  数组是可以在编译时固定大小的,也可以是动态的。对于存储器数组来说,成员类型可以是任意的(也可以是其他数组,映射或结构)。对于内存数组来说 ,成员类型不能是一个映射;如果是公开可见的函数参数,成员类型是必须是ABI类型的。

  固定大小k的数组和基本类型 T,可以写成 T[k], 动态数组写成 T[ ] 。例如, 有5个基本类型为 uint 的动态数组的数组 可以写成 uint[ ][5] ( 注意,和一些其他语言相比,这里的符号表示次序是反过来的)。为了访问第三动态数组中的第二个 uint, 必须使用 x[2][1](下标是从零开始的,访问模式和声明模式正好相反, 即x[2]是从右边剔除了一阶)。

  bytesstring 是特殊类型的数组。 bytes 类似于 byte[ ],但它是紧凑排列在calldata里的。string 等于 bytes , 但不允许用长度或所以索引访问(现在情况是这样的)。

  所以 bytes 应该优先于 byte[ ],因为它效率更高。

  

1.1、对数组的增删改查操作。

  在Browser-solidity的左侧,新建一个mshk_top_array.sol文件,内容如下:

  mshk_top_array.sol:

pragma solidity ^0.4.17;

/**
* 数组的增、删、改、查
* https://mshk.top
*/
contract mshk_top_array { //声明一个全局数组变量
uint[] public intArray; /*
* 构造函数
* 默认向数组中添加一个2009
*/
function mshk_top_array() public{
intArray.push(2009);
} /*
* @dev 添加一个值到数组
* @param val uint, 要传入的数值
*/
function add(uint val) public{
intArray.push(val);
} /*
* @dev 获取数组的长度
* @return len uint,返回数组的长度
*/
function length() public view returns (uint) {
return intArray.length;
} /*
* @dev 更新数组的值
* @param _index uint, 指定的索引
* @param _value uint, 要修改的值
*/
function update(uint _index, uint _value) public{
intArray[_index] = _value;
} /*
* @dev 获取指定数组索引的值
* @param _index uint, 索引值
* @return _value uint, 返回结果
*/
function valueByIndex(uint _index) public view returns (uint _value){
uint result = intArray[_index];
return result;
} /*
* @dev 删除指定数组索引的值
* @param _index uint, 索引值
*/
function delByIndex(uint _index) public{
uint len=intArray.length;
if (_index >= len) return;
for (uint i = _index; i<len-1; i++){
intArray[i] = intArray[i+1];
}
delete intArray[len-1];
intArray.length--;
}
}

Array类型有两个成员,lengthpush

更多介绍参考链接: http://solidity.readthedocs.io/en/latest/types.html?highlight=uint#members

  

  在左侧写完代码以后,可以在右侧的Setting选择0.4.17+commit.bdeb9e52,然后在Run选项卡中,进行调试。

  之前的文章中有介绍如何使用Browser-solidity调试Solidity,本文中不多介绍,没看过的同学,可以参考 这里

2、String、Bytes、Mapping的使用

  string类型没有length属性,而bytes类型有length属性

  

  bytes1, bytes2, bytes3, ..., bytes32,如果在bytes后面带了数字进行声明时,最多可以保存32个字符。一旦声明以后,那么length属性就是你声明的长度。

  

  mapping,是由键和值组成的mapping(_KeyType => _ValueType)哈希表,初始化每个存在的key,对应的value的值会初始化为所有的字节都为0。_KeyType_ValueType可以是任意类型。mapping只允许静态变量或是内部方法中的存储空间引用类型。一般键为地址, 值为余额 mapping(address => uint)

string类型的官方介绍:http://solidity.readthedocs.io/en/latest/types.html?highlight=uint#string-literals

bytes数组的官方介绍:http://solidity.readthedocs.io/en/latest/types.html?highlight=bytes#fixed-size-byte-arrays

Mappings类型的官方介绍:http://solidity.readthedocs.io/en/latest/types.html?highlight=bytes#mappings

  

  下面我们创建一个mshk_top_string_bytes_mapping.sol文件,对stringbytesmapping进行测试。

  mshk_top_string_bytes_mapping.sol:

pragma solidity ^0.4.17;

/**
* 对`string`、`bytes`、`mapping`进行测试
* https://mshk.top
*/
contract mshk_top_string_bytes_mapping { //声明一个变量
string public str;
bytes public byt;
mapping(bytes10 => string) public map; /*
* 初始化
*/
function init() public{
str = "abc";
byt = "abc";
map["mshk"] = "mshk.top";
map["idoall"] = "idoall.org";
} /*
* @dev 获取长度
* @param uint 返回长度
*/
function lenght() public view returns(uint){
return byt.length;
} /*
* @dev 获取map的指定key的值
* @param _key bytes10,指定的key,如果key不存在,会返回空字符串
*/
function getMapByKey(bytes10 _key) public view returns(string){
return map[_key];
}
}

  

  下图是在Browser-solidity中运行起来的效果:

  

3、Enums 和 Structs 的简单应用

  Enums是一个用户可以定义类型的方法,可以使用uint转换,默认从0开始递增,但不可以隐性转换,转换失败会抛出异常,声明Enums时,里面至少要有一个成员。一般用来模拟合约的状态。

  下面我们创建一个mshk_top_enums.sol文件,对enums进行测试。

  mshk_top_enums.sol:

pragma solidity ^0.4.17;

/**
* 对`enums`进行测试
* https://mshk.top
*/
contract mshk_top_enums { //定义枚举
enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } //声明变量
ActionChoices choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight; function setGoRight() public {
choice = ActionChoices.GoRight;
} function setGoLeft() public {
choice = ActionChoices.GoLeft;
} function setGoStraight() public {
choice = ActionChoices.GoStraight;
} function setSitStill() public {
choice = ActionChoices.SitStill;
} // Since enum types are not part of the ABI, the signature of "getChoice"
// will automatically be changed to "getChoice() returns (uint8)"
// for all matters external to Solidity. The integer type used is just
// large enough to hold all enum values, i.e. if you have more values,
// `uint16` will be used and so on.
function getChoice() public view returns (ActionChoices) {
return choice;
} function getDefaultChoice() public pure returns (uint) {
return uint(defaultChoice);
}
}

  

  以上代码,第一次调用getChoice方法时,返回的值为0。调用setGoRight方法,对choice设置一个枚举值ActionChoices.GoRight,再次调用getChoice方法时,返回的值为1.

  下图是在Browser-solidity中运行起来的效果:

  

  Structs结构体,和其他语言一样,可以定义任意类型的结构。Structs里面可以定义Mappings,同样在Mappings中也可以定义Structs。虽然结构本身可以作为mapping的成员值,但是结构不可以包含它本身类型,避免死循环。

  下面我们创建一个mshk_top_struct.sol文件,对structs进行测试。

  mshk_top_struct.sol:

pragma solidity ^0.4.17;

/**
* 对 structs 进行测试
* https://mshk.top
*/
contract mshk_top_struct { // Defines a new type with two fields.
struct User {
string name;
uint age;
} //用户列表
User[] public users; /*
* @dev 添加方法
*/
function add(string _name, uint _age) public{
users.push(
User({
name:_name,
age:_age
})
);
}
}

  以上代码,在add方法中,输入"张三",18,然后在users中输入索引值0,能够看到如下图中的效果:

  

  Mapping类型被定义成如mapping(_KeyType => _ValueType)一样,KeyTypeValueType 可以是任何类型,其中 ValueType 甚至也可以是Mapping类型。

  mshk_top_struct_mapping.sol:

pragma solidity ^0.4.17;

/**
* 使用 struct 和 mapping 编写一个简单的智能合约
* https://mshk.top
*/
contract mshk_top_struct_mapping { mapping (address => uint) public balanceOf;
address public owner;
event Sent(address sender, address receiver, uint amount); //定义一个时间 //获取部署合约的账户地址, 并初始化该地址的余额
function mshk_top_struct_mapping() public{
owner = msg.sender;
balanceOf[owner] = 10000;
}
//账户地址交易
function transfer(address _to, uint amount) public{
if(balanceOf[msg.sender] < amount) {return;} //进行判断,防止发送账户的余额不足
if(balanceOf[_to] + amount < balanceOf[_to]){return;} //防止自己给自己转账,或递归调用(因为每次调用都有额外的花费)
balanceOf[_to] += amount;
balanceOf[msg.sender] -= amount;
Sent(msg.sender, _to, amount); ///调用事件
} //挖矿
function mint(uint amount) public{
balanceOf[owner] += amount;
} }

  以上代码,在Browser-solidity中创建以后,能够看到如下图中的效果:

  

4、Ether 单位和 Time 单位

  Ether的单位关键字有wei, finney, szabo, ether,换算格式如下:

  • 1 ether = 1 * 10^18 wei;
  • 1 ether = 1 * 10^6 szabo;
  • 1 ehter = 1* 10^3 finney;

  mshk_top_ether.sol:

pragma solidity ^0.4.17;

/**
* 对 比特币 Ether 的几个单位进行测试
* https://mshk.top
*/
contract mshk_top_ether { // 定义全局变量
uint public balance; function mshk_top_ether() public{
balance = 1 ether; //1000000000000000000
} function mshk_finney() public{
balance = 1 finney; //1000000000000000
} function mshk_szabo() public{
balance = 1 szabo; //1000000000000
} function mshk_wei() public{
balance = 1 wei; //1
}
}

  以上代码,在Browser-solidity中创建以后,能够看到如下图中的效果:

  

  Time的单位关键字有seconds, minutes, hours, days, weeks, years,换算格式如下:

  • 1 == 1 seconds
  • 1 minutes == 60 seconds
  • 1 hours == 60 minutes
  • 1 days == 24 hours
  • 1 weeks == 7 days
  • 1 years == 365 days

  mshk_top_time.sol:

pragma solidity ^0.4.17;

/**
* 对 Time 单位进行测试
* https://mshk.top
*/
contract mshk_top_time { // 定义全局变量
uint public _time; function mshk_top_time() public{
_time = 100000000;
} function mshk_seconds() public view returns(uint){
return _time + 1 seconds; //100000001
} function mshk_minutes() public view returns(uint){
return _time + 1 minutes; //100000060
} function mshk_hours() public view returns(uint){
return _time + 1 hours; //100003600
} function mshk_weeks() public view returns(uint){
return _time + 1 weeks; //100604800
} function mshk_years() public view returns(uint){
return _time + 1 years; //131536000
}
}

  以上代码,在Browser-solidity中创建以后,能够看到如下图中的效果:

  

5、Address

  address类型是一个由 20 字节长度的值(以太坊的地址)组成的。地址类型有很多成员变量,是所有合约的基础。常用的两个成员为:

  • <address>.balance,地址的余额(单位为:wei)
  • <address>.transfer,发送以太币(单位为:wei)到一个地址,如果失败会抛出异常,会撤回发送。

  mshk_top_address.sol:

pragma solidity ^0.4.17;

/**
* 对 Address 的测试
* https://mshk.top
*/
contract mshk_top_address { // 定义全局变量
address public _a;
address public _b; function mshk_top_address() public{
_a = msg.sender; //调用合约用户的地址
_b = this; //当前合约的地址
} function geta() public view returns(address){
return _a;
} function getb() public view returns(address){
return _b;
}
}

  以上代码,在Browser-solidity中创建以后,能够看到如下图中的效果:

6、更多数据类型介绍

  有兴趣的同学,如果想看更多的数据类型介绍 ,可以参考 以太坊数据类型官方文档

7、相关文章

Tools and Technologies in the Ethereum Ecosystem

Solidity撰寫智能合約與注意事項(一)

Types


博文作者:迦壹

博客地址:以太坊智能合约 Solidity 的常用数据类型介绍

转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作!


以太坊智能合约 Solidity 的常用数据类型介绍的更多相关文章

  1. 以太坊智能合约介绍,Solidity介绍

    以太坊智能合约介绍,Solidity介绍 一个简单的智能合约 先从一个非常基础的例子开始,不用担心你现在还一点都不了解,我们将逐步了解到更多的细节. Storage contract SimpleSt ...

  2. Go语言打造以太坊智能合约测试框架(level1)

    传送门: 柏链项目学院 Go语言打造以太坊智能合约测试框架 前言 这是什么? 这是一个基于go语言编写的,自动化测试以太坊智能合约的开发框架,使用此框架,可以自动化的部署合约,自动测试合约内的功能函数 ...

  3. 如何通过以太坊智能合约来进行众筹(ICO)

    前面我们有两遍文章写了如何发行代币,今天我们讲一下如何使用代币来公开募资,即编写一个募资合约. 写在前面 本文所讲的代币是使用以太坊智能合约创建,阅读本文前,你应该对以太坊.智能合约有所了解,如果你还 ...

  4. 深入以太坊智能合约 ABI

    开发 DApp 时要调用在区块链上的以太坊智能合约,就需要智能合约的 ABI.本文希望更多了解 ABI,如为什么需要 ABI?如何解读 Ethereum 的智能合约 ABI?以及如何取得合约的 ABI ...

  5. Go语言打造以太坊智能合约测试框架(level3)

    传送门: 柏链项目学院 第三课 智能合约自动化测试 之前课程回顾 我们之前介绍了go语言调用exec处理命令行,介绍了toml配置文件的处理,以及awk处理文本文件获得ABI信息.我们的代码算是完成了 ...

  6. rpc接口调用以太坊智能合约

    rpc接口调用以太坊智能合约 传送门: 柏链项目学院   在以太坊摸爬滚打有些日子了,也遇到了各种各样的问题.这几天主要研究了一下如何通过rpc接口编译.部署和调用合约.也遇到了一些困难和问题,下面将 ...

  7. 使用web3.js监听以太坊智能合约event

    传送门: 柏链项目学院 使用web3.js监听以太坊智能合约event   当我们在前端页面调用合约时发现有些数据不会立即返回,这时还需要再调用更新数据的函数.那么这样的方法使用起来非常不便,监听ev ...

  8. 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明

    以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明 为了让你的Ðapp运行上以太坊,一种选择是使用web3.js library提供的web3.对象.底层实 ...

  9. 以太坊智能合约Hello World示例程序

    简介 以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开 ...

随机推荐

  1. [Swift]LeetCode967. 连续差相同的数字 | Numbers With Same Consecutive Differences

    Return all non-negative integers of length N such that the absolute difference between every two con ...

  2. OpenOCD的概念,安装和使用

    概念: OpenOCD是一个运行于PC上的开源调试软件,它可以控制包括Wiggler之内的很多JTAG硬件:我们可以将它理解为一种GDB服务程序.OpenOCD的源码只能通过SVN下载,地址是:svn ...

  3. Mysql的两种“超过多少次”写法(力扣596)

    题目: 有一个courses 表 ,有: student (学生) 和 class (课程). 请列出所有超过或等于5名学生的课. 例如,表: +---------+------------+ | s ...

  4. java程序员的NodeJS初识篇

    摘要 作为一个一直用java来写后端的程序员用NodeJS来写后台,实在不是很爽.这里记下这两个月的NodeJS学习所遇之坑,与java转NodeJS的同仁共勉.学习时间不长,若有理解错误,望指正. ...

  5. 强如 Disruptor 也发生内存溢出?

    前言 OutOfMemoryError 问题相信很多朋友都遇到过,相对于常见的业务异常(数组越界.空指针等)来说这类问题是很难定位和解决的. 本文以最近碰到的一次线上内存溢出的定位.解决问题的方式展开 ...

  6. java代码之美(8)---guava字符串工具

    guava字符串工具 在java开发过程中对字符串的处理是非常频繁的,google的guava工具对字符串的一些处理进行优化,使我们开发过程中让自己的代码看去更加美观,清爽. 一.Joiner 根据给 ...

  7. vue组件如何被其他项目引用

    自己写的vue组件怎么才能让其他人引用呢,或者是共用组件如何让其他项目引用.本文就粗细的介绍下,如有疑问欢迎共同讨论.在这里你能了解下如下知识点: 1. 如何发布一个包到npmjs仓库上 2.如何引用 ...

  8. Nancy in .Net Core学习笔记 - 视图引擎

    前文中我们介绍了Nancy中的路由,这一篇我们来介绍一下Nancy中的视图引擎. Nancy中如何返回一个视图(View) 在ASP.NET Mvc中,我们使用ViewResult类来返回一个视图.N ...

  9. 就算会用python画颗心,可你依然还是只单身狗

    :) 标题是开玩笑的,千万别认真. 随着AI的飞速发展,有志于此行的码农也是急剧的增加,带来的就是大家对算法.数学的兴趣也格外升高. 本文的来历是这样,今天某老同事在朋友圈发了一张屏拍,求公式. 看了 ...

  10. 《HelloGitHub月刊》第 08 期

    <HelloGitHub>第 08 期 兴趣是最好的老师,<HelloGitHub>就是帮你找到兴趣! 简介 最开始我只是想把自己在浏览GitHub过程中,发现的有意思.高质量 ...