[译]区块链上生成随机数

栏目: IT技术 · 发布时间: 4年前

内容简介:在区块链上如何生成随机数。本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

在区块链上如何生成随机数。

[译]区块链上生成随机数

什么是随机数?

想象一下你身边的随机噪音或者任何随机发生的事情,可以说检测到这些随机模式的可能性为0。这就是随机数的意思 - 一个可以生成在指定范围内的任意不确定数字的模式。

当我这么说的时候,考虑一下1~100之间的某个数。由于不确定性,我猜不到你的脑子里现在想的是哪个数。

随机数是从某个特定分布中选中的数,通常也会要求这些数之间彼此独立, 这样在前后两个数之间就不会存在相关性。计算机生成的随机数有时会 称为 伪随机数 ,这一术语中保留了 随机 ,表示其不可预测性。当没有额外的约定时,通常随机数采样自均匀分布。当然也可以使用其他的概率分布, 例如, Box-Muller变换 可以将一对满足均匀分布的随机数转换为一个二维正态分布。

什么是伪随机数?

伪随机数也被称为确定性随机位。这些数是使用被称为 伪随机数发生器(Pseudo-Random Number Generators)/PRNG ) 的计算机算法生成的,它们是确定性的,因此并不是真的随机,这些伪随机数在经过一定的序列之后可能会重复。

为了生成随机数,我们需要使用一个数来初始化算法,这个数被称为 种子/SEED )。 通常使用系统时间(补齐后作为一个数或任意数字)作为种子,为了确保这些伪随机数有足够的随机性, 我们会加一些 盐/SALT (可以将它视为你的伪随机数的密码 )以避免 哈希碰撞 (如果数字生成时间很短,并且我们没有使用盐或糖,则可能是同一种子将用于生成两个或多个数字,因此每次相同的数字都会生成相同的哈希)。

区块链上如何实现伪随机数.

从前面的描述中,我们知道计算机里的随机数并不是真的随机,并且至少需要一个系统时间来初始化算法,如果你要用它来开发某些有很强的随机要求的应用是不那么好的, 例如博彩游戏、计算机仿真、密码学等,这就有可能发生哈希碰撞。

这就是为什么在区块链上基本上不可能生成随机数的原因,我们需要获取区块时间或区块哈希之类的作为种子,由于早期第一代和第二代区块链的出块速度很慢,那么发生哈希碰撞的机会非常大。

但是, 第三代的区块链 已经可以达到很快的出块速度了,比如0.5~1秒,这样我们就可以利用区块时间戳或区块哈希来初始化 伪随机数发生器

我用 Solidity 编写了智能合约,以演示如何在区块链上实现伪随机数。

你可以说这是一个 真随机数发生器/TRNG ,因为我们没有使用算法来生成随机数,而只是将区块时间与种子、盐、糖组合后计算哈希。我们选择的这三个值可以是相同的并且是确定性的,但是区块哈希是不确定性的。 下面的代码支持以太坊、波场或其他任何支持Solidity的第三代区块链:

pragma solidity ^0.5.8;

/**
 * @title True random number generator
 * @notice This is a contract to generate a true random number on blockchai.
 * Though true random number generators doesn't require seed. But, to simplify
 * the functions i used seed and other terms used in PRNGs,
 * seed should be enough to generate a random number, but to randomize the pattern
 * even more i added two more functions with salt and sugar.
 */
contract PRNG {
    /**
        * @notice Generates a random number between 0 - 100
        * @param seed The seed to generate different number if block.timestamp is same
        * for two or more numbers.
        */
    function importSeedFromThird(uint256 seed) public view returns (uint8) {
        uint8 randomNumber = uint8(
            uint256(keccak256(abi.encodePacked(block.timestamp, seed))) % 100
        );
        return randomNumber;
    }

    /**
     * @notice Generates a random number between 0 - 100
     * @param seed The seed to generate different number if block.timestamp is same
     * for two or more numbers.
     * @param salt The salt to randomize the pattern
     */
    function importSeedFromThirdSalt(uint256 seed, uint256 salt)
        public
        view
        returns (uint8)
    {
        uint8 randomNumber = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, seed, salt))) % 100);
        return randomNumber;
    }

    /**
     * @notice Generates a random number between 0 - 100
     * @param seed The seed to generate different number if block.timestamp is same
     * for two or more numbers.
     * @param salt The salt to randomize the pattern
     * @param sugar The sugar same as salt but for more randomization
     */
    function importSeedFromThirdSaltSugar(
        uint256 seed,
        uint256 salt,
        uint256 sugar
    ) public view returns (uint8) {
        uint8 randomNumber = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, seed, salt, sugar))) % 100);
        return randomNumber;
    }
}

在上面的合约中,我们实现了三个函数,分别使用不同的参数生成Solidity随机数:

  • importSeedFromThird:只需要种子的Solidity随机数发生器

  • importSeedFromThirdSalt:需要种子、盐的Solidity随机数发生器

  • importSeedFromThirdSaltSugar:需要种子、盐、糖的Solidity随机数发生器

abi.encodePacked紧密打包数据的bytes而没有任何填充,因为如果没有填充,则无法从此函数中提取数据。函数返回 bytes 类型,可以转化为 uint256 类型。参考Solidity 中文文档 keccak256sha3 类似的 hash函数,只是采用不同的补齐模式,具体可以参考 这里 .

因此,在上面的函数中,我们实际上将包含时间、种子、盐、糖的数据进行了编码 从而获得更强的随机性,并尽可能让随机数不可预测。 当然我们可以从上面函数实现中删除时间戳,但是这样的话,我们就完全控制了随机数的发生,从而破坏了区块链的透明特性。

原文:https://medium.com/gammastack/random-number-generation-on-blockchain-d3141e1efc2

[译]区块链上生成随机数

什么是随机数?

想象一下你身边的随机噪音或者任何随机发生的事情,可以说检测到这些随机模式的可能性为0。这就是随机数的意思 - 一个可以生成在指定范围内的任意不确定数字的模式。

当我这么说的时候,考虑一下1~100之间的某个数。由于不确定性,我猜不到你的脑子里现在想的是哪个数。

随机数是从某个特定分布中选中的数,通常也会要求这些数之间彼此独立, 这样在前后两个数之间就不会存在相关性。计算机生成的随机数有时会 称为 伪随机数 ,这一术语中保留了 随机 ,表示其不可预测性。当没有额外的约定时,通常随机数采样自均匀分布。当然也可以使用其他的概率分布, 例如, Box-Muller变换 可以将一对满足均匀分布的随机数转换为一个二维正态分布。

什么是伪随机数?

伪随机数也被称为确定性随机位。这些数是使用被称为 伪随机数发生器(Pseudo-Random Number Generators)/PRNG ) 的计算机算法生成的,它们是确定性的,因此并不是真的随机,这些伪随机数在经过一定的序列之后可能会重复。

为了生成随机数,我们需要使用一个数来初始化算法,这个数被称为 种子/SEED )。 通常使用系统时间(补齐后作为一个数或任意数字)作为种子,为了确保这些伪随机数有足够的随机性, 我们会加一些 盐/SALT (可以将它视为你的伪随机数的密码 )以避免 哈希碰撞 (如果数字生成时间很短,并且我们没有使用盐或糖,则可能是同一种子将用于生成两个或多个数字,因此每次相同的数字都会生成相同的哈希)。

区块链上如何实现伪随机数.

从前面的描述中,我们知道计算机里的随机数并不是真的随机,并且至少需要一个系统时间来初始化算法,如果你要用它来开发某些有很强的随机要求的应用是不那么好的, 例如博彩游戏、计算机仿真、密码学等,这就有可能发生哈希碰撞。

这就是为什么在区块链上基本上不可能生成随机数的原因,我们需要获取区块时间或区块哈希之类的作为种子,由于早期第一代和第二代区块链的出块速度很慢,那么发生哈希碰撞的机会非常大。

但是, 第三代的区块链 已经可以达到很快的出块速度了,比如0.5~1秒,这样我们就可以利用区块时间戳或区块哈希来初始化 伪随机数发生器

