mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-03 09:37:38 +00:00
605d7a8d59
* handle chain flag in integration * handle chain flag in integration * handle chain flag in integration * save * save * merge devel * save * noopWriter - one is enough * chain spec parser * chain spec parser * embed * embed * embed * embed * embed * embed * embed * clean * clean * correct alloc after reset state * correct alloc after reset state * correct alloc after reset state * integration reset state now does re-apply genesis and chainConfig * eips summary * eips summary * eips summary
102 lines
5.0 KiB
Solidity
102 lines
5.0 KiB
Solidity
pragma solidity 0.5.10;
|
|
|
|
/// @dev Randomness test contract based on https://github.com/poanetwork/posdao-contracts.
|
|
/// Generates and stores random numbers in a RANDAO manner and accumulates a random seed.
|
|
contract Random {
|
|
mapping(uint256 => mapping(address => bytes32)) public hashes;
|
|
mapping(uint256 => mapping(address => bytes)) public ciphers;
|
|
mapping(uint256 => mapping(address => uint256)) public secrets;
|
|
uint256 public value;
|
|
|
|
/// @dev Called by the validator's node to store a hash and a cipher of the validator's secret on each collection
|
|
/// round. The validator's node must use its mining address to call this function.
|
|
/// This function can only be called once per collection round (during the `commits phase`).
|
|
/// @param _secretHash The Keccak-256 hash of the validator's secret.
|
|
/// @param _cipher The cipher of the validator's secret. Can be used by the node to decrypt and reveal.
|
|
function commitHash(bytes32 _secretHash, bytes calldata _cipher) external {
|
|
require(block.coinbase == msg.sender);
|
|
require(_isCommitPhase(block.number - 1));
|
|
uint256 round = _collectRound(block.number - 1);
|
|
require(!isCommitted(round, msg.sender));
|
|
hashes[round][msg.sender] = _secretHash;
|
|
ciphers[round][msg.sender] = _cipher;
|
|
}
|
|
|
|
/// @dev Called by the validator's node to XOR its secret with the current random seed.
|
|
/// The validator's node must use its mining address to call this function.
|
|
/// This function can only be called once per collection round (during the `reveals phase`).
|
|
/// @param _number The validator's secret.
|
|
function revealNumber(uint256 _number) external {
|
|
require(block.coinbase == msg.sender);
|
|
require(_isRevealPhase(block.number - 1));
|
|
uint256 round = _collectRound(block.number - 1);
|
|
require(!sentReveal(round, msg.sender));
|
|
require(hashes[round][msg.sender] == keccak256(abi.encodePacked(_number)));
|
|
secrets[round][msg.sender] = _number;
|
|
value ^= _number;
|
|
}
|
|
|
|
/// @dev Returns the Keccak-256 hash and cipher of the validator's secret for the specified collection round
|
|
/// and the specified validator stored by the validator through the `commitHash` function.
|
|
/// @param _collectRound The serial number of the collection round for which hash and cipher should be retrieved.
|
|
/// @param _miningAddress The mining address of validator.
|
|
function getCommitAndCipher(
|
|
uint256 _collectRound,
|
|
address _miningAddress
|
|
) public view returns(bytes32, bytes memory) {
|
|
return (hashes[_collectRound][_miningAddress], ciphers[_collectRound][_miningAddress]);
|
|
}
|
|
|
|
/// @dev Returns a boolean flag indicating whether the specified validator has committed their secret's hash for the
|
|
/// specified collection round.
|
|
/// @param _collectRound The serial number of the collection round for which the checkup should be done.
|
|
/// @param _miningAddress The mining address of the validator.
|
|
function isCommitted(uint256 _collectRound, address _miningAddress) public view returns(bool) {
|
|
return hashes[_collectRound][_miningAddress] != bytes32(0);
|
|
}
|
|
|
|
/// @dev Returns a boolean flag indicating whether the current phase of the current collection round
|
|
/// is a `commits phase`. Used by the validator's node to determine if it should commit the hash of
|
|
/// the secret during the current collection round.
|
|
function isCommitPhase() public view returns(bool) {
|
|
return _isCommitPhase(block.number);
|
|
}
|
|
|
|
/// @dev Returns a boolean flag indicating whether the current phase of the current collection round
|
|
/// is a `reveals phase`. Used by the validator's node to determine if it should reveal the secret during
|
|
/// the current collection round.
|
|
function isRevealPhase() public view returns(bool) {
|
|
return _isRevealPhase(block.number);
|
|
}
|
|
|
|
/// @dev Returns a boolean flag of whether the specified validator has revealed their secret for the
|
|
/// specified collection round.
|
|
/// @param _collectRound The serial number of the collection round for which the checkup should be done.
|
|
/// @param _miningAddress The mining address of the validator.
|
|
function sentReveal(uint256 _collectRound, address _miningAddress) public view returns(bool) {
|
|
return secrets[_collectRound][_miningAddress] != uint256(0);
|
|
}
|
|
|
|
/// @dev Returns the current collect round number.
|
|
function currentCollectRound() public view returns(uint256) {
|
|
return _collectRound(block.number);
|
|
}
|
|
|
|
/// @dev Returns the current random value.
|
|
function getValue() public view returns(uint256) {
|
|
return value;
|
|
}
|
|
|
|
function _collectRound(uint256 blockNumber) private pure returns(uint256) {
|
|
return blockNumber / 6;
|
|
}
|
|
|
|
function _isCommitPhase(uint256 blockNumber) private pure returns(bool) {
|
|
return blockNumber % 6 < 3;
|
|
}
|
|
|
|
function _isRevealPhase(uint256 blockNumber) private pure returns(bool) {
|
|
return blockNumber % 6 >= 3;
|
|
}
|
|
}
|