6分钟以太坊实战 - 智能合约与Solidity高级语言(一)

简介: 1. 简介 合约是存放在以太坊区块链具有特定地址的代码和数据集合。 合约账户之间可以相互传递消息以实现图灵完备运算。 合约以以太坊特定的二进制字节码通过以太坊虚拟机(EVM)运行于区块链上。目前,合约通常是以Solidity(一门长得很像js的语言)高级语言编写,编译后传到区块链上运行。

1. 简介

合约是存放在以太坊区块链具有特定地址的代码和数据集合。 合约账户之间可以相互传递消息以实现图灵完备运算。 合约以以太坊特定的二进制字节码通过以太坊虚拟机(EVM)运行于区块链上。目前,合约通常是以Solidity(一门长得很像js的语言)高级语言编写,编译后传到区块链上运行。可使用浏览器版IDE Remix进行智能合约的开发。

2. Solidity高级语言

一个完整的智能合约往往会包含状态变量、函数、函数修改器、事件、结构体等基本要素,就像一个合约就像Java程序里面的类一样,支持继承。下面我们会逐一介绍solidity这门语言所特有的点及注意事项。

2.1. 基本类型

Solidity主要包括了值类型和引用类型两种。值类型与一般开发语言类似,有布尔、整型、定长字节数据、函数等。引用类型有数组、不定长字节数组、结构体、字符串等。像布尔值、整型、结构体、字典映射等均与c++或者java语言类似,用法可以参考官方文档,这里不在赘述。但我们在开发时需要注意几点:

1) 引入新的值类型:地址(address)

2) 对于复杂的数据类型数组和结构体,需要注意额外属性——存储位置

3) 函数可见性分为public,private,internal,external。可用view,payable,pure等关键字修饰。

4) 小数问题。

5) 数组可变与不变及基础操作。

下面简单解释下这几点。

2.1.1. 地址类型:

地址就相当于一个以太坊的账户,是一个串160位定长的16进制字符串。

地址具有balance属性,值代该地址账户下的以太币余额,基础单位是位(wei)而非ether,1 ether = 1e18wei。

地址拥有send,call,delegatecall,callcode函数,后面新加入了transfer方法。send和transfer函数用于向指定地址发送以太币。如:

to.transfer(msg.value)

to表示接受者的地址,而msg.value表示本次消息附带的以太币数量,值得注意的是msg是一个神奇的全局变量,它为合约提供了一些区块链的属性。需要注意的是send如果传输失败会返回一个返回值false,成功则返回true。而transfer会将传输作为一个事物进行传输,一旦失败则会滚。其余三个函数主要用于同一些支持ABI协议的进行交互。

call方法返回一个bool值,以表明执行成功还是失败。正常结束返回true,异常终止返回false。我们无法解析返回结果,因为这样我们得事前知道返回的数据的编码和数据大小(这里的潜在假设是不知道对方使用的协议格式,所以也不会知道返回的结果如何解析,有点祼协议测试的感觉)。

同样我们也可以使用delegatecall(),它与call方法的区别在于,仅仅是代码会执行,而其它方面,如(存储,余额等)都是用的当前的合约的数据。delegatecall()方法的目的是用来执行另一个合约中的工具库。所以开发者需要保证两个合约中的存储变量能兼容,来保证delegatecall()能顺利执行。

在homestead阶段之前,仅有一个受限的多样的callcode()方法可用,但并未提供对msg.sender,msg.value的访问权限。

在使用call时应该足够谨慎,因为这个能影响合约的安全性。

2.1.2. 存储位置:

数组和结构体可选的存储位置有memory和storage两处。

Memory即为内存存储,分配并使用、不可变长、使用完被回收;storage则会永久的存储在区块链上,主要用于记录长期保留的状态。

在不声明存储位置的情况下,会默认选择指定的位置,也可通过关键字storage和memory声明。

默认的函数参数,包括返回的参数,他们是memory的。默认的局部变量是storage的。而默认的状态变量(合约声明的公有变量)是storage。

2.1.3. 函数可见性及关键字


下面我们通过一个实际的例子来进行讲解。

eadad99f2f3bee8b9513819350de06daa0b57089

上图中我们定义了四个函数和一个永久存储在区块链上的状态变量a。可以看到,我们一共定义了public,private,external,internal四个类型的函数,他们之间的区别在于:

Public:

函数默认声明为public,允许内部及外部访问,可以被继承。

Private:    

只能被当前合约访问,不可被继承,需要注意,即使声明为private,数据依然能被所有人查看,只是禁止了其他合约对函数的访问和数据的修改。

External:

可以提供对外访问,可被子类继承,但不能进行内部调用。

Internal:

可以内部进行访问和调用,可以继承。

可以看到,我们在四个函数可见性声明的后面还加了view, pure, payable等关键字。

主要是对函数作用进行声明,如view可以理解为它将此函数声明为了一个常量函数,承诺不会对区块链上的状态变量进行更改,老一点的版本中可能看到的是constant。

Pure声明的函数表示该函数不仅不会修改状态变量而且也不访问链上数据,可以作为一些工具类使用,如提供计算方法等。

Payable声明表示该函数存在交易,会产生以太币的转移。

