diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index acbf6cf..1d47b4a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ on: jobs: build: name: Lint, build and test - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -49,40 +49,3 @@ jobs: - name: Test run: make backend-test - - deploy-to-dockerhub: - name: Build and push Docker images - needs: build - if: github.event_name == 'push' - runs-on: ubuntu-18.04 - steps: - - uses: docker/setup-buildx-action@v2 - - uses: actions/setup-go@v2 - with: - go-version: "1.17" - - uses: actions/setup-node@v2 - with: - node-version: "10" - - uses: arduino/setup-protoc@v1 - with: - version: "3.19" - - - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - uses: actions/checkout@v3 - - - run: make configs webapp-proto - - - uses: docker/build-push-action@v4 - with: - context: backend - push: true - tags: c4dt/service-stainless-backend:latest - - uses: docker/build-push-action@v4 - with: - context: webapp - push: true - tags: c4dt/service-stainless-backend:latest diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..7ff4bd4 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,44 @@ +name: Build docker +on: + push: + +jobs: + build-and-push-image: + runs-on: ubuntu-22.04 + permissions: + contents: write + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Log into registry ${{ env.REGISTRY }} + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v3 + with: + node-version: 14 + + - name: Build requirements + run: | + sudo apt install -y protobuf-compiler + make configs webapp-build + + - name: Build and push Docker image for nodes + uses: docker/build-push-action@v4 + with: + context: backend + file: backend/Dockerfile.persistent + push: true + tags: ghcr.io/c4dt/service-stainless-persistent:latest + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: webapp + push: true + tags: ghcr.io/c4dt/service-stainless-webapp:latest diff --git a/Makefile b/Makefile index d7905d4..5503ddd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .DEFAULT_GOAL := all services: - git clone -b stainless https://github.com/c4dt/services.git + git clone -b stainless_archive https://github.com/c4dt/services.git services/%: | services @: nothing @@ -32,24 +32,24 @@ $Sbackend-docker-build: | $Sexternal-deps $Dbackend/build/bevmadmin: | $Dbackend/build cd $Dbackend/cothority/bevm/bevmadmin && GO111MODULE=on go build -o ../../../build/$(@F) -$Dbackend/build/ident_bevm: $Dbackend/build/bcadmin $Dbackend/build/conodes.toml $Dbackend/build/bevmadmin $Dbackend/build/ident - rm -rf $Dbackend/build/bevm_admin $Dbackend/build/bevm_user +$Dbackend/configs/ident_bevm: $Dbackend/build/bcadmin $Dbackend/configs/conodes.toml $Dbackend/build/bevmadmin $Dbackend/configs/ident + rm -rf $Dbackend/configs/bevm_admin $Dbackend/configs/bevm_user $(call $Swith-conodes, \ - bevm_admin_key=$$( $< --config $Dbackend/build/bevm_admin key ) ; \ - bevm_user_key=$$( $< --config $Dbackend/build/bevm_user key ) ; \ - bevm_user_private_key=$$( $< --config $Dbackend/build/bevm_user key --print $Dbackend/build/bevm_user/key-* | grep Private | cut -d \ -f 2 ) ; \ - bevm_darc=$$( $< --config $Dbackend/build darc add --bc $Dbackend/build/bc-* --unrestricted --identity $$bevm_admin_key --desc "BEvm Darc" | awk -F: '/BaseID:/ {print $$3}' ) ; \ - $< --config $Dbackend/build/bevm_admin link $(word 2,$^) $$( grep ByzCoinID $Dbackend/build/ident | cut -d \ -f 2 ) --darc $$bevm_darc --identity $$bevm_admin_key ; \ - $< --config $Dbackend/build/bevm_admin darc rule --bc $Dbackend/build/bevm_admin/bc-* --rule "spawn:bevm" --identity $$bevm_admin_key ; \ - $< --config $Dbackend/build/bevm_admin darc rule --bc $Dbackend/build/bevm_admin/bc-* --rule "invoke:bevm.credit" --identity $$bevm_user_key ; \ - $< --config $Dbackend/build/bevm_admin darc rule --bc $Dbackend/build/bevm_admin/bc-* --rule "invoke:bevm.transaction" --identity $$bevm_user_key ; \ - bevm_instance_id=$$($(word 3,$^) --config $Dbackend/build/bevm_admin spawn --bc $Dbackend/build/bevm_admin/bc-* | awk '{print $$NF}' ) ; \ + bevm_admin_key=$$( $< --config $Dbackend/configs/bevm_admin key ) ; \ + bevm_user_key=$$( $< --config $Dbackend/configs/bevm_user key ) ; \ + bevm_user_private_key=$$( $< --config $Dbackend/configs/bevm_user key --print $Dbackend/configs/bevm_user/key-* | grep Private | cut -d \ -f 2 ) ; \ + bevm_darc=$$( $< --config $Dbackend/configs darc add --bc $Dbackend/configs/bc-* --unrestricted --identity $$bevm_admin_key --desc "BEvm Darc" | awk -F: '/BaseID:/ {print $$3}' ) ; \ + $< --config $Dbackend/configs/bevm_admin link $(word 2,$^) $$( grep ByzCoinID $Dbackend/configs/ident | cut -d \ -f 2 ) --darc $$bevm_darc --identity $$bevm_admin_key ; \ + $< --config $Dbackend/configs/bevm_admin darc rule --bc $Dbackend/configs/bevm_admin/bc-* --rule "spawn:bevm" --identity $$bevm_admin_key ; \ + $< --config $Dbackend/configs/bevm_admin darc rule --bc $Dbackend/configs/bevm_admin/bc-* --rule "invoke:bevm.credit" --identity $$bevm_user_key ; \ + $< --config $Dbackend/configs/bevm_admin darc rule --bc $Dbackend/configs/bevm_admin/bc-* --rule "invoke:bevm.transaction" --identity $$bevm_user_key ; \ + bevm_instance_id=$$($(word 3,$^) --config $Dbackend/configs/bevm_admin spawn --bc $Dbackend/configs/bevm_admin/bc-* | awk '{print $$NF}' ) ; \ ( echo "bevm_admin_key: $${bevm_admin_key#ed25519:}" ; \ echo "bevm_user_private_key: $$bevm_user_private_key" ; \ echo "bevm_darc: $$bevm_darc" ; \ echo "bevm_instance_id: $$bevm_instance_id" ) > $@) -$Dbackend/build/config_bevm.toml: $Dbackend/build/ident_bevm +$Dbackend/configs/config_bevm.toml: $Dbackend/configs/ident_bevm awk ' \ /^bevm_user_private_key:/ {printf("bevmUserID = \"%s\"\n", $$2)} \ /^bevm_instance_id:/ {printf("bevmInstanceID = \"%s\"\n", $$2)} \ @@ -57,7 +57,7 @@ $Dbackend/build/config_bevm.toml: $Dbackend/build/ident_bevm $Swebapp-build $Swebapp-test $Swebapp-serve: $Dwebapp/src/assets/configs/bevm.toml $Dwebapp/src/assets/configs/stainless.toml -$Dwebapp/src/assets/configs/bevm.toml: $Dbackend/build/config_bevm.toml | $Dwebapp/src/assets/configs/ +$Dwebapp/src/assets/configs/bevm.toml: $Dbackend/configs/config_bevm.toml | $Dwebapp/src/assets/configs/ cp $^ $@ $Dwebapp/src/assets/configs/stainless.toml: $Dwebapp/src/assets/configs/$(toml_filename) | $Dwebapp/src/assets/configs/ @@ -75,6 +75,14 @@ ifneq ($S,) all: $Sall endif +persistent: configs webapp-build + docker build -t ghcr.io/c4dt/service-stainless-persistent:latest -f backend/Dockerfile.persistent backend + docker build -t ghcr.io/c4dt/service-stainless-webapp:latest webapp + +push: + docker push ghcr.io/c4dt/service-stainless-persistent:latest + docker push ghcr.io/c4dt/service-stainless-webapp:latest + .PHONY: configs configs: webapp/src/assets/configs/byzcoin.toml configs: webapp/src/assets/configs/bevm.toml diff --git a/README.md b/README.md index 871e29e..40f97c5 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,41 @@ -![Build Status](https://github.com/c4dt/service-stainless/actions/workflows/build.yml/badge.svg) +# Stainless-ByzCoin Demonstrator has been Archived + +This repo has been archived and is only available to run the demo. # Stainless-ByzCoin Demonstrator +The Stainless demonstrator shows how Stainless helps develop Smart Contracts free of errors. +It provides an interactive environment where the user can verify prewritten Smart Contracts, +deploy them on a blockchain, and call their functions. + +A first introductory scenario involves a Candy Shop that maintains its candy balance with a simple +Smart Contract, which prevents people from cheating by taking away more candies than are available. +A second scenario illustrates a bug in a Smart Contract that appeared on the Ethereum blockchain +a few years ago, and led to a controversial fork to prevent significant monetary loss. +It also explains how Stainless could have prevented it. + +Please refer to the [project's showcase](https://factory.c4dt.org/showcase/stainless-for-smart-contracts/presentation) +for additional information on the project's theoretical background. + +## Running the Demo + Steps to run locally: -You first need to generate the node's configs ``` -make configs +git clone https://github.com/c4dt/service-stainless +cd service-stainless +docker-compose up -d +open localhost:8080 ``` -If you want our prebuilt images -``` -docker-compose pull -``` -Else if you want to build the images yourself -``` -make webapp-proto -docker-compose build -``` +The demo has instructions how to run it. -Launch it with -``` -docker-compose up -``` +## Persistent data + +On the first run, pre-computed data is copied to your repo at [./backend/configs]. +It contains the state of the blockchain and some variables. -And open a browser to http://localhost:80/stainless-demo/ +If you want to start over, you have to: +- delete the [./backend/configs] +- [remove the local storage](https://intercom.help/scoutpad/en/articles/3478364-how-to-clear-local-storage-of-web-browser) +from your browser diff --git a/backend/.gitignore b/backend/.gitignore index 47b947c..0bd150b 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,3 +1,4 @@ /build/ +/configs/ /cothority/ /proto/ diff --git a/backend/Dockerfile b/backend/Dockerfile index f32e883..688e457 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,13 +1,19 @@ -FROM golang:1 as builder +FROM golang:1.21 as builder + +RUN apt update \ + && apt install --no-install-recommends --yes unzip COPY build/*.go build/go.* /src/main/ -COPY *.go go.* /backend/ -COPY cothority/ /backend/cothority/ -COPY proto/ /backend/proto/ -COPY stainless/ /backend/stainless/ +COPY *.go go.* /src/ +COPY cothority /src/cothority/ +COPY proto /src/proto/ +COPY stainless /src/stainless/ RUN cd /src/main && go build -v -o /conode +COPY build/stainless.zip /tmp/ +RUN unzip -d /stainless /tmp/stainless.zip + FROM debian:bookworm-slim as runner # libgomp is needed for z3 @@ -16,16 +22,12 @@ RUN apt update \ procps \ openjdk-17-jre-headless \ libgomp1 \ - npm \ - unzip \ + npm \ && apt clean RUN npm install --global solc@0.5 COPY build/cvc4 /usr/local/bin/ -COPY build/stainless.zip /tmp/ -RUN unzip -d /usr/local/bin /tmp/stainless.zip && rm -f /tmp/stainless.zip - -COPY --from=builder /conode /usr/local/bin/conode +COPY --from=builder /conode /stainless /usr/local/bin/ -ENTRYPOINT ["/usr/local/bin/conode"] +CMD /usr/local/bin/conode -d 2 -c /config/private.toml server diff --git a/backend/Dockerfile.persistent b/backend/Dockerfile.persistent new file mode 100644 index 0000000..7f639ec --- /dev/null +++ b/backend/Dockerfile.persistent @@ -0,0 +1,6 @@ +FROM ghcr.io/c4dt/service-stainless-backend + +COPY configs /configs/ +ENV CONODE_SERVICE_PATH=/config + +CMD ( mkdir -p /config; test -f /config/private.toml || cp -a /configs/conode-$NODE_NBR/* /config ); /usr/local/bin/conode -d 2 -c /config/private.toml server diff --git a/docker-compose.yml b/docker-compose.yml index 383b03d..3bd34a3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,53 +2,43 @@ version: "3" services: conode-1: - image: c4dt/service-stainless-backend:latest - build: - context: backend + image: ghcr.io/c4dt/service-stainless-persistent:latest volumes: - - ./backend/build/conode-1:/config - network_mode: host - command: "-d 2 -c /config/private.toml server" + - ./backend/configs/conode-1:/config + ports: + - "7772-7779:7772-7779" environment: - - CONODE_SERVICE_PATH=/config + - NODE_NBR=1 - DEBUG_COLOR=true + conode-2: - image: c4dt/service-stainless-backend:latest - build: - context: backend - network_mode: host + image: ghcr.io/c4dt/service-stainless-persistent:latest volumes: - - ./backend/build/conode-2:/config - command: "-d 2 -c /config/private.toml server" + - ./backend/configs/conode-2:/config environment: - - CONODE_SERVICE_PATH=/config + - NODE_NBR=2 - DEBUG_COLOR=true + network_mode: service:conode-1 + conode-3: - image: c4dt/service-stainless-backend:latest - build: - context: backend - network_mode: host + image: ghcr.io/c4dt/service-stainless-persistent:latest volumes: - - ./backend/build/conode-3:/config - command: "-d 2 -c /config/private.toml server" + - ./backend/configs/conode-3:/config environment: - - CONODE_SERVICE_PATH=/config + - NODE_NBR=3 - DEBUG_COLOR=true + network_mode: service:conode-1 + conode-4: - image: c4dt/service-stainless-backend:latest - build: - context: backend - network_mode: host + image: ghcr.io/c4dt/service-stainless-persistent:latest volumes: - - ./backend/build/conode-4:/config - command: "-d 2 -c /config/private.toml server" + - ./backend/configs/conode-4:/config environment: - - CONODE_SERVICE_PATH=/config + - NODE_NBR=4 - DEBUG_COLOR=true + network_mode: service:conode-1 + demo: - image: c4dt/service-stainless-demo:latest - build: - context: webapp - network_mode: host - volumes: - - ./webapp/src/assets:/webapp/assets + image: ghcr.io/c4dt/service-stainless-webapp:latest + ports: + - "8080:8080" diff --git a/webapp/.gitignore b/webapp/.gitignore index 2ccbe46..b0a5c34 100644 --- a/webapp/.gitignore +++ b/webapp/.gitignore @@ -1 +1,2 @@ /node_modules/ +/dist/ diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 8c4c4c3..ee3f41c 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -1,16 +1,15 @@ -FROM node:16-alpine AS builder +FROM node:14-alpine AS builder WORKDIR /webapp -COPY package*.json . +COPY package*.json ./ RUN npm ci COPY . . RUN npx ng build --prod -FROM joseluisq/static-web-server:2 AS runner +FROM python:3 COPY --from=builder /webapp/dist /webapp -WORKDIR /webapp -ENV SERVER_ROOT=/webapp +CMD python3 -m http.server 8080 --directory /webapp diff --git a/webapp/angular.json b/webapp/angular.json index 3073282..f9ca084 100644 --- a/webapp/angular.json +++ b/webapp/angular.json @@ -16,7 +16,7 @@ "customWebpackConfig": { "path": "./extra-webpack.config.js" }, - "outputPath": "dist/stainless-demo", + "outputPath": "dist", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", diff --git a/webapp/src/app/stainless/stainless.component.ts b/webapp/src/app/stainless/stainless.component.ts index 0005996..4e490c4 100644 --- a/webapp/src/app/stainless/stainless.component.ts +++ b/webapp/src/app/stainless/stainless.component.ts @@ -369,7 +369,7 @@ export class StainlessComponent implements OnInit { // Call Stainless service to perform verification const response = await this.performLongAction( () => this.config.stainlessRPC.verify(sourceFiles), - "Performing verification" + "Performing verification. Wait for 2-3 minutes" ); if (response === null) { return; @@ -408,7 +408,7 @@ export class StainlessComponent implements OnInit { // Call Stainless service to generate bytecode and ABI const response = await this.performLongAction( () => this.config.stainlessRPC.genBytecode(sourceFiles), - "Compiling..." + "Compiling... wait for 1 minute" ); if (response === null) { return;