最近开始接触了一下ETH的智能合约,主要是通过Chainlink这个优秀的预言机项目。

合约的特点

ETH上的合约主要是用Solidity语言来开发的,使用下来感觉语言本身还不是很成熟,

数据结构比较单一,适合实现简单的计算逻辑和数据存储。

与其他开发项目相比,代码一旦发布后很难修改,代码“性能”需要特别关注。

合约代码在执行过程中依据Op来计算需要消耗的gas费,所以代码的质量非常关键。

在我们了解Chainlink项目和开发自己的合约时碰到了下面几个案例,分享一下。

写入与更新

Chainlink的历史数据是保存在合约的一个Map中,key是roundid,value是价格。

在我们测试Map的写入与更新时发现,第一次写入某一个key和后面更新key的Value,

费用差距是巨大的,大概是2倍左右。我们在设计类似保存历史数据的环节时,采用了

循环key值,比如自增ID对1024取模,这样只有第一轮是insert,第1025次之后就是

update了,费用会降低下来,在合约里只能查询一段时间的历史记录,之前的会被覆盖。

代理

因为链上的合约一旦部署成功后,就不能修改了,如果想要升级就要使用新的合约地址了,

这对外部依赖是非常不友好的。参考Chainlink和Openzapplin项目,一般都是采用代理

模式将接口和实现解耦和,接口层记录了实现合约的地址,提供一个Update实现合约地址的

方法,进行替换,来达到升级的目的。虽然可以实现,但是开发时非常繁琐。

存储与计算分离

上面提到了升级的问题,如果你的合约里还保存了一些数据,那么在升级时也需要将其转移到

新的合约里。部署合约是有费用成本的,如果在部署合约时,涉及到了大量的数据copy,

这个成本会变得非常昂贵。代理模式只是解决了升级当中的持续稳定服务问题,在设计合约时,

还需要将合约里的存储结构和计算逻辑进行解耦,一般我们只对计算逻辑进行升级,而存储部分

不会移动,仅仅会修改一些写权限的控制,将新合约地址更新到存储数据的合约中去。