Files
explorer-monorepo/scripts/force-deploy-link.sh

231 lines
8.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Force Deploy LINK Token - All Methods
# Tries multiple approaches to force forge to broadcast
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$PROJECT_ROOT/.env" 2>/dev/null || source "$PROJECT_ROOT/../.env" 2>/dev/null || true
RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}"
FORCE_GAS="${1:-5000000000}" # Default 5 gwei (increased for better confirmation)
# Export variables to ensure they're available in subshells
export RPC_URL
export PRIVATE_KEY
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ FORCE DEPLOY LINK TOKEN - ALL METHODS ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "RPC: $RPC_URL"
echo "Forced Gas: $(echo "scale=2; $FORCE_GAS / 1000000000" | bc) gwei"
echo ""
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
cd "$TEMP_DIR"
forge init --no-git --force . > /dev/null 2>&1
cat > src/MockLinkToken.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract MockLinkToken {
string public name = "Chainlink Token";
string public symbol = "LINK";
uint8 public decimals = 18;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 public totalSupply;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function mint(address to, uint256 amount) external {
balanceOf[to] += amount;
totalSupply += amount;
emit Transfer(address(0), to, amount);
}
function transfer(address to, uint256 amount) external returns (bool) {
require(balanceOf[msg.sender] >= amount, "insufficient balance");
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) external returns (bool) {
require(balanceOf[from] >= amount, "insufficient balance");
require(allowance[from][msg.sender] >= amount, "insufficient allowance");
balanceOf[from] -= amount;
balanceOf[to] += amount;
allowance[from][msg.sender] -= amount;
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
}
EOF
cat > script/DeployLink.s.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {Script, console} from "forge-std/Script.sol";
import {MockLinkToken} from "../src/MockLinkToken.sol";
contract DeployLink is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
MockLinkToken link = new MockLinkToken();
console.log("LINK_TOKEN_ADDRESS", address(link));
link.mint(vm.addr(deployerPrivateKey), 1_000_000e18);
vm.stopBroadcast();
}
}
EOF
cat > foundry.toml << EOF
[profile.default]
gas_price = $FORCE_GAS
legacy = true
[rpc_endpoints]
chain138 = "$RPC_URL"
EOF
export PRIVATE_KEY
echo "=== Method 1: forge script with --broadcast --skip-simulation ==="
DEPLOY_OUTPUT=$(forge script script/DeployLink.s.sol:DeployLink \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY" \
--broadcast \
--skip-simulation \
--gas-price "$FORCE_GAS" \
--legacy \
-vv 2>&1) || true
LINK_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "LINK_TOKEN_ADDRESS[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}' || echo "")
# Verify broadcast actually happened
if echo "$DEPLOY_OUTPUT" | grep -qi "dry run\|simulation only\|not broadcasting"; then
echo "⚠️ WARNING: Script may have run in dry-run mode despite --broadcast flag"
echo "Output contains dry-run indicators"
LINK_ADDRESS="" # Clear address if dry-run detected
fi
# Verify deployment actually happened on-chain (not just simulation)
if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
echo "Address extracted: $LINK_ADDRESS"
echo "Verifying on-chain deployment (waiting 15 seconds)..."
sleep 15 # Wait for transaction to propagate
CODE=$(cast code "$LINK_ADDRESS" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
echo "✓✓✓ SUCCESS! LINK deployed and CONFIRMED: $LINK_ADDRESS"
echo "$LINK_ADDRESS" > /tmp/link_address.txt
exit 0
else
echo "⚠️ Address extracted but contract not yet on-chain"
echo "This may be from simulation. Trying Method 2..."
LINK_ADDRESS="" # Clear to force Method 2
fi
fi
echo "Method 1 failed, trying Method 2..."
echo ""
echo "=== Method 2: forge create with explicit gas and verify ==="
# Ensure RPC_URL is set and not empty
if [ -z "$RPC_URL" ]; then
echo "ERROR: RPC_URL is not set!"
RPC_URL="http://192.168.11.250:8545"
echo "Using default: $RPC_URL"
export RPC_URL
fi
# Ensure PRIVATE_KEY is set
if [ -z "$PRIVATE_KEY" ]; then
echo "ERROR: PRIVATE_KEY is not set!"
echo "Cannot deploy without private key"
exit 1
fi
echo "Deploying with forge create (this may take a moment)..."
DEPLOY_OUTPUT=$(forge create src/MockLinkToken.sol:MockLinkToken \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY" \
--gas-price "$FORCE_GAS" \
--gas-limit 10000000 \
--legacy \
--broadcast \
2>&1) || true
echo "Deployment output:"
echo "$DEPLOY_OUTPUT" | head -20
LINK_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "Deployed to: 0x[0-9a-fA-F]{40}" | awk '{print $3}' || echo "")
# Also check for errors
if echo "$DEPLOY_OUTPUT" | grep -qi "error\|fail\|revert"; then
echo "⚠️ Deployment errors detected in output above"
fi
if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
echo "✓✓✓ SUCCESS! LINK deployed: $LINK_ADDRESS"
echo "$LINK_ADDRESS" > /tmp/link_address.txt
exit 0
fi
echo "Method 2 failed, trying Method 3..."
echo ""
echo "=== Method 3: Get bytecode and deploy via cast send ==="
forge build > /dev/null 2>&1
BYTECODE=$(cat out/MockLinkToken.sol/MockLinkToken.json | jq -r '.bytecode.object' 2>/dev/null || echo "")
if [ -n "$BYTECODE" ] && [ "$BYTECODE" != "null" ] && [ ${#BYTECODE} -gt 100 ]; then
ACCOUNT=$(cast wallet address "$PRIVATE_KEY")
NONCE=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL")
echo "Deploying via cast send..."
TX_OUTPUT=$(timeout 60 cast send --create "$BYTECODE" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY" \
--gas-price "$FORCE_GAS" \
--nonce "$NONCE" \
--legacy \
2>&1) || true
LINK_ADDRESS=$(echo "$TX_OUTPUT" | grep -oE "contractAddress[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}' || echo "")
if [ -z "$LINK_ADDRESS" ]; then
LINK_ADDRESS=$(echo "$TX_OUTPUT" | grep -oE "0x[0-9a-fA-F]{40}" | head -1 || echo "")
fi
if [ -n "$LINK_ADDRESS" ] && [ ${#LINK_ADDRESS} -eq 42 ]; then
echo "✓✓✓ SUCCESS! LINK deployed: $LINK_ADDRESS"
echo "$LINK_ADDRESS" > /tmp/link_address.txt
exit 0
fi
fi
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ ALL METHODS FAILED ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "Possible issues:"
echo "1. Network RPC not responding"
echo "2. Stuck transaction at nonce 37 blocking new transactions"
echo "3. Network requires different gas configuration"
echo "4. Private key or account issues"
echo ""
echo "Recommendation: Use Remix IDE to deploy"
echo " https://remix.ethereum.org"
echo ""
exit 1