Skip to content

Commit

Permalink
Merge pull request #870 from keep-network/relay-request-callback
Browse files Browse the repository at this point in the history
Relay request callback

Update both Solidity and Go code to provide optional relay request callback.
  • Loading branch information
pdyraga authored Jun 21, 2019
2 parents af2ad08 + adb8af8 commit 793cca1
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 522 deletions.
164 changes: 0 additions & 164 deletions cmd/relay.go

This file was deleted.

25 changes: 23 additions & 2 deletions contracts/solidity/contracts/KeepRandomBeaconImplV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ contract KeepRandomBeaconImplV1 is Ownable {
address sender;
uint256 payment;
bytes groupPubKey;
address callbackContract;
string callbackMethod;
}

mapping(uint256 => Request) internal _requests;
Expand Down Expand Up @@ -79,7 +81,7 @@ contract KeepRandomBeaconImplV1 is Ownable {
// to trigger the creation of the first group. Requests are removed on successful
// entries so genesis entry can only be called once.
_requestCounter++;
_requests[_requestCounter] = Request(msg.sender, 0, genesisGroupPubKey);
_requests[_requestCounter] = Request(msg.sender, 0, genesisGroupPubKey, address(0), "");
}

/**
Expand All @@ -96,6 +98,19 @@ contract KeepRandomBeaconImplV1 is Ownable {
* @return An uint256 representing uniquely generated relay request ID. It is also returned as part of the event.
*/
function requestRelayEntry(uint256 seed) public payable returns (uint256) {
return requestRelayEntry(seed, address(0), "");
}

/**
* @dev Creates a request to generate a new relay entry, which will include a
* random number (by signing the previous entry's random number).
* @param seed Initial seed random value from the client. It should be a cryptographically generated random value.
* @param callbackContract Callback contract address. Callback is called once a new relay entry has been generated.
* @param callbackMethod Callback contract method signature. String representation of your method with a single
* uint256 input parameter i.e. "relayEntryCallback(uint256)".
* @return An uint256 representing uniquely generated relay request ID. It is also returned as part of the event.
*/
function requestRelayEntry(uint256 seed, address callbackContract, string memory callbackMethod) public payable returns (uint256) {
require(
msg.value >= _minPayment,
"Payment is less than required minimum."
Expand All @@ -110,7 +125,7 @@ contract KeepRandomBeaconImplV1 is Ownable {

_requestCounter++;

_requests[_requestCounter] = Request(msg.sender, msg.value, groupPubKey);
_requests[_requestCounter] = Request(msg.sender, msg.value, groupPubKey, callbackContract, callbackMethod);

emit RelayEntryRequested(_requestCounter, msg.value, _previousEntry, seed, groupPubKey);
return _requestCounter;
Expand Down Expand Up @@ -161,6 +176,12 @@ contract KeepRandomBeaconImplV1 is Ownable {
require(_requests[requestID].groupPubKey.equalStorage(groupPubKey), "Provided group was not selected to produce entry for this request.");
require(BLS.verify(groupPubKey, abi.encodePacked(previousEntry, seed), bytes32(groupSignature)), "Group signature failed to pass BLS verification.");

address callbackContract = _requests[requestID].callbackContract;

if (callbackContract != address(0)) {
callbackContract.call(abi.encodeWithSignature(_requests[requestID].callbackMethod, groupSignature));
}

delete _requests[requestID];
_previousEntry = groupSignature;

Expand Down
65 changes: 0 additions & 65 deletions contracts/solidity/contracts/KeepRandomBeaconStub.sol

This file was deleted.

29 changes: 29 additions & 0 deletions contracts/solidity/contracts/examples/CallbackContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
pragma solidity ^0.5.4;


/**
* @title CallbackContract
* @dev Example callback contract for Random Beacon.
*/
contract CallbackContract {

uint256 internal _lastEntry;

/**
* @dev Example of a callback method. Method signature can be
* calculated as bytes4(keccak256("callback(uint256)")
*/
function callback(uint256 requestResponse)
public
{
_lastEntry = requestResponse;
}

/**
* @dev Returns previous entry.
*/
function lastEntry() public view returns (uint256)
{
return _lastEntry;
}
}
32 changes: 32 additions & 0 deletions contracts/solidity/scripts/genesis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const KeepRandomBeaconProxy = artifacts.require('KeepRandomBeacon.sol')
const KeepRandomBeacon = artifacts.require("KeepRandomBeaconImplV1")

// The data below should match genesis relay request data defined on contract
// initialization i.e. in 2_deploy_contracts.js. Successful genesis entry will
// trigger creation of the first group that will be chosen to respond on the
// next relay request, resulting another relay entry with creation of another
// group and so on.

// https://www.wolframalpha.com/input/?i=pi+to+78+digits
const previousEntry = web3.utils.toBN('31415926535897932384626433832795028841971693993751058209749445923078164062862')

// https://www.wolframalpha.com/input/?i=e+to+78+digits
const seed = web3.utils.toBN('27182818284590452353602874713526624977572470936999595749669676277240766303535')

// Data generated using client keep-core/pkg/bls package signing previous entry using master secret key '123'
const groupPubKey = "0x1f1954b33144db2b5c90da089e8bde287ec7089d5d6433f3b6becaefdb678b1b2a9de38d14bef2cf9afc3c698a4211fa7ada7b4f036a2dfef0dc122b423259d0"
const groupSignature = web3.utils.toBN('10920102476789591414949377782104707130412218726336356788412941355500907533021')

module.exports = async function () {

const keepRandomBeaconProxy = await KeepRandomBeaconProxy.deployed()
let contract = await KeepRandomBeacon.at(keepRandomBeaconProxy.address)
try {
await contract.relayEntry(1, groupSignature, groupPubKey, previousEntry, seed)
console.log('Genesis entry successfully submitted.')
} catch(error) {
console.error('Genesis entry submission failed with', error)
}

process.exit()
}
31 changes: 31 additions & 0 deletions contracts/solidity/scripts/request-relay-entry-with-callback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const crypto = require("crypto")
const KeepRandomBeacon = artifacts.require("KeepRandomBeaconImplV1")
const KeepRandomBeaconProxy = artifacts.require('KeepRandomBeacon.sol')

// Example usage:
// truffle exec ./scripts/request-relay-entry-with-callback.js yourContractAddress "callbackMethodName" payment
// truffle exec ./scripts/request-relay-entry-with-callback.js 0x9F57C01059057d821c6b4B04A4598322661C934F "callback(uint256)" 100

module.exports = async function() {

const keepRandomBeaconProxy = await KeepRandomBeaconProxy.deployed()
const contractInstance = await KeepRandomBeacon.at(keepRandomBeaconProxy.address)

try {
let tx = await contractInstance.methods['requestRelayEntry(uint256,address,string)'](crypto.randomBytes(32), process.argv[4], process.argv[5], {value: process.argv[6]})
console.log('Successfully requested relay entry with a callback. RequestId =', tx.logs[0].args.requestID.toString())
console.log(
'\n---Transaction Summary---' + '\n' +
'From:' + tx.receipt.from + '\n' +
'To:' + tx.receipt.to + '\n' +
'BlockNumber:' + tx.receipt.blockNumber + '\n' +
'TotalGas:' + tx.receipt.cumulativeGasUsed + '\n' +
'TransactionHash:' + tx.receipt.transactionHash + '\n' +
'--------------------------'
)
} catch(error) {
console.error('Request failed with', error)
}

process.exit()
}
Loading

0 comments on commit 793cca1

Please sign in to comment.