Deploying Smart Contracts
Deploy your first Solidity contract to Beatoz
Deploying Smart Contracts
In this tutorial, you'll learn how to compile and deploy a Solidity smart contract to the Beatoz blockchain.
Prerequisites
Complete the beginner tutorials before starting this guide.
Project Setup
Step 1: Create Project Directory
mkdir beatoz-contract-demo
cd beatoz-contract-demo
npm init -y
Step 2: Install Dependencies
npm install @beatoz/web3 hardhat dotenv
npm install --save-dev @nomicfoundation/hardhat-toolbox
Step 3: Initialize Hardhat
npx hardhat init
Select "Create an empty hardhat.config.js" when prompted.
Writing Your First Contract
TestnetSimpleStorage Contract
Create contracts/SimpleStorage.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract SimpleStorage {
uint256 private storedValue;
event ValueChanged(uint256 oldValue, uint256 newValue);
constructor(uint256 initialValue) {
storedValue = initialValue;
}
function set(uint256 newValue) public {
uint256 oldValue = storedValue;
storedValue = newValue;
emit ValueChanged(oldValue, newValue);
}
function get() public view returns (uint256) {
return storedValue;
}
}
Configure Hardhat
Update hardhat.config.js:
require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.19",
paths: {
sources: "./contracts",
artifacts: "./artifacts",
},
};
Compile the Contract
npx hardhat compile
You should see "Compiled 1 Solidity file successfully" in the output.
Deploy Script
Create scripts/deploy.js:
const { Web3 } = require('@beatoz/web3');
const fs = require('fs');
const path = require('path');
require('dotenv').config();
async function main() {
// Connect to Beatoz Testnet
const web3 = new Web3('https://rpc-testnet0.beatoz.io');
// Load deployer account
const deployer = web3.beatoz.accounts.privateKeyToAccount(
process.env.PRIVATE_KEY
);
console.log('Deployer:', deployer.address);
const balance = await web3.beatoz.getBalance(deployer.address);
console.log('Balance:', web3.utils.fromFons(balance, 'beatoz'), 'BTZ');
// Load compiled contract
const artifactPath = path.join(
__dirname,
'../artifacts/contracts/SimpleStorage.sol/SimpleStorage.json'
);
const artifact = JSON.parse(fs.readFileSync(artifactPath, 'utf-8'));
const status = await web3.beatoz.status();
const chainId = status.node_info.network;
const contract = new web3.beatoz.Contract(artifact.abi);
// Constructor argument: SimpleStorage(42)
const result = await contract
.deploy(artifact.bytecode, [42], deployer, chainId, 3_000_000)
.send();
console.log('✅ Contract deployed successfully!');
console.log('Contract Address:', result.contractAddress);
console.log('Transaction Hash:', result.hash);
console.log('Block Height:', result.height);
return result.contractAddress;
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Environment Setup
Create .env file:
PRIVATE_KEY=your_private_key_here
Security
Never commit your .env file to version control!
Add .env to your .gitignore file.
Deploy to Testnet
node scripts/deploy.js
Expected output:
Deployer: 0x1234...
✅ Contract deployed successfully!
Contract Address: 0xabcd...
Transaction Hash: 0x5678...
Block Height: 12345
Using the Contract Class
The deploy script above uses the Contract class exposed by @beatoz/web3:
const contract = new web3.beatoz.Contract(abi);
const result = await contract
.deploy(bytecode, constructorArguments, deployerAccount, chainId, gasLimit)
.send();
console.log(result.contractAddress);
Verify Deployment
After deployment, verify your contract is working:
async function verifyDeployment(contractAddress) {
const web3 = new Web3('https://rpc-testnet0.beatoz.io');
const contract = new web3.beatoz.Contract(abi, contractAddress);
// Call the get() function
const value = await contract.methods.get().call();
console.log('Stored value:', value); // Should print 42
}
Complete Project Structure
beatoz-contract-demo/
├── contracts/
│ └── SimpleStorage.sol
├── scripts/
│ └── deploy.js
├── artifacts/ # Generated by Hardhat
├── .env
├── .gitignore
├── hardhat.config.js
└── package.json
Troubleshooting
"Insufficient balance"
Get tokens from the Faucet before deploying.
"Out of gas"
Increase the gas limit in your deployment script.
"Invalid nonce"
Fetch the latest nonce before each transaction.