当需要更改链上数据又不需要交易时,可像第四个函数_internal一样不做声明。

2.1.4. 小数

目前solidity暂不支持定长浮点型。

倘若计算结果是浮点型,则会转为ufixed(无符号浮点型)或者fixed(有符号浮点型)类型。如1/4可以得到一个ufixed0x8,但1/3是无限的,在solidity里面只能用ufixed0x256的最大长度来表示。

2.1.5. 数组

Solidity中数组分为可变数组和定长数组,由2.1.2可知,数组分为存在合约内部的和存在于内存中两类,存储与内存中的数组是不允许创建变长数组的。如:

uint[] memory a;

这样的声明是不被允许的。

数组可通过 .length方法获取长度和更改长度,.push方法加入新元素。但要注意,定长数组是无法通过length和push方法更改长度或插入的。如:

dceac16083fd24068bfb3004e1cff9a175fd3411

这样的操作方式是不被允许的。

接下来我们介绍下声明数组的问题。

在storage中,声明定长数组,并初始化变量:

uint[2] a = [1,2];

在storage中,声明变长数组,并初始化变量:

uint[] a = [1,2];

二维数组初始化:

uint[2][3] a = [[1,1],[2,2],[3,3]];

这里我们一定要注意,这个数组声明和java等语言的行列刚好是相反的。

在memory中,声明定长数组:

uint[] memory a = new uint[](2);

在memory中,声明定长数组并初始化:

uint[2] memory a = [uint(1),2];

而uint[] memory a = [uint(1),2];这种方式是错误的,大家会奇怪为什么要在第一个元素一前面加上uint的类型,这是因为我们前面声明的是uint的数组,而在solidity中有uint8,uint248等多种不同位数的无符号int型常量,在不声明的情况下,默认使用uint256,而我们初始化的数组元素是1和2,系统会判定为uint8,所以需要我们在第一个元素1前面强制转化为uint型。当然,我们也可以如下的声明方式:

uint8[2] memory a = [1,2];

但要注意,那么a数组里面就不可以出现2进制里面大于8位的数了。


原文发布时间为:2018-03-20

本文作者:can@链博科技

本文来自云栖社区合作伙伴“中生代技术”,了解相关信息可以关注“中生代技术”微信公众号

相关文章
|
3天前
|
人工智能 API 内存技术
刚刚 DeepSeek V4.1 Flash 开启内测,1 分钟教你用上!
刚刚 DeepSeek 内测群发布了 DeepSeek V4.1 Flash 中间版本内测的消息,这次的模型采用了新的结构,原生支持多模态、能力更强、速度更快、且成本更低。
1595 4
|
7天前
|
人工智能 运维 BI
阿里云千问办公QwenWork深度解析:基于Qwen3.8,六大核心能力重构企业全自动化工作流与计费选型指南
传统AI办公工具大多停留在对话问答、文档摘要、简单文案生成层面,只能完成单点碎片化任务,无法自主拆解复杂业务流程,很难串联多工具、多文档、外部业务系统完成端到端完整工作交付。很多企业在落地AI办公的时候,需要组合多款不同工具,来回切换界面,手动复制粘贴中间结果,智能化改造落地门槛居高不下。千问办公QwenWork是整合多款智能体产品能力打造的一体化企业办公智能体平台,底层基座依托Qwen3.8大模型,打通桌面端Agent、云端Agent、企业协同Agent三种运行形态,不再局限简单问答,接收业务目标之后自主拆解任务步骤,调用各类工具,处理文档、表格、浏览器自动化、数据查询,直接输出可交付的办公
1589 0
|
4天前
|
SQL 人工智能 前端开发
QoderWake 1.0 正式发布:从桌面里的 Agent,到工作现场的数字员工
QoderWake v1.0正式发布:企业级数字员工团队平台。支持“一句话建岗”,预置10类特训岗位;Waker常驻钉钉/飞书群,@即响应、自动协作、跨任务记忆;具备定时/事件/API多触发方式与统一任务看板;已沉淀27.6万条记忆、12.3万项技能,助力组织实现人机协同增效。
695 0
|
16天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
3825 5
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
7天前
|
人工智能 自然语言处理 安全
阿里云AI数智鉴密:AI 生成内容如何拿到一张"防篡改的身份证"
隐形水印 + C2PA签名:让AI生成内容“持证上岗”。
1139 0
|
8天前
|
网络协议 Linux iOS开发
【2026实测】Wireshark下载+安装+汉化+使用教程(图文版,巨详细)
Wireshark 是一款免费开源的网络协议分析工具,可实时捕获、解析并可视化数据包,助你诊断网络故障、分析通信协议(如HTTP、DNS、TCP等)。支持Windows/macOS/Linux,含中文界面,新手入门便捷。(239字)
|
2天前
|
缓存 测试技术 API
DeepSeek V4.1 Flash 内测接入:改个模型名即可调用(附代码)
DeepSeek V4.1 Flash 内测不用申请,base_url 不变、改个模型名就能调,9/10 到期。本文讲清接入、计费限流与多模态注意点。
630 0
DeepSeek V4.1 Flash 内测接入:改个模型名即可调用(附代码)