PlatONnetwork/PlatON-Go

[VM] EVM指令TIMESTAMP返回值应以秒为单位

Closed this issue · 6 comments

PlatON的blockheader中TIMESTAMP的单位是毫秒, 为了兼容EVM, 需要将该指令返回值转换为秒

PlatON的blockheader中TIMESTAMP的单位是毫秒,为了做到于EVM兼容,有以下方案:

  1. 直接在底层分叉修改,获取header.time时除以1000
  2. 增加TIMESTAMP2指令,如果用户合约想和ETH保持一致,需要将合约中所有timestamp改为timestamp2
  3. 在合约中增加一个全局flag,用户只需要在创建合约时指定(不可修改),底层根据flag选择返回s或是ms
  4. 底层不改,合约层自己适配,增加一个类似系统lib的库, 将底层返回的ms改为s,将所有block.timestamp改为调用库函数获取

以上方案中各个方案都有明显的缺点,这里简单说明一下:

  1. 方案1对已有合约冲击太大, 将会导致已经部署的合约失效,并且当前没办法判断哪些合约会有影响
  2. 方案2中增加EVM指令算是一个很大的动作,一方面在EVM增加opcode,可能会导致后续EVM扩展指令时冲突,可以尝试将PlatON和Alaya不使用的 difficulty 指令修改为 TIMESTAMP2,但这又存在另外一个问题,如果用户合约原本是使用difficulty,如没经过重新编译也是可以正常运行,但指令返回值就不是difficulty了。2是这种方案仍需要用户修改原合约
  3. 方案3和方案2有类似的地方,需要编译器的支持
  4. 方案4对用户使用不太友好,需要遍历所有使用timestamp的地方并替换

另外还有一个问题, ETH的header.time是唯一的,2个不同高度区块的时间戳不可能相同,而PlatON&Alaya的时间戳以ms为单位不可能相同,但转换为s就有可能相同了,如果PlatON&Alaya支持了按s取值,用户在设计合约的时候要格外注意这点,因此,其实还有一个‘方案5’,那就是保持现状。
大家有什么建议呢?

个人看法如下:
timestamp涉及到合约和sdk,同时有些DAPP的逻辑也会与timestamp相关,如果要改最好选择方案1,这样改得彻底。
另外,因为PlatON有自己独特的共识机制,跟以太坊不一样,开发者移植之前还是需要有一些基本的了解,这样才能保证DAPP迁移的正确性(DAPP安全性和业务逻辑正确性是非常重要的),这部分工作量也比较小。
综合来说,我的看法是 方案4或者方案5。

愚见:
1、更改的意义不大,对于使用者都是uint256的表现形式(绝大多数),进行秒与毫秒调整或者不调整应该都比较容易;
2、为了完全兼容调整,需要慎重;

个人看法如下:
timestamp涉及到合约和sdk,同时有些DAPP的逻辑也会与timestamp相关,如果要改最好选择方案1,这样改得彻底。
另外,因为PlatON有自己独特的共识机制,跟以太坊不一样,开发者移植之前还是需要有一些基本的了解,这样才能保证DAPP迁移的正确性(DAPP安全性和业务逻辑正确性是非常重要的),这部分工作量也比较小。
综合来说,我的看法是 方案4或者方案5。

方案5才是最好的

which release version this fix in? or no fix?

Not yet fixed
Since the block gen interval may be less than 1 second, it is not appropriate to reduce the accuracy of the timestamp of the blocks, but it is possible to do so from the RPC layer and is compatible with eth, and there is a branch that implements such a feature that will be released soon