From f7d20a1b5cf3da29388985c1c2cf5ff0c5c3c6a3 Mon Sep 17 00:00:00 2001 From: "@therightchoyce" Date: Mon, 25 Jul 2022 07:06:55 -0400 Subject: [PATCH 1/2] Add example deploy script --- packages/contracts/.env | 1 + packages/contracts/.gitignore | 7 ++++ packages/contracts/package.json | 4 +-- packages/contracts/script/Deploy.s.sol | 47 ++++++++++++++++++++++++++ packages/contracts/script/Deploy.sh | 20 +++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 packages/contracts/script/Deploy.s.sol create mode 100755 packages/contracts/script/Deploy.sh diff --git a/packages/contracts/.env b/packages/contracts/.env index c698147..a7aeb47 100644 --- a/packages/contracts/.env +++ b/packages/contracts/.env @@ -1,5 +1,6 @@ DEPLOYER= DEPLOYER_PRIVATE_KEY= +CHAIN_ID=5 CHAIN_NAME=goerli RPC_URL= ETHERSCAN_API_KEY= diff --git a/packages/contracts/.gitignore b/packages/contracts/.gitignore index a221ed3..330a052 100644 --- a/packages/contracts/.gitignore +++ b/packages/contracts/.gitignore @@ -15,3 +15,10 @@ out/console2.sol/**/*.abi.json # Why do these globs make this so hard? .env.* + +# Ignore scripting output +out/*.s.sol/**/* + +# Ignore broadcast outputs +broadcast/* + diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 12e145a..c970aad 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -11,7 +11,7 @@ "clean": "rm -rf types", "build": "pnpm clean && pnpm compile && pnpm types", "compile": "forge build --force", - "types": "typechain --target ethers-v5 \"out/**/!(*.t|test|Test|Script|Vm|console|console2).sol/!(*.abi).json\" --out-dir types && tsc", + "types": "typechain --target ethers-v5 \"out/**/!(*.s|*.t|test|Test|Script|Vm|console|console2).sol/!(*.abi).json\" --out-dir types && tsc", "prettier": "pnpm lint:fix && prettier --write \"src/**/*.sol\" --plugin=prettier-plugin-solidity", "lint": "solhint --config ../../.solhint.json \"src/**/*.sol\"", "lint:fix": "pnpm lint --fix" @@ -28,4 +28,4 @@ "typechain": "^8.0.0", "typescript": "^4.5.5" } -} +} \ No newline at end of file diff --git a/packages/contracts/script/Deploy.s.sol b/packages/contracts/script/Deploy.s.sol new file mode 100644 index 0000000..8040362 --- /dev/null +++ b/packages/contracts/script/Deploy.s.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.9; + +import "forge-std/Script.sol"; + +import {ExampleNFT} from "../src/ExampleNFT.sol"; + +/// @dev This is best run by calling "$ ./scripts/Deploy.sh" from the root of the "contracts" app! + +contract Deploy is Script { + /// @dev Deployable contracts + ExampleNFT public exampleNFT; + + // Renderer public renderer; -- uncomment if you have a renderer contract + + /// @notice Allows for easily loading ENV vars + /// @dev The Solenv include path is relative to the project root, or whereever you run the shell command from + // function setUp() external { + // Solenv.config("./packages/contracts/.env.local"); + // } + + function deployTokenContract() public { + /// @dev Deploy the base contract with any inputs + exampleNFT = new ExampleNFT(); + } + + function deployRendererContract() public { + /// @dev If you setup a renderer contract, easily deploy it alongside the base contract + // renderer = new Renderer( + // address(exampleNFT), + // ); + } + + function run() public { + vm.startBroadcast(); + + deployTokenContract(); + // deployRendererContract(); + + /// @dev Update token contract to point to the renderer + // exampleNFT.setRenderer(renderer); + + vm.stopBroadcast(); + + console.log("Deployed contract to ==> ", address(exampleNFT)); + } +} diff --git a/packages/contracts/script/Deploy.sh b/packages/contracts/script/Deploy.sh new file mode 100755 index 0000000..6fa40fc --- /dev/null +++ b/packages/contracts/script/Deploy.sh @@ -0,0 +1,20 @@ +# Expects jq to be installed + +# Run this from the root of the contract dir!!! +# To test this deploy without actually deploy to a public network, remove the "broadcast" flag +# If the verification fails, run this script again and remove the "broadcast" flag +# If you are using Solenv, you must add the "--ffi" flag +# if you get a permission denied error, ensure there is execute permisions on the file.. 755 or similiar + +source .env + +if [ -z "$CHAIN_ID" ]; then + echo "CHAIN_ID is not set" + exit 1 +fi + +forge script script/Deploy.s.sol:Deploy -vvvv --chain-id $CHAIN_ID \ + --rpc-url $RPC_URL \ + --private-key $DEPLOYER_PRIVATE_KEY \ + --broadcast \ + --verify --etherscan-api-key $ETHERSCAN_API_KEY \ No newline at end of file From 65e26de9eec4c82d57c0b4b13c9a76ccd6d2cfe2 Mon Sep 17 00:00:00 2001 From: "@therightchoyce" Date: Tue, 26 Jul 2022 17:00:32 -0400 Subject: [PATCH 2/2] Add shell script to copy the broadcast output to the deploys folder --- packages/contracts/script/Deploy.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/contracts/script/Deploy.sh b/packages/contracts/script/Deploy.sh index 6fa40fc..049d49b 100755 --- a/packages/contracts/script/Deploy.sh +++ b/packages/contracts/script/Deploy.sh @@ -13,8 +13,15 @@ if [ -z "$CHAIN_ID" ]; then exit 1 fi +CONTRACT_NAME="ExampleNFT" +DEPLOY_OUTPUT="deploys/$CHAIN_NAME/$CONTRACT_NAME.json" +mkdir -p $(dirname $DEPLOY_OUTPUT) + forge script script/Deploy.s.sol:Deploy -vvvv --chain-id $CHAIN_ID \ --rpc-url $RPC_URL \ --private-key $DEPLOYER_PRIVATE_KEY \ --broadcast \ - --verify --etherscan-api-key $ETHERSCAN_API_KEY \ No newline at end of file + --verify --etherscan-api-key $ETHERSCAN_API_KEY + +# Transaction 0 should be the first transaction you broadcast +jq '{deployedTo: .transactions[0].contractAddress, deployer: .transactions[0].tx.from, transactionHash: .transactions[0].hash}' ./broadcast/Deploy.s.sol/$CHAIN_ID/run-latest.json > $DEPLOY_OUTPUT