🎯 Recommended Samples
Balanced sample collections from various categories for you to explore
Truffle Development Suite Samples
Truffle Ethereum development framework examples including smart contracts, testing, deployment, migrations, debugging, and development workflows
💻 Truffle Hello World - Basic Setup javascript
🟢 simple
⭐⭐
Complete Truffle project setup with smart contract, tests, migrations, and configuration for Ethereum development
⏱️ 20 min
🏷️ truffle, ethereum, smart contracts, development
Prerequisites:
Node.js, Truffle Suite installed, Ganache or other Ethereum client
// Truffle Hello World - Complete Project Setup
// Initialize: truffle init
// ===== truffle-config.js =====
module.exports = {
// Networks configuration
networks: {
development: {
host: "127.0.0.1",
port: 7545,
network_id: "*",
},
ganache: {
host: "127.0.0.1",
port: 7545,
network_id: "*",
},
// Testnet configurations
goerli: {
provider: () => {
const wallet = require('ethereumjs-wallet').default;
const HDWalletProvider = require('@truffle/hdwallet-provider');
const mnemonic = process.env.MNEMONIC;
const infuraKey = process.env.INFURA_KEY;
return new HDWalletProvider({
mnemonic: {
phrase: mnemonic
},
providerOrUrl: `https://goerli.infura.io/v3/${infuraKey}`
});
},
network_id: 5,
gas: 4465030,
gasPrice: 10000000000,
},
sepolia: {
provider: () => {
const HDWalletProvider = require('@truffle/hdwallet-provider');
const privateKey = process.env.PRIVATE_KEY;
const infuraKey = process.env.INFURA_KEY;
return new HDWalletProvider(privateKey, `https://sepolia.infura.io/v3/${infuraKey}`);
},
network_id: 11155111,
gas: 4465030,
gasPrice: 10000000000,
},
},
// Solidity compiler configuration
compilers: {
solc: {
version: "0.8.19",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
},
// Mocha test configuration
mocha: {
timeout: 100000,
},
// Plugins configuration
plugins: [
'truffle-plugin-verify',
'truffle-contract-size',
'solidity-coverage',
],
// API keys for plugins
api_keys: {
etherscan: process.env.ETHERSCAN_API_KEY,
},
// Verify contracts after deployment
verify: {
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
},
},
};
// ===== contracts/Storage.sol =====
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract Storage {
uint256 private number;
string private message;
address public owner;
event DataStored(uint256 indexed newValue, string indexed newMessage, address indexed storedBy);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event MessageUpdated(string indexed oldMessage, string indexed newMessage);
constructor(uint256 _initialNumber, string memory _initialMessage) {
number = _initialNumber;
message = _initialMessage;
owner = msg.sender;
emit DataStored(_initialNumber, _initialMessage, msg.sender);
}
modifier onlyOwner() {
require(msg.sender == owner, "Storage: caller is not the owner");
_;
}
function store(uint256 _num, string memory _msg) public onlyOwner {
uint256 oldValue = number;
string memory oldMessage = message;
number = _num;
message = _msg;
emit DataStored(_num, _msg, msg.sender);
emit MessageUpdated(oldMessage, _msg);
}
function retrieve() public view returns (uint256, string memory) {
return (number, message);
}
function getNumber() public view returns (uint256) {
return number;
}
function getMessage() public view returns (string memory) {
return message;
}
function transferOwnership(address _newOwner) public onlyOwner {
require(_newOwner != address(0), "Storage: new owner is the zero address");
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
}
// ===== test/storage.test.js =====
const { expect } = require('chai');
const { ethers } = require('hardhat');
describe('Storage Contract', function () {
let storage;
let owner;
let addr1;
let addr2;
beforeEach(async function () {
[owner, addr1, addr2] = await ethers.getSigners();
const Storage = await ethers.getContractFactory('Storage');
storage = await Storage.deploy(42, "Hello, Truffle!");
await storage.deployed();
});
describe('Deployment', function () {
it('Should set the right owner', async function () {
expect(await storage.owner()).to.equal(owner.address);
});
it('Should set the initial number', async function () {
const [number] = await storage.retrieve();
expect(number).to.equal(42);
});
it('Should set the initial message', async function () {
const [, message] = await storage.retrieve();
expect(message).to.equal("Hello, Truffle!");
});
it('Should emit DataStored event on deployment', async function () {
await expect(storage.deployTransaction)
.to.emit(storage, 'DataStored')
.withArgs(42, "Hello, Truffle!", owner.address);
});
});
describe('Store function', function () {
it('Should allow owner to store new values', async function () {
await storage.store(100, "New message");
const [number, message] = await storage.retrieve();
expect(number).to.equal(100);
expect(message).to.equal("New message");
});
it('Should emit DataStored event when storing', async function () {
await expect(storage.store(100, "New message"))
.to.emit(storage, 'DataStored')
.withArgs(100, "New message", owner.address);
});
it('Should emit MessageUpdated event when storing', async function () {
await expect(storage.store(100, "New message"))
.to.emit(storage, 'MessageUpdated')
.withArgs("Hello, Truffle!", "New message");
});
it('Should not allow non-owner to store values', async function () {
await expect(
storage.connect(addr1).store(100, "Unauthorized")
).to.be.revertedWith('Storage: caller is not the owner');
});
});
describe('Get functions', function () {
it('Should return correct number', async function () {
expect(await storage.getNumber()).to.equal(42);
});
it('Should return correct message', async function () {
expect(await storage.getMessage()).to.equal("Hello, Truffle!");
});
});
describe('Ownership transfer', function () {
it('Should allow owner to transfer ownership', async function () {
await storage.transferOwnership(addr1.address);
expect(await storage.owner()).to.equal(addr1.address);
});
it('Should emit OwnershipTransferred event', async function () {
await expect(storage.transferOwnership(addr1.address))
.to.emit(storage, 'OwnershipTransferred')
.withArgs(owner.address, addr1.address);
});
it('Should not allow transfer to zero address', async function () {
await expect(
storage.transferOwnership(ethers.constants.AddressZero)
).to.be.revertedWith('Storage: new owner is the zero address');
});
it('Should allow new owner to store values', async function () {
await storage.transferOwnership(addr1.address);
await storage.connect(addr1).store(200, "New owner message");
const [number, message] = await storage.retrieve();
expect(number).to.equal(200);
expect(message).to.equal("New owner message");
});
it('Should not allow old owner to store after transfer', async function () {
await storage.transferOwnership(addr1.address);
await expect(
storage.store(300, "Old owner message")
).to.be.revertedWith('Storage: caller is not the owner');
});
});
describe('Edge cases', function () {
it('Should handle zero values', async function () {
await storage.store(0, "");
const [number, message] = await storage.retrieve();
expect(number).to.equal(0);
expect(message).to.equal("");
});
it('Should handle large values', async function () {
const largeNumber = ethers.constants.MaxUint256;
await storage.store(largeNumber, "Maximum value");
const [number] = await storage.retrieve();
expect(number).to.equal(largeNumber);
});
});
});
// ===== migrations/1_initial_migration.js =====
const Migrations = artifacts.require("Migrations");
module.exports = function (deployer) {
deployer.deploy(Migrations);
};
// ===== migrations/2_deploy_storage.js =====
const Storage = artifacts.require("Storage");
module.exports = function (deployer) {
// Deploy with initial values
deployer.deploy(Storage, 42, "Hello, Truffle!");
};
// ===== scripts/deploy.js =====
const Storage = artifacts.require("Storage");
async function main() {
console.log("Starting deployment...");
// Get deployer account
const accounts = await web3.eth.getAccounts();
const deployer = accounts[0];
console.log("Deploying contracts with account:", deployer);
// Get account balance
const balance = await web3.eth.getBalance(deployer);
console.log("Account balance:", web3.utils.fromWei(balance, "ether"), "ETH");
// Deploy Storage contract
console.log("Deploying Storage contract...");
const storage = await Storage.new(100, "Initial deployment message", {
from: deployer,
gas: 2000000,
gasPrice: web3.utils.toWei("20", "gwei"),
});
console.log("Storage contract deployed to:", storage.address);
// Verify deployment
const [number, message] = await storage.retrieve();
console.log("Initial values:");
console.log(" Number:", number.toString());
console.log(" Message:", message);
console.log("Deployment completed successfully!");
return storage;
}
// For use with truffle exec
if (typeof module !== 'undefined' && module.exports) {
module.exports = function(callback) {
main().then(() => callback()).catch(err => callback(err));
};
}
// ===== scripts/interact.js =====
const Storage = artifacts.require("Storage");
async function main() {
console.log("Contract Interaction Example");
console.log("==========================");
// Get deployed contract
const storage = await Storage.deployed();
console.log("Storage contract address:", storage.address);
// Get current values
const [number, message] = await storage.retrieve();
console.log("\nCurrent values:");
console.log(" Number:", number.toString());
console.log(" Message:", message);
// Store new values
console.log("\nStoring new values...");
const tx = await storage.store(200, "Updated via script");
console.log("Transaction hash:", tx.tx);
console.log("Gas used:", tx.receipt.gasUsed.toString());
// Verify updated values
const [newNumber, newMessage] = await storage.retrieve();
console.log("\nUpdated values:");
console.log(" Number:", newNumber.toString());
console.log(" Message:", newMessage);
// Get contract owner
const owner = await storage.owner();
console.log("\nContract owner:", owner);
console.log("\nInteraction completed!");
}
// For use with truffle exec
if (typeof module !== 'undefined' && module.exports) {
module.exports = function(callback) {
main().then(() => callback()).catch(err => callback(err));
};
}
// ===== package.json =====
{
"name": "truffle-hello-world",
"version": "1.0.0",
"description": "Truffle Hello World example project",
"main": "truffle-config.js",
"scripts": {
"compile": "truffle compile",
"migrate": "truffle migrate",
"test": "truffle test",
"dev": "truffle migrate --network development",
"goerli": "truffle migrate --network goerli",
"sepolia": "truffle migrate --network sepolia",
"verify": "truffle run verify Storage --network sepolia",
"console": "truffle console",
"coverage": "truffle run coverage"
},
"dependencies": {
"@truffle/hdwallet-provider": "^2.1.15",
"@openzeppelin/contracts": "^4.9.0",
"ethereumjs-wallet": "^1.0.2"
},
"devDependencies": {
"chai": "^4.3.8",
"solidity-coverage": "^0.8.4",
"truffle-plugin-verify": "^0.6.4",
"truffle-contract-size": "^2.0.1"
}
}
💻 Truffle Advanced Testing javascript
🟡 intermediate
⭐⭐⭐⭐
Comprehensive testing strategies including unit tests, integration tests, gas optimization tests, and custom test utilities
⏱️ 35 min
🏷️ truffle, testing, smart contracts, gas
Prerequisites:
Truffle basics, Chai assertion library, Understanding of smart contract testing
// Truffle Advanced Testing Suite
// Comprehensive testing patterns for smart contracts
const { expect } = require('chai');
const { ethers } = require('hardhat');
const { time } = require('@openzeppelin/test-helpers');
// ===== Test Utilities =====
class ContractTestHelper {
constructor(contract) {
this.contract = contract;
}
// Revert expectation helper
async expectRevert(promise, expectedError) {
await expect(promise).to.be.revertedWith(expectedError);
}
// Event emission helper
async expectEvent(promise, eventName, ...args) {
const tx = await promise;
await expect(tx).to.emit(this.contract, eventName);
if (args.length > 0) {
await expect(tx).to.emit(this.contract, eventName).withArgs(...args);
}
return tx;
}
// Balance change helper
async expectBalanceChange(account, change) {
const before = await ethers.provider.getBalance(account);
const result = await this.contract.deployTransaction;
const receipt = await result.wait();
const after = await ethers.provider.getBalance(account);
const actualChange = after.sub(before);
expect(actualChange).to.equal(change);
}
// Gas usage helper
async measureGas(transactionFunction) {
const tx = await transactionFunction();
const receipt = await tx.wait();
return receipt.gasUsed.toString();
}
// Time helper for time-dependent contracts
async increaseTime(seconds) {
await ethers.provider.send('evm_increaseTime', [seconds]);
await ethers.provider.send('evm_mine');
}
// Mine blocks helper
async mineBlocks(count) {
for (let i = 0; i < count; i++) {
await ethers.provider.send('evm_mine');
}
}
}
// ===== test/advanced/Storage.advanced.test.js =====
describe('Storage Contract - Advanced Testing', function () {
let storage;
let owner, addr1, addr2, addrs;
let helper;
beforeEach(async function () {
[owner, addr1, addr2, ...addrs] = await ethers.getSigners();
const Storage = await ethers.getContractFactory('Storage');
storage = await Storage.deploy(42, "Initial message");
await storage.deployed();
helper = new ContractTestHelper(storage);
});
describe('State Testing', function () {
it('Should maintain consistent state across operations', async function () {
// Initial state
const initialNumber = await storage.getNumber();
const initialMessage = await storage.getMessage();
expect(initialNumber).to.equal(42);
expect(initialMessage).to.equal("Initial message");
// State change
await storage.store(100, "Updated message");
// Verify new state
const newNumber = await storage.getNumber();
const newMessage = await storage.getMessage();
expect(newNumber).to.equal(100);
expect(newMessage).to.equal("Updated message");
// State should persist
const [number, message] = await storage.retrieve();
expect(number).to.equal(100);
expect(message).to.equal("Updated message");
});
it('Should handle boundary values correctly', async function () {
// Test with zero
await storage.store(0, "");
let [number, message] = await storage.retrieve();
expect(number).to.equal(0);
expect(message).to.equal("");
// Test with maximum uint256
const maxUint256 = ethers.constants.MaxUint256;
await storage.store(maxUint256, "Max value");
[number, message] = await storage.retrieve();
expect(number).to.equal(maxUint256);
expect(message).to.equal("Max value");
});
});
describe('Access Control Testing', function () {
it('Should enforce ownership restrictions', async function () {
// Owner can call restricted functions
await expect(storage.store(1, "Owner test")).to.not.be.reverted;
// Non-owners cannot call restricted functions
await expect(
storage.connect(addr1).store(1, "Non-owner test")
).to.be.revertedWith('Storage: caller is not the owner');
// After ownership transfer, new owner can call
await storage.transferOwnership(addr1.address);
await expect(
storage.connect(addr1).store(2, "New owner test")
).to.not.be.reverted;
// Old owner cannot call after transfer
await expect(
storage.store(3, "Old owner test")
).to.be.revertedWith('Storage: caller is not the owner');
});
});
describe('Event Testing', function () {
it('Should emit correct events with proper parameters', async function () {
// Test DataStored event
await expect(storage.store(100, "Test message"))
.to.emit(storage, 'DataStored')
.withArgs(100, "Test message", owner.address);
// Test MessageUpdated event
await expect(storage.store(200, "New test"))
.to.emit(storage, 'MessageUpdated')
.withArgs("Test message", "New test");
// Test OwnershipTransferred event
await expect(storage.transferOwnership(addr1.address))
.to.emit(storage, 'OwnershipTransferred')
.withArgs(owner.address, addr1.address);
});
});
describe('Gas Optimization Testing', function () {
it('Should measure gas consumption for different operations', async function () {
// Measure deployment gas
const deployGas = await helper.measureGas(async () => {
const Storage = await ethers.getContractFactory('Storage');
return await Storage.deploy(42, "Test");
});
console.log('Deployment gas:', deployGas);
// Measure store operation gas
const storeGas = await helper.measureGas(async () => {
return await storage.store(100, "Gas test message");
});
console.log('Store operation gas:', storeGas);
// Measure retrieve operation gas
const retrieveGas = await helper.measureGas(async () => {
return await storage.retrieve();
});
console.log('Retrieve operation gas:', retrieveGas);
// Measure transfer ownership gas
const transferGas = await helper.measureGas(async () => {
return await storage.transferOwnership(addr1.address);
});
console.log('Transfer ownership gas:', transferGas);
// Assertions for gas efficiency
expect(parseInt(storeGas)).to.be.lessThan(100000);
expect(parseInt(retrieveGas)).to.be.lessThan(50000);
});
});
describe('Integration Testing', function () {
it('Should work correctly with multiple accounts', async function () {
// Deploy with one account
const deployer = owner;
expect(await storage.owner()).to.equal(deployer.address);
// Transfer to another account
await storage.transferOwnership(addr1.address);
expect(await storage.owner()).to.equal(addr1.address);
// New owner performs operations
await storage.connect(addr1).store(300, "Multi-account test");
const [number, message] = await storage.retrieve();
expect(number).to.equal(300);
expect(message).to.equal("Multi-account test");
// Original account should no longer have access
await expect(
storage.store(400, "Should fail")
).to.be.revertedWith('Storage: caller is not the owner');
});
});
describe('Error Handling Testing', function () {
it('Should handle error conditions gracefully', async function () {
// Test unauthorized access
await expect(
storage.connect(addr1).store(1, "Unauthorized")
).to.be.revertedWith('Storage: caller is not the owner');
// Test invalid ownership transfer
await expect(
storage.transferOwnership(ethers.constants.AddressZero)
).to.be.revertedWith('Storage: new owner is the zero address');
});
});
describe('Fuzz Testing', function () {
it('Should handle random inputs correctly', async function () {
const testCases = [
{ number: 0, message: "" },
{ number: 1, message: "1" },
{ number: ethers.constants.MaxUint256, message: "A".repeat(1000) },
{ number: 12345, message: "Random message 🚀" },
{ number: 0, message: "Zero number test" },
];
for (const testCase of testCases) {
await storage.store(testCase.number, testCase.message);
const [number, message] = await storage.retrieve();
expect(number).to.equal(testCase.number);
expect(message).to.equal(testCase.message);
}
});
});
});
// ===== test/advanced/GasProfiler.js =====
class GasProfiler {
constructor() {
this.measurements = [];
}
async measureFunction(contract, functionName, args = [], description = '') {
const tx = await contract[functionName](...args);
const receipt = await tx.wait();
const measurement = {
description: description || functionName,
functionName,
gasUsed: receipt.gasUsed.toString(),
transactionHash: tx.hash,
timestamp: new Date().toISOString(),
};
this.measurements.push(measurement);
console.log(`⛽ ${measurement.description}: ${measurement.gasUsed} gas`);
return measurement;
}
getMeasurements() {
return this.measurements;
}
exportMeasurements() {
return {
timestamp: new Date().toISOString(),
measurements: this.measurements,
totalGasUsed: this.measurements.reduce((sum, m) => sum + parseInt(m.gasUsed), 0),
averageGasUsed: Math.round(
this.measurements.reduce((sum, m) => sum + parseInt(m.gasUsed), 0) /
this.measurements.length
),
};
}
generateReport() {
const report = this.exportMeasurements();
console.log('\n=== Gas Profiling Report ===');
console.log(`Total measurements: ${this.measurements.length}`);
console.log(`Total gas used: ${report.totalGasUsed.toLocaleString()}`);
console.log(`Average gas per operation: ${report.averageGasUsed.toLocaleString()}`);
console.log('\nDetailed measurements:');
this.measurements.forEach((m, i) => {
console.log(`${i + 1}. ${m.description}: ${parseInt(m.gasUsed).toLocaleString()} gas`);
});
return report;
}
}
// Usage in tests
describe('Gas Profiling', function () {
let storage, profiler;
beforeEach(async function () {
const Storage = await ethers.getContractFactory('Storage');
storage = await Storage.deploy(42, "Test");
await storage.deployed();
profiler = new GasProfiler();
});
it('Should profile gas usage', async function () {
await profiler.measureFunction(storage, 'store', [100, "Test 1"], "Store operation 1");
await profiler.measureFunction(storage, 'retrieve', [], "Retrieve operation");
await profiler.measureFunction(storage, 'store', [200, "Test 2"], "Store operation 2");
await profiler.measureFunction(storage, 'transferOwnership', [addr1.address], "Transfer ownership");
const report = profiler.generateReport();
// Assertions for gas efficiency
expect(report.averageGasUsed).to.be.lessThan(100000);
});
});
// ===== test/hooks/beforeEach.js =====
// Global test setup and teardown
const { expect } = require('chai');
// Test timeout helper
const testTimeout = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
};
// Clean revert helper
const cleanRevert = async (promise) => {
try {
await promise;
throw new Error('Expected revert but transaction succeeded');
} catch (error) {
expect(error.message).to.include('revert');
}
};
// Snapshot helper for EVM state
const takeSnapshot = async () => {
return await ethers.provider.send('evm_snapshot', []);
};
const revertToSnapshot = async (snapshotId) => {
await ethers.provider.send('evm_revert', [snapshotId]);
};
// Global setup
before(async function () {
this.timeout(60000); // Increase timeout for network tests
// Log test environment
const network = await ethers.provider.getNetwork();
console.log(`Testing on network: ${network.name} (Chain ID: ${network.chainId})`);
// Get accounts
const accounts = await ethers.provider.listAccounts();
console.log(`Testing with ${accounts.length} accounts`);
});
// Global teardown
after(async function () {
console.log('All tests completed');
});
💻 Truffle Deployment Scripts and Strategies javascript
🟡 intermediate
⭐⭐⭐⭐
Production-ready deployment scripts including verification, gas optimization, upgradable contracts, and multi-network deployment
⏱️ 40 min
🏷️ truffle, deployment, production, optimization
Prerequisites:
Truffle experience, Understanding of contract deployment, Gas optimization knowledge
// Truffle Deployment Scripts and Strategies
// Production-ready deployment automation
// ===== scripts/deployWithVerification.js =====
const Storage = artifacts.require("Storage");
const { expect } = require('chai');
async function main() {
console.log("🚀 Starting Deployment with Verification");
console.log("=====================================");
// Get network information
const network = await web3.eth.net.getId();
console.log(`Deploying to network: ${network}`);
// Get deployer account
const accounts = await web3.eth.getAccounts();
const deployer = accounts[0];
console.log(`Deployer address: ${deployer}`);
// Check account balance
const balance = await web3.eth.getBalance(deployer);
const balanceEth = web3.utils.fromWei(balance, 'ether');
console.log(`Account balance: ${balanceEth} ETH`);
if (parseFloat(balanceEth) < 0.1) {
console.warn("⚠️ Warning: Low account balance for deployment");
}
// Gas price estimation
const gasPrice = await web3.eth.getGasPrice();
const gasPriceGwei = web3.utils.fromWei(gasPrice, 'gwei');
console.log(`Current gas price: ${gasPriceGwei} gwei`);
try {
// Deploy contract
console.log("\n📦 Deploying Storage contract...");
const estimatedGas = await Storage.deploy.estimateGas(42, "Hello, Production!");
console.log(`Estimated gas: ${estimatedGas}`);
const storage = await Storage.new(42, "Hello, Production!", {
from: deployer,
gas: Math.floor(estimatedGas * 1.2), // 20% buffer
gasPrice: gasPrice,
});
console.log(`✅ Storage contract deployed to: ${storage.address}`);
// Wait for a few confirmations
console.log("⏳ Waiting for confirmations...");
await new Promise(resolve => setTimeout(resolve, 3000));
// Verify deployment
const [number, message] = await storage.retrieve();
console.log(`📋 Contract initialized with:`);
console.log(` Number: ${number}`);
console.log(` Message: ${message}`);
// Contract verification (if supported)
if (network !== 1337 && network !== 31337) { // Not development networks
console.log("\n🔍 Verifying contract on Etherscan...");
try {
await run('verify:verify', {
address: storage.address,
constructorArguments: [42, "Hello, Production!"],
});
console.log("✅ Contract verified on Etherscan");
} catch (error) {
console.log("❌ Contract verification failed:", error.message);
}
}
// Save deployment info
const deploymentInfo = {
network: network,
contract: "Storage",
address: storage.address,
deployer: deployer,
gasUsed: storage.deployTransaction.gasUsed,
gasPrice: gasPrice,
transactionHash: storage.deployTransaction.transactionHash,
blockNumber: storage.deployTransaction.blockNumber,
timestamp: new Date().toISOString(),
};
console.log("\n📄 Deployment Summary:");
console.log(JSON.stringify(deploymentInfo, null, 2));
return deploymentInfo;
} catch (error) {
console.error("❌ Deployment failed:", error);
throw error;
}
}
// Export for truffle exec
module.exports = function(callback) {
main()
.then(() => callback())
.catch(err => callback(err));
};
// ===== scripts/upgradeableDeployment.js =====
// OpenZeppelin upgradeable contracts deployment
const { deployProxy, upgradeProxy } = require('@openzeppelin/truffle-upgrades');
const StorageV1 = artifacts.require('StorageV1');
const StorageV2 = artifacts.require('StorageV2');
async function deployV1() {
console.log("🚀 Deploying Storage V1 (Upgradeable)");
const storage = await deployProxy(StorageV1, [42, "Hello, V1!"], {
initializer: 'initialize',
});
console.log(`Storage V1 deployed to: ${storage.address}`);
// Test initial functionality
const [number, message] = await storage.retrieve();
console.log(`Initial values - Number: ${number}, Message: ${message}`);
return storage;
}
async function upgradeToV2() {
console.log("🔄 Upgrading to Storage V2");
const existing = await StorageV1.deployed();
const upgraded = await upgradeProxy(existing.address, StorageV2);
console.log(`Storage upgraded to V2 at: ${upgraded.address}`);
// Test new functionality
await upgraded.setAdditionalData("Additional V2 feature");
const additionalData = await upgraded.getAdditionalData();
console.log(`Additional data: ${additionalData}`);
return upgraded;
}
// ===== scripts/multiNetworkDeployment.js =====
const Storage = artifacts.require("Storage");
// Network configurations
const NETWORKS = {
development: {
name: "Development",
gasLimit: 8000000,
gasPrice: 20000000000, // 20 gwei
},
goerli: {
name: "Goerli Testnet",
gasLimit: 6000000,
gasPrice: 20000000000, // 20 gwei
confirmations: 2,
},
sepolia: {
name: "Sepolia Testnet",
gasLimit: 6000000,
gasPrice: 20000000000, // 20 gwei
confirmations: 2,
},
mainnet: {
name: "Ethereum Mainnet",
gasLimit: 8000000,
gasPrice: 30000000000, // 30 gwei
confirmations: 5,
},
};
async function deployToNetwork(networkName) {
const networkConfig = NETWORKS[networkName];
if (!networkConfig) {
throw new Error(`Network ${networkName} not configured`);
}
console.log(`🌐 Deploying to ${networkConfig.name}`);
const network = await web3.eth.net.getId();
const accounts = await web3.eth.getAccounts();
const deployer = accounts[0];
console.log(`Deployer: ${deployer}`);
const balance = await web3.eth.getBalance(deployer);
console.log(`Balance: ${web3.utils.fromWei(balance, 'ether')} ETH`);
// Get current gas price for mainnet
let gasPrice = networkConfig.gasPrice;
if (networkName === 'mainnet') {
gasPrice = await web3.eth.getGasPrice();
console.log(`Current gas price: ${web3.utils.fromWei(gasPrice, 'gwei')} gwei`);
}
try {
const storage = await Storage.new(42, "Multi-network deployment", {
from: deployer,
gas: networkConfig.gasLimit,
gasPrice: gasPrice,
});
console.log(`✅ Deployed to: ${storage.address}`);
// Wait for confirmations on testnets/mainnet
if (networkConfig.confirmations > 0) {
console.log(`⏳ Waiting for ${networkConfig.confirmations} confirmations...`);
for (let i = 0; i < networkConfig.confirmations; i++) {
await new Promise(resolve => setTimeout(resolve, 15000)); // 15 seconds per block
console.log(`Confirmation ${i + 1}/${networkConfig.confirmations}`);
}
}
// Verify deployment
const [number, message] = await storage.retrieve();
console.log(`✅ Verification successful - Number: ${number}, Message: ${message}`);
return {
network: networkName,
address: storage.address,
transactionHash: storage.deployTransaction.transactionHash,
};
} catch (error) {
console.error(`❌ Deployment to ${networkName} failed:`, error);
throw error;
}
}
async function deployToAllNetworks() {
const deployments = {};
const currentNetwork = await web3.eth.net.getId();
for (const networkName of Object.keys(NETWORKS)) {
try {
// Skip if we're not on the right network
if (currentNetwork !== 1337 && networkName === 'development') continue;
const deployment = await deployToNetwork(networkName);
deployments[networkName] = deployment;
console.log(`✅ ${networkName}: ${deployment.address}`);
} catch (error) {
console.error(`❌ ${networkName}: Deployment failed`);
deployments[networkName] = { error: error.message };
}
}
console.log("\n📊 Deployment Summary:");
console.log(JSON.stringify(deployments, null, 2));
return deployments;
}
// ===== scripts/gasOptimization.js =====
const Storage = artifacts.require("Storage");
class GasOptimizer {
constructor() {
this.measurements = [];
}
async optimizeGasPrice() {
const currentGasPrice = await web3.eth.getGasPrice();
const recommendedGasPrice = Math.floor(currentGasPrice * 0.9); // 10% less
console.log(`Current gas price: ${web3.utils.fromWei(currentGasPrice, 'gwei')} gwei`);
console.log(`Recommended: ${web3.utils.fromWei(recommendedGasPrice, 'gwei')} gwei`);
return recommendedGasPrice;
}
async estimateDeploymentGas(contractName, constructorArgs) {
const Contract = artifacts.require(contractName);
try {
const estimatedGas = await Contract.deploy.estimateGas(...constructorArgs);
const bufferedGas = Math.floor(estimatedGas * 1.1); // 10% buffer
console.log(`Estimated gas for ${contractName}: ${estimatedGas}`);
console.log(`With 10% buffer: ${bufferedGas}`);
return { estimated: estimatedGas, buffered: bufferedGas };
} catch (error) {
console.error(`Gas estimation failed for ${contractName}:`, error);
return null;
}
}
async deployWithGasOptimization(contractName, constructorArgs = [], options = {}) {
console.log(`⛡️ Optimizing deployment for ${contractName}`);
// Get optimized gas price
const optimizedGasPrice = await this.optimizeGasPrice();
// Estimate gas usage
const gasEstimate = await this.estimateDeploymentGas(contractName, constructorArgs);
if (!gasEstimate) {
throw new Error(`Failed to estimate gas for ${contractName}`);
}
const Contract = artifacts.require(contractName);
// Deploy with optimized parameters
const deployOptions = {
gas: gasEstimate.buffered,
gasPrice: optimizedGasPrice,
...options,
};
console.log(`📦 Deploying ${contractName} with optimized gas settings...`);
const startTime = Date.now();
const contract = await Contract.new(...constructorArgs, deployOptions);
const endTime = Date.now();
const deploymentTime = endTime - startTime;
const deploymentCost = web3.utils.fromWei(
(gasEstimate.buffered * optimizedGasPrice).toString(),
'ether'
);
console.log(`✅ ${contractName} deployed to: ${contract.address}`);
console.log(`⏱️ Deployment time: ${deploymentTime}ms`);
console.log(`💰 Deployment cost: ${deploymentCost} ETH`);
// Store measurement
this.measurements.push({
contract: contractName,
address: contract.address,
gasUsed: contract.deployTransaction.gasUsed.toString(),
gasPrice: optimizedGasPrice.toString(),
cost: deploymentCost,
time: deploymentTime,
timestamp: new Date().toISOString(),
});
return contract;
}
getOptimizationReport() {
const totalCost = this.measurements.reduce((sum, m) => sum + parseFloat(m.cost), 0);
const avgGasPrice = this.measurements.reduce((sum, m) =>
sum + parseInt(m.gasPrice), 0) / this.measurements.length;
return {
deployments: this.measurements.length,
totalCost: totalCost.toFixed(6),
averageGasPrice: web3.utils.fromWei(avgGasPrice.toFixed(0), 'gwei'),
deployments: this.measurements,
};
}
}
// Usage example
async function deployWithOptimization() {
const optimizer = new GasOptimizer();
// Deploy multiple contracts with optimization
await optimizer.deployWithGasOptimization('Storage', [100, "Gas optimized"]);
const report = optimizer.getOptimizationReport();
console.log("\n📊 Gas Optimization Report:");
console.log(JSON.stringify(report, null, 2));
}
// Export for truffle exec
module.exports = function(callback) {
deployWithOptimization()
.then(() => callback())
.catch(err => callback(err));
};
// ===== scripts/deploymentManager.js =====
class DeploymentManager {
constructor() {
this.deployments = new Map();
this.dependencies = new Map();
}
addDependency(contractName, dependencyNames = []) {
this.dependencies.set(contractName, dependencyNames);
}
async deploySequential() {
console.log("🔗 Starting sequential deployment");
const deployedContracts = {};
// Simple dependency resolution (would need more complex algorithm for real use)
for (const [contractName, dependencies] of this.dependencies) {
console.log(`\n📦 Deploying ${contractName}`);
// Check if dependencies are deployed
for (const dep of dependencies) {
if (!deployedContracts[dep]) {
throw new Error(`Dependency ${dep} not deployed for ${contractName}`);
}
}
// Deploy contract (simplified example)
const Contract = artifacts.require(contractName);
const contract = await Contract.new();
deployedContracts[contractName] = contract;
this.deployments.set(contractName, {
address: contract.address,
transactionHash: contract.deployTransaction.transactionHash,
});
console.log(`✅ ${contractName} deployed to: ${contract.address}`);
}
return deployedContracts;
}
async verifyDeployments() {
console.log("\n🔍 Verifying all deployments");
for (const [contractName, deployment] of this.deployments) {
try {
const Contract = artifacts.require(contractName);
const contract = await Contract.at(deployment.address);
// Basic verification - would need contract-specific tests
console.log(`✅ ${contractName} at ${deployment.address} is verified`);
} catch (error) {
console.error(`❌ ${contractName} verification failed:`, error.message);
}
}
}
exportDeploymentManifest() {
const manifest = {
version: "1.0.0",
timestamp: new Date().toISOString(),
network: await web3.eth.net.getId(),
deployments: Object.fromEntries(this.deployments),
dependencies: Object.fromEntries(this.dependencies),
};
console.log("\n📄 Deployment Manifest:");
console.log(JSON.stringify(manifest, null, 2));
return manifest;
}
}
// Usage example
async function manageDeployment() {
const manager = new DeploymentManager();
// Define deployment dependencies
manager.addDependency('Storage', []);
manager.addDependency('StorageManager', ['Storage']);
manager.addDependency('StorageFactory', ['Storage', 'StorageManager']);
// Execute deployment
await manager.deploySequential();
// Verify deployments
await manager.verifyDeployments();
// Export manifest
manager.exportDeploymentManifest();
}
// Export for truffle exec
module.exports = function(callback) {
manageDeployment()
.then(() => callback())
.catch(err => callback(err));
};