forge-deploy 0.0.7

A cli that goes along a set of soldity contract to keep track of deployments by name in forge.
forge-deploy-0.0.7 is not a library.

forge-deploy

A cli and associated contracts to keep track of deployments by name and reuse them in solidity.

It tries to keep compatibility with hardhat-deploy as far as possible (work in progress).

Features

  • generate type-safe deployment function for forge contracts. no need to pass in string of text and hope the abi encoded args are in the correct order.
  • save deployments in json file (based on hardhat-deploy schema)

How to use

  1. have a forge project and cd into it

    mkdir my-project;
    cd my-project;
    forge init;
    
  2. add the forge package

    forge install wighawag/forge-deploy;
    
  3. install the cli tool locally as the tool is likely to evolve rapidly

    cargo install --version 0.0.7 --root . forge-deploy;
    

    This will install version 0.0.7 in the bin folder,

    You can then execute it via

    ./bin/forge-deploy <command> 
    

    you can also compile it directly from the lib/forge-deploy/ folder.

  4. add to .gitignore the generated file + the binary we just installed

    cat >> .gitignore <<EOF
    
    # forge-deploy
    /generated
    /deployments/localhost
    /deployments/31337
    
    # forge-deploy cli binary
    /.crates2.json
    /.crates.toml
    /bin
    EOF
    
  5. generate the type-safe deployment functions

    ./bin/forge-deploy gen-deployer;
    
  6. add a deploy script

    replace the file script/Counter.s.sol with this content:

    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.13;
    
    import "forge-deploy/DeployScript.sol";
    import "generated/deployer/DeployerFunctions.g.sol";
    
    contract CounterScript is DeployScript {
        using DeployerFunctions for Deployer;
    
        function deploy() override internal {
            deployer.deploy_Counter("MyCounter");
        }
    }
    
  7. you also need to allow forge to read and write on certain paths by editing foundry.toml:

    echo '\nfs_permissions = [{ access = "read", path = "./deployments"}, { access = "read", path = "./out"}, { access = "read", path = "./contexts.json"}]' >> foundry.toml;
    
  8. You can now execute the script via forge script

    Note that you need to execute ./bin/forge-deploy sync directly afterward

    For example:

    forge script script/Counter.s.sol --rpc-url $RPC_URL --broadcast --private-key $DEPLOYER_PRIVATE_KEY -v && ./bin/forge-deploy sync;
    

    with anvil and default account

    forge script script/Counter.s.sol --rpc-url http://localhost:8545 --broadcast --private-key ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -v && ./bin/forge-deploy sync;
    
  9. If you use just, see example in examples/basic with its own justfile

Quick Start

Get anvil started somewhere:

anvil;

then copy and execute this and see the result

mkdir my-forge-deploy-project;
cd my-forge-deploy-project;
forge init;
forge install wighawag/forge-deploy;
cargo install --version 0.0.7 --root . forge-deploy;
echo '\nfs_permissions = [{ access = "read", path = "./deployments"}, { access = "read", path = "./out"}, { access = "read", path = "./contexts.json"}]' >> foundry.toml;
cat >> .gitignore <<EOF

# forge-deploy
/generated
/deployments/localhost
/deployments/31337

# forge-deploy cli binary
/.crates2.json
/.crates.toml
/bin
EOF
./bin/forge-deploy gen-deployer;
cat > script/Counter.s.sol <<EOF
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-deploy/DeployScript.sol";
import "generated/deployer/DeployerFunctions.g.sol";

contract CounterScript is DeployScript {
    using DeployerFunctions for Deployer;

    function deploy() override internal {
        deployer.deploy_Counter("MyCounter");
    }
}
EOF
forge script script/Counter.s.sol --rpc-url http://localhost:8545 --broadcast --private-key ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -v && ./bin/forge-deploy sync;

More info

Note that the generated solidity is optional.

You can instead simply use the default deploy function

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-deploy/DeployScript.sol";
import "forge-deploy/DefaultDeployerFunction.sol";

contract CounterScript is DeployScript {
    using DefaultDeployerFunction for Deployer;

    function deploy() override internal {
        .deploy("MyCounter2", "Counter.sol:Counter", "", DeployOptions({
            deterministic: 0,
            proxyOnTag: "",
            proxyOwner: address(0)
        }));
    }
}