gpt4 book ai didi

solidity - Chainlink VRF 还是 RANDAO?

转载 作者:行者123 更新时间:2023-12-03 08:01:28 24 4
gpt4 key购买 nike

    bytes9 private _randomness;

function getRandomness() public view returns (uint256) {
return uint256(keccak256(abi.encode(_randomness, address(this))));
}

modifier updateRandomness() {
bytes32 randomness = _randomness;
assembly {
// Pick any of the last 256 blocks psuedorandomly for the blockhash.
// Store the blockhash, the current `randomness` and the `coinbase()`
// into the scratch space.
mstore(0x00, blockhash(sub(number(), add(1, byte(0, randomness)))))
// `randomness` is left-aligned.
// `coinbase()` is right-aligned.
// `difficulty()` is right-aligned.
// After the merge, if [EIP-4399](https://eips.ethereum.org/EIPS/eip-4399)
// is implemented, the randomness will be determined by the beacon chain.
mstore(0x20, xor(randomness, xor(coinbase(), difficulty())))
// Compute the new `randomness` by hashing the scratch space.
randomness := keccak256(0x00, 0x40)
}
_randomness = bytes9(randomness);
_;
}

function generateNFT() external updateRandomness {
uint256 randomNum = getRandomness();
uint256 remaining = MAX_SUPPLY - totalSupply();
uint256 newId = (randomNum % remaining);
// ...
}

看起来合并后,获得可靠的随机值可能是可行的。

这可能是 chainlink VRF 的一个很好的替代品?

最佳答案

摘要

对于伪随机性,您可以使用类似 EIP-4399 的东西:

uint256 randomness = uint(keccak256(abi.encodePacked(msg.sender, block.difficulty, block.timestamp)));

(你甚至不需要使用汇编,难度直接暴露在solidity中)

但为了真正的随机性,你需要类似 Chainlink VRF 的东西.

    function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
uint256 randomness = _randomWords[0];
}

为什么合并后的 ETH 中的难度PREVRANDAO是伪随机的?

当验证者要提议一个区 block 时,他们面临 fairly minimal penalty因为没有这样做。考虑到智能合约试图通过 PREVRANDAO 使自身变得不可预测/不可控制,此选项允许他们通过以下方式廉价地偏向合约的行为。

1。你总是需要一个验证器来连续提议两个区 block

PREVRANDAO 的值没有 entropy如果没有提出区 block ,则给出前一个区 block 的 PREVRANDAO 值。当您提出一个 block 时,它就是 PREVRANDAO 用于生成随机数的数学方程的一部分。因此,如果您不提议区 block ,您会得到一个“较少”的随机数。

因此,PREVRANDAO 的用户需要检查验证器自上次调用 PREVRANDAO 以来是否已提供了一个区 block 。否则,他们不一定会在连续调用 PREVRANDAO 时绘制统计上独立的随机输出。

这意味着致力于提议特定区 block 的验证者可以有效地将下一个区 block 的 PREVRANDAO 值设置为两个可能的值:

  • 由其强制 PREVRANDAO 输入值生成的值
  • 如果没有提出区 block ,则 PREVRANDAO 被确定性地设置为

仅此选择就允许验证者影响随机数,而不再使数字随机。

即使合约做了一些更聪明的事情,比如从某个高度之后提议的第一个 block 中获取 PREVRANDAO 输出,该高度之后的每个验证器都具有相同的选项。无论合约尝试以哪种方式访问​​ PREVRANDAO,最后贡献的验证者始终对控制合约的随机输出具有可预测的控制权。

Chainlink VRF 不会出现这些问题,因为考虑到区 block 哈希,输出是确定性的(对于不知道 key 的人来说,计算是不可行的。)

2。如果数字不利,验证者可以选择不发布

再一次,您在预合并时仍然遇到此问题。不发布区 block 的惩罚几乎可以忽略不计,因此如果 PREVRAND 值不是他们想要的值,节点可能会受到经济激励而不在彩票类型的智能合约中提出区 block 。有足够多的节点执行此操作,您就会遇到问题。

仅获取当前的 PREVRANDAO 值而不查看最近的历史记录,可以让验证者对合约将使用的输出进行一些控制,即使它不想中止,因为验证者可以决定是否中止或者它建议的区 block 不包含将触发 PREVRANDAO 的使用的交易。唯一涉及的成本是交易费/小费。

3。如果所有应用程序都使用 PREVRANDAO 作为种子

如果所有应用程序都使用 PREVRANDAO 作为种子,在某种程度上,您可以基于此将胜利或黑客“链接”在一起。

更多信息

Ethereum Magicians 中还有一个关于此的有趣线程。论坛。

关于solidity - Chainlink VRF 还是 RANDAO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73938799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com