Skip to content

Instantly share code, notes, and snippets.

@PatrickAlphaC
Created August 7, 2020 04:09
Show Gist options
  • Save PatrickAlphaC/1bb62664cfad04de04d9dc5d059eb519 to your computer and use it in GitHub Desktop.
Save PatrickAlphaC/1bb62664cfad04de04d9dc5d059eb519 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&gist=1bb62664cfad04de04d9dc5d059eb519
pragma solidity ^0.6.6;
contract Governance {
uint256 public one_time;
address public lottery;
address public randomness;
constructor() public {
one_time = 1;
}
function init(address _lottery, address _randomness) public {
require(_randomness != address(0), "governance/no-randomnesss-address");
require(_lottery != address(0), "no-lottery-address-given");
//require(one_time > 0, "can-only-be-called-once");
//one_time = one_time - 1;
randomness = _randomness;
lottery = _lottery;
}
}
pragma solidity 0.6.6;
interface GovernanceInterface {
function lottery() external view returns (address);
function randomness() external view returns (address);
}
pragma solidity ^0.6.6;
import "github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/ChainlinkClient.sol";
import {RandomnessInterface} from "./RandomnessInterface.sol";
import {GovernanceInterface} from "./GovernanceInterface.sol";
contract Lottery is ChainlinkClient {
enum LOTTERY_STATE { OPEN, CLOSED, CALCULATING_WINNER }
LOTTERY_STATE public lottery_state;
uint256 public lotteryId;
address payable[] public players;
GovernanceInterface public governance;
// .01 ETH
uint256 public MINIMUM = 1000000000000000;
// 0.1 LINK
uint256 public ORACLE_PAYMENT = 100000000000000000;
// Alarm stuff
address CHAINLINK_ALARM_ORACLE = 0xc99B3D447826532722E41bc36e644ba3479E4365;
bytes32 CHAINLINK_ALARM_JOB_ID = "2ebb1c1a4b1e4229adac24ee0b5f784f";
constructor(address _governance) public
{
setPublicChainlinkToken();
lotteryId = 1;
lottery_state = LOTTERY_STATE.CLOSED;
governance = GovernanceInterface(_governance);
}
function enter() public payable {
assert(msg.value == MINIMUM);
assert(lottery_state == LOTTERY_STATE.OPEN);
players.push(msg.sender);
}
function start_new_lottery(uint256 duration) public {
require(lottery_state == LOTTERY_STATE.CLOSED, "can't start a new lottery yet");
lottery_state = LOTTERY_STATE.OPEN;
Chainlink.Request memory req = buildChainlinkRequest(CHAINLINK_ALARM_JOB_ID, address(this), this.fulfill_alarm.selector);
req.addUint("until", now + duration);
sendChainlinkRequestTo(CHAINLINK_ALARM_ORACLE, req, ORACLE_PAYMENT);
}
function fulfill_alarm(bytes32 _requestId)
public
recordChainlinkFulfillment(_requestId)
{
require(lottery_state == LOTTERY_STATE.OPEN, "The lottery hasn't even started!");
// add a require here so that only the oracle contract can
// call the fulfill alarm method
lottery_state = LOTTERY_STATE.CALCULATING_WINNER;
lotteryId = lotteryId + 1;
pickWinner();
}
function pickWinner() private {
require(lottery_state == LOTTERY_STATE.CALCULATING_WINNER, "You aren't at that stage yet!");
RandomnessInterface(governance.randomness()).getRandom(lotteryId, lotteryId);
//this kicks off the request and returns through fulfill_random
}
function fulfill_random(uint256 randomness) external {
require(lottery_state == LOTTERY_STATE.CALCULATING_WINNER, "You aren't at that stage yet!");
require(randomness > 0, "random-not-found");
// assert(msg.sender == governance.randomness());
uint256 index = randomness % players.length;
players[index].transfer(address(this).balance);
players = new address payable[](0);
lottery_state = LOTTERY_STATE.CLOSED;
// You could have this run forever
// start_new_lottery();
// or with a cron job from a chainlink node would allow you to
// keep calling "start_new_lottery" as well
}
function get_players() public view returns (address payable[] memory) {
return players;
}
function get_pot() public view returns(uint256){
return address(this).balance;
}
}
pragma solidity 0.6.6;
interface LotteryInterface {
function fulfill_random(uint) external;
}
pragma solidity 0.6.6;
import "https://raw.githubusercontent.com/smartcontractkit/chainlink/7a4e19a8ff07db1be0b397465d38d175bc0bb5b5/evm-contracts/src/v0.6/VRFConsumerBase.sol";
import {LotteryInterface} from "./LotteryInterface.sol";
import {GovernanceInterface} from "./GovernanceInterface.sol";
contract Randomness is VRFConsumerBase {
bytes32 internal keyHash;
uint256 internal fee;
mapping (uint => uint) public randomNumber;
mapping (bytes32 => uint) public requestIds;
GovernanceInterface public governance;
uint256 public most_recent_random;
/**
* Constructor inherits VRFConsumerBase
*
* Network: Ropsten
* Chainlink VRF Coordinator address: 0xf720CF1B963e0e7bE9F58fd471EFa67e7bF00cfb
* LINK token address: 0x20fE562d797A42Dcb3399062AE9546cd06f63280
* Key Hash: 0xced103054e349b8dfb51352f0f8fa9b5d20dde3d06f9f43cb2b85bc64b238205
*/
constructor(address _governance)
VRFConsumerBase(
0xf720CF1B963e0e7bE9F58fd471EFa67e7bF00cfb, // VRF Coordinator
0x20fE562d797A42Dcb3399062AE9546cd06f63280 // LINK Token
) public
{
keyHash = 0xced103054e349b8dfb51352f0f8fa9b5d20dde3d06f9f43cb2b85bc64b238205;
fee = 0.1 * 10 ** 18; // 0.1 LINK
governance = GovernanceInterface(_governance);
}
/**
* Requests randomness from a user-provided seed
*/
function getRandom(uint256 userProvidedSeed, uint256 lotteryId) public {
require(LINK.balanceOf(address(this)) > fee, "Not enough LINK - fill contract with faucet");
bytes32 _requestId = requestRandomness(keyHash, fee, userProvidedSeed);
requestIds[_requestId] = lotteryId;
}
/**
* Callback function used by VRF Coordinator
*/
function fulfillRandomness(bytes32 requestId, uint256 randomness) external override {
require(msg.sender == vrfCoordinator, "Fulillment only permitted by Coordinator");
most_recent_random = randomness;
uint lotteryId = requestIds[requestId];
randomNumber[lotteryId] = randomness;
LotteryInterface(governance.lottery()).fulfill_random(randomness);
}
}
pragma solidity 0.6.6;
interface RandomnessInterface {
function randomNumber(uint) external view returns (uint);
function getRandom(uint, uint) external;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment