> For the complete documentation index, see [llms.txt](https://igra-labs.gitbook.io/igralabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://igra-labs.gitbook.io/igralabs-docs/quickstart/deploy-your-first-contract.md).

# Deploy Your First Contract

This guide walks through deploying a smart contract to Igra using Hardhat or Foundry. Both work out of the box with no modifications.

## Prerequisites

* Node.js 18+ (for Hardhat) or Foundry installed
* Testnet iKAS in your wallet ([get some here](/igralabs-docs/quickstart/network-info.md#get-testnet-ikas))
* Private key for deployment

***

## Option 1: Hardhat

### Setup

```bash
mkdir igra-demo && cd igra-demo
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init
```

Select "Create a JavaScript project" when prompted.

### Configure Network

Edit `hardhat.config.js`:

```javascript
require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: "0.8.24",
  networks: {
    igra_mainnet: {
      url: "https://rpc.igralabs.com:8545",
      chainId: 38833,
      accounts: [process.env.PRIVATE_KEY],
      gasPrice: 1100000000000,  // 1100 gwei, legacy
    },
    galleon_testnet: {
      url: "https://galleon-testnet.igralabs.com:8545",
      chainId: 38836,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
```

### Write Contract

Create `contracts/HelloIgra.sol`:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract HelloIgra {
    string public message;

    event MessageChanged(string oldMessage, string newMessage);

    constructor(string memory _message) {
        message = _message;
    }

    function setMessage(string memory _message) public {
        string memory oldMessage = message;
        message = _message;
        emit MessageChanged(oldMessage, _message);
    }
}
```

### Deploy Script

Create `scripts/deploy.js`:

```javascript
const hre = require("hardhat");

async function main() {
  const HelloIgra = await hre.ethers.getContractFactory("HelloIgra");
  const hello = await HelloIgra.deploy("Hello from Igra!");

  await hello.waitForDeployment();

  console.log("HelloIgra deployed to:", await hello.getAddress());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
```

### Deploy

```bash
export PRIVATE_KEY=your_private_key_here
npx hardhat run scripts/deploy.js --network galleon_testnet
```

Output:

```
HelloIgra deployed to: 0x...
```

### Verify Contract

```bash
npx hardhat verify --network galleon_testnet CONTRACT_ADDRESS "Hello from Igra!"
```

Add to `hardhat.config.js` for verification:

```javascript
module.exports = {
  // ... existing config
  etherscan: {
    apiKey: {
      igra_mainnet: "no-api-key-needed",
      galleon_testnet: "no-api-key-needed",
    },
    customChains: [
      {
        network: "igra_mainnet",
        chainId: 38833,
        urls: {
          apiURL: "https://explorer.igralabs.com/api",
          browserURL: "https://explorer.igralabs.com",
        },
      },
      {
        network: "galleon_testnet",
        chainId: 38836,
        urls: {
          apiURL: "https://explorer.galleon-testnet.igralabs.com/api",
          browserURL: "https://explorer.galleon-testnet.igralabs.com",
        },
      },
    ],
  },
};
```

***

## Option 2: Foundry

### Setup

```bash
mkdir igra-demo && cd igra-demo
forge init
```

### Configure Network

Create or edit `foundry.toml`:

```toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.24"

[rpc_endpoints]
igra_mainnet = "https://rpc.igralabs.com:8545"
galleon_testnet = "https://galleon-testnet.igralabs.com:8545"

[etherscan]
igra_mainnet = { key = "no-api-key-needed", url = "https://explorer.igralabs.com/api", chain = 38833 }
galleon_testnet = { key = "no-api-key-needed", url = "https://explorer.galleon-testnet.igralabs.com/api" }
```

### Write Contract

Create `src/HelloIgra.sol`:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract HelloIgra {
    string public message;

    event MessageChanged(string oldMessage, string newMessage);

    constructor(string memory _message) {
        message = _message;
    }

    function setMessage(string memory _message) public {
        string memory oldMessage = message;
        message = _message;
        emit MessageChanged(oldMessage, _message);
    }
}
```

### Deploy

```bash
forge create --rpc-url galleon_testnet \
  --private-key $PRIVATE_KEY \
  src/HelloIgra.sol:HelloIgra \
  --constructor-args "Hello from Igra!"
```

Output:

```
Deployer: 0x...
Deployed to: 0x...
Transaction hash: 0x...
```

### Verify Contract

```bash
# For Igra Mainnet
forge verify-contract CONTRACT_ADDRESS \
  src/HelloIgra.sol:HelloIgra \
  --chain-id 38833 \
  --verifier blockscout \
  --verifier-url https://explorer.igralabs.com/api \
  --constructor-args $(cast abi-encode "constructor(string)" "Hello from Igra!")

# For Galleon Testnet
forge verify-contract CONTRACT_ADDRESS \
  src/HelloIgra.sol:HelloIgra \
  --chain-id 38836 \
  --verifier blockscout \
  --verifier-url https://explorer.galleon-testnet.igralabs.com/api \
  --constructor-args $(cast abi-encode "constructor(string)" "Hello from Igra!")
```

***

## Interact with Your Contract

### Using Hardhat Console

```bash
npx hardhat console --network galleon_testnet
```

```javascript
const HelloIgra = await ethers.getContractFactory("HelloIgra");
const hello = HelloIgra.attach("YOUR_CONTRACT_ADDRESS");

await hello.message();
// 'Hello from Igra!'

await hello.setMessage("Updated message");
await hello.message();
// 'Updated message'
```

### Using Cast (Foundry)

```bash
# Read message
cast call CONTRACT_ADDRESS "message()(string)" --rpc-url galleon_testnet

# Write message
cast send CONTRACT_ADDRESS "setMessage(string)" "New message" \
  --rpc-url galleon_testnet \
  --private-key $PRIVATE_KEY
```

***

## Things to Note

**Fast confirmations:** Transactions confirm in under 1 second. You will see your deployment almost instantly.

**Low fees:** Gas costs are minimal. The base fee is 1 wei.

**Standard EVM:** Any Solidity or Vyper contract that works on Ethereum will work on Igra without changes.

**Transaction size:** The RPC accepts transactions up to 128 KB. Standard Solidity contracts (24 KB contract-size limit) deploy without issues.

***

## AI Agents

AI agents can search and read this documentation through the Igra Network MCP server. Add it to any MCP client as a remote (HTTP) server:

```
https://igra-labs.gitbook.io/igralabs-docs/~gitbook/mcp
```

***

## Next Steps

* [Network Info](/igralabs-docs/quickstart/network-info.md) - RPC endpoints and chain parameters
* [Ethereum Compatibility](/igralabs-docs/for-developers/ethereum-compatibility-and-known-constraints.md) - Differences from Ethereum
* [Architecture Overview](/igralabs-docs/for-developers/architecture/overview.md) - How Igra works under the hood
