最佳实践
#
介绍本指南向用户介绍智能合约开发中需要关注的一些关键点,主要偏向于在实际开发中的实践。用户可以通过本指南快速了解针对一笔交易如何合理的设置手续费、如何避免被因交易失败的同时损失手续费以及如何编码更加规范的智能合约。
#
费用合理设置当需要在PlatON
的主网上部署合约时,需要设置一个合理的费用限制。费用限制是指 PlatON
中智能合约部署/执行的能源消耗成本的上限。该限制主要通过 Gas
完成,Gas
是 PlatON 网络世界的燃料值,它决定了 PlatON 网络生态系统的正常运行。通常使用 Gas 来衡量执行某些动作需要多少"工作量",这些工作量就是为了执行该动作所需要支付给 PlatON 网络的费用额度。简单理解, Gas 是网络旷工的佣金,并通过 LAT
的方式支付,在网络上的任何交易、合约执行,数据存储,都需要使用到 Gas。
PlatON与以太坊区块链系统类似,使用 LAT
进行支付和维护网络,一枚 LAT 分为:mLAT/uLAT/gVON/mVON/kVON/VON
,其中VON
是最小单位。
Gas 主要由两个部分组成:GasLimit(限制)和GasPrice(单价)。其中 GasLimit
是用户愿意为执行某个操作或确认交易支付的最大 Gas
消耗量(最少21,000)。GasPrice是 gVON
的数量,用于愿意为每个 Gas
所支付的单价。
用户发送一笔交易时,会设定 GasLimit
和 GasPrice
,二者的乘积(GasLimit * GasPrice
)是用户的交易成本,同时该成本会作为佣金奖励给旷工。
交易设置的 GasPrice
越高,则交易的执行优先级更高,交易成本也会更大。每笔交易在完成后,剩余未使用的Gas都会退回到发送者的地址账户中。有一点要特别注意,如果因为 GasLimit
设置过低导致交易执行失败,此时的 Gas 不会被回退到用户地址,用户依然需要为这次失败的交易支付能量成本。因此,无论交易是否执行成功,交易发送者都需要向旷工支付一定的计算费用。
在 PlatON
网络中,最高 Gas 的限制为 4,700,000
,最低为 22,000
,过低或者过高都会导致交易失败。在部署大型合约或者运行复杂功能时,可以将Gas的限制调高,例如:1,000,000
。如果是普通转账则设置为最低值即可。具体的值需要根据合约的规模及复杂度进行估算,在合约发布前可以调用接口 platon_estimateGas
进行大概估算,避免因不足而导致失败。 点击查看JSON-RPC参考文档。
LAT 单位转换
单位 | VON值 | VON |
---|---|---|
VON | 1 | 1 VON |
kVON | 1e3 VON | 1,000 |
mVON | 1e6 VON | 1,000,000 |
gVON | 1e9 VON | 1,000,000,000 |
LAT | 1e18 VON | 1,000,000,000,000,000,000 |
mLAT | 1e24 VON | 1,000,000,000,000,000,000,000,000 |
gLAT | 1e27 VON | 1,000,000,000,000,000,000,000,000,000 |
#
避免超时在 PlatON
网络上发送交易,没有超时的概念,但是最终会根据所设置的 Gas 限制值停止,如果限制值低于合约部署所需要的消耗,则交易发送失败,同时会扣除对应的手续费。手续费的设定不可能无限大,因为在网络中,区块本身有一个最大的Gas上限,当交易的 GasLimit
超过该值时,交易将无法被接收。
如果是针对已发布的合约执行 call
调用(call调用指合约逻辑内无状态变更操作),存在 5s 超时的限制,如果在 5s
内合约逻辑没有执行完成,虚拟机会超时强制退出,导致查询失败。
为避免部署合约交易失败,请尝试将大型合约分成较小的块,并根据需要相互引用。 为了避免无限循环,请注意常见的陷阱和递归调用。
#
非法操作处罚如果智能合约不是通过标准有效的编译器编译合约或者随意的更改指令码,都会导致操作码无效。此类合约不仅无法部署和执行成功,而且还会产生 GasLimit*GasPrice
的全额惩罚,当次交易的手续费会全部被扣除,这是一个力度很大的惩罚,如果操作者没注意该点,不断重试,那么付出的成本会更高,代价更重。
一般产生无效操作码有以下情况:
1.对正常已编译出的合约手动更改了指令码;
2.合约编译器版本与网络锁支持的合约版本不一致;
在 PlatON
网络中操作合约时,请务必先确认当前网络所支持的智能合约版本,然后选择对应版本对的编译器。
常规操作是使用 PlatON
社区提供的最新的Truffle
/PlatON-CDT
来编译/部署/执行合约,同时在切换到主网操作前,务必在测试网进行有效的验证。
#
编码规范#
命名规范基本规则:
- 使用能准确说明变量、字段、类、接口等完整的描述信息;
- 采用大小写混合(特殊字符除外),提高命名的可读性;
- 采用区块链行业内的术语;
- 尽可能少的使用缩写,如果一定使用,则推荐使用公共缩写和习惯缩写等;
- 避免使用相似或者仅仅是大小上有区分的命名;
- 目录统一使用小写,无特殊符号;
- EVM智能合约,文件名与合约名保持一致;
- 命名建议统一使用驼峰规则;
#
智能合约文件组织文件组织规则:
- 一般超过1000行的程序代码就比较难以阅读,尽量避免出现一个文件内代码行数过长的情况。每个合约文件应只包含一个单一的合约类或合约接口。
文件组织顺序:
- 文件注释:所有合约源文件在开头有一个注释,其中列出文件的版权声明、文件名、功能描述及创建、修改记录;
- 文件/包引用:在合约源文件中,第一个非注释行是编译器版本,之后跟上引用语句;
- 类或接口注释:在类、接口定义之前应该进行注释,包括类、接口的描述、最新修改者、版本号、参考链接等;
- 实例变量:首先是公共级别的,随后是保护级别的,最后是私有级别;
- 普通方法:合约内的函数应该按功能分组,而不应该按作用域或访问权限进行分组;
#
几点建议- 在智能合约中,获取 public 修饰的状态变量的值,不需要编写
get
函数; - 在智能合约中,在合约中加入
payable
修饰的匿名函数,则合约地址可接受 LAT 转账;