界: Time and State

分布式计算是关于时间和状态的。也就是说,为了让多个组件相互通信,必须共享状态,所有这些都需要时间。

大多数程序员都会将其工作拟人化。他们会让一个控制线程以同样的方式(他们必须自己完成工作时采取的方式)执行整个程序。然而,现代计算机不同任务之间切换得非常快,在多核、多 CPU 或分布式系统中,两个事件可能完全同时发生。程序员预期的程序执行过程与实际情况之间存在差距,即存在缺陷。这些缺陷与线程、流程、时间和信息之间的意外交互有关。这些交互是通过共享状态发生的:信号量、变量、文件系统,以及总而言之,可以存储信息的任何内容。

Often Misused: Block Values

Abstract
函数使用 block.timestampblock.number 作为代理的时间。
Explanation
block.timestampblock.number 关联的值通常由开发人员用于触发与时间相关的事件,但是,这些值通常给人以一种此类时间使用起来不太安全的感觉。

由于区块链的去中心化性质,节点只能在一定程度上同步时间。使用 block.timestamp 说的好听点是不可靠,在最坏的情况下,恶意矿工如果看到这样做的好处,则会改变其区块的时间戳。

至于 block.number,即使可以预测区块之间的时间(大约 14 秒),区块时间也不恒定,可能会随着网络活动而发生变化。这使得 block.number 对于与时间相关的计算来说变得不可靠。

示例 1:以下代码使用 block.number 在一定时间后解锁资金。


function withdraw() public {
require(users[msg.sender].amount > 0, 'no amount locked');
require(block.number >= users[msg.sender].unlockBlock, 'lock period not over');
uint amount = users[msg.sender].amount;
users[msg.sender].amount = 0;
(bool success, ) = msg.sender.call.value(amount)("");
require(success, 'transfer failed');
}
References
[1] Enterprise Ethereum Alliance Don't misuse block data
[2] Standards Mapping - CIS Azure Kubernetes Service Benchmark 2
[3] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 2
[4] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 3
[5] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[6] Standards Mapping - Smart Contract Weakness Classification SWC-116
desc.structural.solidity.swc116