我用 Solidity 编写了智能合约,以演示如何在区块链上实现伪随机数。

你可以说这是一个 真随机数发生器/TRNG ,因为我们没有使用算法来生成随机数,而只是将区块时间与种子、盐、糖组合后计算哈希。我们选择的这三个值可以是相同的并且是确定性的,但是区块哈希是不确定性的。 下面的代码支持以太坊、波场或其他任何支持Solidity的第三代区块链:

pragma solidity ^0.5.8;

/**
 * @title True random number generator
 * @notice This is a contract to generate a true random number on blockchai.
 * Though true random number generators doesn't require seed. But, to simplify
 * the functions i used seed and other terms used in PRNGs,
 * seed should be enough to generate a random number, but to randomize the pattern
 * even more i added two more functions with salt and sugar.
 */
contract PRNG {
    /**
        * @notice Generates a random number between 0 - 100
        * @param seed The seed to generate different number if block.timestamp is same
        * for two or more numbers.
        */
    function importSeedFromThird(uint256 seed) public view returns (uint8) {
        uint8 randomNumber = uint8(
            uint256(keccak256(abi.encodePacked(block.timestamp, seed))) % 100
        );
        return randomNumber;
    }

    /**
     * @notice Generates a random number between 0 - 100
     * @param seed The seed to generate different number if block.timestamp is same
     * for two or more numbers.
     * @param salt The salt to randomize the pattern
     */
    function importSeedFromThirdSalt(uint256 seed, uint256 salt)
        public
        view
        returns (uint8)
    {
        uint8 randomNumber = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, seed, salt))) % 100);
        return randomNumber;
    }

    /**
     * @notice Generates a random number between 0 - 100
     * @param seed The seed to generate different number if block.timestamp is same
     * for two or more numbers.
     * @param salt The salt to randomize the pattern
     * @param sugar The sugar same as salt but for more randomization
     */
    function importSeedFromThirdSaltSugar(
        uint256 seed,
        uint256 salt,
        uint256 sugar
    ) public view returns (uint8) {
        uint8 randomNumber = uint8(uint256(keccak256(abi.encodePacked(block.timestamp, seed, salt, sugar))) % 100);
        return randomNumber;
    }
}

在上面的合约中,我们实现了三个函数,分别使用不同的参数生成Solidity随机数:

  • importSeedFromThird:只需要种子的Solidity随机数发生器

  • importSeedFromThirdSalt:需要种子、盐的Solidity随机数发生器

  • importSeedFromThirdSaltSugar:需要种子、盐、糖的Solidity随机数发生器

abi.encodePacked紧密打包数据的bytes而没有任何填充,因为如果没有填充,则无法从此函数中提取数据。函数返回 bytes 类型,可以转化为 uint256 类型。参考Solidity 中文文档 keccak256sha3 类似的 hash函数,只是采用不同的补齐模式,具体可以参考 这里 .

因此,在上面的函数中,我们实际上将包含时间、种子、盐、糖的数据进行了编码 从而获得更强的随机性,并尽可能让随机数不可预测。 当然我们可以从上面函数实现中删除时间戳,但是这样的话,我们就完全控制了随机数的发生,从而破坏了区块链的透明特性。

原文: https://medium.com/gammastack/random-number-generation-on-blockchain-d3141e1efc2

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 8分钟前
  • 阅读 ( 5 )
  • 学分 ( 0 )
  • 分类:智能合约

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据结构与算法:python语言实现

数据结构与算法:python语言实现

迈克尔.·T·古德里奇、罗伯托·塔玛西亚、迈克尔·H·戈德瓦瑟 / 张晓、赵晓南 / 机械工业出版社 / 2018-9 / 109.00元

本书采用Python语言讨论数据结构和算法,详细讲解其设计、分析与实现过程,是一本内容全面且特色鲜明的教材。书中将面向对象视角贯穿始终,充分利用Python语言优美而简洁的特点,强调代码的健壮性和可重用性,关注各种抽象数据类型以及不同算法实现策略的权衡。一起来看看 《数据结构与算法:python语言实现》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具