diff --git a/cspell.json b/cspell.json index c378967..cc8004d 100644 --- a/cspell.json +++ b/cspell.json @@ -125,7 +125,10 @@ "blocktime", "EVMs", "timeframe", - "malincentives" + "malincentives", + "INITIALSUPPLY", + "solady", + "BASEURI" ], "flagWords": ["hte", "addresss"] } diff --git a/docs/develop/smart-contracts/deploy.md b/docs/develop/smart-contracts/deploy.md index 0ebb69d..4823177 100644 --- a/docs/develop/smart-contracts/deploy.md +++ b/docs/develop/smart-contracts/deploy.md @@ -1,7 +1,7 @@ --- title: Deploy description: How to deploy a smart contract to the Quai Network. -sidebar_position: 3 +sidebar_position: 2 keywords: - smart contract - solidityx @@ -45,6 +45,8 @@ Contrary to monolithic blockchains, Quai Network's multi-threaded architecture a Sister contracts are created by deploying contracts across all chains that the project intends to support. After the deployment of these sister contracts, a trust on first-use (TOFU) strategy is used to link the contracts together, allowing each contract to be aware of the state and activities of all of its sisters. Each sister contract contains an objective reference to the public address of every other sister contract. -Contracts intended to function across many chains will contain initially empty slots for the addresses of its sisters. If a contract intends to maintain functionality across the initial network of 13 chains, 12 slots are required for all 12 sister contracts to be referenced. +Contracts intended to function across many chains will contain initially empty slots for the addresses of its sisters. If a contract intends to maintain functionality across the initial network of 9 chains, 8 slots are required for all 8 sister contracts to be referenced. -Information on how to deploy a multi-chain smart contracts with hardhat can be found in the [Multi-Chain Deployment Tutorial](/develop/tutorials/multi-chain.md). +Tutorials on how to deploy a multi-chain smart contracts with hardhat can be found in the [Multi-Chain Deployment Tutorial](/develop/tutorials/multi-chain.md). + +Resources for automated cross-chain deployment and sister contract linking and be found in the [`quais-by-example` repository](https://github.com/dominant-strategies/quais-by-example/tree/main). diff --git a/docs/develop/smart-contracts/languages.md b/docs/develop/smart-contracts/languages.md index c8dbbe6..1f9043b 100644 --- a/docs/develop/smart-contracts/languages.md +++ b/docs/develop/smart-contracts/languages.md @@ -1,7 +1,7 @@ --- title: Languages description: Smart contract development languages supported on Quai Network. -sidebar_position: 2 +sidebar_position: 1 keywords: - solidity - solidityx @@ -14,6 +14,29 @@ Quai Network runs a modified Ethereum Virtual Machine environment that provides Generic [Solidity](#solidity) smart contracts can be deployed to any single chain in the network and will function as expected. However, to take full advantage of Quai's cross-chain functionality, developers must use [SolidityX](#solidityx) based smart contracts. +### Choosing Solidity vs SolidityX + +There are a few main differences between Solidity and SolidityX that developers should consider when choosing which language to use for smart contract development on Quai Network. + +#### Solidity + +- **Recommended for developers new to Quai Network** +- Single chain deployments without cross-chain functionality +- Easier to use, deploy, and test + compatible with existing Solidity tooling +- Supports any previously existing Solidity compiler version +- Compatible with existing Solidity contract libraries like [OpenZeppelin](https://www.openzeppelin.com/contracts) and [Solady](https://github.com/Vectorized/solady). +- **Recommended for most use cases** + +#### SolidityX + +- **Recommended for more advanced developers looking to experiment with cross-chain functionality** +- Enables cross-chain contract deployments +- Requires the [SolidityX compiler](https://github.com/dominant-strategies/SolidityX/releases/tag/0.8.19-solidityx) and additional configuration (can be difficult to set up) +- Not compatible with pre-existing Solidity contract libraries. +- Will be forward compatible with [dynamic scaling events](/learn/advanced-introduction/poem/infinite-execution-shards/dynamic-sharding.mdx) + +## Language Details + ### Solidity Solidity is a contract-oriented, high-level programming language for creating smart contracts. It was influenced by C++, Python, and JavaScript and is designed to target the Ethereum Virtual Machine (EVM) environments. Solidity is statically typed, supports inheritance, and libraries. It allows developers to create smart contracts for a wide range of use cases and applications. Key features of Solidity include: diff --git a/docs/develop/smart-contracts/opcode-additions.md b/docs/develop/smart-contracts/opcode-additions.md index f1b2d44..fc59ba9 100644 --- a/docs/develop/smart-contracts/opcode-additions.md +++ b/docs/develop/smart-contracts/opcode-additions.md @@ -1,7 +1,7 @@ --- title: Opcode Additions description: Specification of the isaddrinternal and etx opcodes additions on Quai Network. -sidebar_position: 1 +sidebar_position: 3 keywords: - solidityx - quai virtual machine diff --git a/docs/develop/tutorials/multi-chain.md b/docs/develop/tutorials/multi-chain.md deleted file mode 100644 index fc2bfdc..0000000 --- a/docs/develop/tutorials/multi-chain.md +++ /dev/null @@ -1,577 +0,0 @@ ---- -title: Multi-Chain Deployment Tutorial -description: A guide to deploying and linking multi-chain smart contracts on Quai Network. -sidebar_position: 2 -keywords: - - multi chain smart contract - - solidityx - - hardhat - - QRC20 - - QRC721 ---- - -## Introduction - -In this article, we'll detail how to **deploy, link, and interact with multi-chain smart contracts** across 2 different shards on Quai Network. _This method can be extended to deploy trustless cross-chain contracts across all 9 shards._ - -We'll be using the basic implementation of a [QRC20 token](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC20X.sol), an adapted version of the [ERC-20 standard](https://eips.ethereum.org/EIPS/eip-20), to showcase cross-chain contracts for this tutorial. - -:::warning -If you want to skip basic environment setup for contract deployment, the [hardhat-example](https://github.com/dominant-strategies/hardhat-example) repository provides a **pre-configured environment for deploying smart contracts on Quai Network**. Clone the repository on your local machine to get started. -::: - -## Dependency Overview - -To deploy multi-chain smart contracts, we'll need a few tool-kits and dependencies. - -Here's an **overview of all of the dependencies** we'll install in the [Environment Setup section](#environment-setup): - -- [**NodeJS**](https://nodejs.org/en/download/): Javascript runtime environment. -- [**Hardhat**](https://hardhat.org/) **+** [**quai-hardhat-plugin**](https://www.npmjs.com/package/quai-hardhat-plugin)**:** An EVM development environment toolkit with plugin support for Quai Network opcodes and contracts. -- [**SolidityX**](https://github.com/dominant-strategies/SolidityX)**:** Quai Network's implementation of Solidity with support for [cross-chain opcodes](/develop/smart-contracts/opcode-additions.md). -- [**quais.js**](https://www.npmjs.com/package/quais)**:** A javascript library for blockchain development on Quai Network. -- [**quais-polling**](https://www.npmjs.com/package/quais-polling): A shim package that adds polling functionality back to quais.js for specific use cases. -- [**Dotenv**](https://www.npmjs.com/package/dotenv): A zero-dependency module that securely loads environment variables. - -:::info -Ensure you have NodeJS installed prior to moving on. **We'll install all other relevant dependencies in the Environment Setup section.** -::: - -## Environment Setup - -We'll be installing Hardhat with the accompanying [quai-hardhat-plugin](https://www.npmjs.com/package/quai-hardhat-plugin) that provides support for utilizing locally built Solidity compilers like [SolidityX](https://github.com/dominant-strategies/SolidityX/). - -Hardhat is typically utilized through local installations within individual project directories. Start by creating an `npm` project. - -```bash -mkdir deploy-multi-chain-contract -cd deploy-multi-chain-contract -npm init -y -``` - -Install Hardhat with: - -```bash -npm install hardhat --save-dev -``` - -Install quais, quais-polling, quai-hardhat-plugin and dotenv: - -```bash -npm install dotenv quais quais-polling quai-hardhat-plugin --save-dev -``` - -Lastly, initialize Hardhat: - -```bash -npx hardhat -``` - -This command will display a number of project initialization options like below: - -```bash -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -Welcome to Hardhat v2.17.2 - -? What do you want to do? … -❯ Create a Javascript project - Create a TypeScript project - Create an empty hardhat.config.js - Quit -``` - -For the purpose of this article, we'll be selecting `Create a Javascript Project`, which will provide us with a basic project structure to adapt for a multi-chain contract deployment. - -:::info -Selecting this option allows you to automatically install `@nomicfoundation/hardhat-toolbox`. -::: - -### Environment Variables - -Deploying a multi-chain smart contracts via Hardhat requires private keys for multiple addresses with funds available to deploy contracts in each deployment chain. In order to keep private keys from being committed to a repository, we'll load them in from a `.env` file. Hardhat by default includes your `.env` files in the `.gitignore` file to prevent keys or sensitive information from making it off of your machine. - -:::danger -Private key safety is paramount and you should ensure that when deploying, your keys are properly handled. -::: - -To create an `.env` file, run the following command: - -```bash -touch .env -``` - -After creating your environment file, we'll need to configure it for multi-chain deployments. This can be done by pasting the following code into the file: - -```bash title=".env" -# Unique Privkey for each deployment address -CYPRUS1PK="0x3700000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x00 - 0x1D -CYPRUS2PK="0x9400000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x1E - 0x3A -CYPRUS3PK="0x0200000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x3B - 0x57 -PAXOS1PK="0x7100000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x58 - 0x73 -PAXOS2PK="0x8500000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x74 - 0x8F -PAXOS3PK="0x0400000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x90 - 0xAB -HYDRA1PK="0x9100000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0xAC - 0xC7 -HYDRA2PK="0x5900000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0xC8 - 0xE3 -HYDRA3PK="0xa700000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0xE4 - 0xFF - -# Chain ID (local: 1337, testnet: 9000, devnet: 12000) -CHAINID="9000" - -# RPC endpoints -CYPRUS1URL="https://rpc.cyprus1.colosseum.quaiscan.io" -CYPRUS2URL="https://rpc.cyprus2.colosseum.quaiscan.io" -CYPRUS3URL="https://rpc.cyprus3.colosseum.quaiscan.io" -PAXOS1URL="https://rpc.paxos1.colosseum.quaiscan.io" -PAXOS2URL="https://rpc.paxos2.colosseum.quaiscan.io" -PAXOS3URL="https://rpc.paxos3.colosseum.quaiscan.io" -HYDRA1URL="https://rpc.hydra1.colosseum.quaiscan.io" -HYDRA2URL="https://rpc.hydra2.colosseum.quaiscan.io" -HYDRA3URL="https://rpc.hydra3.colosseum.quaiscan.io" -``` - -In this environment file, we've introduced private keys and RPC endpoint URLs for each of the chains in Quai Network as well as the `CHAINID` variable to allow for easy configuration of the network environment you're deploying to. - -**You'll need to change the chain specific keys and RPC endpoint URLs** for each of the chains you plan to deploy a contract on, i.e. if you want to deploy on Cyprus 1 and Paxos 2, you'll need to change the `CYPRUS1PK`, `PAXOS2PK`, `CYPRUS1URL`, and `PAXOS2URL` to deploy to those chains. - -Information on endpoints can be found in the [local network specifications](/develop/networks.md#local-network) section for **local nodes** and the [testnet specifications](/develop/networks.md#testnet) section for **remote nodes**. - -### SolidityX Compiler - -To be able to properly compile and deploy SolidityX contracts, we'll need the [SolidityX](https://github.com/dominant-strategies/SolidityX).There are two methods of installing the SolidityX compiler for use with Hardhat: - -- Install the SolidityX compiler via [`quai-hardhat-plugin`](https://www.npmjs.com/package/quai-hardhat-plugin) (**Recommended**) -- Install and build the SolidityX compiler from source - -#### Installing via Plugin - -If you've installed `quai-hardhat-plugin` already, the SolidityX compiler will be installed automatically when you run `npx hardhat compile` for MacOS and Linux users. Windows is not currently supported by the plugin. - -#### Installing from Source - -**Note:** Building the compiler from source still requires the `quai-hardhat-plugin` to be installed. - -Visit the [SolidityX Repository](https://github.com/dominant-strategies/SolidityX) for instructions on how to clone and build the SolidityX compiler for your specific operating system. - -Once you've built the SolidityX compiler, you'll need to add path to your `solc` binary into the `customCompilerPath` variable in the `hardhat.config.js` file. The file already includes common paths for MacOS and Linux as comments. - -:::info -Take note of the file location of the resultant location of the `solc` binaries. We'll need it in the next section. -::: - -### Hardhat Configuration - -Hardhat uses `hardhat.config.js` to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc. - -For multi-chain deployments, we've created a specialized `hardhat.config.js` file that contains routing for each shard within Quai Network based on your defined environment variables. - -With the help of `quai-hardhat-plugin`, `hardhat.config.js` allows us to pass in our locally built SolidityX compiler for use with cross-chain enabled contracts. Replace the `compilerPath` variable with the path to your locally built `solc` from the [previous section](#solidityx-compiler). - -:::info -This `hardhat.config.js` file is not the sole way to configure multi-chain contract deployments, but provides a template for easily executing them in efficient manner. -::: - -```javascript title="hardhat.config.js" -/** - * @type import('hardhat/config').HardhatUserConfig - */ - -require('@nomicfoundation/hardhat-toolbox'); -require('quai-hardhat-plugin'); -const dotenv = require('dotenv'); -dotenv.config({ path: '.env' }); - -const chainId = Number(process.env.CHAINID); - -module.exports = { - defaultNetwork: 'cyprus1', - networks: { - cyprus1: { - url: process.env.CYPRUS1URL.toString(), - accounts: [process.env.CYPRUS1PK], - chainId: chainId, - }, - cyprus2: { - url: `${process.env.CYPRUS2URL}`, - accounts: [process.env.CYPRUS2PK], - chainId: chainId, - }, - cyprus3: { - url: `${process.env.CYPRUS3URL}`, - accounts: [process.env.CYPRUS3PK], - chainId: chainId, - }, - paxos1: { - url: `${process.env.PAXOS1URL}`, - accounts: [process.env.PAXOS1PK], - chainId: chainId, - }, - paxos2: { - url: `${process.env.PAXOS2URL}`, - accounts: [process.env.PAXOS2PK], - chainId: chainId, - }, - paxos3: { - url: `${process.env.PAXOS3URL}`, - accounts: [process.env.PAXOS3PK], - chainId: chainId, - }, - hydra1: { - url: `${process.env.HYDRA1URL}`, - accounts: [process.env.HYDRA1PK], - chainId: chainId, - }, - hydra2: { - url: `${process.env.HYDRA2URL}`, - accounts: [process.env.HYDRA2PK], - chainId: chainId, - }, - hydra3: { - url: `${process.env.HYDRA3URL}`, - accounts: [process.env.HYDRA3PK], - chainId: chainId, - }, - }, - - // optional solidityx config for locally built solcx, if not specified solcx will be downloaded - - // common macOS path to local solc (uncomment and edit path if using macOS) - // solidityx: { compilerPath: '/usr/local/bin/solc' }, - // common Linux path to local solc (uncomment and edit path if using Linux) - // solidityx: { compilerPath: '/path/to/SolidityX/build/solc/solc' }, - - solidity: { - compilers: [ - { - version: '0.8.0', - }, - ], - }, - - paths: { - sources: './contracts', - cache: './cache', - artifacts: './artifacts', - }, - mocha: { - timeout: 20000, - }, -}; -``` - -All changes made in your `.env` file will be auto-configured for deployments within the `hardhat.config.js` file and passed on to the dependent deploy scripts. - -To deploy a contract to one of the chains defined above, all you'll need to do is pass the desired network name in as a flag to the deployment command. - -### Smart Contracts - -As mentioned in the above introduction, we'll be deploying the initial implementation of the [QRC-20 smart contract](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC20X.sol). - -:::info -Before configuring and deploying the QRC-20, we recommend getting familiar with the [contract specs](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC20X.sol). -::: - -Start by removing the sample `Lock.sol` contract provide by Hardhat in the `contracts` directory. - -```bash -rm -rf contracts/Lock.sol -``` - -After `Lock.sol` has been removed, create a new contract in the same directory named `QRC20.sol`. - -```bash -touch contracts/QRC20.sol -``` - -Copy the [QRC-20 Token code](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC20X.sol) and paste it into the `QRC20.sol` file. - -## Deploy - -### Compile with Hardhat + SolidityX - -If you've used Hardhat before in this directory, you'll need to reset your compilers before compiling any SolidityX based contracts. You can do this with the following command: - -```bash -npx hardhat clean --global -``` - -Now that we've reset our compilers, we can go ahead and compile the `QRC20.sol` contract using the SolidityX compiler: - -```bash -npx hardhat compile -``` - -Which should output: - -```bash -Downloading compiler 0.8.0 - -Compiled 1 Solidity file successfully -``` - -### Add Deployment Script - -The Hardhat sample project has a pre-made deployment script named `deploy.js` in the `scripts` directory. Copy the following into the `deploy.js` file. - -In the `deploy.js` script below, you can configure your token deployment details via the `constructorArgs` object. The `constructorArgs` object contains the following parameters: - -- `name`: The name of your token -- `symbol`: The symbol of your token -- `totalSupply`: The total supply of your token - -:::info -Note, the `_totalSupply` variable is specific to each chain's contract deployment. Deploying the same contract with the same `_totalSupply` will mint the same total supply to each chain. -::: - -```javascript title="deploy.js" -const hre = require('hardhat'); -const quais = require('quais'); -const { pollFor } = require('quais-polling'); -const QRC20Json = require('../artifacts/contracts/QRC20.sol/QRC20.json'); - -const constructorArgs = { - name: 'Test Token', - symbol: 'TSTK', - totalSupply: 10000000, -}; - -async function main() { - const quaisProvider = new quais.providers.JsonRpcProvider(hre.network.config.url); - const walletWithProvider = new quais.Wallet(hre.network.config.accounts[0], quaisProvider); - - const QuaisContract = new quais.ContractFactory(QRC20Json.abi, QRC20Json.bytecode, walletWithProvider); - const quaisContract = await QuaisContract.deploy( - constructorArgs.name, - constructorArgs.symbol, - constructorArgs.totalSupply, - { - gasLimit: 5000000, - } - ); - const deployReceipt = await pollFor( - quaisProvider, // provider passed to poller - 'getTransactionReceipt', // method to call on provider - [quaisContract.deployTransaction.hash], // params to pass to method - 1.5, // initial polling interval in seconds - 1 // request timeout in seconds - ); - console.log('Contract deployed. Transaction hash: ', deployReceipt.transactionHash); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); -``` - -`deploy.js` will pull the network configurations and deployment accounts from your `.env` and `hardhat.config.js` files via the [Hardhat Runtime Environment](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-runtime-environment) based on the chain flag specified in your deployment command. - -While this `deploy.js` script is configured for manual deployments to each desired shard, automating larger deployments is trivial. An example of a deployment configuration that automates deployments to all shards within Quai Network can be found in [Dominant Strategies' hardhat-example repo](https://github.com/dominant-strategies/hardhat-example/tree/main/scripts). - -:::warning -Note, we've hardcoded the `gasLimit` in this deploy script to 5 million gas for sake of simplicity. When deploying a contract, it's generally more efficient to use [quais.js](https://www.npmjs.com/package/quais) to estimate the gas required for a deployment. -::: - -### Deploy Your Contracts - -For this tutorial, we'll be deploying **two instances** of our QRC-20 contract on two chains, each on a separate chain. You can extend the methodology used here to deploy contracts to any combination of shards within Quai Network. - -We'll be deploying on QRC-20 contract to the Cyprus-1 chain. To do this, we'll pass `cyprus1` as the network flag in the deployment command like below: - -```bash -npx hardhat run scripts/deploy.js --network cyprus1 -``` - -Running this should output: - -```bash -Found address 0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601 on shard zone-0-0 for shard zone-0-0 -Contract deployed. Transaction hash: 0xb3c0a0d0f3bc47f4bcd5df67666d76246636741afb6134c2ba4145c51ed030d3 -``` - -Now, we can deploy an identical QRC-20 contract to another shard within Quai, like Cyprus-2. Like before, you'll pass `cyprus2` as the network flag in the deployment command. - -```bash -npx hardhat run scripts/deploy.js --network cyprus2 -``` - -Which again should output something like this: - -```bash -Found address 0x2F4C5243BEd5dC46787378894eDF662Db9FE4685 on shard zone-0-1 for shard zone-0-1 -Contract deployed. Transaction hash: 0xf6802822b4f1994d0be4ae03e2b1302ed42f3b95bf0c4607f3fae671f9719333 -``` - -We've now deployed our "Quai Cross-Chain Token" to both the Cyprus-1 and Cyprus-2 chains! - -:::warning -Make sure to save these two contract addresses, we'll need them in the next section. -::: - -## Link Sister Contracts - -To complete our cross-chain token deployment, we'll need to link the two deployed contracts. - -_"Linking"_ the two QRC-20 contracts can be done by adding their deployed contract addresses to the approved contracts array within each token contract. This can be done using the `AddApprovedAddresses` method. It accepts 2 arrays as arguments: chain indexes and approved addresses. - -The `AddApprovedAddresses` method seen below can be used to add as few as 1 or as many as 8 sister contracts to the `approvedAddresses` array of a QRC-20 contract. - -```solidity title="QRC20.sol" -function AddApprovedAddresses(uint8[] calldata chain, address[] calldata addr) external { - require(msg.sender == _deployer, "Sender is not deployer"); - require(chain.length == addr.length, "chain and address arrays must be the same length"); - for(uint8 i = 0; i < chain.length; i++) { - require(chain[i] < 9, "Max 9 zones"); - require(ApprovedAddresses[chain[i]] == address(0), "The approved address for this zone already exists"); - ApprovedAddresses[chain[i]] = addr[i]; - } -} -``` - -Once the sister contract addresses have been added to the respective `ApprovedAddresses` of each of the QRC-20 contracts, the `crossChainTransfer` method becomes available, which allows anyone who owns the QRC-20 token to trustlessly send their balance between the shards that the contracts are deployed to. - -#### Script - -To link the sister contracts, we'll utilize `quais.js` and some of the Hardhat Runtime Environment that we used in the deploy script. Start by creating another file in the scripts directory named `addApprovedAddresses.js`. - -```bash -touch scripts/addApprovedAddresses.js -``` - -Then, paste the following code into `addApprovedAddresses.js`: - -```javascript title="addApprovedAddresses.js" -const quais = require('quais'); -const { pollFor } = require('quais-polling'); -const QRC20 = require('../artifacts/contracts/QRC20.sol/QRC20.json'); - -async function AddApprovedQRC20Addresses() { - const provider = new quais.providers.JsonRpcProvider(hre.network.config.url); // grab network config from hre - const privateKey = hre.network.config.accounts[0]; // grab wallet from hre - const wallet = new quais.Wallet(privateKey, provider); // create wallet from key and provider - const contractAddress = 'contract address you want to change the address array for'; // contract address to add approved addresses to - const qrc20 = new quais.Contract(contractAddress, QRC20.abi, wallet); // define contract from address and abi - - try { - const transaction = await qrc20.AddApprovedAddresses( - [0, 1], // chain indexes (cyprus1 is 0, cyprus2 is 1, etc.) - ['0x1...', '0x2....'] // contract addresses (must be in same order as chain indexes) - ); - console.log('Transaction sent:', transaction.hash); // log transaction hash - const transactionReceipt = await pollFor( - provider, // provider passed to poller - 'getTransactionReceipt', // method to call on provider - [transaction.hash], // params to pass to method - 1.5, // initial polling interval in seconds - 1 // request timeout in seconds - ); - console.log('Transaction mined with hash', transactionReceipt.hash); - } catch (error) { - console.error('Error sending transaction:', error); - } -} - -AddApprovedQRC20Addresses(); -``` - -The `addApprovedAddresses.js` script uses the `QRC20.sol` ABI to compose and send a transaction that inserts new addresses to the `approvedAddresses` array in any deployed QRC20 contract. - -The script works by: - -1. First, creating a quais `provider` with our specified network configuration from Hardhat -2. Creating a quais `wallet` with our `provider` and key config from Hardhat -3. Defining the contract we'd like to add an approved address to with the imported `QRC20.sol` ABI, contract address, and `wallet` -4. Composing the `addApprovedAddresses` transaction with the inputs - 1. `chainIndex` array: integer chain indices corresponding to the addresses we'd like to add to `approvedAddresses` - 2. `address` array: the contract addresses that we'd like to add to `approvedAddresses` -5. Sending the transaction and waiting for inclusion in a block. - -#### Transaction Data - -Now that we've set up our script, **we're ready to link our two deployed contracts**. - -Start by grabbing the addresses of the two contracts we deployed in the [deploy section](#deploy-your-contracts). - -```bash -Cyprus 1 contract address: 0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601 -Cyprus 2 contract address: 0x2F4C5243BEd5dC46787378894eDF662Db9FE4685 -``` - -We'll take these contract addresses and use them to build the transaction data passed to the `addApprovedAddresses` method. - -:::tip -**You can pass the same transaction data to every contract you want to link**, as the `addApprovedAddresses` method **can take in and handle its own contract address as an argument**. This removes the need to alter the transaction data for each contract you want to link. -::: - -The transaction data we'll need to pass to the `addApprovedAddresses` method is **(notice the order of the arrays)**: - -- `chainIndex` array: `[0, 1]` -- `address` array: `['0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601', '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'] - -The built transaction should look similar to this: - -```javascript -const transactionData = await contract.populateTransaction.AddApprovedAddress( - [0, 1], // chain indexes [cyprus1, cyprus2] - ['0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601', '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'] // contract addresses [cyprus1, cyprus2] -); -``` - -:::info -You can extend this transaction data structure to link as many contracts as you'd like by adding additional chain indexes and contract addresses to the arrays. **Always make sure to add the same number of chain indexes and contract addresses to the arrays in matching order**. -::: - -#### Linking Contracts - -First, we're going to send the linking transaction to our Cyprus 1 contract. To do this, start by changing the `contractAddress` variable to our **Cyprus 1 contract address** in the `addApprovedAddresses.js` script: - -```javascript -const contractAddress = '0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601'; -``` - -Now, we're ready to run the script and complete the Cyprus 1 contract linkage. Make sure to pass the `--network cyprus1` flag **when sending transactions to the Cyprus 1 contract**. - -```bash -npx hardhat run scripts/addApprovedAddresses.js --network cyprus1 -``` - -The script should output something like this: - -```bash -Transaction sent: 0x2a499178c3f0046b4d44a57a966f9e224759c1b3158af984fcb5a1432b16ee8e -Transaction mined with hash: 0x2a499178c3f0046b4d44a57a966f9e224759c1b3158af984fcb5a1432b16ee8e -``` - -We've now linked our Cyprus 1 contract to our Cyprus 2 contract, but we're not done yet. - -To finish linking these two sister contracts, we'll need to send the exact same transaction data to the Cyprus 2 contract. In the `addApprovedAddresses.js` script, change the `contractAddress` variable to **our Cyprus 2 contract address**: - -```javascript -const contractAddress = '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'; -``` - -Lastly, send the linkage transaction to our Cyprus 2 token by running the script with the `--network cyprus2` flag: - -```bash -Transaction sent: 0x348e8dea20b73089b51e6b3d2b3abd8a9e8ca63e06be20375cf721e13aabd590 -Transaction mined with hash: 0x348e8dea20b73089b51e6b3d2b3abd8a9e8ca63e06be20375cf721e13aabd590 -``` - -**Once the second transaction is confirmed, our two QRC20 contracts have been successfully linked across chains.** You can now send your "Quai Cross Chain Token" from Cyprus 1 to Cyprus 2 without a bridge or external service! - -This deployment and linking process can be repeated for any number of chains within Quai Network purely by deploying the contract to the desired chains and linking them with the `addApprovedAddresses` method. **You now have the tools to deploy and link contracts across all 9 shards within Quai Network**. - -For a more detailed example on how to deploy and link contracts across all shards within Quai Network, check out the [Dominant Strategies' quais-by-example repo](https://github.com/dominant-strategies/quais-by-example/tree/main/contract-qrc20). - -:::info -The same deploy and link method can be used for any other SolidityX based contract with cross-chain logic, including the [QRC-721 Token Standard](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC721X.sol). -::: diff --git a/docs/develop/tutorials/single-chain.md b/docs/develop/tutorials/single-chain.md deleted file mode 100644 index 4cf12dc..0000000 --- a/docs/develop/tutorials/single-chain.md +++ /dev/null @@ -1,304 +0,0 @@ ---- -title: Single-Chain Deployment Tutorial -description: A guide to deploying a simple single-chain smart contract on Quai Network. -sidebar_position: 1 -keywords: - - simple smart contract - - solidity - - hardhat - - greeter ---- - -## Introduction - -This article shows how to **deploy a simple smart contract using Hardhat** on any of Quai Network's 9 chains. This tutorial covers deploying a **simple, non SolidityX** based smart contract to a single chain within Quai Network. For more complex deployments involving SolidityX or multi-chain deployments, visit the [Multi-Chain Deploy Tutorial page](/develop/tutorials/single-chain.md). - -:::warning -If you want to skip basic environment setup for contract deployment, the [hardhat-example](https://github.com/dominant-strategies/hardhat-example) repository provides a **pre-configured environment for deploying smart contracts on Quai Network**. Clone the repository on your local machine to get started. -::: - -## Prerequisites - -### NodeJS - -To use Hardhat, you'll need the LTS version of [_nodejs_](https://nodejs.org/en/download/). NodeJS bundles `npm` and `npx`. - -Hardhat also supports yarn usage. - -### Hardhat - -[Hardhat](https://hardhat.org/) is an EVM development environment for professionals written in TypeScript. It is useful for performing frequent tasks such as running tests, automatically checking code for mistakes, or interacting with a smart contract. - -### Quai Network and Solidity - -It is useful to have basic knowledge of both [Quai Network](/learn/intro.md) and [Solidity](https://docs.soliditylang.org/en/latest/). Quai Network utilizes a modified version of Solidity named [SolidityX](https://github.com/dominant-strategies/SolidityX) that provides support for [additional opcodes](/develop/smart-contracts/opcode-additions.md). - -Deployment of a smart contract on a Quai Network chain requires: - -- An active instance of a [Quai Network node](/participate/node/run-a-node.md) or a remote node's RPC endpoint. -- Sufficient balance in the address that you are deploying with. - -## Environment Setup - -### Initialize Hardhat - -Hardhat is utilized through a local installation within individual project directories. Start by creating an `npm` project. - -:::warning -For the purposed of this simplified tutorial, **we'll be installing the generic version of Solidity that does not support cross-chain capabilities.** If you're interested in deploying a contract that utilizes SolidityX's cross-chain capabilities, visit the [Multi-Chain Smart Contract Tutorial](/develop/tutorials/multi-chain.md). -::: - -```bash -mkdir deploy-simple-quai-contract -cd deploy-simple-quai-contract -npm init -y -``` - -Running `npm init` will prompt you to name your project and configure a few other variables. - -Install Hardhat by running: - -```bash -npm install --save-dev hardhat -``` - -Install dependencies: - -```bash -npm install dotenv quais quais-polling quai-hardhat-plugin -``` - -Initialize the Hardhat development process using: - -```bash -npx hardhat -``` - -After running this command, Hardhat will output a number of options below: - -```bash -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -Welcome to Hardhat v2.17.2 - -? What do you want to do? … -❯ Create a Javascript project - Create a TypeScript project - Create an empty hardhat.config.js - Quit -``` - -For this article, we will select the `Create a Javascript project` option. This will provide you with a preset basic Hardhat project structure with simple smart contracts, tests, and example scripts written in Javascript. - -:::info -Selecting this option allows you to optionally install `@nomicfoundation/hardhat-toolbox`. -::: - -### Smart Contracts - -The `Create a Javascript project` setup option provides a sample contract named `Lock.sol`. In this tutorial, we're going to deploy a simpler contract example named `Greeter.sol`. - -In the contracts folder, create a file named `Greeter.sol` and paste the following code into it. - -```solidity title="Greeter.sol" -//SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.9; - -contract Greeter { - string private greeting; - - constructor(string memory _greeting) { - greeting = _greeting; - } - - function greet() public view returns (string memory) { - return greeting; - } - - function setGreeting(string memory _greeting) public { - greeting = _greeting; - } -} -``` - -The `Greeter.sol` contract allows the deployer to initialize a contract with a greeting stored on-chain, retrieve the greeting string, and change the greeting as needed. - -### Environment Variables - -To prevent committing your private keys or RPC endpoints, create an environment file to securely store variables. Ensure that `.env` is in your `.gitignore`. - -Use the following command to create an environment file: - -```bash -touch .env -``` - -After creating the `.env` file, paste the following code into it. - -```bash title=".env" -## Sample environment file - change all values as needed - -# Privkey - priv key for the account you want to deploy from -PRIVKEY="0x0000000000000000000000000000000000000000000000000000000000000000" - -# RPC - change this based on shard you want to deploy to -RPCURL="http://rpc.cyprus3.colosseum.quaiscan.io" # cyprus 3 colosseum rpc endpoint -``` - -:::info -The `PRIVKEY` and `RPCURL` values must be configured for the same shard, i.e. a Cyprus 3 RPC endpoint and a Cyprus 3 private key must be used together. **Using a Cyprus 3 RPC endpoint with a Cyprus 2 (or any other shard's) private key will result in an error.** -::: - -Information on endpoints can be found in the [local network specifications](/develop/networks.md#local-network) section for **local nodes** and the [testnet specifications](/develop/networks.md#testnet) section for **remote nodes**. - -After providing a private key and a desired RPC URL, we're now ready to securely consume them inside of `hardhat.config.js`. - -### Hardhat Configuration - -Hardhat uses `hardhat.config.js` to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc. - -Paste the following code into your `hardhat.config.js` file to configure deployments to either the `colosseum`, `garden`, or `local` networks. - -```javascript title="hardhat.config.js" -/** - * @type import('hardhat/config').HardhatUserConfig - */ - -require('@nomicfoundation/hardhat-toolbox'); -const dotenv = require('dotenv'); -dotenv.config({ path: '.env' }); - -module.exports = { - defaultNetwork: 'colosseum', - networks: { - // testnet - colosseum: { - url: `${process.env.RPCURL}`, - accounts: [process.env.PRIVKEY], - chainId: 9000, // colosseum chainId - }, - // devnet - garden: { - url: `${process.env.RPCURL}`, - accounts: [process.env.PRIVKEY], - chainId: 12000, // garden chainId - }, - - // local - local: { - url: `${process.env.RPCURL}`, - accounts: [process.env.PRIVKEY], - chainId: 1337, // local chainId - }, - }, - - // include compiler version defined in your smart contract - solidity: { - compilers: [ - { - version: '0.8.9', - }, - ], - }, - - paths: { - sources: './contracts', - cache: './cache', - artifacts: './artifacts', - }, - mocha: { - timeout: 20000, - }, -}; -``` - -## Deploy - -### Compile with Hardhat - -Smart contract compilation with Hardhat is simple and can be done using `npx` in the CLI. - -Compile the `Greeter.sol` contract using: - -```bash -npx hardhat compile -``` - -Which should output: - -```bash -Downloading compiler 0.8.9 - -Compiled 1 Solidity file successfully -``` - -### Add Deployment Script - -The Hardhat sample project has a pre-made deployment script named `deploy.js` in the `scripts` directory. Copy the following into the `deploy.js` file. - -```javascript title="deploy.js" -const quais = require('quais'); -const { pollFor } = require('quais-polling'); -const GreeterJson = require('../artifacts/contracts/Greeter.sol/Greeter.json'); - -async function main() { - const quaisProvider = new quais.providers.JsonRpcProvider(hre.network.config.url); - const walletWithProvider = new quais.Wallet(hre.network.config.accounts[0], quaisProvider); - await quaisProvider.ready; - - const QuaisContract = new quais.ContractFactory(GreeterJson.abi, GreeterJson.bytecode, walletWithProvider); - const quaisContract = await QuaisContract.deploy('Hello Quai', { - gasLimit: 1000000, - }); - - // Use quais-polling to wait for contract to be deployed - const deployReceipt = await pollFor( - quaisProvider, // provider passed to poller - 'getTransactionReceipt', // method to call on provider - [quaisContract.deployTransaction.hash], // params to pass to method - 1.5, // initial polling interval in seconds - 1 // request timeout in seconds - ); - console.log('Contract deployed to address: ', deployReceipt.contractAddress); -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); -``` - -Using `deploy.js`, we can set the initial greeting and log out the contract address upon deployment. Scripts can be used to automate many different functions other than deployment. - -### Deploy Your Contract - -To deploy `Greeter.sol` to the colosseum network (configured for Cyprus 3 in your env) set in your `hardhat.config.js`, run: - -```bash -npx hardhat run scripts/deploy.js --network colosseum -``` - -Which should output: - -```bash -Contract deployed to address: 0x13d8c5fc0AB5A87870353f3C0409c102f2a772A9 -``` - -Congratulations, you've now deployed a simple smart contract to Quai Network! - -## Interact with a Smart Contract - -Hardhat console does not currently offer support for interaction with smart contracts on Quai Network. In order to interact with your smart contract, you'll need to utilize the the [client JSON RPC](/develop/apis/json-rpc-api.md) or [quais.js](https://www.npmjs.com/package/quais) library. You can find quais examples in the [quais-by-example](https://github.com/dominant-strategies/quais-by-example) repository. - -## Summary - -Now you have all the tools you need to create a simple Hardhat project, deploy, and interact with your own smart contracts. diff --git a/docs/develop/tutorials/solidity.md b/docs/develop/tutorials/solidity.md new file mode 100644 index 0000000..126bcdf --- /dev/null +++ b/docs/develop/tutorials/solidity.md @@ -0,0 +1,246 @@ +--- +title: Deploy with Solidity +description: A guide to deploying a simple single-chain smart contract on Quai Network. +sidebar_position: 1 +keywords: + - simple smart contract + - solidity + - hardhat + - greeter +--- + +## Introduction + +This article shows how to **deploy a Solidity smart contract using Hardhat** on any of Quai Network's chains. For more complex deployments involving SolidityX and multi-chain deployments, visit the [Deploy with SolidityX Tutorial](/develop/tutorials/solidityX.md). + +## Prerequisites + +To deploy single chain smart contracts on Quai, we'll need a few tool-kits and dependencies. + +Here's an **overview of all of the dependencies** we'll be using: + +- [**NodeJS**](https://nodejs.org/en/download/): Javascript runtime environment. Use the LTS version. +- Quai Network [**hardhat-example**](https://github.com/dominant-strategies/hardhat-example): A simple Hardhat project with sample contracts and deploy scripts. + +## Environment Setup + +### Dependencies + +Start by cloning the `hardhat-example` repository, **navigating to the `Solidity` directory** we'll be using for this tutorial, and installing the dependencies via `npm`. + +```bash +git clone https://github.com/dominant-strategies/hardhat-example.git +cd hardhat-example/Solidity +npm install +``` + +### Smart Contracts + +The `Solidity` directory comes with 2 sample contracts: `ERC20.sol` and `ERC721.sol` inside of the `contracts/` directory. Both contracts are implementations derived from the [Open Zeppelin library](https://www.openzeppelin.com/contracts). + +We'll be using the `ERC20.sol` sample contract for this tutorial, but you can also add your own contracts or use contracts from other libraries. + +### Environment Variables + +We've included a sample environment file, [`.env.dist`](https://github.com/dominant-strategies/hardhat-example/blob/main/.env.dist), file at the root of the `hardhat-example` repo to hold token details, private keys, and RPC URLs in a secure fashion. + +:::note +The `.env.dist` file is a template file and should not be used as is. You should copy the `.env.dist` file to a new `.env` file in the repository root using the following command: + +This file lives at the root of the `hardhat-example` repository and serves as the config file for both the `Solidity` and `SolidityX` directories. +::: + +Copy the `.env.dist` file in the root to a new `.env` file in the repository root using the following command: + +```bash +cp ../.env.dist ../.env +``` + +Open the `.env` file and add your private keys, RPC URLs, and token args for the contract you'd like to deploy. The `.env` file should look like this: + +```bash title=".env" +# Unique Privkey for each deployment address +CYPRUS1PK="0x3700000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x00 - 0x1D +CYPRUS2PK="0x9400000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x1E - 0x3A +...more priv keys + +# Chain ID (local: 1337, testnet: 9000, devnet: 12000) +CHAINID="9000" + +# RPC endpoints +CYPRUS1URL="https://rpc.cyprus1.colosseum.quaiscan.io" +CYPRUS2URL="https://rpc.cyprus2.colosseum.quaiscan.io" +CYPRUS3URL="https://rpc.cyprus3.colosseum.quaiscan.io" +...more rpc urls + +# Token Arguments +...more token args +``` + +:::info +The `PRIVKEY` values must all be for unique addresses and correspond to the chain name, i.e. your `CYPRUS1PK` should be the private key of your Cyprus-1 address. + +All of the `RPCURL` values have already been filled in for you, but you can change them to your own RPC URLs if you're running your own nodes. +::: + +Further information on RPC endpoints can be found in the [local network specifications](/develop/networks.md#local-network) section for **local nodes** and the [testnet specifications](/develop/networks.md#testnet) section for **remote nodes**. + +After filling in your private keys, RPC URLs, we're now ready to securely consume them inside of `hardhat.config.js`. + +### Hardhat Configuration + +Hardhat uses `hardhat.config.js` to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc. + +`hardhat-example` contains a prebuilt `hardhat.config.js` file with configurations for deploying and verifying smart contracts on any shard in the network. + +The file should look like this: + +```javascript title="hardhat.config.js" +/** + * @type import('hardhat/config').HardhatUserConfig + */ + +require("@nomicfoundation/hardhat-toolbox"); +const dotenv = require("dotenv"); +dotenv.config({ path: "../.env" }); + +module.exports = { + defaultNetwork: "cyprus1", + networks: { + cyprus1: { + url: `${process.env.CYPRUS1URL}`, + accounts: [process.env.CYPRUS1PK], + chainId: Number(process.env.CHAINID), + }, + cyprus2: { + url: `${process.env.CYPRUS2URL}`, + accounts: [process.env.CYPRUS2PK], + chainId: Number(process.env.CHAINID), + }, + ...more networks + }, + + solidity: { + version: "0.8.20", + settings: { + optimizer: { + enabled: true, + runs: 1000, + }, + }, + }, + +etherscan: { + apiKey: { + cyprus1: "abc", + ...more api keys + }, + customChains: [ + { + network: "cyprus1", + chainId: Number(process.env.CHAINID), + urls: { + apiURL: "https://cyprus1.colosseum.quaiscan.io/api", + browserURL: "https://cyprus1.colosseum.quaiscan.io", + }, + }, + ...more verification configs + ], + }, +}; +``` + +Inside the config file you can find deployment and verification definitions for: + +- `cyprus1` +- `cyprus2` +- `cyprus3` +- `paxos1` +- `paxos2` +- `paxos3` +- `hydra1` +- `hydra2` +- `hydra3` + +When deploying or verifying a contract, `hardhat.config.js` will pull your private keys and RPC URLs from the `.env` file and use them to deploy and verify your contracts. You can also specify the Solidity version and compiler settings in the `solidity` object. + +## Deploy + +### Compile with Hardhat + +Smart contract compilation with Hardhat is simple and can be done using `npx` in the CLI. + +Compile all of the contracts inside the `contracts/` directory with: + +```bash +npx hardhat compile +``` + +Which should output: + +```bash +Downloading compiler 0.8.20 + +Compiled 2 Solidity files successfully +``` + +### Deployment Scripts + +Inside the `scripts/` directory, you'll find a deploy script for both `ERC20.sol` and `ERC721.sol`: `deployERC20.js` and `deployERC721.js`. For this tutorial, we'll be using `deployERC20.js`. + +The `deployERC20.js` script pulls your network configuration from `hardhat.config.js` and your token arguments from the `.env` file at the root of the repository and uses them to deploy your contract. + +Token arguments are consumed via the `tokenArgs` object: + +```js +tokenArgs = { + name: process.env.ERC20_NAME, // Name of token + symbol: process.env.ERC20_SYMBOL, // Symbol of token + initialSupply: process.env.ERC20_INITIALSUPPLY, // Initial supply of token, will be minted to deployer +}; +``` + +Your specified network configuration is consumed inside of the `provider` and `wallet` variables in tandem with the compiled contract ABI and bytecode to create a new contract instance: + +```js +const provider = new quais.providers.JsonRpcProvider(hre.network.config.url); +const wallet = new quais.Wallet(hre.network.config.accounts[0], provider); +const ERC20 = new quais.ContractFactory(ERC20Json.abi, ERC20Json.bytecode, wallet); +``` + +We'll use these ideas to properly modify the token args and network specification to deploy our contract in the next step. + +:::tip +The `deployERC721.js` script functions in a similar manner, but with different contract arguments and a different contract ABI and bytecode. You can replicate this configuration for any contract you'd like to deploy. +::: + +### Deploy Your Contract + +The deploy script takes in a `--network` flag to specify the network you'd like to deploy to (available options can be found [here](#hardhat-configuration)). For this tutorial, we'll be deploying to `cyprus1`. + +```bash +npx hardhat run scripts/deploy.js --network cyprus1 +``` + +Which should output: + +```bash +1 -- Deploy transaction broadcasted: 0x235fdeb85db5b6cee8da9780e2246907e8342751849f5ce3514847a5dffd916f +2 -- Waiting for transaction to be mined. +3 -- Transaction mined. ERC20 deployed to: 0x13d8c5fc0AB5A87870353f3C0409c102f2a772A9 + -- Gas used: 249168 +``` + +Congratulations, you've now deployed a ERC20 token to Quai Network! + +:::warning +The `ERC20.sol` and `ERC721.sol` sample contracts are basic implementations of each token for example purposes. It is highly recommended to modify these contracts to fit your specific use case before deploying them for any production use. +::: + +## Interact with a Smart Contract + +Hardhat console does not currently offer support for interaction with smart contracts on Quai Network. In order to interact with your smart contract, you'll need to utilize the the [client JSON RPC](/develop/apis/json-rpc-api.md) or [quais.js](https://www.npmjs.com/package/quais) library. You can find quais examples in the [quais-by-example](https://github.com/dominant-strategies/quais-by-example) repository. + +## Summary + +Now you have all the tools you need to create a simple Hardhat project, deploy, and interact with your own smart contracts. diff --git a/docs/develop/tutorials/solidityX.md b/docs/develop/tutorials/solidityX.md new file mode 100644 index 0000000..d9ec661 --- /dev/null +++ b/docs/develop/tutorials/solidityX.md @@ -0,0 +1,448 @@ +--- +title: Deploy with SolidityX +description: A guide to deploying and linking multi-chain smart contracts on Quai Network. +sidebar_position: 2 +keywords: + - multi chain smart contract + - solidityx + - hardhat + - QRC20 + - QRC721 +--- + +## Introduction + +In this article, we'll detail how to **deploy, link, and interact with multi-chain smart contracts** across 2 different shards on Quai Network. _This method can be extended to deploy trustless cross-chain contracts across all 9 shards._ + +We'll be using the basic implementation of a [QRC721 token](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC721X.sol), an adapted version of the [ERC721 standard](https://eips.ethereum.org/EIPS/eip-721), to showcase cross-chain contracts for this tutorial. + +## Prerequisites + +To deploy single chain smart contracts on Quai, we'll need a few tool-kits and dependencies. + +Here's an **overview of all of the dependencies** we'll be using: + +- [**NodeJS**](https://nodejs.org/en/download/): Javascript runtime environment. Use the LTS version. +- Quai Network [**hardhat-example**](https://github.com/dominant-strategies/hardhat-example): A simple Hardhat project with sample contracts and deploy scripts. + +## Environment Setup + +### Dependencies + +Start by cloning the `hardhat-example` repository, **navigating to the `SolidityX` directory** we'll be using for this tutorial, and installing the dependencies via `npm`. + +```bash +git clone https://github.com/dominant-strategies/hardhat-example.git +cd hardhat-example/SolidityX +npm install +``` + +:::tip +If you've already cloned the `hardhat-example` repository for the [Single-Chain Deployment Tutorial](/develop/tutorials/solidity.md), you can skip the cloning step. Just navigate to the `SolidityX` directory and run `npm install`. +::: + +### Smart Contracts + +The `SolidityX` directory comes with 2 sample contracts: `QRC20.sol` and `QRC721.sol` inside of the `contracts/` directory. Both of the included contracts are the initial SolidityX/cross-chain implementations of existing token standards. Source code for the contracts can be found in the [SolidityX-Contracts Repository](https://github.com/dominant-strategies/SolidityX-Contracts) + +As mentioned above, we'll be deploying the [QRC721 smart contract](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC721X.sol). Before configuring and deploying the QRC721, we recommend getting familiar with the [contract specs](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC721X.sol) as **constructor arguments passed to the contract work a bit different than standard Solidity contracts**. + +### Environment Variables + +We've included a sample environment file, [`.env.dist`](https://github.com/dominant-strategies/hardhat-example/blob/main/.env.dist), file at the root of the `hardhat-example` repo to hold token details, private keys, and RPC URLs in a secure fashion. + +:::note +The `.env.dist` file is a template file and should not be used as is. You should copy the `.env.dist` file to a new `.env` file in the repository root using the following command: + +This file lives at the root of the `hardhat-example` repository and serves as the config file for both the `Solidity` and `SolidityX` directories. +::: + +Copy the `.env.dist` file in the root to a new `.env` file in the repository root using the following command: + +```bash +cp ../.env.dist ../.env +``` + +Open the `.env` file and add your private keys, RPC URLs, and token args for the contract you'd like to deploy. The `.env` file should look like this: + +```bash title=".env" +# Unique Privkey for each deployment address +CYPRUS1PK="0x3700000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x00 - 0x1D +CYPRUS2PK="0x9400000000000000000000000000000000000000000000000000000000000000" # For pubkey starting with 0x1E - 0x3A +...more priv keys + +# Chain ID (local: 1337, testnet: 9000, devnet: 12000) +CHAINID="9000" + +# RPC endpoints +CYPRUS1URL="https://rpc.cyprus1.colosseum.quaiscan.io" +CYPRUS2URL="https://rpc.cyprus2.colosseum.quaiscan.io" +CYPRUS3URL="https://rpc.cyprus3.colosseum.quaiscan.io" +...more rpc urls + +# Token Arguments +...more token args +``` + +:::info +The `PRIVKEY` values must all be for unique addresses and correspond to the chain name, i.e. your `CYPRUS1PK` should be the private key of your Cyprus-1 address. + +All of the `RPCURL` values have already been filled in for you, but you can change them to your own RPC URLs if you're running your own nodes. +::: + +Further information on RPC endpoints can be found in the [local network specifications](/develop/networks.md#local-network) section for **local nodes** and the [testnet specifications](/develop/networks.md#testnet) section for **remote nodes**. + +After filling in your private keys, RPC URLs, we're now ready to securely consume them inside of `hardhat.config.js`. + +### Hardhat Configuration + +Hardhat uses `hardhat.config.js` to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc. `hardhat-example/SolidityX` contains a prebuilt `hardhat.config.js` file with configurations for **compiling, deploying, verifying SolidityX smart contracts** on Quai. + +The below configuration file has **two main differences** from the `hardhat.config.js` file use for basic Solidity contract deployment: + +- It imports the `quai-hardhat-plugin` to **handle SolidityX compiler download** +- Inclusion of the optional `solidityx` object to specify a locally built SolidityX compiler (_if you don't want to use the plugin to download the compiler_) + +The file should look like this: + +```javascript title="hardhat.config.js" +/** + * @type import('hardhat/config').HardhatUserConfig + */ + +require("@nomicfoundation/hardhat-toolbox"); +require('quai-hardhat-plugin'); +const dotenv = require("dotenv"); +dotenv.config({ path: "../.env" }); + +module.exports = { + defaultNetwork: "cyprus1", + networks: { + cyprus1: { + url: `${process.env.CYPRUS1URL}`, + accounts: [process.env.CYPRUS1PK], + chainId: Number(process.env.CHAINID), + }, + cyprus2: { + url: `${process.env.CYPRUS2URL}`, + accounts: [process.env.CYPRUS2PK], + chainId: Number(process.env.CHAINID), + }, + ...more networks + }, + + // optional solidityx config for locally built solcx, if not specified solcx will be downloaded + + // common macOS path to local solc (uncomment and edit path if using macOS) + // solidityx: { compilerPath: '/usr/local/bin/solc' }, + // common Linux path to local solc (uncomment and edit path if using Linux) + // solidityx: { compilerPath: '/path/to/SolidityX/build/solc/solc' }, + + + solidity: { + version: "0.8.0", + settings: { + optimizer: { + enabled: true, + runs: 1000, + }, + }, + }, + +etherscan: { + apiKey: { + cyprus1: "abc", + ...more api keys + }, + customChains: [ + { + network: "cyprus1", + chainId: Number(process.env.CHAINID), + urls: { + apiURL: "https://cyprus1.colosseum.quaiscan.io/api", + browserURL: "https://cyprus1.colosseum.quaiscan.io", + }, + }, + ...more verification configs + ], + }, +}; +``` + +Inside the config file you can find deployment and verification definitions for: + +- `cyprus1` +- `cyprus2` +- `cyprus3` +- `paxos1` +- `paxos2` +- `paxos3` +- `hydra1` +- `hydra2` +- `hydra3` + +When deploying or verifying a contract, `hardhat.config.js` will pull your private keys and RPC URLs from the `.env` file and use them to deploy and verify your contracts. + +### SolidityX Compiler + +To be able to properly compile and deploy SolidityX contracts, we'll need the [SolidityX](https://github.com/dominant-strategies/SolidityX). There are two methods of installing the SolidityX compiler for use with Hardhat: + +- Install the SolidityX compiler via [`quai-hardhat-plugin`](https://www.npmjs.com/package/quai-hardhat-plugin) (**Recommended**) +- Install and build the SolidityX compiler from source + +#### Installing via Plugin + +As noted above, the `hardhat.config.js` file already includes the `quai-hardhat-plugin` to handle the SolidityX compiler download. If you've followed the above steps, you're already set up to use the plugin to download the SolidityX compiler. + +#### Installing from Source + +:::warning +Building the compiler from source and importing still requires the `quai-hardhat-plugin` to be installed and configured in the `hardhat.config.js` file. +::: + +Visit the [SolidityX Repository](https://github.com/dominant-strategies/SolidityX) for instructions on how to clone and build the SolidityX compiler for your specific operating system. + +Once you've built the SolidityX compiler, you'll need to add path to your `solc` binary into the `compilerPath` variable in the `solidityX` object in your `hardhat.config.js`. The file already includes common paths for MacOS and Linux as comments. + +## Deploy + +### Compile with Hardhat + SolidityX + +SolidityX contract compilation with Hardhat is simple and can be done using `npx` in the CLI. + +Compile all of the contracts inside the `contracts/` directory with: + +```bash +npx hardhat compile +``` + +Which should output something like: + +```bash +Info Using SolidityX at: /Users/user/hardhat-example/SolidityX/solc +Warning: This is a pre-release compiler version, please do not use it in production. + +Compiled 2 Solidity files successfully (evm target: istanbul). +``` + +### Deployment Scripts + +Inside the `scripts/` directory, you'll find a deploy script for both `QRC20.sol` and `QRC721.sol`: `deployQRC20.js` and `deployQRC721.js`. For this tutorial, we'll be using `deployQRC721.js`. + +The `deployQRC721.js` script works by pulling your specified network/accounts config from `hardhat.config.js` and the QRC721 arguments specified in the `.env` file at the root of the repository and uses them to deploy your contract. + +Token arguments are consumed via the `tokenArgs` object: + +```javascript +const tokenArgs = { + name: process.env.QRC721NAME, + symbol: process.env.QRC721SYMBOL, + baseURI: process.env.QRC721BASEURI, +}; +``` + +Your specified network configuration is consumed inside of the `provider` and `wallet` variables in tandem with the compiled contract ABI and bytecode to create a new contract instance: + +```javascript +const provider = new ethers.providers.JsonRpcProvider(hre.network.config.url); +const wallet = new ethers.Wallet(hre.network.config.accounts[0], provider); +const contract = new ethers.ContractFactory(QRC721.abi, QRC721.bytecode, wallet); +``` + +We'll use these ideas to properly modify the token args and network specification to deploy our contracts in the next step. + +### Deploy Your Contracts + +For this tutorial, we'll be deploying **one instances** of our QRC721 contract on two different chains. You can extend the methodology used here to deploy and link contracts to any combination of shards within Quai Network. + +We'll be deploying the first QRC721 contract on Cyprus-1 chain. To do this, we'll pass `cyprus1` as the network flag in the deployment command like below: + +```bash +npx hardhat run scripts/deployQRC721.js --network cyprus1 +``` + +Running this should output: + +```bash +1 -- Deploy transaction broadcasted: 0xb3c0a0d0f3bc47f4bcd5df67666d76246636741afb6134c2ba4145c51ed030d3 +2 -- Waiting for transaction to be mined. +3 -- Transaction mined. QRC721 deployed to: 0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601 + -- Gas used: 293212 +``` + +Now, we can deploy an identical QRC721 contract to another shard within Quai, like Cyprus-2. Like before, you'll pass `cyprus2` as the network flag in the deployment command. + +:::warning +When deploying QRC721s, we recommend changing the `baseURI` variable for each chain to prevent duplicate mints or additionally modifying the QRC721 contract to handle minting on different shards. This variable can be changed in the `.env` file at the root of the repository. +::: + +```bash +npx hardhat run scripts/deploy.js --network cyprus2 +``` + +Which again should output something like this: + +```bash +1 -- Deploy transaction broadcasted: 0xf6802822b4f1994d0be4ae03e2b1302ed42f3b95bf0c4607f3fae671f9719333 +2 -- Waiting for transaction to be mined. +3 -- Transaction mined. QRC721 deployed to: 0x2F4C5243BEd5dC46787378894eDF662Db9FE4685 + -- Gas used: 293543 +``` + +We've now deployed our test QRC721 contract to both the Cyprus-1 and Cyprus-2 chains! + +:::note +Make sure to save these two contract addresses, we'll need them in the next section. +::: + +## Link Sister Contracts + +To complete our cross-chain NFT deployment, we'll need to link the two deployed contracts. + +_"Linking"_ the two QRC721 contracts can be done by adding the deployed contract addresses of our QRC721s to the **approved contracts array** within each contract. This can be done using the `AddApprovedAddresses` method. It accepts 2 arrays as arguments: chain indexes and approved addresses. + +The `AddApprovedAddresses` method seen below can be used to add as few as 1 or as many as 8 sister contracts to the `approvedAddresses` array of a QRC721 or QRC20 contract. + +```solidity title="QRC721.sol" +function AddApprovedAddresses(uint8[] calldata chain, address[] calldata addr) external { + require(msg.sender == _deployer, "Sender is not deployer"); + require(chain.length == addr.length, "chain and address arrays must be the same length"); + for(uint8 i = 0; i < chain.length; i++) { + require(chain[i] < 9, "Max 9 zones"); + require(ApprovedAddresses[chain[i]] == address(0), "The approved address for this zone already exists"); + ApprovedAddresses[chain[i]] = addr[i]; + } +} +``` + +Once the sister contract addresses have been added to the respective `ApprovedAddresses` of each of the QRC721 contracts, the cross-chain functionality of the `transferFrom` method becomes available, which allows anyone who owns a token from the collection to trustlessly send their it between shards that the contracts are deployed to. + +#### Script + +To link the sister contracts, we'll utilize `quais.js` and some of the Hardhat Runtime Environment that we used in the deploy script. Start by creating another file in the scripts directory named `addApprovedAddresses.js`. + +```bash +touch scripts/addApprovedAddresses.js +``` + +Then, paste the following code into `addApprovedAddresses.js`: + +```javascript title="addApprovedAddresses.js" +const quais = require('quais'); +const { pollFor } = require('quais-polling'); +const QRC721 = require('../artifacts/contracts/QRC721.sol/QRC721.json'); + +async function AddApprovedQRC721Addresses() { + const provider = new quais.providers.JsonRpcProvider(hre.network.config.url); + const privateKey = hre.network.config.accounts[0]; + const wallet = new quais.Wallet(privateKey, provider); + const contractAddress = 'contract address you want to change the address array for'; // contract address to add approved addresses to + const qrc721 = new quais.Contract(contractAddress, QRC721.abi, wallet); + try { + const tx = await qrc721.AddApprovedAddresses( + [0, 1], // chain indexes (cyprus1 is 0, cyprus2 is 1, etc.) + ['0x1...', '0x2....'] // contract addresses (must be in same order as chain indexes) + ); + console.log('Transaction sent:', tx.hash); + const txReceipt = await pollFor(provider, 'getTransactionReceipt', [tx.hash], 1.5, 1); + console.log('Transaction mined with hash', txReceipt.hash); + } catch (error) { + console.error('Error sending transaction:', error); + } +} + +AddApprovedQRC721Addresses(); +``` + +The `addApprovedAddresses.js` script uses the `QRC721.sol` ABI to compose and send a transaction that inserts new addresses to the `approvedAddresses` array in any deployed QRC721 contract. + +The script works by: + +1. First, creating a quais `provider` with our specified network configuration from Hardhat +2. Creating a quais `wallet` with our `provider` and key config from Hardhat +3. Defining the contract we'd like to add an approved address to with the imported `QRC721.sol` ABI, contract address, and `wallet` +4. Composing the `addApprovedAddresses` transaction with the inputs + 1. `chainIndex` array: integer chain indices corresponding to the addresses we'd like to add to `approvedAddresses` + 2. `address` array: the contract addresses that we'd like to add to `approvedAddresses` +5. Sending the transaction and waiting for inclusion in a block. + +#### Transaction Data + +Now that we've set up our script, **we're ready to link our two deployed contracts**. + +Start by grabbing the addresses of the two contracts we deployed in the [deploy section](#deploy-your-contracts). + +```bash +Cyprus 1 contract address: 0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601 +Cyprus 2 contract address: 0x2F4C5243BEd5dC46787378894eDF662Db9FE4685 +``` + +We'll take these contract addresses and use them to build the transaction data passed to the `addApprovedAddresses` method. + +:::tip +**You can pass the same transaction data to every contract you want to link**, as the `addApprovedAddresses` method **can take in and handle its own contract address as an argument**. This removes the need to alter the transaction data for each contract you want to link. +::: + +The transaction data we'll need to pass to the `addApprovedAddresses` method is **(notice the order of the arrays)**: + +- `chainIndex` array: `[0, 1]` +- `address` array: `['0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601', '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'] + +The built transaction should look similar to this: + +```javascript +const transactionData = await contract.populateTransaction.AddApprovedAddress( + [0, 1], // chain indexes [cyprus1, cyprus2] + ['0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601', '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'] // contract addresses [cyprus1, cyprus2] +); +``` + +:::info +You can extend this transaction data structure to link as many contracts as you'd like by adding additional chain indexes and contract addresses to the arrays. **Always make sure to add the same number of chain indexes and contract addresses to the arrays in matching order**. +::: + +#### Linking Contracts + +First, we're going to send the linking transaction to our Cyprus 1 contract. To do this, start by changing the `contractAddress` variable to our **Cyprus 1 contract address** in the `addApprovedAddresses.js` script: + +```javascript +const contractAddress = '0x1A3fA2C0B9c490a07a421d2b169E034C1bFcA601'; +``` + +Now, we're ready to run the script and complete the Cyprus 1 contract linkage. Make sure to pass the `--network cyprus1` flag **when sending transactions to the Cyprus 1 contract**. + +```bash +npx hardhat run scripts/addApprovedAddresses.js --network cyprus1 +``` + +The script should output something like this: + +```bash +Transaction sent: 0x2a499178c3f0046b4d44a57a966f9e224759c1b3158af984fcb5a1432b16ee8e +Transaction mined with hash: 0x2a499178c3f0046b4d44a57a966f9e224759c1b3158af984fcb5a1432b16ee8e +``` + +We've now linked our Cyprus 1 contract to our Cyprus 2 contract, but we're not done yet. + +To finish linking these two sister contracts, we'll need to send the exact same transaction data to the Cyprus 2 contract. In the `addApprovedAddresses.js` script, change the `contractAddress` variable to **our Cyprus 2 contract address**: + +```javascript +const contractAddress = '0x2F4C5243BEd5dC46787378894eDF662Db9FE4685'; +``` + +Lastly, send the linkage transaction to our Cyprus 2 token by running the script with the `--network cyprus2` flag: + +```bash +Transaction sent: 0x348e8dea20b73089b51e6b3d2b3abd8a9e8ca63e06be20375cf721e13aabd590 +Transaction mined with hash: 0x348e8dea20b73089b51e6b3d2b3abd8a9e8ca63e06be20375cf721e13aabd590 +``` + +**Once the second transaction is confirmed, our two QRC721 contracts have been successfully linked across chains.** After minting a token, you can now send your NFTs from Cyprus 1 to Cyprus 2 without a bridge or external service! + +This deployment and linking process can be repeated for any number of chains within Quai Network purely by deploying the contract to the desired chains and linking them with the `addApprovedAddresses` method. **You now have the tools to deploy and link contracts across all 9 shards within Quai Network**. + +For a more detailed example on how to deploy and link contracts across all shards within Quai Network, check out the [Dominant Strategies' quais-by-example repo](https://github.com/dominant-strategies/quais-by-example/tree/main/contract-qrc721). + +:::info +The same deploy and link method can be used for any other SolidityX based contract with cross-chain logic, including the [QRC-20 Token Standard](https://github.com/dominant-strategies/SolidityX-Contracts/blob/main/QRC20X.sol). +::: diff --git a/docs/participate/mining/gpu-miner/gpu-miner-faq.md b/docs/participate/mining/gpu-miner/gpu-miner-faq.md index e8b927e..534d7d2 100644 --- a/docs/participate/mining/gpu-miner/gpu-miner-faq.md +++ b/docs/participate/mining/gpu-miner/gpu-miner-faq.md @@ -152,7 +152,7 @@ This flight sheet was created and is maintained by a Quai community member, not ![Flight Sheets](/img/FS4.jpg) 8. On "Miner name", type "quai_custom". -9. On "Installation URL", copy/paste "[https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.3.tar.gz](https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.3.amd.tar.gz)". +9. On "Installation URL", copy/paste "[https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.3.amd.tar.gz](https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.3.amd.tar.gz)" if you have AMD cards and "[https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.2.tar.gz](https://quai-gpu-releases.s3.eu-west-1.amazonaws.com/quai_custom-0.3.2.tar.gz)" if you have NVIDIA cards. 10. On "Hash algorithm", type "progpow". 11. On "Wallet and worker template", type "%WAL%.%WORKER_NAME%". 12. On "Pool URL", type "stratum://EXTERNALIPADDRESS:PORT". diff --git a/docs/participate/stratum-proxy/run-stratum.md b/docs/participate/stratum-proxy/run-stratum.md index c03da40..804b050 100644 --- a/docs/participate/stratum-proxy/run-stratum.md +++ b/docs/participate/stratum-proxy/run-stratum.md @@ -152,20 +152,20 @@ Available options for `REGION-NAME`, `ZONE-NAME`, `REGION-PORT`, and `ZONE-PORT` If you're running a version of `go-quai-stratum` prior to [v0.9.0-rc.0](https://github.com/dominant-strategies/go-quai-stratum/releases/tag/v0.9.0-rc.0), you'll need to pass in the corresponding web socket ports as chain names are not supported prior to this version. -| Chain Name | Type | Chain Index | Web Socket Port | Stratum Command | -| ---------- | ------ | ----------- | --------------- | ------------------------------------------------------- | -| Cyprus | Region | | 8579 | | -| Paxos | Region | | 8581 | | -| Hydra | Region | | 8583 | | -| Cyprus-1 | Zone | [0 0] | 8611 | ./build/bin/quai-stratum --region=cyprus --zone=cyprus1 | -| Cyprus-2 | Zone | [0 1] | 8643 | ./build/bin/quai-stratum --region=cyprus --zone=cyprus2 | -| Cyprus-3 | Zone | [0 2] | 8675 | ./build/bin/quai-stratum --region=cyprus --zone=cyprus3 | -| Paxos-1 | Zone | [1 0] | 8613 | ./build/bin/quai-stratum --region=paxos --zone=paxos1 | -| Paxos-2 | Zone | [1 1] | 8645 | ./build/bin/quai-stratum --region=paxos --zone=paxos2 | -| Paxos-3 | Zone | [1 2] | 8677 | ./build/bin/quai-stratum --region=paxos --zone=paxos3 | -| Hydra-1 | Zone | [2 0] | 8615 | ./build/bin/quai-stratum --region=hydra --zone=hydra1 | -| Hydra-2 | Zone | [2 1] | 8647 | ./build/bin/quai-stratum --region=hydra --zone=hydra2 | -| Hydra-3 | Zone | [2 2] | 8679 | ./build/bin/quai-stratum --region=hydra --zone=hydra3 | +| Chain Name | Type | Chain Index | Web Socket Port | Stratum Command | +| ---------- | ------ | ----------- | --------------- | ---------------------------------------------------------- | +| Cyprus | Region | | 8579 | | +| Paxos | Region | | 8581 | | +| Hydra | Region | | 8583 | | +| Cyprus-1 | Zone | [0 0] | 8611 | ./build/bin/go-quai-stratum --region=cyprus --zone=cyprus1 | +| Cyprus-2 | Zone | [0 1] | 8643 | ./build/bin/go-quai-stratum --region=cyprus --zone=cyprus2 | +| Cyprus-3 | Zone | [0 2] | 8675 | ./build/bin/go-quai-stratum --region=cyprus --zone=cyprus3 | +| Paxos-1 | Zone | [1 0] | 8613 | ./build/bin/go-quai-stratum --region=paxos --zone=paxos1 | +| Paxos-2 | Zone | [1 1] | 8645 | ./build/bin/go-quai-stratum --region=paxos --zone=paxos2 | +| Paxos-3 | Zone | [1 2] | 8677 | ./build/bin/go-quai-stratum --region=paxos --zone=paxos3 | +| Hydra-1 | Zone | [2 0] | 8615 | ./build/bin/go-quai-stratum --region=hydra --zone=hydra1 | +| Hydra-2 | Zone | [2 1] | 8647 | ./build/bin/go-quai-stratum --region=hydra --zone=hydra2 | +| Hydra-3 | Zone | [2 2] | 8679 | ./build/bin/go-quai-stratum --region=hydra --zone=hydra3 | :::danger **Do not open the above web socket ports except** in the specific case where your miner is on a different network than your node/stratum (and even then, be sure to only open the port to the necessary machine). You may be putting your local network security at risk. @@ -174,7 +174,7 @@ If you're running a version of `go-quai-stratum` prior to [v0.9.0-rc.0](https:// The proxy by default listens for miner connections on the `3333` port. You can change the port the proxy listens on by passing it in with the `--stratum` flag in the run command if you'd like. ```bash -./build/bin/quai-stratum --region=REGION-NAME --zone=ZONE-NAME --stratum=LISTENING-PORT +./build/bin/go-quai-stratum --region=REGION-NAME --zone=ZONE-NAME --stratum=LISTENING-PORT ``` :::info