Skip to content

Commit

Permalink
Merge pull request #26 from orochi-network/misc/integrate_testnet_chain
Browse files Browse the repository at this point in the history
Misc: Add more testnet chain info & modify deploy Orochi script
  • Loading branch information
chiro-hiro committed May 23, 2024
2 parents 8bb75f8 + 2ff2187 commit 854146f
Show file tree
Hide file tree
Showing 27 changed files with 4,579 additions and 53 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,9 @@ typechain-types/
artifacts/
cache/
flatten/
.env*
.env*
cache-zk
deployments-zk
artifacts-zk
.upgradable
.openzeppelin
161 changes: 161 additions & 0 deletions contracts/examples/DiceGameV3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@orochi-network/contracts/IOrandConsumerV3.sol';
import '@orochi-network/contracts/IOrocleAggregatorV2.sol';

error WrongGuessingValue(uint128 guessing);

// Application should be an implement of IOrandConsumerV2 interface
contract DiceGameV3 is IOrandConsumerV3, Ownable {
// Set new provider
event SetProvider(address indexed oldProvider, address indexed newProvider);

// Set new oracle
event SetOracle(address indexed oldProvider, address indexed newProvider);

// Fulfill awaiting result
event Fulfilled(uint256 indexed gameId, uint256 guessed, uint256 indexed result);

// New guess from player
event NewGuess(address indexed player, uint256 indexed gameId, uint128 indexed guessed);

// Game structure
struct Game {
uint128 guessed;
uint128 result;
}

// Provider address
address private orandProvider;

// Orochi Network oracle
address private oracle;

// Game result storage
mapping(uint256 => Game) private gameResult;

// Total game
uint256 private totalGame;

// Fulfiled randomness
uint256 private fulfilled;

// We batching the radomness in one epoch
uint256 private maximumBatching;

// Only allow Orand to submit result
modifier onlyOrandProvider() {
if (msg.sender != orandProvider) {
revert InvalidProvider();
}
_;
}

// Constructor
constructor(address provider, address oracleAddress) {
_setProvider(provider);
_setOracle(oracleAddress);
}

//=======================[ Internal ]====================

// Set provider
function _setOracle(address oracleAddress) internal {
emit SetOracle(oracle, oracleAddress);
oracle = oracleAddress;
}

// Set provider
function _getOracle() internal view returns (address) {
return oracle;
}

// Set provider
function _setProvider(address provider) internal {
emit SetProvider(orandProvider, provider);
orandProvider = provider;
}

// Set provider
function _getProvider() internal view returns (address) {
return orandProvider;
}

//=======================[ Owner ]====================

// Set provider
function setProvider(address provider) external onlyOwner returns (bool) {
_setProvider(provider);
return true;
}

// Set oracle
function setOracle(address oracleAddress) external onlyOwner returns (bool) {
_setOracle(oracleAddress);
return true;
}

//=======================[ OrandProviderV2 ]====================

// Consume the result of Orand V2 with batching feature
function consumeRandomness(uint256 randomness) external override onlyOrandProvider returns (bool) {
// We keep batching < maximumBatching
if (fulfilled < totalGame) {
Game memory currentGame = gameResult[fulfilled];
currentGame.result = uint128((randomness % 6) + 1);
gameResult[fulfilled] = currentGame;
emit Fulfilled(fulfilled, currentGame.guessed, currentGame.result);
fulfilled += 1;
return true;
}
// We will let the provider know that all are fulfilled
return false;
}

//=======================[ External ]====================

// Player can guessing any number in range of 1-6
function guessingDiceNumber(uint128 guessing) external returns (bool) {
// Player only able to guessing between 1-6 since it's dice number
if (guessing < 1 || guessing > 6) {
revert WrongGuessingValue(guessing);
}
gameResult[totalGame] = Game({ guessed: guessing, result: 0 });

// Request randomness from Orand
IOrocleAggregatorV2(oracle).request(0, '0x');

emit NewGuess(msg.sender, totalGame, guessing);
totalGame += 1;
return true;
}

//=======================[ External View ]====================

// Get provider
function getProvider() external view returns (address) {
return _getProvider();
}

// Get oracle
function getOracle() external view returns (address) {
return _getOracle();
}

// Get result from smart contract
function getResult(uint256 gameId) external view returns (Game memory result) {
return gameResult[gameId];
}

function getStateOfGame() external view returns (uint256 fulfill, uint256 total) {
return (fulfilled, totalGame);
}

function isFulfilled() external view returns (bool) {
if (fulfilled < totalGame) {
return false;
}
return true;
}
}
1 change: 0 additions & 1 deletion contracts/multicast/MultiCast.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.19;

