以太坊:Solidity手册

本文档根据当前 最新官方版本v0.5.8 进行翻译,本翻译最初 HiBlock 社区发起,后经过 深入浅出区块链社区 社区成员根据最新版本补充翻译。

本中文文档大部分情况下,英中直译,但有时为了更好的理解也会使用意译,如需转载请联系Tiny熊(微信:xlbxiong).

Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在 以太坊虚拟机(EVM) 上运行。

Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。

在部署合约时,应该尽量使用最新版本,因为新版本会有一些重大的新特性以及bug修复。

警告

Solidity 最近发布了 0.5.x 有很多与之前版本不兼容的升级,理解更新可阅读 更新列表.

语言文档

如果你才接触智能合约概念,推荐从一些 简单的Solidity合约例子 开始,当你想开始尝试了解更多的细节,可以 学习 合约样例 和 深入理解Solidity 。

你还可以进一步阅读 区块链 基础,然后是 以太坊虚拟机 。

提示

译者注:理解智能合约及虚拟机是怎么运行,推荐这两篇非常好的文章 完全理解以太坊智能合约 及 深入浅出以太坊虚拟机 。

提示

目前尝试 Solidity 编程的最好的方式是使用 Remix (需要时间加载,请耐心等待)。Remix 是一个基于 Web 浏览器的 IDE,它可以让你编写 Solidity 智能合约,然后部署并运行该智能合约。

警告

因为软件是人编写的,就会有 bug,所以,创建智能合约也应该遵循软件开发领域熟知的最佳实践。这些实践包括代码审查、测试、审计和正确性证明。也请注意,有时候用户在代码方面比软件的作者更谙熟。最后,区块链本身有些东西需要留意,请参考 安全考量。

如果还有问题,你可以尝试搜索或在 Ethereum Stackexchange 上提问,或者到我们的 gitter 频道来。随时欢迎改善 Solidity 或本文档的想法!

翻译版本

本文档由社区志愿者翻译成多种语言,但是 英语版本 作为主要参考。

  • 简体中文版 (由 HiBlock社区 深入浅出区块链社区 贡献者翻译)

  • 西班牙语版

  • 俄语版 (已过时)

  • 韩语版 (in progress)

目录

Keyword Index, Search Page

Solidity 手册

  • 入门智能合约
    • 简单的智能合约
      • 存储合约(把一个数据保存到链上)
      • 子货币合约(Subcurrency)示例
    • 区块链基础
      • 交易/事务
      • 区块
    • 以太坊虚拟机
      • 概述
      • 账户
      • 交易
      • Gas
      • 存储,内存和栈
      • 指令集
      • 消息调用
      • 委托调用/代码调用和库
      • 日志
      • 合约创建
      • 失效和自毁
  • 安装Solidity编译器
    • 版本
    • Remix
    • npm / Node.js
    • Docker
    • 二进制包
    • 从源代码编译
      • 克隆代码库
      • 先决条件 - macOS
      • 先决条件 - Windows
      • 外部依赖
      • 命令行构建
    • CMake参数
      • SMT Solvers
    • 版本号字符串详解
    • 版本信息详情
  • 根据例子学习Solidity
    • 投票合约
      • 可能的优化
    • 秘密竞价(盲拍)合约
      • 简单的公开拍卖
      • 秘密竞拍(盲拍)
    • 安全的远程购买合约
    • 微支付通道合约
      • 创建及验证签名
        • 创建签名
        • 哪些内容需要签名
        • 打包参数
        • 在Solidity中还原消息签名者
        • 提取签名参数
        • 计算信息的Hash
        • ReceiverPays 完整合约代码
      • 编写一个简单的支付通道
        • 什么是支付通道?
        • 打开支付通道
        • 进行支付
        • 关闭状态通道
        • 通道有效期
        • 完整合约代码
        • 验证支付
    • 库合约使用
  • 深入理解Solidity
    • Solidity 源文件结构
      • Pragmas
      • 版本标识
        • 标注实验性功能
      • 导入其他源文件
        • 语法与语义
        • 路径
        • 在实际的编译器中使用
      • 注释
    • 合约结构
      • 状态变量
      • 函数
      • 函数 修饰器modifier
      • 事件 Event
      • 结构体
      • 枚举类型
    • 类型
      • 值类型
        • 布尔类型
        • 整型
        • 定长浮点型
        • 地址类型 Address
        • 合约类型
        • 定长字节数组
        • 变长字节数组
        • 地址字面常量
        • 有理数和整数字面常量
        • 字符串字面常量及类型
        • 十六进制字面常量
        • 枚举类型
        • 函数类型
      • 引用类型
        • 数据位置
        • 数组
        • 结构体
      • 映射
      • 涉及 LValues 的运算符
        • 删除
      • 基本类型之间的转换
        • 隐式转换
        • 显式转换
      • 字面常量与基本类型的转换
        • 整型
        • 定长字节数组
        • 地址类型
      • 类型推断(已弃用)
    • 单位和全局变量
      • 以太币Ether 单位
      • 时间单位
      • 特殊变量和函数
        • 区块和交易属性
        • ABI 编码函数
        • 错误处理
        • 数学和密码学函数
        • 地址相关
        • 合约相关
        • 类型信息
    • 表达式和控制结构
      • 输入参数和输出参数
        • 输入参数
        • 输出参数
      • 控制结构
      • 函数调用
        • 内部函数调用
        • 外部函数调用
        • 具名调用和匿名函数参数
        • 省略函数参数名称
      • 通过 new 创建合约
      • 赋值
        • 解构赋值和返回多值
        • 数组和结构体的复杂性
      • 作用域和声明
      • 错误处理:Assert, Require, Revert and Exceptions
    • 合约
      • 创建合约
      • 可见性和 getter 函数
        • Getter 函数
      • 函数 修饰器modifier
      • Constant 状态变量
      • 函数
        • 函数参数及返回值
        • View 函数
        • Pure 函数
        • Fallback 回退函数
        • 函数重载
      • 事件
        • 日志的底层接口
        • 其它学习事件机制的资源
      • 继承
        • 构造器
        • 基类构造函数的参数
        • 多重继承与线性化
        • 继承有相同名字的不同类型成员
      • 抽象合约
      • 接口
        • 库的调用保护
      • Using For
    • Solidity汇编
      • 内联汇编
        • 例子
        • 语法
        • 操作码
        • 字面常量
        • 函数风格
        • 访问外部变量和函数
        • 标签
        • 汇编局部变量声明
        • 赋值
        • If
        • Switch
        • 循环
        • 函数
        • 注意事项
        • Solidity 惯例
      • 独立汇编
        • 汇编语法
    • 杂项
      • 存储storage 中的状态变量储存结构
      • 内存memory 中的存储结构
      • 调用数据存储结构
      • 内部机制 - 清理变量
      • 内部机制 - 优化器
      • 源代码映射
      • 技巧和窍门
      • 速查表
        • 操作符优先级
        • 全局变量
        • 函数可见性说明符
        • 修改器
        • 保留字
        • 语法表
    • Solidity v0.5.0 重大更新
      • 语义变化
      • 语义及语法更改
      • 准确性要求
      • 弃用元素
        • 弃用命令行及 JSON 接口
        • 构造函数变更
        • 弃用函数
        • 弃用类型转换
        • 弃用字面量及后缀
        • 弃用变量
        • 弃用语法
      • 和老合约进行交互
      • 举例
  • 注释描述规范
    • 文档举例
    • 标签
      • Dynamic expressions
      • Inheritance Notes
    • 文档输出
      • 用户文档
      • 开发者文档
  • 安全考量
    • 陷阱
      • 私有信息和随机性
      • 重入
      • gas 限制和循环
      • 发送和接收 以太币Ether
      • 调用栈深度
      • tx.origin问题
      • 整型溢出问题
      • 细枝末节
    • 推荐做法
      • 认真对待警告
      • 限定 以太币Ether 的数量
      • 保持合约简练且模块化
      • 使用“检查-生效-交互”(Checks-Effects-Interactions)模式
      • 包含故障-安全(Fail-Safe)模式
    • 形式化验证
  • 资源
    • 常用资源
    • Solidity IDE及编辑器
    • Solidity 工具
    • 第三方 Solidity 解析器
  • 使用编译器
    • 使用命令行编译器
    • 编译器输入输出JSON描述
      • 输入说明
      • 输出说明
        • 错误类型
  • 合约的元数据
    • 元数据哈希字节码的编码
    • 自动化接口生成和 以太坊标准说明格式Ethereum Nature Specification Format(natspec) 的使用方法
    • 源代码验证的使用方法
  • 应用二进制接口Application Binary Interface(ABI) 说明
    • 基本设计
    • 函数选择器Function Selector
    • 参数编码
    • 类型
    • 编码的形式化说明
    • 函数选择器Function Selector 和参数编码
    • 例子
    • 动态类型的使用
    • 事件
    • JSON
      • 处理 元组tuple 类型
    • 非标准打包模式
  • Yul
    • Yul 语言说明
      • 语法层面的限制
      • 作用域规则
      • 形式规范
      • 类型转换函数
      • 低级函数
      • 后端
      • 后端: EVM
      • 后端: “EVM 1.5”
      • 后端: eWASM
    • Yul 对象说明
  • 编程风格指南
    • 概述
    • 代码结构
      • 缩进
      • 制表符或空格
      • 空行
      • 代码行的最大长度
      • 源文件编码格式
      • Imports 规范
      • 函数顺序
      • 表达式中的空格
      • 控制结构
      • 函数声明
      • 映射
      • 变量声明
      • 其他建议
    • 命名规范
      • 命名方式
      • 应避免的名称
      • 合约和库名称
      • 结构体名称
      • 事件名称
      • 函数名称
      • 函数参数命名
      • 局部变量和状态变量名称
      • 常量命名
      • 修饰符命名
      • 枚举变量命名
      • 避免命名冲突
    • 描述注释 NatSpec
  • 通用模式
    • 从合约中提款
    • 限制访问
    • 状态机
      • 示例
  • 已知bug列表
  • 贡献方式
    • 怎样报告问题
    • Pull Request 的工作流
    • 运行编译器测试
      • 编写和运行语法测试
    • 通过 AFL 运行 Fuzzer
    • Whiskers 模板系统
  • LLL
  • 常见问题
    • 基本问题
      • 可以在特定的区块上进行操作吗?(比如发布一个合约或执行一笔交易)
      • 什么是交易的“有效载荷(payload)”?
      • 存在反编译器吗?
      • 创建一个可以被中止并退款的合约
      • 调用 Solidity 方法可以返回一个数组或字符串(string)吗?
      • 数组可以使用 in-line 的方式(指在声明变量的同一个语句中)来初始化吗?比如: string[] myarray = ["a", "b"];
      • 合约的函数可以返回结构(struct)吗?
      • 我从一个返回的枚举类型(enum)中,使用 web3.js 只得到了整数值。我该如何获取具名数值?
      • 可以使用 in-line 的方式来初始化状态变量吗?
      • 结构(structs)如何使用?
      • 循环(for loops)如何使用?
      • 有没有一些简单的操作字符串的例子(substringindexOfcharAt 等)?
      • 我能拼接两个字符串吗?
      • 为什么大家都选择将合约实例化成一个变量(ContractB b;),然后去执行变量的函数(b.doSomething();),而不是直接调用这个 低级函数low-level function .call() ?
      • 没被使用的 gas 会被自动退回吗?
      • 当返回一个值的时候,比如说 uint 类型的值, 可以返回一个 undefined 或者类似 null 的值吗?
      • 注释会被包含在已部署的合约里吗,而且会增加部署的 gas 吗?
      • 如果在调用合约的函数时一起发送了以太币,将会发生什么?
      • 合约对合约的交易可以获得交易回执吗?
      • 关键字 memory 是什么?是用来做什么的?
    • 高级问题
      • 怎样才能在合约中获取一个随机数?(实施一份自动回款的博彩合约)
      • 从另一份合约中的 non-constant 函数获取返回值
      • 让合约在首次被挖出时就开始做些事情
      • 怎样才能创建二维数组?
      • 当我们复制一个结构(struct)时, 结构 (struct)中定义的映射会被怎么处理?
      • 我应该如何初始化一份只包含指定数量 wei 的合约?
      • 合约的函数可以接收二维数组吗?
      • bytes32 和 string 有什么关系吗?为什么 bytes32 somevar = "stringliteral"; 可以生效,还有保存下来的那个 32 字节的 16 进制数值有什么含义吗?
      • 一份合约可以传递一个数组(固定长度)或者一个字符串或者一个 bytes (不定长度)给另一份合约吗?
      • 有些时候,当我想用类似这样的表达式: arrayname.length = 7; 来修改数组长度,却会得到一个编译错误 Value must be an lvalue。这是为什么?
      • Solidity 的函数可以返回一个字符串数组吗(string[])?
      • 如果你发起了一次获取数组的调用,有可能获得整个数组吗?还是说另外需要写一个辅助函数来实现?
      • 如果某个账户只存储了值但没有任何代码,将会发生什么?例子: http://test.ether.camp/account/5f740b3a43fbb99724ce93a879805f4dc89178b5
      • 在定制 通证token 的合约中,下面这些奇怪的校验是做什么的?
      • 更多问题?

你可能感兴趣的:(区块链,以太坊,以太坊)