Working Foundry
This commit is contained in:
parent
90c8985375
commit
df55a62430
1
.gitignore
vendored
1
.gitignore
vendored
@ -48,3 +48,4 @@ profile.cov
|
||||
|
||||
**/yarn-error.log
|
||||
foundry/deployments/local-private-network/geth-linux-amd64
|
||||
foundry/projects/local-private-network/geth-linux-amd64
|
||||
|
59
foundry/README.md
Normal file
59
foundry/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Foundry README
|
||||
|
||||
# Overview
|
||||
|
||||
This document will go through the steps needed to test using Foundry. Currently, we use Foundry in the following capacity.
|
||||
|
||||
1. Create a private network with our internal version of Geth.
|
||||
2. Deploy a smart contract to the private network.
|
||||
3. Test the smart contract on the private network.
|
||||
4. Create a transaction on the private network.
|
||||
|
||||
# Steps
|
||||
|
||||
The steps to create a new project are as follows.
|
||||
|
||||
## 1. Creating New Project
|
||||
|
||||
1. `cd foundry/projects`.
|
||||
2. Create a directory that captures your project: `mkdir local-private-network; cd local-private-network`.
|
||||
3. Create a [new foundry project](https://onbjerg.github.io/foundry-book/forge/creating-a-new-project.html): `forge init stateful`.
|
||||
4. Follow the foundry [documentation](https://onbjerg.github.io/foundry-book/forge/tests.html) for writing smart contract tests.
|
||||
|
||||
## 2. Deployments
|
||||
|
||||
You can choose to have custom deployments for your workflow. However, it is recommended to utilize Docker.
|
||||
|
||||
# Existing Projects
|
||||
|
||||
Below, you can find existing projects and their descriptions.
|
||||
|
||||
## `local-private-network`
|
||||
|
||||
The purpose of this project is as follows:
|
||||
|
||||
1. Compile the geth from the local source.
|
||||
2. Build a docker container with `ipld-eth-db` and another container for the `local-private-network`.
|
||||
3. Run the compiled version of geth.
|
||||
4. Deploy a smart contract to the private blockchain.
|
||||
5. Trigger a transaction on the newly deployed smart contract.
|
||||
|
||||
## Using This Project
|
||||
|
||||
If you want to test your local geth code, do the following:
|
||||
|
||||
1. cd `foundry/projects/local-private-network`.
|
||||
2. `./wrapper.sh` - This script will do all the heavy lifting for you.
|
||||
3. Keep an eye out for the outputs from the docker container.
|
||||
4. Enter the docker container and do as you please.
|
||||
5. If you want to change your geth code, you will have to run `./wrapper.sh` for subsequent runs.
|
||||
6. If you do not change your geth code, you have to run: `docker-compose up --build`.
|
||||
|
||||
### Key Notes:
|
||||
|
||||
- The command to [deploy](https://onbjerg.github.io/foundry-book/forge/deploying.html) the smart contract is: `forge create --keystore $ETH_KEYSTORE_FILE --rpc-url [http://127.0.0.1:8545](http://127.0.0.1:8545/) --constructor-args 1 --password "" --legacy /root/stateful/src/Stateful.sol:Stateful`
|
||||
- The command to interact create a [transaction](https://onbjerg.github.io/foundry-book/reference/cast.html) is: `cast send --keystore $ETH_KEYSTORE_FILE --rpc-url [http://127.0.0.1:8545](http://127.0.0.1:8545/) --password "" --legacy $DEPLOYED_ADDRESS "off()"`
|
||||
- The `Dockerfile` compiles `cast` and `forge`.
|
||||
- The `foundry/projects/local-private-network/deploy-local-network.sh` file does most heavy lifting. It spins up geth and triggers various events.
|
||||
- The `foundry/projects/local-private-network/start-private-network.sh` file triggers `deploy-local-network.sh`. This file runs all the tests.
|
||||
- The `geth` node will stay running even after the tests are terminated.
|
@ -1,21 +0,0 @@
|
||||
FROM frolvlad/alpine-bash
|
||||
|
||||
RUN apk update ; apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted ca-certificates curl bash git jshon jq
|
||||
|
||||
#USER guest
|
||||
WORKDIR /root
|
||||
|
||||
# copy all files
|
||||
ADD ./deploy-local-network.sh .
|
||||
ADD ./geth-linux-amd64 /bin/geth
|
||||
ADD ./start-private-network.sh .
|
||||
|
||||
RUN curl -L https://foundry.paradigm.xyz | bash; \
|
||||
/bin/bash -c 'source $HOME/.bashrc'; \
|
||||
/root/.foundry/bin/foundryup
|
||||
|
||||
RUN chmod +x /bin/geth
|
||||
|
||||
EXPOSE 8545
|
||||
EXPOSE 8546
|
||||
ENTRYPOINT ["./start-private-network.sh"]
|
@ -1,36 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
# clean up
|
||||
trap 'killall geth && rm -rf "$TMPDIR"' EXIT
|
||||
trap "exit 1" SIGINT SIGTERM
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
/bin/bash deploy-local-network.sh --rpc-addr 0.0.0.0 --chain-id 4 --db-user $DB_USER --db-password $DB_PASSWORD --db-name $DB_NAME \
|
||||
--db-host $DB_HOST --db-port $DB_PORT --db-write $DB_WRITE --dir "$TMPDIR" --address $ADDRESS \
|
||||
--db-type $DB_TYPE --db-driver $DB_DRIVER --db-waitforsync $DB_WAIT_FOR_SYNC &
|
||||
echo "sleeping 90 sec"
|
||||
# give it a few secs to start up
|
||||
sleep 90
|
||||
|
||||
#read -r ACC BAL <<< "$(seth ls --keystore "$TMPDIR/8545/keystore")"
|
||||
#echo $ACC
|
||||
#echo $BAL
|
||||
#
|
||||
#
|
||||
## Deploy a contract:
|
||||
#solc --bin --bin-runtime docker/stateful.sol -o "$TMPDIR"
|
||||
#A_ADDR=$(seth send --create "$(<"$TMPDIR"/A.bin)" "constructor(uint y)" 1 --from "$ACC" --keystore "$TMPDIR"/8545/keystore --password /dev/null --gas 0xfffffff)
|
||||
#
|
||||
#echo $A_ADDR
|
||||
#
|
||||
## Call transaction
|
||||
#
|
||||
#TX=$(seth send "$A_ADDR" "off()" --gas 0xffff --password /dev/null --from "$ACC" --keystore "$TMPDIR"/8545/keystore --async)
|
||||
#echo $TX
|
||||
#RESULT=$(seth run-tx "$TX")
|
||||
#echo $RESULT
|
||||
|
||||
# Run forever
|
||||
tail -f /dev/null
|
37
foundry/projects/local-private-network/Dockerfile
Normal file
37
foundry/projects/local-private-network/Dockerfile
Normal file
@ -0,0 +1,37 @@
|
||||
FROM frolvlad/alpine-bash
|
||||
|
||||
# copy all files
|
||||
|
||||
RUN apk update ; apk add --no-cache --allow-untrusted ca-certificates curl bash git jq
|
||||
|
||||
ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
|
||||
ENV GLIBC_VERSION=2.35-r0
|
||||
|
||||
RUN set -ex && \
|
||||
apk --update add libstdc++ curl ca-certificates && \
|
||||
for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
|
||||
do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
|
||||
apk add --allow-untrusted /tmp/*.apk ; \
|
||||
rm -v /tmp/*.apk ;/usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
|
||||
|
||||
RUN apk add gcompat; echo "Sorry"
|
||||
WORKDIR /root
|
||||
|
||||
COPY stateful ./stateful
|
||||
ADD ./start-private-network.sh .
|
||||
ADD ./deploy-local-network.sh .
|
||||
ADD ../../geth-linux-amd64 /bin/geth
|
||||
|
||||
RUN curl -L https://foundry.paradigm.xyz | bash; \
|
||||
/bin/bash -c 'source $HOME/.bashrc'; \
|
||||
/root/.foundry/bin/foundryup
|
||||
|
||||
ENV PATH "$PATH:/root/.foundry/bin/"
|
||||
RUN echo "export PATH=${PATH}" >> $HOME/.bashrc;
|
||||
|
||||
RUN chmod +x /bin/geth
|
||||
|
||||
|
||||
EXPOSE 8545
|
||||
EXPOSE 8546
|
||||
ENTRYPOINT ["./start-private-network.sh"]
|
@ -9,8 +9,8 @@ start_path=$(pwd)
|
||||
cd ../../../
|
||||
echo -e "${GREEN}Building geth!${NC}"
|
||||
docker build -t vulcanize/go-ethereum -f Dockerfile .
|
||||
docker run --rm --entrypoint cat vulcanize/go-ethereum /usr/local/bin/geth > foundry/deployments/local-private-network/geth-linux-amd64
|
||||
chmod +x foundry/deployments/local-private-network/geth-linux-amd64
|
||||
docker run --rm --entrypoint cat vulcanize/go-ethereum /usr/local/bin/geth > foundry/projects/local-private-network/geth-linux-amd64
|
||||
chmod +x foundry/projects/local-private-network/geth-linux-amd64
|
||||
|
||||
echo -e "${GREEN}geth build complete!${NC}"
|
||||
cd $start_path
|
@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
OPTS="dapp testnet [<options>] <args>...
|
||||
dapp testnet --help
|
||||
OPTS="./deploy-local-network.sh [<options>] <args>...
|
||||
./deploy-local-network.sh --help
|
||||
--
|
||||
db-user=name database user
|
||||
db-password=password database password
|
||||
@ -184,4 +184,4 @@ printf 'dapp-testnet: Account: %s (default)\n' "${address[0]}" >&2
|
||||
|
||||
[[ "${#address[@]}" -gt 1 ]] && printf 'dapp-testnet: Account: %s\n' "${address[@]:1}" >&2
|
||||
|
||||
while true; do sleep 3600; done
|
||||
while true; do sleep 3600; done
|
50
foundry/projects/local-private-network/start-private-network.sh
Executable file
50
foundry/projects/local-private-network/start-private-network.sh
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
# clean up
|
||||
trap 'killall geth && rm -rf "$TMPDIR"' EXIT
|
||||
trap "exit 1" SIGINT SIGTERM
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
/bin/bash deploy-local-network.sh --rpc-addr 0.0.0.0 --chain-id 4 --db-user $DB_USER --db-password $DB_PASSWORD --db-name $DB_NAME \
|
||||
--db-host $DB_HOST --db-port $DB_PORT --db-write $DB_WRITE --dir "$TMPDIR" --address $ADDRESS \
|
||||
--db-type $DB_TYPE --db-driver $DB_DRIVER --db-waitforsync $DB_WAIT_FOR_SYNC &
|
||||
echo "sleeping 90 sec"
|
||||
# give it a few secs to start up
|
||||
sleep 90
|
||||
|
||||
# Run tests
|
||||
cd stateful
|
||||
forge build
|
||||
forge test --fork-url http://localhost:8545
|
||||
|
||||
# Deploy contracts
|
||||
|
||||
ETH_KEYSTORE_FILES=()
|
||||
echo "ETH KEYSTORE: $TMPDIR/8545/keystore"
|
||||
for entry in `ls $TMPDIR/8545/keystore`; do
|
||||
ETH_KEYSTORE_FILES+=("${TMPDIR}/8545/keystore/${entry}")
|
||||
done
|
||||
|
||||
echo "ETH_KEYSTORE_FILES: $ETH_KEYSTORE_FILES"
|
||||
ETH_KEYSTORE_FILE=${ETH_KEYSTORE_FILES[0]}
|
||||
|
||||
if [ "${#ETH_KEYSTORE_FILES[@]}" -eq 1 ]; then
|
||||
echo "Only one KEYSTORE"
|
||||
else
|
||||
echo "WARNING: More than one file in keystore: ${ETH_KEYSTORE_FILES}"
|
||||
fi
|
||||
|
||||
DEPLOYED_ADDRESS=$(forge create --keystore $ETH_KEYSTORE_FILE --rpc-url http://127.0.0.1:8545 --constructor-args 1 --password "" --legacy /root/stateful/src/Stateful.sol:Stateful | grep "Deployed to:" | cut -d " " -f 3)
|
||||
echo "Contract has been deployed to: $DEPLOYED_ADDRESS"
|
||||
|
||||
# Call a transaction
|
||||
|
||||
TX_OUT=$(cast send --keystore $ETH_KEYSTORE_FILE --rpc-url http://127.0.0.1:8545 --password "" --legacy $DEPLOYED_ADDRESS "off()")
|
||||
|
||||
echo "TX OUTPUT: $TX_OUT"
|
||||
|
||||
|
||||
# Run forever
|
||||
tail -f /dev/null
|
@ -0,0 +1,7 @@
|
||||
[default]
|
||||
src = 'src'
|
||||
out = 'out'
|
||||
libs = ['lib']
|
||||
remappings = ['ds-test/=lib/ds-test/src/']
|
||||
|
||||
# See more config options https://github.com/gakonst/foundry/tree/master/config
|
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity 0.8.10;
|
||||
|
||||
contract Stateful {
|
||||
uint x;
|
||||
|
||||
constructor(uint y) public {
|
||||
x = y;
|
||||
}
|
||||
|
||||
function off() public {
|
||||
require(x == 1);
|
||||
x = 0;
|
||||
}
|
||||
|
||||
function on() public {
|
||||
require(x == 0);
|
||||
x = 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity 0.8.10;
|
||||
|
||||
import "ds-test/test.sol";
|
||||
import {Stateful} from "../Stateful.sol";
|
||||
|
||||
contract StatefulTest is DSTest {
|
||||
Stateful contractA;
|
||||
//contractA A;
|
||||
uint x;
|
||||
function setUp() public {
|
||||
x = 1;
|
||||
contractA = new Stateful(x);
|
||||
}
|
||||
|
||||
function testExample() public {
|
||||
contractA.off();
|
||||
}
|
||||
}
|
7
foundry/projects/local-private-network/wrapper.sh
Executable file
7
foundry/projects/local-private-network/wrapper.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# This script will run everthing for you. Sit back and enjoy they show.
|
||||
|
||||
set -e
|
||||
|
||||
./compile-geth.sh
|
||||
docker-compose up --build
|
Loading…
Reference in New Issue
Block a user