import '../libraries/Bytes.sol';
import 'hardhat/console.sol';

error InvalidLength();

Expand Down
21 changes: 21 additions & 0 deletions contracts/test/TestERC721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/utils/Counters.sol';
import '@openzeppelin/contracts/access/Ownable.sol';

// An ambition is hiding in the bush
contract TestERC721 is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;

constructor() ERC721('TestBigO', 'TestO') {}

function mintNFT(address recipient) public returns (uint256) onlyOwner {
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_mint(recipient, newTokenId);
return newTokenId;
}
}
62 changes: 61 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { HardhatUserConfig } from 'hardhat/types';
import { env } from './env';
import '@nomicfoundation/hardhat-toolbox';
import '@openzeppelin/hardhat-upgrades';
import '@matterlabs/hardhat-zksync';
import '@matterlabs/hardhat-zksync-deploy';
import '@matterlabs/hardhat-zksync-solc';

const isZkSolc = process.env.USE_ZKSOLC === 'true';

if (fs.existsSync('./typechain-types')) {
const dir = fs.opendirSync(`${__dirname}/tasks`);
Expand All @@ -29,6 +34,10 @@ const config: HardhatUserConfig = {
gasReporter: {
enabled: true,
},
zksolc: {
version: '1.4.1',
settings: {},
},
networks: {
sepolia: {
url: 'https://eth-sepolia.api.onfinality.io/public',
Expand Down Expand Up @@ -75,6 +84,11 @@ const config: HardhatUserConfig = {
chainId: 42161,
accounts: { mnemonic: env.OROCHI_MNEMONIC },
},
arbitrumTest: {
url: 'https://sepolia-rollup.arbitrum.io/rpc',
chainId: 421614,
accounts: { mnemonic: env.OROCHI_MNEMONIC },
},
polygon: {
url: 'https://rpc-mainnet.matic.quiknode.pro',
chainId: 137,
Expand All @@ -96,7 +110,7 @@ const config: HardhatUserConfig = {
accounts: { mnemonic: env.OROCHI_MNEMONIC },
},
bnbChainTest: {
url: 'https://data-seed-prebsc-1-s1.binance.org:8545',
url: 'https://bsc-testnet-rpc.publicnode.com',
chainId: 97,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
Expand All @@ -109,8 +123,54 @@ const config: HardhatUserConfig = {
mnemonic: env.OROCHI_MNEMONIC,
},
},
moonbeamTest: {
url: 'https://rpc.api.moonbase.moonbeam.network',
chainId: 1287,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},
saakuruTest: {
url: 'https://rpc.testnet.oasys.games/',
chainId: 9372,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},
zkFairTest: {
url: 'https://testnet-rpc.zkfair.io',
chainId: 43851,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},
zircuitTest: {
url: `https://zircuit1.p2pify.com/`,
chainId: 48899,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},
xLayerTest: {
url: `https://testrpc.xlayer.tech/`,
chainId: 195,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},
zkLinkTest: {
url: `https://sepolia.rpc.zklink.io`,
zksync: true,
ethNetwork: 'https://sepolia.rpc.zklink.io',
chainId: 810181,
accounts: {
mnemonic: env.OROCHI_MNEMONIC,
},
},

// Hard hat network
hardhat: {
zksync: isZkSolc,
chainId: 911,
hardfork: 'london',
blockGasLimit: 30000000,
Expand Down
7 changes: 6 additions & 1 deletion helpers/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/* eslint-disable no-await-in-loop */
import '@nomicfoundation/hardhat-ethers';
import { Wallet, ethers } from 'ethers';
import { HDNodeWallet, Wallet, ethers } from 'ethers';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { Wallet as zkSyncWallet, Provider } from 'zksync-ethers';
import { env } from '../env';

export function getZkSyncWallet(wallet: HDNodeWallet, provider: Provider) {
return new zkSyncWallet(wallet.privateKey);
}

export async function getWallet(hre: HardhatRuntimeEnvironment, chainId: bigint): Promise<ethers.HDNodeWallet> {
if (chainId === 911n) {
const wallet = (await hre.ethers.getSigners())[0];
Expand Down
14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
"scripts": {
"compile": "rm -rf ./cache ./artifacts ./typechain-types ./flatten && hardhat compile",
"build": "yarn run compile && hardhat typechain && yarn flatten",
"compile:zk": "rm -rf ./cache-zk ./artifacts-zk ./typechain-types ./flatten ./deployments-zk ./.upgradable && USE_ZKSOLC=true hardhat compile",
"build:zk": "yarn run compile:zk && hardhat typechain && yarn flatten",
"prepack": "bash ./scripts/prepack.sh",
"clean": "hardhat clean && rimraf build contracts/build",
"release": "yarn build && yarn flatten",
"coverage": "hardhat compile && hardhat coverage",
"node:local": "hardhat node",
"deploy:orochi": "hardhat deploy:orochi",
"test": "hardhat test",
"flatten": "mkdir -p flatten/ && npx hardhat flatten ./contracts/orocle-v1/OrocleV1.sol > ./flatten/OrocleV1.sol && npx hardhat flatten ./contracts/orand-v2/OrandProviderV2.sol > ./flatten/OrandProviderV2.sol && npx hardhat flatten ./contracts/orosign/OrosignV1.sol > ./flatten/OrosignV1.sol && npx hardhat flatten ./contracts/orosign/OrosignMasterV1.sol > ./flatten/OrosignMasterV1.sol && npx hardhat flatten ./contracts/examples/DiceGame.sol > ./flatten/DiceGame.sol"
"flatten": "mkdir -p flatten/ && npx hardhat flatten ./contracts/orocle-v1/OrocleV1.sol > ./flatten/OrocleV1.sol && npx hardhat flatten ./contracts/orand-v2/OrandProviderV2.sol > ./flatten/OrandProviderV2.sol && npx hardhat flatten ./contracts/orosign/OrosignV1.sol > ./flatten/OrosignV1.sol && npx hardhat flatten ./contracts/orosign/OrosignMasterV1.sol > ./flatten/OrosignMasterV1.sol && npx hardhat flatten ./contracts/examples/DiceGame.sol > ./flatten/DiceGame.sol && npx hardhat flatten ./contracts/orocle-v2/OrocleV2.sol > ./flatten/OrocleV2.sol && npx hardhat flatten ./contracts/orand-v3/OrandProviderV3.sol > ./flatten/OrandProviderV3.sol"
},
"keywords": [
"vrf",
Expand All @@ -29,6 +31,11 @@
"author": "chiro@orochi.network",
"license": "MIT",
"devDependencies": {
"@matterlabs/hardhat-zksync": "^1.0.0",
"@matterlabs/hardhat-zksync-deploy": "^1.3.0",
"@matterlabs/hardhat-zksync-solc": "^1.1.4",
"@matterlabs/hardhat-zksync-upgradable": "^1.4.1",
"@matterlabs/zksync-contracts": "^0.6.1",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.5",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
Expand All @@ -47,7 +54,8 @@
"solidity-coverage": "^0.8.0",
"ts-node": "^10.9.2",
"typechain": "^8.3.0",
"typescript": "^5.3.3"
"typescript": "^5.3.3",
"zksync-ethers": "^6.7.1"
},
"dependencies": {
"@openzeppelin/contracts": "4.9.6",
Expand All @@ -57,4 +65,4 @@
"axios": "^1.6.5",
"dotenv": "^16.3.1"
}
}
}
21 changes: 21 additions & 0 deletions package/IOrandConsumerV3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

error InvalidProvider();

/**
* @dev IOrandConsumerV3 must be implemented for all service that use Orand
*/
interface IOrandConsumerV3 {
/**
* Consume the verifiable randomness from Orand provider
* @param randomness Randomness value
* @return return false if you want to stop batching otherwise return true
*/
function consumeRandomness(uint256 randomness) external returns (bool);
/**
* Check the fulfill status of randomness batching
* @return true if all requests are fulfilled otherwise return false
*/
function isFulfilled() external returns (bool);
}
Loading

0 comments on commit 854146f

Please sign in to comment.