Solidity 合约开发要掌握的特性和关键词记录

3 篇文章 1 订阅
1 篇文章 1 订阅

最近看了一些Solidity开发资料,目前latest是0.6.12,记性不好,记录一下。

1.入门扫盲

常用的关键词

变量相关类型备注
uint无符号整数uint 默认为 uint256的缩写
mapping映射键值对存储key/val,可嵌套
address地址类型一般是两种类型:用户或者合约,自带成员函数 transfer 和 send等,更多成员函数
struct结构体可以有多个属性,类似Go的struct
enum枚举通常由多个常量值构成的自定义类型
storage引用类型永久存储在链上,类似硬盘
memory引用类型临时存储,外部函数对某合约调用完时回收,类似内存
calldata引用类型只读,用来存储函数传的参数,方便的在函数内引用而不占用空间。0.6.9之前只能外部调用
delete初始化为0Solidity没有null和undefined的概念,注意:delete数组某个索引后可能留空位置。
bytes定长字节数组类似byte[],bytes能“紧打包”,将元素连续存起来,意味使用Gas更低。
strings特殊数组与bytes相同,但不允许用长度或索引来访问。

更多请查看Solidity文档:全局变量 、保留关键字、修饰符、函数可见性 速查表

函数相关类型备注
event事件合约和区块链的通讯机制,前端可触发event方法做出反应。
emit触发事件事件的调用方法
indexed事件索引最多三个,特殊数据结构,前端能通过filter筛选事件,普通的是日志数据结构。
payable函数类型表示可以接受ETH的函数
Internal函数类型内部,类似private,继承关系可使用。
external函数类型外部,类似public,不能在继承关系中使用。
view函数修饰符表示函数只读不改,不会消耗Gas
pure函数修饰符表示函数只做计算不读不改,不会消耗Gas
virtual函数类型函数重写,接口默认会进行标记virtual,private不能使用该标记。
override函数类型函数重写,配合父合约标记的virtual函数使用
abstract抽象合约定于与现实分离,用于提高扩展性,消除代码重复
interface接口不实现任何函数,只制定接口,其他合约继承后需要实现
library两种使用方法,一种是using for,一种是直接实例化,自动添加库所有方法给一个数据类型
is继承可用“,”多继承,存在钻石问题,注意顺序加载:base,base-A,base-A-A这样写。
import导入可以导入其他sol文件
constructor()构造函数初始化合约调用一次的函数
modifier函数修饰符修饰已有的函数,并且能自定义条件函数。
receive()特殊函数一个合约只有一个接收以太函数,在没有payable修饰符还转账情况下自动调用。
fallback()回退函数externall类型,调用不存在的函数时调用,但是转账类型交易如果不加payable会报异常。
全局变量类型备注
ether费用单位以太单位,类似还有wei、 finney、 szabo
Now时间单位当前时间戳,因为是32位,会有2038问题。类似还有seconds、minutes、hours、days、weeks、years(0.5.0因闰年已移除)
msg.sender全局变量当前调用者的address
msg.value全局变量当前交易的wei数量
tx.gasprice全局变量交易的 gas 价格
block.number全局变量当前区块号

更多请查看Solidity文档:特殊变量和函数

用过的一些方法

方法名描述备注
require()错误处理不满足条件就撤销更改,0.5版新增第二个参数可以抛出message
assert()错误处理和 require 类似,require失败会返回剩下的Gas,assert则不会,出现严重错误时使用。
keccak256()数学和密码学函数伪随机的散列函数,更多数学和密码学函数
uint8()类型强转uint8 c = a * uint8(b); 类似的有uint256,uint16,但是uint8不能转到uint256。
arr.push()数组成员方法在尾部加入新元素,类似的还有length、pop
生成随机数0-100的随机数非安全,可能被算力强的节点利用,只打包对自己有利的区块发布到链上:uint random = uint(keccak256(now, msg.sender, randNonce)) % 100

记录一些特别的操作

关键词类型备注
5 ** 2乘方操作x 的 y次方,5 ** 2 = 25
变量名含"_"私有变量名一种习惯,区别全局变量
public函数修饰符默认会提供getter方法
uint[]动态数组类似的有uint[10]固定数组,Person[]结构体数组
return (a,b,c)函数参数和返回批量返回函数值和接受值 跟 Go类似
_;占位符modifier中的_; 表示“被修饰的函数开始执行”
0x0黑洞地址没有私钥的地址,常用来烧币,主动报废一些token。

记录常用的OpenZeppelin安全审查后的合约库

库名描述备注
SafeMath安全数学运算可防止 overflow 和 underflow 的加减乘除
SafeCast安全类型转换和SafeMath类似,防止转换时的 overflow 和 underflow
Ownable访问权限合约的主人才可以调用哦
Roles角色控制、访问层次比Ownable多了个角色概念,可以进行权限分组了。
ERC20代币标准普通代币的一些定义
ERC721代币标准用于加密收藏品,有不可分割、不可互换、整单位交易等特性。
Address地址检测让我看看你是个合约,还是用户

具体描述参考:OpenZeppelin 7个最常使用的合约

2.省Gas秘籍

以太坊是去中心化的应用,为了防止某些用户无限循环,占用网络资源。每次执行Dapp都需要支付一定的Gas,Gas使用以太币购买。

利用view特性

view的定义是只读不改,不会真正改变链上任何数据。因此用户从外部调用一个view修饰的函数,不会产生任何Gas。

如果 一个 view 函数有进行 内部调用,虽然不属于同一个合约,但依旧会产生Gas。因为调用的函数会生成事务,要进行节点验证产生成本。所以只有外部调用view是免费的。

结构封装(Struct packing)

struct MiniMe {
  uint32 a;
  uint32 b;
  uint c;
}

在Struct里使用合适的uint类型,并且把同样类型的变量放一起(即在 struct 中将把变量按照类型依次放置), 这样能让Solidity空间最小化。

用uint8代替uint256并不会节省空间,因为Solidity会默认使用256保留。

参考:
https://learnblockchain.cn/docs/solidity/
https://cryptozombies.io/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值