GOAT Network
App Development

Solidity Smart Contracts

GOAT Network is EVM-compatible, so you can use standard Ethereum development workflows with Solidity, Hardhat, Foundry, and ethers.

Tooling Options

Install Hardhat toolchain
npm install --save-dev @nomicfoundation/hardhat-toolbox dotenv
hardhat.config.ts
import '@nomicfoundation/hardhat-toolbox';
import { config as loadEnv } from 'dotenv';

loadEnv();

export default {
  solidity: '0.8.24',
  networks: {
    goatTestnet3: {
      url: 'https://rpc.testnet3.goat.network',
      chainId: 48816,
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
    },
    goatMainnet: {
      url: 'https://rpc.goat.network',
      chainId: 2345,
      accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [],
    },
  },
};
Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
forge init my-goat-project
foundry.toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

Example Contract

src/HelloGOAT.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract HelloGOAT {
  string public message = "Hello, GOAT Network!";

  function setMessage(string memory nextMessage) external {
    message = nextMessage;
  }
}

Deploy

scripts/deploy.ts
import { ethers } from 'hardhat';

async function main() {
  const factory = await ethers.getContractFactory('HelloGOAT');
  const contract = await factory.deploy();

  await contract.waitForDeployment();
  console.log('HelloGOAT:', await contract.getAddress());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
Hardhat deploy
npx hardhat run scripts/deploy.ts --network goatTestnet3
script/Deploy.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Script} from "forge-std/Script.sol";
import {HelloGOAT} from "../src/HelloGOAT.sol";

contract Deploy is Script {
  function run() external {
    vm.startBroadcast();
    new HelloGOAT();
    vm.stopBroadcast();
  }
}
Foundry deploy
forge script script/Deploy.s.sol \
  --rpc-url https://rpc.testnet3.goat.network \
  --broadcast

Test

test/HelloGOAT.ts
import { expect } from 'chai';
import { ethers } from 'hardhat';

describe('HelloGOAT', () => {
  it('updates the stored message', async () => {
    const factory = await ethers.getContractFactory('HelloGOAT');
    const contract = await factory.deploy();
    await contract.waitForDeployment();

    await contract.setMessage('Hello, GOAT test!');
    expect(await contract.message()).to.equal('Hello, GOAT test!');
  });
});
test/HelloGOAT.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {Test} from "forge-std/Test.sol";
import {HelloGOAT} from "../src/HelloGOAT.sol";

contract HelloGOATTest is Test {
  function testSetMessage() external {
    HelloGOAT hello = new HelloGOAT();
    hello.setMessage("Hello, GOAT test!");
    assertEq(hello.message(), "Hello, GOAT test!");
  }
}

Interact with the Contract

ethers.js contract interaction
import { Contract, JsonRpcProvider, Wallet } from 'ethers';

const provider = new JsonRpcProvider('https://rpc.testnet3.goat.network');
const signer = new Wallet(process.env.PRIVATE_KEY!, provider);

const contract = new Contract(process.env.HELLO_GOAT_ADDRESS!, [
  'function message() view returns (string)',
  'function setMessage(string nextMessage)',
], signer);

console.log(await contract.message());
await (await contract.setMessage('Updated from ethers v6')).wait();

Store PRIVATE_KEY in environment variables or a secret store. Never commit real credentials to source control.

On this page