├── files ├── common │ ├── logs │ │ ├── besu │ │ │ └── .gitignore │ │ ├── quorum │ │ │ └── .gitignore │ │ └── tessera │ │ │ └── .gitignore │ ├── config │ │ ├── ethsigner │ │ │ ├── password │ │ │ ├── createKey.js │ │ │ └── key │ │ ├── nodes │ │ │ ├── member1 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── tm.pub │ │ │ │ ├── tma.pub │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── tm.key │ │ │ │ ├── tma.key │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── member2 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── tm.pub │ │ │ │ ├── tma.pub │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── tm.key │ │ │ │ ├── tma.key │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── member3 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── tm.pub │ │ │ │ ├── tma.pub │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── tm.key │ │ │ │ ├── tma.key │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── rpcnode │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── validator1 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── validator2 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ ├── validator3 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ │ └── validator4 │ │ │ │ ├── accountPassword │ │ │ │ ├── address │ │ │ │ ├── nodekey │ │ │ │ ├── accountPrivateKey │ │ │ │ ├── nodekey.pub │ │ │ │ └── accountKeystore │ │ ├── grafana │ │ │ └── provisioning │ │ │ │ ├── dashboards │ │ │ │ └── dashboard.yml │ │ │ │ └── datasources │ │ │ │ ├── loki.yml │ │ │ │ └── prometheus.yml │ │ └── tessera │ │ │ ├── docker-entrypoint.sh │ │ │ ├── Dockerfile │ │ │ └── data │ │ │ ├── logback.xml │ │ │ └── tessera-config-template.json │ ├── dapps │ │ └── quorumToken │ │ │ ├── frontend │ │ │ ├── .eslintrc.json │ │ │ ├── next.config.js │ │ │ ├── styles │ │ │ │ └── globals.css │ │ │ ├── src │ │ │ │ ├── pages │ │ │ │ │ ├── _app.tsx │ │ │ │ │ ├── _document.js │ │ │ │ │ └── index.tsx │ │ │ │ └── components │ │ │ │ │ ├── quorumToken │ │ │ │ │ ├── QuorumTokenABI.tsx │ │ │ │ │ ├── TransferQuorumToken.tsx │ │ │ │ │ └── ReadQuorumToken.tsx │ │ │ │ │ ├── Layout.tsx │ │ │ │ │ └── MMAccount.tsx │ │ │ ├── .gitignore │ │ │ ├── tsconfig.json │ │ │ ├── package.json │ │ │ └── public │ │ │ │ ├── next.svg │ │ │ │ └── favicon.svg │ │ │ ├── .gitignore │ │ │ ├── tsconfig.json │ │ │ ├── contracts │ │ │ └── QuorumToken.sol │ │ │ ├── scripts │ │ │ └── deploy_quorumtoken.ts │ │ │ ├── hardhat.config.ts │ │ │ ├── package.json │ │ │ ├── test │ │ │ └── QuorumToken.test.ts │ │ │ └── README.md │ ├── restart.sh │ ├── static │ │ ├── qs-dapp.png │ │ ├── blockchain-network.png │ │ ├── npm-send-private-tx.png │ │ └── metamask-faucet-transfer.png │ ├── logstash │ │ ├── pipeline │ │ │ ├── 10_filebeat_redis.conf │ │ │ ├── 20_logstash.conf │ │ │ ├── 10_metricbeat_redis.conf │ │ │ ├── 20_besu.conf │ │ │ ├── 20_tessera.conf │ │ │ ├── 20_quorum.conf │ │ │ └── 30_elasticsearch.conf │ │ ├── config │ │ │ ├── logstash.yml │ │ │ └── log4j2.properties │ │ └── Dockerfile │ ├── smart_contracts │ │ ├── contracts │ │ │ ├── Counter.sol │ │ │ └── SimpleStorage.sol │ │ ├── package.json │ │ └── scripts │ │ │ └── compile.js │ ├── filebeat │ │ ├── Dockerfile │ │ └── filebeat.yml │ ├── metricbeat │ │ ├── Dockerfile │ │ └── metricbeat.yml │ ├── chainlens │ │ ├── nginx.conf │ │ └── 5xx.html │ ├── extra │ │ ├── package.json │ │ └── generate_node_details.js │ ├── attach.sh │ ├── loki │ │ └── loki.yml │ ├── .env │ ├── splunk │ │ ├── splunk.yml │ │ └── log4j2.xml │ ├── stop.sh │ ├── resume.sh │ ├── run.sh │ ├── remove.sh │ ├── promtail │ │ └── promtail.yml │ └── .common.sh ├── besu │ ├── quorum-explorer │ │ ├── .gitignore │ │ ├── env │ │ └── config.json │ ├── config │ │ ├── besu │ │ │ ├── config.toml │ │ │ ├── log-config.xml │ │ │ ├── static-nodes.json │ │ │ ├── permissions_config.toml │ │ │ ├── log-config-splunk.xml │ │ │ └── CLIQUEgenesis.json │ │ └── prometheus │ │ │ └── prometheus.yml │ └── smart_contracts │ │ └── scripts │ │ ├── public │ │ ├── hre_eth_tx.js │ │ ├── web3_eth_tx.js │ │ ├── hre_public_tx.js │ │ └── hre_1559_public_tx.js │ │ ├── keys.js │ │ └── privacy │ │ └── concurrent_private_txs.js └── goquorum │ ├── config │ ├── permissions │ │ └── .gitignore │ ├── goquorum │ │ ├── data │ │ │ ├── passwords.txt │ │ │ ├── disallowed-nodes.json │ │ │ ├── static-nodes.json │ │ │ ├── permissioned-nodes.json │ │ │ ├── raft-standard-genesis.json │ │ │ ├── raft-enhanced-genesis.json │ │ │ ├── istanbul-standard-genesis.json │ │ │ ├── qbft-enhanced-genesis.json │ │ │ ├── qbft-standard-genesis.json │ │ │ └── istanbul-enhanced-genesis.json │ │ ├── Dockerfile │ │ └── docker-entrypoint.sh │ └── prometheus │ │ └── prometheus.yml │ ├── quorum-explorer │ ├── .gitignore │ ├── env │ └── config.json │ ├── smart_contracts │ ├── permissioning │ │ ├── scripts │ │ │ ├── compile.sh │ │ │ ├── copyAndRestart.sh │ │ │ ├── deployEthers.js │ │ │ └── keys.js │ │ ├── package.json │ │ └── contracts │ │ │ ├── v1 │ │ │ └── PermissionsUpgradable.sol │ │ │ └── v2 │ │ │ └── PermissionsUpgradable.sol │ └── scripts │ │ ├── compile.js │ │ ├── public │ │ ├── hre_eth_tx.js │ │ └── hre_public_tx.js │ │ └── keys.js │ └── README.md ├── .gitattributes ├── .gitignore ├── .editorconfig ├── .github └── workflows │ ├── ci.yml │ └── codeql-analysis.yml ├── templates └── besu │ └── config │ └── besu │ └── .env ├── index.js ├── package.json └── src ├── questions └── types.ts ├── networkBuilder.ts ├── spinner.ts ├── index.ts └── fileRendering.ts /files/common/logs/besu/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /files/common/logs/quorum/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/logs/tessera/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/besu/quorum-explorer/.gitignore: -------------------------------------------------------------------------------- 1 | !dist 2 | -------------------------------------------------------------------------------- /files/common/config/ethsigner/password: -------------------------------------------------------------------------------- 1 | Password1 -------------------------------------------------------------------------------- /files/goquorum/config/permissions/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/member2/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/member3/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/accountPassword: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/passwords.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/goquorum/quorum-explorer/.gitignore: -------------------------------------------------------------------------------- 1 | !dist 2 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/disallowed-nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/address: -------------------------------------------------------------------------------- 1 | 0x13a52aab892e1322e8b52506276363d4754c122e 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/tm.pub: -------------------------------------------------------------------------------- 1 | BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo= -------------------------------------------------------------------------------- /files/common/config/nodes/member1/tma.pub: -------------------------------------------------------------------------------- 1 | 8SjRHlUBe4hAmTk3KDeJ96RhN+s10xRrHDrxEi1O5W0= -------------------------------------------------------------------------------- /files/common/config/nodes/member2/address: -------------------------------------------------------------------------------- 1 | 0xe090a28b8a9d0a69ec259cb745036d5d1030e3ea 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member2/tm.pub: -------------------------------------------------------------------------------- 1 | QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc= -------------------------------------------------------------------------------- /files/common/config/nodes/member2/tma.pub: -------------------------------------------------------------------------------- 1 | 2T7xkjblN568N1QmPeElTjoeoNT4tkWYOJYxSMDO5i0= -------------------------------------------------------------------------------- /files/common/config/nodes/member3/address: -------------------------------------------------------------------------------- 1 | 0x401bdfcd9221cd790e7cd66eece303ed4d4b53b1 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member3/tm.pub: -------------------------------------------------------------------------------- 1 | 1iTZde/ndBHvzhcl7V68x44Vx7pl8nwx9LqnM/AfJUg= -------------------------------------------------------------------------------- /files/common/config/nodes/member3/tma.pub: -------------------------------------------------------------------------------- 1 | 3nLS1GSlPs3/AccoZ20WTBrYP/ua5KDlUM1uGrDKHTs= -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/address: -------------------------------------------------------------------------------- 1 | 0xdf8b560be949c229c821731554c33ead5e3888a4 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/address: -------------------------------------------------------------------------------- 1 | 0x93917cadbace5dfce132b991732c6cda9bcc5b8a 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/address: -------------------------------------------------------------------------------- 1 | 0x27a97c9aaf04f18f3014c32e036dd0ac76da5f18 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/address: -------------------------------------------------------------------------------- 1 | 0xce412f988377e31f4d0ff12d74df73b51c42d0ca 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/address: -------------------------------------------------------------------------------- 1 | 0x98c1334496614aed49d2e81526d089f7264fed9c 2 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/nodekey: -------------------------------------------------------------------------------- 1 | b9a4bd1539c15bcc83fa9078fe89200b6e9e802ae992f13cd83c853f16e8bed4 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member2/nodekey: -------------------------------------------------------------------------------- 1 | f18166704e19b895c1e2698ebc82b4e007e6d2933f4b31be23662dd0ec602570 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member3/nodekey: -------------------------------------------------------------------------------- 1 | 4107f0b6bf67a3bc679a15fe36f640415cf4da6a4820affaac89c8b280dfd1b3 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/nodekey: -------------------------------------------------------------------------------- 1 | 0e93a540518eeb673d94fb496b746008ab56605463cb9212493997f5755124d1 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/nodekey: -------------------------------------------------------------------------------- 1 | 1a2c4ff0f1b38e2322658dba692816138eb22d002515df1fffca21278f406aa9 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/nodekey: -------------------------------------------------------------------------------- 1 | 7f9af699dd2bb1af76c90b3f67183dd48abae509c315eb8f2c55301ad90ba978 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/nodekey: -------------------------------------------------------------------------------- 1 | fe006b00c738e7e5af7f7623290ffc83f394741ae6fb6afc6081cab49e1e1a70 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/nodekey: -------------------------------------------------------------------------------- 1 | 8f6ae009cdbbf6e6fa739b91a4483f251bbe89f6570d34856554533b36c93c55 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x8bbbb1b345af56b560a5b20bd4b0ed1cd8cc9958a16262bc75118453cb546df7 -------------------------------------------------------------------------------- /files/common/config/nodes/member2/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x4762e04d10832808a0aebdaa79c12de54afbe006bfffd228b3abcc494fe986f9 -------------------------------------------------------------------------------- /files/common/config/nodes/member3/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x61dced5af778942996880120b303fc11ee28cc8e5036d2fdff619b5675ded3f0 -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x60bbe10a196a4e71451c0f6e9ec9beab454c2a5ac0542aa5b8b733ff5719fec3 -------------------------------------------------------------------------------- /files/common/config/nodes/member1/tm.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"Wl+xSyXVuuqzpvznOS7dOobhcn4C5auxkFRi7yLtgtA="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/config/nodes/member2/tm.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"nDFwJNHSiT1gNzKBy9WJvMhmYRkW3TzFUmPsNzR6oFk="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/config/nodes/member3/tm.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"tMxUVR8bX7aq/TbpVHc2QV3SN2iUuExBwefAuFsO0Lg="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0xe6181caaffff94a09d7e332fc8da9884d99902c7874eb74354bdcadf411929f1 -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x5ad8b28507578c429dfa9f178d7f742f4861716ee956eb75648a7dbc5ffe915d -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0xf23f92ed543046498d7616807b18a8f304855cb644df25bc7d0b0b37d8a66019 -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/accountPrivateKey: -------------------------------------------------------------------------------- 1 | 0x7f012b2a11fc651c9a73ac13f0a298d89186c23c2c9a0e83206ad6e274ba3fc7 -------------------------------------------------------------------------------- /files/common/config/nodes/member1/tma.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"wGEar7J9G0JAgdisp61ZChyrJWeW2QPyKvecjjeVHOY="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/config/nodes/member2/tma.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"rwfJC1kNa8BjPfc+zZXug+it9sdWa0vbdN6pp6IXlAs="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/config/nodes/member3/tma.key: -------------------------------------------------------------------------------- 1 | {"data":{"bytes":"yLcbICXicELZOnvpkDXB2UkQUiNAMIfsEOsgtFOGkQU="},"type":"unlocked"} -------------------------------------------------------------------------------- /files/common/restart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./stop.sh 4 | echo "Waiting 30s for containers to stop" 5 | sleep 30 6 | ./resume.sh 7 | -------------------------------------------------------------------------------- /files/common/static/qs-dapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/quorum-dev-quickstart/HEAD/files/common/static/qs-dapp.png -------------------------------------------------------------------------------- /files/common/static/blockchain-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/quorum-dev-quickstart/HEAD/files/common/static/blockchain-network.png -------------------------------------------------------------------------------- /files/common/static/npm-send-private-tx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/quorum-dev-quickstart/HEAD/files/common/static/npm-send-private-tx.png -------------------------------------------------------------------------------- /files/common/static/metamask-faucet-transfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/quorum-dev-quickstart/HEAD/files/common/static/metamask-faucet-transfer.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .lh/ 3 | *.iml 4 | *.lock 5 | *.log 6 | node_modules 7 | .vscode 8 | build 9 | logs/ 10 | /volumes/ 11 | .DS_Store 12 | quorum-test-network/* 13 | -------------------------------------------------------------------------------- /files/common/config/nodes/member1/nodekey.pub: -------------------------------------------------------------------------------- 1 | 98496800174b3c73ae33cba59f8f5e686cd488f7897c2edb52e2cf46383d75cd03dbb58dde07185bc0953f98800ca9a89f4b5ef450c5e51292ea08ec6130ee0c 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member2/nodekey.pub: -------------------------------------------------------------------------------- 1 | ad2c79c6561bc8212c2e8382611c62e406e767d1f3106c68ca206900f575cb8ba9a8be111c645cd9803701d684454c782c40d2361b000a32ed03d26228b30ec1 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/member3/nodekey.pub: -------------------------------------------------------------------------------- 1 | af19c92deb635bd7720634de9b2e7908208530d6f5e96eee003a8f1799e5be4037957d7e2fdbe3605e3a38dab05c961679c02133a0e624e23a72f7961e8af6ac 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/nodekey.pub: -------------------------------------------------------------------------------- 1 | 86fcc16f4730fbfd238dc17ea552854c0943923bb1d5e886e5601b8d884fb0519060e0023f495dd24ffe60a65660fb7fdcdebfceedd2b3673dfa63658825924b 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/nodekey.pub: -------------------------------------------------------------------------------- 1 | 8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/nodekey.pub: -------------------------------------------------------------------------------- 1 | b9050e002aa42464e6b07c811a1f9dfec01249af03f67b753e8415420649b184447bb2a784863ccbf327ad9e31aaba803464979dfe6a7facc669151a5fa6ad1b 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/nodekey.pub: -------------------------------------------------------------------------------- 1 | 59cf0c623c582fa9b19bdf70fb6bade07f4ae32218dd4d1c7e2c7e65acf87da45cf2ab55d16d27360aafef17622c37c09db60d7680ebcc17b78867f4c05bcaa4 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/nodekey.pub: -------------------------------------------------------------------------------- 1 | 2fd5b5b6ad529f55b71602026d1849d0036f06482368b5812fa793014195d3571b0840dbc4175617de2a12db8f1222c012420d471ae5c0d982118625cae58868 2 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | typechain-types 7 | 8 | # Hardhat files 9 | cache 10 | artifacts 11 | 12 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | } 5 | 6 | module.exports = nextConfig 7 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/scripts/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd ./contracts/v2 3 | for f in *.sol 4 | do 5 | echo "Compiling $f contract..." 6 | solc --bin --abi --optimize --overwrite -o ./output $f 7 | done -------------------------------------------------------------------------------- /files/common/logstash/pipeline/10_filebeat_redis.conf: -------------------------------------------------------------------------------- 1 | input { 2 | redis { 3 | host => "${REDIS_HOST}" 4 | port => "${REDIS_PORT}" 5 | codec => "json" 6 | data_type => "list" 7 | key => "filebeat" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/20_logstash.conf: -------------------------------------------------------------------------------- 1 | filter { 2 | if [service_name] == "logstash" { 3 | json { 4 | source => "message" 5 | } 6 | 7 | date { 8 | match => [ "timeMillis", "UNIX_MS" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/scripts/copyAndRestart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Copying permission-config.json file to the volume" 4 | cp permission-config.json ../../config/permissions/ 5 | cd ../../ 6 | echo "Restarting network stop" 7 | ./restart.sh 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/10_metricbeat_redis.conf: -------------------------------------------------------------------------------- 1 | input { 2 | redis { 3 | host => "${REDIS_HOST}" 4 | port => "${REDIS_PORT}" 5 | codec => "json" 6 | data_type => "list" 7 | type => "metricbeat" 8 | key => "metricbeat" 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/20_besu.conf: -------------------------------------------------------------------------------- 1 | filter { 2 | if [service_name] == "besu" { 3 | json { 4 | source => "message" 5 | } 6 | date { 7 | match => [ "timestamp" , "ISO8601" ] 8 | remove_field => [ "timestamp" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/20_tessera.conf: -------------------------------------------------------------------------------- 1 | filter { 2 | if [service_name] == "tessera" { 3 | json { 4 | source => "message" 5 | } 6 | date { 7 | match => [ "timestamp" , "ISO8601" ] 8 | remove_field => [ "timestamp" ] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /files/common/config/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: 1 3 | 4 | providers: 5 | - name: 'Prometheus' 6 | orgId: 1 7 | folder: '' 8 | type: file 9 | disableDeletion: false 10 | editable: true 11 | options: 12 | path: /etc/grafana/provisioning/dashboards 13 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "resolveJsonModule": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /files/common/config/tessera/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir -p /var/log/tessera/; 4 | mkdir -p /data/tm/; 5 | 6 | envsubst < /data/tessera-config-template.json > /data/tessera-config.json 7 | 8 | cat /data/tessera-config.json 9 | 10 | exec /tessera/bin/tessera \ 11 | -configfile /data/tessera-config.json 12 | 13 | -------------------------------------------------------------------------------- /files/common/logstash/config/logstash.yml: -------------------------------------------------------------------------------- 1 | # ensure name is set so that monitoring in Kibana is easy to identify 2 | node.name: "logstash-quorum" 3 | 4 | log.format: json 5 | path: 6 | config: /usr/share/logstash/pipeline 7 | logs: /usr/share/logstash/logs 8 | 9 | xpack: 10 | monitoring: 11 | enabled: true 12 | elasticsearch: 13 | hosts: ${ES_HOST} -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/contracts/QuorumToken.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract QuorumToken is ERC20 { 7 | constructor(uint256 initialSupply) 8 | ERC20("QuorumToken", "QT") 9 | { 10 | _mint(msg.sender, initialSupply); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/styles/globals.css: -------------------------------------------------------------------------------- 1 | :root, 2 | body { 3 | height: 100%; 4 | margin: 0; 5 | padding: 0; 6 | width: 100%; 7 | } 8 | 9 | #__next { 10 | display: flex; 11 | flex: 1; 12 | flex-direction: column; 13 | height: 100%; 14 | width: 100%; 15 | } 16 | 17 | main { 18 | display: flex; 19 | flex: 1; 20 | flex-direction: column; 21 | } -------------------------------------------------------------------------------- /files/common/config/ethsigner/createKey.js: -------------------------------------------------------------------------------- 1 | const Web3 = require('web3') 2 | 3 | // Web3 initialization (should point to the JSON-RPC endpoint) 4 | const web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:8545')) 5 | 6 | var V3KeyStore = web3.eth.accounts.encrypt("797bbe0373132e8c5483515b68ecbb6d3581b56f0205b653ad2b30a559e83891", "Password1"); 7 | console.log(JSON.stringify(V3KeyStore)); 8 | process.exit(); 9 | -------------------------------------------------------------------------------- /files/common/smart_contracts/contracts/Counter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | contract Counter { 4 | int private count = 0; 5 | function incrementCounter() public { 6 | count += 1; 7 | } 8 | function decrementCounter() public { 9 | count -= 1; 10 | } 11 | function getCount() public view returns (int) { 12 | return count; 13 | } 14 | } -------------------------------------------------------------------------------- /files/common/filebeat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.elastic.co/beats/filebeat:7.14.1 2 | ENV ENV_NAME dev 3 | ENV IP_ADDRESS "127.0.0.1" 4 | ENV REDIS_HOST localhost 5 | ENV REDIS_PORT 6379 6 | 7 | USER root 8 | ADD ./filebeat.yml /usr/share/filebeat/filebeat.yml 9 | RUN chown root:filebeat /usr/share/filebeat/filebeat.yml && chmod go-w /usr/share/filebeat/filebeat.yml 10 | USER filebeat 11 | 12 | CMD ["filebeat", "-c", "filebeat.yml"] 13 | -------------------------------------------------------------------------------- /files/common/metricbeat/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.elastic.co/beats/metricbeat:7.14.1 2 | ENV IP_ADDRESS "127.0.0.1" 3 | ENV REDIS_HOST localhost 4 | ENV REDIS_PORT 6379 5 | 6 | USER root 7 | ADD ./metricbeat.yml /usr/share/metricbeat/metricbeat.yml 8 | RUN chown root:metricbeat /usr/share/metricbeat/metricbeat.yml && chmod go-w /usr/share/metricbeat/metricbeat.yml 9 | USER metricbeat 10 | 11 | CMD ["metricbeat", "-c", "metricbeat.yml"] 12 | -------------------------------------------------------------------------------- /files/common/chainlens/nginx.conf: -------------------------------------------------------------------------------- 1 | events { } 2 | 3 | http { 4 | server { 5 | listen 80; 6 | charset utf-8; 7 | 8 | location /api/ { 9 | proxy_pass http://chainlensapi:8090/; 10 | } 11 | 12 | location / { 13 | proxy_pass http://chainlensweb:3000/; 14 | } 15 | 16 | error_page 500 502 503 504 /5xx.html; 17 | location /5xx.html { 18 | root /www/error_pages/; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /files/common/extra/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@consensys-software/generate_node_details", 3 | "version": "1.0.0", 4 | "description": "Example script to create nodekeys and address for a Quorum (Besu or GoQuorum) node", 5 | "scripts": {}, 6 | "license": "Apache-2.0", 7 | "dependencies": { 8 | "secp256k1": "^4.0.0", 9 | "keccak": "^3.0.0", 10 | "ethereumjs-wallet": "^1.0.2", 11 | "yargs": "^17.2.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /files/common/attach.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MEMBER_NUMBER=$1 4 | MEMBER_NODE="member${MEMBER_NUMBER}quorum" 5 | echo "Attempting to connect to $MEMBER_NODE" 6 | if [ -z `docker compose -f docker-compose.yml ps -q ${MEMBER_NODE} 2>/dev/null` ] ; then 7 | echo "$MEMBER_NUMBER is not a valid member node. Must be between 1 and 3" >&2 8 | exit 1 9 | fi 10 | 11 | # can also do geth attach http://localhost:8545 12 | docker compose exec ${MEMBER_NODE} /bin/sh -c "geth attach /data/geth.ipc" 13 | -------------------------------------------------------------------------------- /files/goquorum/README.md: -------------------------------------------------------------------------------- 1 | # Quorum Dev Quickstart 2 | 3 | Please go to our [official docs](https://consensys.net/docs/goquorum/en/latest/tutorials/quorum-dev-quickstart/) 4 | 5 | 6 | ## Moving to production 7 | 8 | When you are ready to move to production, please create new keys for your nodes using the 9 | [Quorum Genesis Tool](https://www.npmjs.com/package/quorum-genesis-tool) and read through the the 10 | [GoQuorum documentation](https://consensys.net/docs/goquorum/en/latest/deploy/install/) 11 | -------------------------------------------------------------------------------- /files/common/config/ethsigner/key: -------------------------------------------------------------------------------- 1 | {"version":3,"id":"0e3d044a-26b4-429f-a5d3-def4a62a77ec","address":"9b790656b9ec0db1936ed84b3bea605873558198","crypto":{"ciphertext":"4d34be50618c36fb57349a8a7dc7b0c46f7c6883c817087863ff4f1fbc957582","cipherparams":{"iv":"723a6a815dcaf255ebd1da1bfb14e1b8"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"dklen":32,"salt":"3d04a3f225d3d5874388484730a30d45627399d69721a7c7fb653f8e0e90a67b","n":8192,"r":8,"p":1},"mac":"5c04e705196b35abace4da61700921d7762dba782ed68a4cd9917dd75badaacb"}} -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG QUORUM_VERSION=latest 2 | 3 | FROM quorumengineering/quorum:${QUORUM_VERSION} 4 | 5 | RUN apk add --no-cache curl 6 | 7 | COPY docker-entrypoint.sh /usr/local/bin/ 8 | COPY data data 9 | 10 | RUN mkdir -p /data /permissions /var/log/quorum \ 11 | && addgroup -g 1000 quorum \ 12 | && adduser -u 1000 -G quorum -s /bin/sh -D quorum \ 13 | && chown -R quorum:quorum /data /permissions /var/log/quorum 14 | USER quorum 15 | 16 | ENTRYPOINT ["docker-entrypoint.sh"] -------------------------------------------------------------------------------- /files/common/config/nodes/member2/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"ca843569e3427144cead5e4d5999a3d0ccf92b8e","crypto":{"cipher":"aes-128-ctr","ciphertext":"01d409941ce57b83a18597058033657182ffb10ae15d7d0906b8a8c04c8d1e3a","cipherparams":{"iv":"0bfb6eadbe0ab7ffaac7e1be285fb4e5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7b90f455a95942c7c682e0ef080afc2b494ef71e749ba5b384700ecbe6f4a1bf"},"mac":"4cc851f9349972f851d03d75a96383a37557f7c0055763c673e922de55e9e307"},"id":"354e3b35-1fed-407d-a358-889a29111211","version":3} -------------------------------------------------------------------------------- /files/common/config/nodes/member3/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"0fbdc686b912d7722dc86510934589e0aaf3b55a","crypto":{"cipher":"aes-128-ctr","ciphertext":"6b2c72c6793f3da8185e36536e02f574805e41c18f551f24b58346ef4ecf3640","cipherparams":{"iv":"582f27a739f39580410faa108d5cc59f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"1a79b0db3f8cb5c2ae4fa6ccb2b5917ce446bd5e42c8d61faeee512b97b4ad4a"},"mac":"cecb44d2797d6946805d5d744ff803805477195fab1d2209eddc3d1158f2e403"},"id":"f7292e90-af71-49af-a5b3-40e8493f4681","version":3} -------------------------------------------------------------------------------- /files/common/config/nodes/validator1/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"ed9d02e382b34818e88b88a309c7fe71e65f419d","crypto":{"cipher":"aes-128-ctr","ciphertext":"4e77046ba3f699e744acb4a89c36a3ea1158a1bd90a076d36675f4c883864377","cipherparams":{"iv":"a8932af2a3c0225ee8e872bc0e462c11"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"8ca49552b3e92f79c51f2cd3d38dfc723412c212e702bd337a3724e8937aff0f"},"mac":"6d1354fef5aa0418389b1a5d1f5ee0050d7273292a1171c51fd02f9ecff55264"},"id":"a65d1ac3-db7e-445d-a1cc-b6c5eeaa05e0","version":3} -------------------------------------------------------------------------------- /files/common/config/nodes/member1/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"f0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5","crypto":{"cipher":"aes-128-ctr","ciphertext":"f2af258ee3733513333652be19197ae7eace4b5e79a346cf25b02a857e6043f3","cipherparams":{"iv":"587d7faaa6403b8a73273d0ad58dd71f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b93c7d69c5bb0a760c3b7fdf791c47896a552c5c977648b392a24d708674dcf3"},"mac":"d83bcb555c92fc5a32ceacabbb6b99f59515ec3986b9fe5995c67e027bd750c8"},"id":"5392d73f-08dd-42b8-bca9-6f6d35c419d9","version":3} 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/rpcnode/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"c9c913c8c3c1cd416d80a0abf475db2062f161f6","crypto":{"cipher":"aes-128-ctr","ciphertext":"ce8e51e64e9f053414616c62b3924536f3f9144638359e2e2eb00e04ad095b0a","cipherparams":{"iv":"648343bce02b158eda9bb2074f8dc601"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0982402da973d8176315aeae4415b328a7ce4393e217a0c4f45385f1cee9bc3e"},"mac":"5707caff457f930655849293dc1101e13ab32b175fdf5538869a2a3ffc716d8b"},"id":"8d031b90-ab7f-48dc-9b7a-ce41abd7f9c8","version":3} 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator2/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"b30f304642de3fee4365ed5cd06ea2e69d3fd0ca","crypto":{"cipher":"aes-128-ctr","ciphertext":"cf7f44a86510c497f2a6727f62b8e89c8cd42dbfd8e3377658d659c776c75f30","cipherparams":{"iv":"5d320e3072939817faa2caefdb810239"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e637b069dacfe77f3a495d8a0d3735544e73973c03e107976545df78e6f04289"},"mac":"e20c97b8ee7d54072b9cfac201d52ef360ecacdbd1f7187e7547b3cd9be00599"},"id":"5bf73d6b-340b-4e9f-a7f3-f9ab41f39726","version":3} 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator3/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"0886328869e4e1f401e1052a5f4aae8b45f42610","crypto":{"cipher":"aes-128-ctr","ciphertext":"6e0e228b810a88f2cea85c439b005a92bba6220de8cd6ba73a8f7ecd681fde09","cipherparams":{"iv":"5264c2defa48f7f9fa103899acaea021"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"15ef956dab453387ddf7afd6775f3727fb560a77028b5a14d774c3bfff17f101"},"mac":"6ca1d88defee18378789d191ca7b32bbecbd6dd5a6c39427ed45b13c9595edc3"},"id":"734d1189-4e1e-44bf-854a-642485532715","version":3} 2 | -------------------------------------------------------------------------------- /files/common/config/nodes/validator4/accountKeystore: -------------------------------------------------------------------------------- 1 | {"address":"f48de4a0c2939e62891f3c6aca68982975477e45","crypto":{"cipher":"aes-128-ctr","ciphertext":"402a2d8eb1ff6bab713ddb81f68142c4f0113d32e9f0cc8969347a4945cd1e5f","cipherparams":{"iv":"a1f708815212854c0c49081869198dd5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"a24d95de8680d8d214ae5e9060e919eb563ce513bf63021497e0d218ed68f89d"},"mac":"571164da79472f210caeb45af2b9715fb22eef8d485ce5c6a4e0c52865398ea7"},"id":"d5723032-0a81-46ec-ac34-9d8362e2250c","version":3} 2 | -------------------------------------------------------------------------------- /files/common/smart_contracts/contracts/SimpleStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.10; 3 | 4 | contract SimpleStorage { 5 | uint public storedData; 6 | event stored(address _to, uint _amount); 7 | constructor(uint initVal) { 8 | emit stored(msg.sender, initVal); 9 | storedData = initVal; 10 | } 11 | function set(uint x) public { 12 | emit stored(msg.sender, x); 13 | storedData = x; 14 | } 15 | function get() view public returns (uint retVal) { 16 | return storedData; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /files/common/logstash/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.elastic.co/logstash/logstash:7.14.1 2 | 3 | ENV ES_HOST http://localhost:9200 4 | ENV REDIS_HOST localhost 5 | ENV REDIS_PORT 6379 6 | 7 | # Remove exisiting file 8 | RUN mkdir -p /usr/share/logstash/logs && \ 9 | rm -f /usr/share/logstash/pipeline/logstash.conf 10 | 11 | # Add pipeline files 12 | ADD pipeline/ /usr/share/logstash/pipeline/ 13 | 14 | # Add configuration files 15 | ADD config/ /usr/share/logstash/config/ 16 | 17 | # Test the configuration 18 | RUN /usr/share/logstash/bin/logstash -t 19 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | 2 | import type { AppProps } from "next/app"; 3 | import { ChakraProvider } from "@chakra-ui/react"; 4 | import "../../styles/globals.css"; 5 | import Layout from '../components/Layout'; 6 | 7 | function MyApp({ Component, pageProps, router }: AppProps) { 8 | 9 | return ( 10 | 11 | Quorum Quickstart DApp 12 | 13 | 14 | 15 | 16 | ) 17 | } 18 | 19 | export default MyApp; 20 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/scripts/deploy_quorumtoken.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "hardhat" 2 | 3 | async function main() { 4 | const initialSupply = ethers.parseEther('10000.0') 5 | const QuorumToken = await ethers.getContractFactory("QuorumToken") 6 | const deploy = await QuorumToken.deploy(initialSupply) 7 | console.log("Contract deploy at: %s", await deploy.getAddress()); 8 | } 9 | 10 | // We recommend this pattern to be able to use async/await everywhere 11 | // and properly handle errors. 12 | main().catch((error) => { 13 | console.error(error) 14 | process.exitCode = 1 15 | }) -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/pages/_document.js: -------------------------------------------------------------------------------- 1 | import { ColorModeScript } from "@chakra-ui/react"; 2 | import NextDocument, { Html, Head, Main, NextScript } from "next/document"; 3 | 4 | export default class Document extends NextDocument { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /files/common/config/tessera/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG TESSERA_VERSION=latest 2 | 3 | FROM quorumengineering/tessera:${TESSERA_VERSION} 4 | 5 | # develop uses a debain container, all releases use an alpine container - this allows both to be used for the quickstart 6 | # set the version in ../../.env 7 | RUN if [ -e /sbin/apk ] ; then apk add gettext --no-cache ; else apt-get update && apt-get install -y gettext && rm -rf /var/lib/apt/lists/* ; fi 8 | 9 | ENV JAVA_OPTS="-Dlogback.configurationFile=/data/logback.xml" 10 | 11 | COPY docker-entrypoint.sh /usr/bin/ 12 | COPY data data 13 | 14 | ENTRYPOINT ["docker-entrypoint.sh"] 15 | 16 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ '*' ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [18.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - name: Install dependencies 25 | run: npm ci 26 | - run: npm run build 27 | - run: npm run lint 28 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "baseUrl": "./src" 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /files/common/metricbeat/metricbeat.yml: -------------------------------------------------------------------------------- 1 | 2 | metricbeat.modules: 3 | - module: prometheus 4 | period: 15s 5 | hosts: 6 | - validator1:9545 7 | - validator2:9545 8 | - validator3:9545 9 | - validator4:9545 10 | - rpcnode:9545 11 | - member1besu:9545 12 | - member2besu:9545 13 | - member3besu:9545 14 | metrics_path: /metrics 15 | 16 | output.redis: 17 | enabled: true 18 | hosts: ["${REDIS_HOST}:${REDIS_PORT}"] 19 | key: metricbeat 20 | 21 | 22 | logging: 23 | level: error 24 | to_files: false 25 | json: true 26 | files: 27 | path: /var/log/metricbeat 28 | name: metricbeat-all.log 29 | keepfiles: 0 30 | #rotateonstartup: true 31 | 32 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@consensys-software/smart_contracts", 3 | "version": "1.0.0", 4 | "description": "Example smart contracts for trying out Quorum", 5 | "scripts": { 6 | "compile": "node scripts/compile.js", 7 | "deploy": "node scripts/deploy.js", 8 | "public-transaction": "node scripts/public_tx.js", 9 | "private-transaction": "node scripts/private_tx.js" 10 | }, 11 | "license": "Apache-2.0", 12 | "dependencies": { 13 | "async-promise-pool": "^1.0.3", 14 | "fs-extra": "^10.0.0", 15 | "solc": "0.7.6", 16 | "web3": "1.5.2", 17 | "ethers": "^5.6.1", 18 | "web3js-quorum": "21.7.0-rc1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/20_quorum.conf: -------------------------------------------------------------------------------- 1 | filter { 2 | if [service_name] == "quorum" { 3 | grok { 4 | match => { "message" => "%{GREEDYDATA:level}\[%{MONTHNUM:monthnum}\-%{DATA:monthday}\|%{TIME:time}\] %{GREEDYDATA:message}" } 5 | overwrite => [ "message" ] 6 | } 7 | mutate { 8 | add_field => { 9 | "timestamp" => "%{monthnum} %{monthday} %{time}" 10 | } 11 | } 12 | date { 13 | match => [ "timestamp" , "MM dd HH:mm:ss.SSS", "MM dd HH:mm:ss.SSS", "ISO8601"] 14 | remove_field => [ "timestamp" ] 15 | } 16 | mutate { 17 | remove_field => [ "time" ,"month","monthday","year","timestamp"] 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /templates/besu/config/besu/.env: -------------------------------------------------------------------------------- 1 | {% if monitoring == "splunk" %} 2 | # OpenTelemetry metrics 3 | BESU_METRICS_ENABLED=true 4 | BESU_METRICS_PROTOCOL=opentelemetry 5 | OTEL_EXPORTER_OTLP_METRIC_ENDPOINT=otelcollector:55680 6 | OTEL_EXPORTER_OTLP_SPAN_ENDPOINT=otelcollector:55680 7 | OTEL_EXPORTER_OTLP_METRIC_INSECURE=true 8 | OTEL_EXPORTER_OTLP_SPAN_INSECURE=true 9 | # Splunk logging configuration 10 | BESU_LOGGING=info 11 | LOGGER=Splunk 12 | SPLUNK_URL=https://splunk:8088/ 13 | SPLUNK_INDEX=logs 14 | SPLUNK_TOKEN=11111111-1111-1111-1111-1111111111113 15 | SPLUNK_SKIPTLSVERIFY=true 16 | LOG4J_CONFIGURATION_FILE=/config/log-config-splunk.xml 17 | 18 | {% else %} 19 | LOG4J_CONFIGURATION_FILE=/config/log-config.xml 20 | 21 | {% endif %} 22 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/components/quorumToken/QuorumTokenABI.tsx: -------------------------------------------------------------------------------- 1 | // In order to interact with a contract from js, we need the contract's ABI 2 | // Im using a human readable format here, but you can just as easily use the compiled output from HardHat 3 | 4 | export const QuorumTokenABI = [ 5 | // Read-Only Functions 6 | "function balanceOf(address owner) view returns (uint256)", 7 | "function totalSupply() view returns (uint256)", 8 | "function decimals() view returns (uint8)", 9 | "function symbol() view returns (string)", 10 | // Authenticated Functions 11 | "function transfer(address to, uint amount) returns (bool)", 12 | // Events 13 | "event Transfer(address indexed from, address indexed to, uint amount)" 14 | ]; -------------------------------------------------------------------------------- /files/common/loki/loki.yml: -------------------------------------------------------------------------------- 1 | auth_enabled: false 2 | 3 | server: 4 | http_listen_port: 3100 5 | grpc_listen_port: 9096 6 | 7 | common: 8 | path_prefix: /tmp/loki 9 | storage: 10 | filesystem: 11 | chunks_directory: /tmp/loki/chunks 12 | rules_directory: /tmp/loki/rules 13 | replication_factor: 1 14 | ring: 15 | instance_addr: 127.0.0.1 16 | kvstore: 17 | store: inmemory 18 | 19 | schema_config: 20 | configs: 21 | - from: 2021-01-01 22 | store: boltdb-shipper 23 | object_store: filesystem 24 | schema: v11 25 | index: 26 | prefix: index_ 27 | period: 24h 28 | 29 | # If you would like to disable reporting, uncomment the following lines: 30 | #analytics: 31 | # reporting_enabled: false -------------------------------------------------------------------------------- /files/common/.env: -------------------------------------------------------------------------------- 1 | # This file defines environment variables defaults for Docker-compose 2 | # but we also use it for shell scripts as a sourced file 3 | 4 | BESU_VERSION=23.4.1 5 | QUORUM_VERSION=23.4.0 6 | TESSERA_VERSION=23.4.0 7 | ETHSIGNER_VERSION=22.1.3 8 | QUORUM_EXPLORER_VERSION=4f60191 9 | 10 | LOCK_FILE=.quorumDevQuickstart.lock 11 | 12 | # GoQuorum consensus algorithm 13 | # istanbul, qbft, raft 14 | # !!! lower case ONLY here 15 | GOQUORUM_CONS_ALGO=qbft 16 | 17 | # Besu consensus algorithm 18 | # IBFT, QBFT, CLIQUE 19 | # PLEASE NOTE: IBFT used here refers to IBFT2.0 and not IBFT1.0 More information can be found https://besu.hyperledger.org/en/latest/HowTo/Configure/Consensus-Protocols/IBFT/ 20 | # We use IBFT here to keep the API names consistent 21 | # !!! upper case ONLY here 22 | BESU_CONS_ALGO=QBFT 23 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev -p 3001", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@chakra-ui/react": "^2.8.0", 13 | "@emotion/react": "^11.11.1", 14 | "@emotion/styled": "^11.11.0", 15 | "ethers": "6.7.1", 16 | "framer-motion": "^10.16.1", 17 | "next": "13.4.19", 18 | "react": "18.2.0", 19 | "react-dom": "18.2.0" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "20.5.4", 23 | "@types/react": "18.2.21", 24 | "@types/react-dom": "18.2.7", 25 | "eslint": "8.47.0", 26 | "eslint-config-next": "13.4.19", 27 | "typescript": "5.1.6" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const main = require("./build").main; 3 | 4 | if (require.main === module) { 5 | // note: main returns a Promise, but we don't need to do anything 6 | // special with it, so we use the void operator to indicate to eslint that 7 | // we left this dangling intentionally... 8 | try { 9 | void main(); 10 | } catch (err) { 11 | if (err && err.stack && process.argv.length >= 3 && process.argv[2] === "--stackTraceOnError") { 12 | console.error(`Fatal error: ${err.stack}`); 13 | } else if (err && err.message) { 14 | console.error(`Fatal error: ${err.message}`); 15 | } else if (err) { 16 | console.error(`Fatal error: ${err}`); 17 | } else { 18 | console.error(`Fatal error: unknown`); 19 | } 20 | process.exit(1); 21 | } 22 | } -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from 'react' 2 | import { Container, Flex, useColorModeValue, Spacer, Heading, Center, Text } from '@chakra-ui/react' 3 | 4 | interface LayoutProps { 5 | children: React.ReactNode; 6 | } 7 | 8 | export default function Layout({ children }: LayoutProps) { 9 | return ( 10 |
11 | 12 | 13 | Quorum Quickstart DApp 14 | 15 | 16 | 17 | 18 | {children} 19 | 20 | 21 |
22 | © {new Date().getFullYear()} ConsenSys Software, Inc. All rights reserved. 23 |
24 | 25 |
26 | ) 27 | } -------------------------------------------------------------------------------- /files/common/smart_contracts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@consensys-software/smart_contracts", 3 | "version": "1.0.0", 4 | "description": "Example smart contracts for trying out Quorum", 5 | "scripts": { 6 | "compile": "node scripts/compile.js", 7 | "deploy": "node scripts/deploy.js", 8 | "public-transaction": "node scripts/public_tx.js", 9 | "private-transaction": "node scripts/private_tx.js" 10 | }, 11 | "license": "Apache-2.0", 12 | "dependencies": { 13 | "async-promise-pool": "^1.0.6", 14 | "fs-extra": "^10.0.0", 15 | "solc": "0.8.10", 16 | "@nomicfoundation/hardhat-ethers": "^3.0.0", 17 | "@nomicfoundation/hardhat-network-helpers": "^1.0.0", 18 | "@nomicfoundation/hardhat-toolbox": "^3.0.0", 19 | "@nomicfoundation/hardhat-verify": "^1.0.0", 20 | "ethers": "6.7.1", 21 | "hardhat-gas-reporter": "^1.0.8", 22 | "@ethereumjs/common": "^4.0.0", 23 | "@ethereumjs/tx": "^5.0.0", 24 | "web3js-quorum": "22.4.0", 25 | "web3": "1.10.2" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /files/common/logstash/pipeline/30_elasticsearch.conf: -------------------------------------------------------------------------------- 1 | output { 2 | if [service_name] == "logstash" { 3 | elasticsearch { 4 | hosts => ["${ES_HOST}"] 5 | index => "logstash-%{+YYYY.MM.dd}" 6 | } 7 | } 8 | 9 | else if [service_name] == "besu" { 10 | elasticsearch { 11 | hosts => ["${ES_HOST}"] 12 | index => "besu-%{+YYYY.MM.dd}" 13 | } 14 | } 15 | 16 | else if [service_name] == "tessera" { 17 | elasticsearch { 18 | hosts => ["${ES_HOST}"] 19 | index => "tessera-%{+YYYY.MM.dd}" 20 | } 21 | } 22 | 23 | else if [service_name] == "quorum" { 24 | elasticsearch { 25 | hosts => ["${ES_HOST}"] 26 | index => "quorum-%{+YYYY.MM.dd}" 27 | } 28 | } 29 | 30 | else if [type] == "metricbeat" { 31 | elasticsearch { 32 | hosts => ["${ES_HOST}"] 33 | index => "metricbeat-%{+YYYY.MM.dd}" 34 | } 35 | } 36 | 37 | else { 38 | elasticsearch { 39 | hosts => ["${ES_HOST}"] 40 | index => "unknown-%{+YYYY.MM.dd}" 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /files/common/splunk/splunk.yml: -------------------------------------------------------------------------------- 1 | splunk: 2 | conf: 3 | indexes: 4 | directory: /opt/splunk/etc/apps/search/local 5 | content: 6 | ledger: 7 | coldPath: $SPLUNK_DB/ledger/colddb 8 | datatype: event 9 | homePath: $SPLUNK_DB/ledger/db 10 | maxTotalDataSizeMB: 4096 11 | thawedPath: $SPLUNK_DB/ledger/thaweddb 12 | logs: 13 | coldPath: $SPLUNK_DB/logs/colddb 14 | datatype: event 15 | homePath: $SPLUNK_DB/logs/db 16 | maxTotalDataSizeMB: 4096 17 | thawedPath: $SPLUNK_DB/logs/thaweddb 18 | metrics: 19 | coldPath: $SPLUNK_DB/metrics/colddb 20 | datatype: metric 21 | homePath: $SPLUNK_DB/metrics/db 22 | maxTotalDataSizeMB: 1024 23 | thawedPath: $SPLUNK_DB/metrics/thaweddb 24 | traces: 25 | coldPath: $SPLUNK_DB/traces/colddb 26 | datatype: event 27 | homePath: $SPLUNK_DB/traces/db 28 | maxTotalDataSizeMB: 1024 29 | thawedPath: $SPLUNK_DB/traces/thaweddb 30 | 31 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/components/MMAccount.tsx: -------------------------------------------------------------------------------- 1 | 2 | import React, {useEffect, useState } from 'react'; 3 | import { Heading, Text, VStack, Box, Button, Input, Spacer, Flex } from '@chakra-ui/react' 4 | 5 | interface MMAccountProps { 6 | balance: string | undefined, 7 | chainId: number | undefined 8 | erc20ContractAddress: string 9 | deployedAddressHandler: any 10 | } 11 | 12 | export default function MMAccount(props:MMAccountProps){ 13 | 14 | return ( 15 | 16 | Account 17 | Details of the account connected to Metamask 18 | Balance of current account (ETH): {props.balance} 19 | ChainId: {props.chainId} 20 | {/* todo: fix formatting here */} 21 | Address that the QuorumToken was deployed to: 22 | 23 | 24 | ) 25 | } -------------------------------------------------------------------------------- /files/common/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -u 2 | 3 | # Copyright 2018 ConsenSys AG. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 11 | # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | # specific language governing permissions and limitations under the License. 13 | 14 | NO_LOCK_REQUIRED=false 15 | 16 | . ./.env 17 | . ./.common.sh 18 | 19 | echo "${bold}*************************************" 20 | echo "Quorum Dev Quickstart " 21 | echo "*************************************${normal}" 22 | echo "Stopping network" 23 | echo "----------------------------------" 24 | 25 | 26 | docker compose stop 27 | 28 | if [ -f "docker-compose-deps.yml" ]; then 29 | echo "Stopping dependencies..." 30 | docker compose -f docker-compose-deps.yml stop 31 | fi 32 | 33 | -------------------------------------------------------------------------------- /files/besu/quorum-explorer/env: -------------------------------------------------------------------------------- 1 | QE_BASEPATH="/explorer" 2 | QE_CONFIG_PATH="/app/config.json" 3 | NODE_ENV=production 4 | 5 | DISABLE_AUTH=true 6 | 7 | NEXTAUTH_URL=http://localhost:25000 8 | NEXTAUTH_URL_INTERNAL=http://localhost:25000 9 | NEXTAUTH_SECRET=68134139e258058cd8c74fc362cec39db176aa17a359e2a63233b9c858947445 10 | # DO NOT RE-USE THE ABOVE GENERATED IN PRODUCTION 11 | # To generate NEXTAUTH_SECRET: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32; 12 | 13 | local_username= 14 | local_password= 15 | 16 | GITHUB_ID= 17 | GITHUB_SECRET= 18 | 19 | AUTH0_ID= 20 | AUTH0_SECRET= 21 | AUTH0_DOMAIN= 22 | 23 | FACEBOOK_ID= 24 | FACEBOOK_SECRET= 25 | 26 | GOOGLE_ID= 27 | GOOGLE_SECRET= 28 | 29 | TWITTER_ID= 30 | TWITTER_SECRET= 31 | 32 | GITLAB_CLIENT_ID= 33 | GITLAB_CLIENT_SECRET= 34 | 35 | AZURE_AD_CLIENT_ID= 36 | AZURE_AD_CLIENT_SECRET= 37 | AZURE_AD_TENANT_ID= 38 | 39 | ATLASSIAN_CLIENT_ID= 40 | ATLASSIAN_CLIENT_SECRET= 41 | 42 | COGNITO_CLIENT_ID= 43 | COGNITO_CLIENT_SECRET= 44 | COGNITO_ISSUER= 45 | 46 | OKTA_CLIENT_ID= 47 | OKTA_CLIENT_SECRET= 48 | OKTA_ISSUER= 49 | 50 | SLACK_CLIENT_ID= 51 | SLACK_CLIENT_SECRET= 52 | -------------------------------------------------------------------------------- /files/goquorum/quorum-explorer/env: -------------------------------------------------------------------------------- 1 | QE_BASEPATH="/explorer" 2 | QE_CONFIG_PATH="/app/config.json" 3 | NODE_ENV=production 4 | 5 | DISABLE_AUTH=true 6 | 7 | NEXTAUTH_URL=http://localhost:25000 8 | NEXTAUTH_URL_INTERNAL=http://localhost:25000 9 | NEXTAUTH_SECRET=68134139e258058cd8c74fc362cec39db176aa17a359e2a63233b9c858947445 10 | # DO NOT RE-USE THE ABOVE GENERATED IN PRODUCTION 11 | # To generate NEXTAUTH_SECRET: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32; 12 | 13 | local_username= 14 | local_password= 15 | 16 | GITHUB_ID= 17 | GITHUB_SECRET= 18 | 19 | AUTH0_ID= 20 | AUTH0_SECRET= 21 | AUTH0_DOMAIN= 22 | 23 | FACEBOOK_ID= 24 | FACEBOOK_SECRET= 25 | 26 | GOOGLE_ID= 27 | GOOGLE_SECRET= 28 | 29 | TWITTER_ID= 30 | TWITTER_SECRET= 31 | 32 | GITLAB_CLIENT_ID= 33 | GITLAB_CLIENT_SECRET= 34 | 35 | AZURE_AD_CLIENT_ID= 36 | AZURE_AD_CLIENT_SECRET= 37 | AZURE_AD_TENANT_ID= 38 | 39 | ATLASSIAN_CLIENT_ID= 40 | ATLASSIAN_CLIENT_SECRET= 41 | 42 | COGNITO_CLIENT_ID= 43 | COGNITO_CLIENT_SECRET= 44 | COGNITO_ISSUER= 45 | 46 | OKTA_CLIENT_ID= 47 | OKTA_CLIENT_SECRET= 48 | OKTA_ISSUER= 49 | 50 | SLACK_CLIENT_ID= 51 | SLACK_CLIENT_SECRET= 52 | -------------------------------------------------------------------------------- /files/common/resume.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -u 2 | 3 | # Copyright 2018 ConsenSys AG. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 11 | # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | # specific language governing permissions and limitations under the License. 13 | 14 | NO_LOCK_REQUIRED=false 15 | 16 | . ./.env 17 | . ./.common.sh 18 | 19 | echo "${bold}*************************************" 20 | echo "Quorum Dev Quickstart " 21 | echo "*************************************${normal}" 22 | echo "Resuming network..." 23 | echo "----------------------------------" 24 | 25 | if [ -f "docker-compose-deps.yml" ]; then 26 | echo "Starting dependencies..." 27 | docker compose -f docker-compose-deps.yml start 28 | sleep 60 29 | fi 30 | 31 | docker compose start 32 | 33 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | // https://hardhat.org/hardhat-runner/docs/config 2 | import { HardhatUserConfig } from "hardhat/config"; 3 | import "@nomicfoundation/hardhat-toolbox"; 4 | 5 | module.exports = { 6 | networks: { 7 | // in built test network to use when developing contracts 8 | hardhat: { 9 | chainId: 1337 10 | }, 11 | quickstart: { 12 | url: "http://127.0.0.1:8545", 13 | chainId: 1337, 14 | // test accounts only, all good ;) 15 | accounts: [ 16 | "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 17 | "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 18 | "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f" 19 | ] 20 | } 21 | }, 22 | defaultNetwork: "hardhat", 23 | solidity: { 24 | version: "0.8.19", 25 | settings: { 26 | optimizer: { 27 | enabled: true, 28 | runs: 200 29 | } 30 | } 31 | }, 32 | paths: { 33 | sources: "./contracts", 34 | tests: "./test", 35 | cache: "./cache", 36 | artifacts: "./artifacts" 37 | }, 38 | mocha: { 39 | timeout: 40000 40 | } 41 | } -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quorumToken", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "compile": "npx hardhat compile", 8 | "test": "npx hardhat test", 9 | "deploy-quorumtoken": "npx hardhat run ./scripts/deploy_quorumtoken.ts --network quickstart " 10 | }, 11 | "dependencies": { 12 | "@openzeppelin/contracts": "^4.9.3", 13 | "hardhat": "^2.17.1" 14 | }, 15 | "devDependencies": { 16 | "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", 17 | "@nomicfoundation/hardhat-ethers": "^3.0.0", 18 | "@nomicfoundation/hardhat-network-helpers": "^1.0.0", 19 | "@nomicfoundation/hardhat-toolbox": "^3.0.0", 20 | "@nomicfoundation/hardhat-verify": "^1.0.0", 21 | "@typechain/ethers-v6": "^0.4.0", 22 | "@typechain/hardhat": "^8.0.0", 23 | "@types/chai": "^4.2.0", 24 | "@types/mocha": ">=9.1.0", 25 | "@types/node": ">=16.0.0", 26 | "chai": "^4.2.0", 27 | "ethers": "6.7.1", 28 | "hardhat-gas-reporter": "^1.0.8", 29 | "solidity-coverage": "^0.8.0", 30 | "ts-node": ">=8.0.0", 31 | "typechain": "^8.1.0", 32 | "typescript": ">=4.5.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /files/besu/config/besu/config.toml: -------------------------------------------------------------------------------- 1 | 2 | genesis-file="/config/genesis.json" 3 | node-private-key-file="/opt/besu/keys/nodekey" 4 | logging="INFO" 5 | data-path="/opt/besu/data" 6 | host-allowlist=["*"] 7 | min-gas-price=0 8 | 9 | # rpc 10 | rpc-http-enabled=true 11 | rpc-http-host="0.0.0.0" 12 | rpc-http-port=8545 13 | rpc-http-cors-origins=["*"] 14 | 15 | # ws 16 | rpc-ws-enabled=true 17 | rpc-ws-host="0.0.0.0" 18 | rpc-ws-port=8546 19 | 20 | # graphql 21 | graphql-http-enabled=true 22 | graphql-http-host="0.0.0.0" 23 | graphql-http-port=8547 24 | graphql-http-cors-origins=["*"] 25 | 26 | # metrics 27 | metrics-enabled=true 28 | metrics-host="0.0.0.0" 29 | metrics-port=9545 30 | 31 | # permissions 32 | permissions-nodes-config-file-enabled=true 33 | permissions-nodes-config-file="/config/permissions_config.toml" 34 | 35 | # bootnodes 36 | bootnodes=["enode://8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22@172.16.239.11:30303"] 37 | 38 | 39 | # Discovery at boot is set to a list of static files, but will also discover new nodes should they be added 40 | # static nodes 41 | static-nodes-file="/config/static-nodes.json" 42 | discovery-enabled=true 43 | -------------------------------------------------------------------------------- /files/besu/config/besu/log-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | INFO 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /files/besu/config/besu/static-nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | "enode://8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22@172.16.239.11:30303", 3 | "enode://b9050e002aa42464e6b07c811a1f9dfec01249af03f67b753e8415420649b184447bb2a784863ccbf327ad9e31aaba803464979dfe6a7facc669151a5fa6ad1b@172.16.239.12:30303", 4 | "enode://59cf0c623c582fa9b19bdf70fb6bade07f4ae32218dd4d1c7e2c7e65acf87da45cf2ab55d16d27360aafef17622c37c09db60d7680ebcc17b78867f4c05bcaa4@172.16.239.13:30303", 5 | "enode://2fd5b5b6ad529f55b71602026d1849d0036f06482368b5812fa793014195d3571b0840dbc4175617de2a12db8f1222c012420d471ae5c0d982118625cae58868@172.16.239.14:30303", 6 | "enode://86fcc16f4730fbfd238dc17ea552854c0943923bb1d5e886e5601b8d884fb0519060e0023f495dd24ffe60a65660fb7fdcdebfceedd2b3673dfa63658825924b@172.16.239.15:30303", 7 | "enode://98496800174b3c73ae33cba59f8f5e686cd488f7897c2edb52e2cf46383d75cd03dbb58dde07185bc0953f98800ca9a89f4b5ef450c5e51292ea08ec6130ee0c@172.16.239.16:30303", 8 | "enode://ad2c79c6561bc8212c2e8382611c62e406e767d1f3106c68ca206900f575cb8ba9a8be111c645cd9803701d684454c782c40d2361b000a32ed03d26228b30ec1@172.16.239.17:30303", 9 | "enode://af19c92deb635bd7720634de9b2e7908208530d6f5e96eee003a8f1799e5be4037957d7e2fdbe3605e3a38dab05c961679c02133a0e624e23a72f7961e8af6ac@172.16.239.18:30303" 10 | ] 11 | -------------------------------------------------------------------------------- /files/besu/config/besu/permissions_config.toml: -------------------------------------------------------------------------------- 1 | nodes-allowlist=[ 2 | "enode://8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22@172.16.239.11:30303", 3 | "enode://b9050e002aa42464e6b07c811a1f9dfec01249af03f67b753e8415420649b184447bb2a784863ccbf327ad9e31aaba803464979dfe6a7facc669151a5fa6ad1b@172.16.239.12:30303", 4 | "enode://59cf0c623c582fa9b19bdf70fb6bade07f4ae32218dd4d1c7e2c7e65acf87da45cf2ab55d16d27360aafef17622c37c09db60d7680ebcc17b78867f4c05bcaa4@172.16.239.13:30303", 5 | "enode://2fd5b5b6ad529f55b71602026d1849d0036f06482368b5812fa793014195d3571b0840dbc4175617de2a12db8f1222c012420d471ae5c0d982118625cae58868@172.16.239.14:30303", 6 | "enode://86fcc16f4730fbfd238dc17ea552854c0943923bb1d5e886e5601b8d884fb0519060e0023f495dd24ffe60a65660fb7fdcdebfceedd2b3673dfa63658825924b@172.16.239.15:30303", 7 | "enode://98496800174b3c73ae33cba59f8f5e686cd488f7897c2edb52e2cf46383d75cd03dbb58dde07185bc0953f98800ca9a89f4b5ef450c5e51292ea08ec6130ee0c@172.16.239.16:30303", 8 | "enode://ad2c79c6561bc8212c2e8382611c62e406e767d1f3106c68ca206900f575cb8ba9a8be111c645cd9803701d684454c782c40d2361b000a32ed03d26228b30ec1@172.16.239.17:30303", 9 | "enode://af19c92deb635bd7720634de9b2e7908208530d6f5e96eee003a8f1799e5be4037957d7e2fdbe3605e3a38dab05c961679c02133a0e624e23a72f7961e8af6ac@172.16.239.18:30303" 10 | ] 11 | 12 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/common/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -u 2 | 3 | # Copyright 2018 ConsenSys AG. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 11 | # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | # specific language governing permissions and limitations under the License. 13 | 14 | NO_LOCK_REQUIRED=true 15 | 16 | . ./.env 17 | . ./.common.sh 18 | 19 | # create log folders with the user permissions so it won't conflict with container permissions 20 | mkdir -p logs/besu logs/quorum logs/tessera 21 | 22 | # Build and run containers and network 23 | echo "docker-compose.yml" > ${LOCK_FILE} 24 | 25 | echo "${bold}*************************************" 26 | echo "Quorum Dev Quickstart" 27 | echo "*************************************${normal}" 28 | echo "Start network" 29 | echo "--------------------" 30 | 31 | if [ -f "docker-compose-deps.yml" ]; then 32 | echo "Starting dependencies..." 33 | docker compose -f docker-compose-deps.yml up --detach 34 | sleep 60 35 | fi 36 | 37 | echo "Starting network..." 38 | docker compose build --pull 39 | docker compose up --detach 40 | 41 | 42 | #list services and endpoints 43 | ./list.sh 44 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/static-nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | "enode://8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22@172.16.239.11:30303?discport=0&raftport=53000", 3 | "enode://b9050e002aa42464e6b07c811a1f9dfec01249af03f67b753e8415420649b184447bb2a784863ccbf327ad9e31aaba803464979dfe6a7facc669151a5fa6ad1b@172.16.239.12:30303?discport=0&raftport=53000", 4 | "enode://59cf0c623c582fa9b19bdf70fb6bade07f4ae32218dd4d1c7e2c7e65acf87da45cf2ab55d16d27360aafef17622c37c09db60d7680ebcc17b78867f4c05bcaa4@172.16.239.13:30303?discport=0&raftport=53000", 5 | "enode://2fd5b5b6ad529f55b71602026d1849d0036f06482368b5812fa793014195d3571b0840dbc4175617de2a12db8f1222c012420d471ae5c0d982118625cae58868@172.16.239.14:30303?discport=0&raftport=53000", 6 | "enode://86fcc16f4730fbfd238dc17ea552854c0943923bb1d5e886e5601b8d884fb0519060e0023f495dd24ffe60a65660fb7fdcdebfceedd2b3673dfa63658825924b@172.16.239.15:30303?discport=0&raftport=53000", 7 | "enode://98496800174b3c73ae33cba59f8f5e686cd488f7897c2edb52e2cf46383d75cd03dbb58dde07185bc0953f98800ca9a89f4b5ef450c5e51292ea08ec6130ee0c@172.16.239.16:30303?discport=0&raftport=53000", 8 | "enode://ad2c79c6561bc8212c2e8382611c62e406e767d1f3106c68ca206900f575cb8ba9a8be111c645cd9803701d684454c782c40d2361b000a32ed03d26228b30ec1@172.16.239.17:30303?discport=0&raftport=53000", 9 | "enode://af19c92deb635bd7720634de9b2e7908208530d6f5e96eee003a8f1799e5be4037957d7e2fdbe3605e3a38dab05c961679c02133a0e624e23a72f7961e8af6ac@172.16.239.18:30303?discport=0&raftport=53000" 10 | ] 11 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/permissioned-nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | "enode://8208a3f344695d44e9cf2c023683cbea7b9343e2f70a5e804bd2c93858e945f8f91439eef96a4ab6c47ff06637d6fbe6472f96de1655a1bee57ea896654f3a22@172.16.239.11:30303?discport=0&raftport=53000", 3 | "enode://b9050e002aa42464e6b07c811a1f9dfec01249af03f67b753e8415420649b184447bb2a784863ccbf327ad9e31aaba803464979dfe6a7facc669151a5fa6ad1b@172.16.239.12:30303?discport=0&raftport=53000", 4 | "enode://59cf0c623c582fa9b19bdf70fb6bade07f4ae32218dd4d1c7e2c7e65acf87da45cf2ab55d16d27360aafef17622c37c09db60d7680ebcc17b78867f4c05bcaa4@172.16.239.13:30303?discport=0&raftport=53000", 5 | "enode://2fd5b5b6ad529f55b71602026d1849d0036f06482368b5812fa793014195d3571b0840dbc4175617de2a12db8f1222c012420d471ae5c0d982118625cae58868@172.16.239.14:30303?discport=0&raftport=53000", 6 | "enode://86fcc16f4730fbfd238dc17ea552854c0943923bb1d5e886e5601b8d884fb0519060e0023f495dd24ffe60a65660fb7fdcdebfceedd2b3673dfa63658825924b@172.16.239.15:30303?discport=0&raftport=53000", 7 | "enode://98496800174b3c73ae33cba59f8f5e686cd488f7897c2edb52e2cf46383d75cd03dbb58dde07185bc0953f98800ca9a89f4b5ef450c5e51292ea08ec6130ee0c@172.16.239.16:30303?discport=0&raftport=53000", 8 | "enode://ad2c79c6561bc8212c2e8382611c62e406e767d1f3106c68ca206900f575cb8ba9a8be111c645cd9803701d684454c782c40d2361b000a32ed03d26228b30ec1@172.16.239.17:30303?discport=0&raftport=53000", 9 | "enode://af19c92deb635bd7720634de9b2e7908208530d6f5e96eee003a8f1799e5be4037957d7e2fdbe3605e3a38dab05c961679c02133a0e624e23a72f7961e8af6ac@172.16.239.18:30303?discport=0&raftport=53000" 10 | ] 11 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/scripts/compile.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const solc = require('solc'); 4 | 5 | const contractsPath = path.resolve(__dirname, '../', 'contracts'); 6 | 7 | function buildSources() { 8 | const sources = {}; 9 | const contractsFiles = fs.readdirSync(contractsPath); 10 | contractsFiles.forEach(file => { 11 | if(file.endsWith(".sol")){ 12 | const contractFullPath = path.resolve(contractsPath, file); 13 | sources[file] = { 14 | content: fs.readFileSync(contractFullPath, 'utf8') 15 | }; 16 | } 17 | }); 18 | return sources; 19 | } 20 | 21 | const input = { 22 | language: 'Solidity', 23 | sources: buildSources(), 24 | settings: { 25 | outputSelection: { 26 | '*': { 27 | '*': [ '*', 'evm.bytecode' ] 28 | } 29 | } 30 | } 31 | } 32 | 33 | function compileContracts() { 34 | const stringifiedJson = JSON.stringify(input); 35 | const compilationResult = solc.compile(stringifiedJson); 36 | const output = JSON.parse(compilationResult); 37 | const compiledContracts = output.contracts; 38 | for (let contract in compiledContracts) { 39 | for(let contractName in compiledContracts[contract]) { 40 | fs.outputJsonSync( 41 | path.resolve(contractsPath, `${contractName}.json`), 42 | compiledContracts[contract][contractName], { spaces: 2 } 43 | ) 44 | } 45 | } 46 | } 47 | 48 | const main = () => { 49 | compileContracts(); 50 | } 51 | 52 | if (require.main === module) { 53 | main(); 54 | } 55 | 56 | module.exports = exports = main 57 | 58 | 59 | -------------------------------------------------------------------------------- /files/common/filebeat/filebeat.yml: -------------------------------------------------------------------------------- 1 | 2 | filebeat.modules: 3 | 4 | # List of inputs to fetch data. 5 | filebeat.inputs: 6 | - paths: 7 | - "/var/log/logstash/logstash-*.log" 8 | type: log 9 | enabled: true 10 | document_type: logstash 11 | fields_under_root: true 12 | fields: 13 | service_name: logstash 14 | env_name: ${ENV_NAME} 15 | ip_address: ${IP_ADDRESS} 16 | 17 | - paths: 18 | - "/var/log/besu/*.log" 19 | type: log 20 | enabled: true 21 | document_type: besu 22 | fields_under_root: true 23 | fields: 24 | service_name: besu 25 | env_name: ${ENV_NAME} 26 | ip_address: ${IP_ADDRESS} 27 | 28 | - paths: 29 | - "/var/log/quorum/*.log" 30 | type: log 31 | enabled: true 32 | document_type: quorum 33 | fields_under_root: true 34 | fields: 35 | service_name: quorum 36 | env_name: ${ENV_NAME} 37 | ip_address: ${IP_ADDRESS} 38 | 39 | - paths: 40 | - "/var/log/tessera/*.log" 41 | type: log 42 | enabled: true 43 | document_type: tessera 44 | fields_under_root: true 45 | fields: 46 | service_name: tessera 47 | env_name: ${ENV_NAME} 48 | ip_address: ${IP_ADDRESS} 49 | 50 | output.redis: 51 | enabled: true 52 | hosts: ["${REDIS_HOST}:${REDIS_PORT}"] 53 | key: filebeat 54 | 55 | 56 | logging: 57 | level: error 58 | metrics.enabled: false 59 | to_files: false 60 | json: true 61 | files: 62 | path: /var/log/filebeat 63 | name: filebeat-all.log 64 | keepfiles: 0 65 | #rotateonstartup: true 66 | 67 | -------------------------------------------------------------------------------- /files/common/smart_contracts/scripts/compile.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const solc = require('solc'); 4 | 5 | const contractsPath = path.resolve(__dirname, '../', 'contracts'); 6 | 7 | function buildSources() { 8 | const sources = {}; 9 | const contractsFiles = fs.readdirSync(contractsPath); 10 | contractsFiles.forEach(file => { 11 | if(file.endsWith(".sol")){ 12 | const contractFullPath = path.resolve(contractsPath, file); 13 | sources[file] = { 14 | content: fs.readFileSync(contractFullPath, 'utf8') 15 | }; 16 | } 17 | }); 18 | return sources; 19 | } 20 | 21 | const input = { 22 | language: 'Solidity', 23 | sources: buildSources(), 24 | settings: { 25 | outputSelection: { 26 | '*': { 27 | '*': [ '*', 'evm.bytecode' ] 28 | } 29 | } 30 | } 31 | } 32 | 33 | function compileContracts() { 34 | const stringifiedJson = JSON.stringify(input); 35 | console.log(stringifiedJson) 36 | const compilationResult = solc.compile(stringifiedJson); 37 | console.log(compilationResult) 38 | const output = JSON.parse(compilationResult); 39 | console.log(output) 40 | const compiledContracts = output.contracts; 41 | for (let contract in compiledContracts) { 42 | for(let contractName in compiledContracts[contract]) { 43 | console.log(contract) 44 | fs.outputJsonSync( 45 | path.resolve(contractsPath, `${contractName}.json`), 46 | compiledContracts[contract][contractName], { spaces: 2 } 47 | ) 48 | } 49 | } 50 | } 51 | 52 | const main = () => { 53 | compileContracts(); 54 | } 55 | 56 | if (require.main === module) { 57 | main(); 58 | } 59 | 60 | module.exports = exports = main 61 | 62 | 63 | -------------------------------------------------------------------------------- /files/common/config/tessera/data/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {"timestamp":"%d{ISO8601}","container":"${hostName}","level":"%level","thread":"%thread","logger":"%logger{36}","message":"%replace(%replace(%msg){'[\r\n]',''}){'"','\\"'}","throwable":"%replace(%replace(%throwable){'[\r\n]',''}){'"','\\"'}"}%n 9 | 10 | 11 | 12 | 13 | /var/log/tessera/tessera-${HOSTNAME}.log 14 | true 15 | true 16 | 17 | {"timestamp":"%d{ISO8601}","container":"${hostName}","level":"%level","thread":"%thread","class":"%c{1}","logger":"%logger{36}","message":"%replace(%msg){'[\r\n]', ''}","throwable":"%replace(%replace(%throwable){'[\r\n]',''}){'"','\\"'}"}%n 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quorum-dev-quickstart", 3 | "version": "0.2.4", 4 | "description": "A utility that lets developers try out the new suite of Quorum tools from ConsenSys!", 5 | "main": "build/index.js", 6 | "repository": "git@github.com:ConsenSys/quorum-dev-quickstart.git", 7 | "contributors": [ 8 | "Joshua Fernandes <3722503+joshuafernandes@users.noreply.github.com>", 9 | "Eric Lin <38420555+Ezzahhh@users.noreply.github.com>" 10 | ], 11 | "license": "Apache-2.0", 12 | "private": false, 13 | "bin": "./index.js", 14 | "scripts": { 15 | "build": "tsc", 16 | "lint": "eslint './src/**'", 17 | "lintAndFix": "eslint --fix './src/**'", 18 | "prepare": "tsc && eslint --fix './src/**'", 19 | "start": "node build/index.js" 20 | }, 21 | "devDependencies": { 22 | "@types/express": "^4.17.7", 23 | "@types/express-session": "^1.17.0", 24 | "@types/got": "^9.6.11", 25 | "@types/node": "^14.0.24", 26 | "@types/nunjucks": "^3.2.0", 27 | "@types/tmp": "^0.2.0", 28 | "@types/yargs": "^17.0.0", 29 | "@typescript-eslint/eslint-plugin": "^3.7.0", 30 | "@typescript-eslint/parser": "^3.7.0", 31 | "eslint": "^7.32.0", 32 | "eslint-config-prettier": "^6.11.0", 33 | "eslint-plugin-import": "^2.22.0", 34 | "eslint-plugin-jsdoc": "^30.0.3", 35 | "eslint-plugin-prefer-arrow": "^1.2.1", 36 | "husky": "^7.0.2", 37 | "lint-staged": "^13.2.1", 38 | "typescript": "^3.9.7" 39 | }, 40 | "dependencies": { 41 | "chalk": "^4.1.0", 42 | "cli-spinners": "^2.6.1", 43 | "express": "^4.17.1", 44 | "express-session": "^1.17.2", 45 | "got": "^11.8.2", 46 | "isbinaryfile": "^4.0.8", 47 | "log-update": "^4.0.0", 48 | "nunjucks": "^3.2.3", 49 | "open": "^8.3.0", 50 | "tmp": "^0.2.1", 51 | "yargs": "^17.2.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /files/common/config/tessera/data/tessera-config-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "mode": "${TESSERA_MODE}", 3 | "useWhiteList": false, 4 | "jdbc": { 5 | "username": "sa", 6 | "password": "", 7 | "url": "jdbc:h2:./data/tm/db;MODE=Oracle;TRACE_LEVEL_SYSTEM_OUT=0", 8 | "autoCreateTables": true 9 | }, 10 | "serverConfigs": [ 11 | { 12 | "app": "ThirdParty", 13 | "enabled": true, 14 | "serverAddress": "http://${HOSTNAME}:9080", 15 | "communicationType": "REST" 16 | }, 17 | { 18 | "app": "Q2T", 19 | "enabled": true, 20 | "serverAddress": "http://${HOSTNAME}:9101", 21 | "sslConfig": { 22 | "tls": "OFF" 23 | }, 24 | "communicationType": "REST" 25 | }, 26 | { 27 | "app": "P2P", 28 | "enabled": true, 29 | "serverAddress": "http://${HOSTNAME}:9000", 30 | "sslConfig": { 31 | "tls": "OFF" 32 | }, 33 | "communicationType": "REST" 34 | } 35 | ], 36 | "peer": [ 37 | { 38 | "url": "http://member1tessera:9000" 39 | }, 40 | { 41 | "url": "http://member2tessera:9000" 42 | }, 43 | { 44 | "url": "http://member3tessera:9000" 45 | } 46 | ], 47 | "keys": { 48 | "passwords": [], 49 | "keyData": [ 50 | { 51 | "privateKeyPath": "/config/keys/tm.key", 52 | "publicKeyPath": "/config/keys/tm.pub" 53 | } 54 | ] 55 | }, 56 | "alwaysSendTo": [], 57 | "bootstrapNode": false, 58 | "features": { 59 | "enableRemoteKeyValidation": false, 60 | "enablePrivacyEnhancements": true 61 | } 62 | } -------------------------------------------------------------------------------- /files/common/remove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -u 2 | 3 | # Copyright 2018 ConsenSys AG. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 11 | # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | # specific language governing permissions and limitations under the License. 13 | 14 | NO_LOCK_REQUIRED=false 15 | 16 | . ./.env 17 | . ./.common.sh 18 | 19 | removeDockerImage(){ 20 | if [[ ! -z `docker ps -a | grep $1` ]]; then 21 | docker image rm $1 22 | fi 23 | } 24 | 25 | echo "${bold}*************************************" 26 | echo "Quorum Dev Quickstart " 27 | echo "*************************************${normal}" 28 | echo "Stop and remove network..." 29 | 30 | docker compose down -v 31 | docker compose rm -sfv 32 | 33 | if [ -f "docker-compose-deps.yml" ]; then 34 | echo "Stopping dependencies..." 35 | docker compose -f docker-compose-deps.yml down -v 36 | docker compose rm -sfv 37 | fi 38 | # pet shop dapp 39 | if [[ ! -z `docker ps -a | grep quorum-dev-quickstart_pet_shop` ]]; then 40 | docker stop quorum-dev-quickstart_pet_shop 41 | docker rm quorum-dev-quickstart_pet_shop 42 | removeDockerImage quorum-dev-quickstart_pet_shop 43 | fi 44 | 45 | if grep -q 'kibana:' docker-compose.yml 2> /dev/null ; then 46 | docker image rm quorum-test-network_elasticsearch 47 | docker image rm quorum-test-network_logstash 48 | docker image rm quorum-test-network_filebeat 49 | docker image rm quorum-test-network_metricbeat 50 | fi 51 | 52 | rm ${LOCK_FILE} 53 | echo "Lock file ${LOCK_FILE} removed" 54 | -------------------------------------------------------------------------------- /files/besu/quorum-explorer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "algorithm": "qbft", 3 | "nodes": [ 4 | { 5 | "name": "rpcnode", 6 | "client": "besu", 7 | "rpcUrl": "http://rpcnode:8545", 8 | "privateTxUrl": "" 9 | }, 10 | { 11 | "name": "validator1", 12 | "client": "besu", 13 | "rpcUrl": "http://validator1:8545", 14 | "privateTxUrl": "" 15 | }, 16 | { 17 | "name": "validator2", 18 | "client": "besu", 19 | "rpcUrl": "http://validator2:8545", 20 | "privateTxUrl": "" 21 | }, 22 | { 23 | "name": "validator3", 24 | "client": "besu", 25 | "rpcUrl": "http://validator3:8545", 26 | "privateTxUrl": "" 27 | }, 28 | { 29 | "name": "validator4", 30 | "client": "besu", 31 | "rpcUrl": "http://validator4:8545", 32 | "privateTxUrl": "" 33 | }, 34 | { 35 | "name": "member1", 36 | "client": "besu", 37 | "rpcUrl": "http://member1besu:8545", 38 | "privateTxUrl": "http://member1tessera:9080", 39 | "privateKey": "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 40 | "accountAddress": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73" 41 | }, 42 | { 43 | "name": "member2", 44 | "client": "besu", 45 | "rpcUrl": "http://member2besu:8545", 46 | "privateTxUrl": "http://member2tessera:9080", 47 | "privateKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 48 | "accountAddress": "0x627306090abaB3A6e1400e9345bC60c78a8BEf57" 49 | }, 50 | { 51 | "name": "member3", 52 | "client": "besu", 53 | "rpcUrl": "http://member3besu:8545", 54 | "privateTxUrl": "http://member3tessera:9080", 55 | "privateKey": "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 56 | "accountAddress": "0xf17f52151EbEF6C7334FAD080c5704D77216b732" 57 | } 58 | ] 59 | } 60 | 61 | -------------------------------------------------------------------------------- /files/common/config/grafana/provisioning/datasources/loki.yml: -------------------------------------------------------------------------------- 1 | # config file version 2 | apiVersion: 1 3 | 4 | # list of datasources that should be deleted from the database 5 | deleteDatasources: 6 | - name: Graphite 7 | orgId: 1 8 | 9 | # list of datasources to insert/update depending 10 | # what's available in the database 11 | datasources: 12 | # name of the datasource. Required 13 | - name: Loki 14 | # datasource type. Required 15 | type: loki 16 | # access mode. proxy or direct (Server or Browser in the UI). Required 17 | access: proxy 18 | # org id. will default to orgId 1 if not specified 19 | orgId: 1 20 | # url 21 | url: http://loki:3100/ 22 | # Deprecated, use secureJsonData.password 23 | password: 24 | # database user, if used 25 | user: 26 | # database name, if used 27 | database: 28 | # enable/disable basic auth 29 | basicAuth: 30 | # basic auth username 31 | basicAuthUser: 32 | # Deprecated, use secureJsonData.basicAuthPassword 33 | basicAuthPassword: 34 | # enable/disable with credentials headers 35 | withCredentials: 36 | # mark as default datasource. Max one per org 37 | isDefault: false 38 | # fields that will be converted to json and stored in jsonData 39 | jsonData: 40 | graphiteVersion: "1.1" 41 | tlsAuth: false 42 | tlsAuthWithCACert: false 43 | # json object of data that will be encrypted. 44 | secureJsonData: 45 | tlsCACert: "..." 46 | tlsClientCert: "..." 47 | tlsClientKey: "..." 48 | # database password, if used 49 | password: 50 | # basic auth password 51 | basicAuthPassword: 52 | version: 1 53 | # allow users to edit datasources from the UI. 54 | editable: true 55 | -------------------------------------------------------------------------------- /files/common/config/grafana/provisioning/datasources/prometheus.yml: -------------------------------------------------------------------------------- 1 | # config file version 2 | apiVersion: 1 3 | 4 | # list of datasources that should be deleted from the database 5 | deleteDatasources: 6 | - name: Graphite 7 | orgId: 1 8 | 9 | # list of datasources to insert/update depending 10 | # what's available in the database 11 | datasources: 12 | # name of the datasource. Required 13 | - name: Prometheus 14 | # datasource type. Required 15 | type: prometheus 16 | # access mode. proxy or direct (Server or Browser in the UI). Required 17 | access: proxy 18 | # org id. will default to orgId 1 if not specified 19 | orgId: 1 20 | # url 21 | url: http://prometheus:9090/ 22 | # Deprecated, use secureJsonData.password 23 | password: 24 | # database user, if used 25 | user: 26 | # database name, if used 27 | database: 28 | # enable/disable basic auth 29 | basicAuth: 30 | # basic auth username 31 | basicAuthUser: 32 | # Deprecated, use secureJsonData.basicAuthPassword 33 | basicAuthPassword: 34 | # enable/disable with credentials headers 35 | withCredentials: 36 | # mark as default datasource. Max one per org 37 | isDefault: true 38 | # fields that will be converted to json and stored in jsonData 39 | jsonData: 40 | graphiteVersion: "1.1" 41 | tlsAuth: false 42 | tlsAuthWithCACert: false 43 | # json object of data that will be encrypted. 44 | secureJsonData: 45 | tlsCACert: "..." 46 | tlsClientCert: "..." 47 | tlsClientKey: "..." 48 | # database password, if used 49 | password: 50 | # basic auth password 51 | basicAuthPassword: 52 | version: 1 53 | # allow users to edit datasources from the UI. 54 | editable: true 55 | -------------------------------------------------------------------------------- /files/goquorum/quorum-explorer/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "algorithm": "qbft", 3 | "nodes": [ 4 | { 5 | "name": "rpcnode", 6 | "client": "goquorum", 7 | "rpcUrl": "http://rpcnode:8545", 8 | "privateTxUrl": "" 9 | }, 10 | { 11 | "name": "validator1", 12 | "client": "goquorum", 13 | "rpcUrl": "http://validator1:8545", 14 | "privateTxUrl": "" 15 | }, 16 | { 17 | "name": "validator2", 18 | "client": "goquorum", 19 | "rpcUrl": "http://validator2:8545", 20 | "privateTxUrl": "" 21 | }, 22 | { 23 | "name": "validator3", 24 | "client": "goquorum", 25 | "rpcUrl": "http://validator3:8545", 26 | "privateTxUrl": "" 27 | }, 28 | { 29 | "name": "validator4", 30 | "client": "goquorum", 31 | "rpcUrl": "http://validator4:8545", 32 | "privateTxUrl": "" 33 | }, 34 | { 35 | "name": "member1", 36 | "client": "goquorum", 37 | "rpcUrl": "http://member1quorum:8545", 38 | "privateTxUrl": "http://member1tessera:9080", 39 | "privateKey": "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 40 | "accountAddress": "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73" 41 | }, 42 | { 43 | "name": "member2", 44 | "client": "goquorum", 45 | "rpcUrl": "http://member2quorum:8545", 46 | "privateTxUrl": "http://member2tessera:9080", 47 | "privateKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 48 | "accountAddress": "0x627306090abaB3A6e1400e9345bC60c78a8BEf57" 49 | }, 50 | { 51 | "name": "member3", 52 | "client": "goquorum", 53 | "rpcUrl": "http://member3quorum:8545", 54 | "privateTxUrl": "http://member3tessera:9080", 55 | "privateKey": "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 56 | "accountAddress": "0xf17f52151EbEF6C7334FAD080c5704D77216b732" 57 | } 58 | ] 59 | } 60 | 61 | -------------------------------------------------------------------------------- /files/common/logstash/config/log4j2.properties: -------------------------------------------------------------------------------- 1 | status = trace 2 | name = LogstashPropertiesConfig 3 | 4 | appender.console.type = Console 5 | appender.console.name = plain_console 6 | appender.console.layout.type = PatternLayout 7 | appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c]%notEmpty{[%X{pipeline.id}]}%notEmpty{[%X{plugin.id}]} %m%n 8 | 9 | appender.json_console.type = Console 10 | appender.json_console.name = json_console 11 | appender.json_console.layout.type = JSONLayout 12 | appender.json_console.layout.compact = true 13 | appender.json_console.layout.eventEol = true 14 | 15 | appender.rolling.type = RollingFile 16 | appender.rolling.name = plain_rolling 17 | appender.rolling.fileName = ${sys:ls.logs}/logstash-${env:HOSTNAME}.log 18 | appender.rolling.filePattern = ${sys:ls.logs}/logstash-${env:HOSTNAME}-%d{yyyy-MM-dd}.bak 19 | appender.rolling.policies.type = Policies 20 | appender.rolling.policies.time.type = TimeBasedTriggeringPolicy 21 | appender.rolling.policies.time.interval = 1 22 | appender.rolling.policies.time.modulate = true 23 | appender.rolling.layout.type = PatternLayout 24 | appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %-.10000m%n 25 | 26 | appender.json_rolling.type = RollingFile 27 | appender.json_rolling.name = json_rolling 28 | appender.json_rolling.fileName = ${sys:ls.logs}/logstash-${env:HOSTNAME}.log 29 | appender.json_rolling.filePattern = ${sys:ls.logs}/logstash-${env:HOSTNAME}-%d{yyyy-MM-dd}.bak 30 | appender.json_rolling.policies.type = Policies 31 | appender.json_rolling.policies.time.type = TimeBasedTriggeringPolicy 32 | appender.json_rolling.policies.time.interval = 1 33 | appender.json_rolling.policies.time.modulate = true 34 | appender.json_rolling.layout.type = JSONLayout 35 | appender.json_rolling.layout.compact = true 36 | appender.json_rolling.layout.eventEol = true 37 | 38 | rootLogger.level = ${sys:ls.log.level} 39 | rootLogger.appenderRef.console.ref = ${sys:ls.log.format}_console 40 | rootLogger.appenderRef.rolling.ref = ${sys:ls.log.format}_rolling 41 | -------------------------------------------------------------------------------- /src/questions/types.ts: -------------------------------------------------------------------------------- 1 | export interface AnswerMap { 2 | [index: string]: any; 3 | } 4 | 5 | /** 6 | * Represents a tree of questions that can be used to build up a template context 7 | */ 8 | export interface QuestionTree { 9 | /** 10 | * The text that the user is shown before waiting for answer input 11 | */ 12 | prompt: string; 13 | 14 | /** 15 | * The name of the question, also used as a variable name in the resulting 16 | * template context 17 | */ 18 | name: string; 19 | 20 | /** 21 | * An optional list of options for multiple-choice questions. 22 | */ 23 | options?: QuestionOption[]; 24 | 25 | /** 26 | * Transformation and validation function that can be used for both free 27 | * form and multiple choice question types. 28 | * 29 | * @param transformerValidator a function that transforms valid input to 30 | * the answer data desired and throws on invalid input. Mutates the given 31 | * AnswerMap as needed. Returns a follow-up question, if necessary. Can be 32 | * async. 33 | */ 34 | transformerValidator?: (rawInput: any, answers: AnswerMap) => Promise | QuestionTree | undefined; 35 | } 36 | 37 | /** 38 | * Represents a single option in a list of options for a multiple choice 39 | * question. 40 | */ 41 | export interface QuestionOption { 42 | /** 43 | * The text shown to the user to describe this option. 44 | */ 45 | label: string; 46 | 47 | /** 48 | * The value that should be used when this option is selected. If the 49 | * question also contains a transformerValidator, this is data will be 50 | * passed as rawInput. 51 | */ 52 | value: any; 53 | 54 | /** 55 | * The follow-up question that should be given to the user after this one, 56 | * if applicable. 57 | */ 58 | nextQuestion?: QuestionTree; 59 | 60 | /** 61 | * Whether or not this option should be the default if no other option is 62 | * selected. 63 | */ 64 | default?: boolean; 65 | } -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/public/hre_eth_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | var ethers = require('ethers'); 4 | 5 | // member1 details 6 | const { accounts, besu } = require("../keys.js"); 7 | const host = besu.rpcnode.url; 8 | // one of the seeded accounts 9 | const accountAPrivateKey = accounts.a.privateKey; 10 | 11 | async function main(){ 12 | const provider = new ethers.JsonRpcProvider(host); 13 | 14 | const walletA = new ethers.Wallet(accountAPrivateKey, provider); 15 | var accountABalance = await provider.getBalance(walletA.address); 16 | console.log("Account A has balance of: " + accountABalance); 17 | 18 | // create a new account to use to transfer eth to 19 | const walletB = ethers.Wallet.createRandom() 20 | var accountBBalance = await provider.getBalance(walletB.address); 21 | console.log("Account B has balance of: " + accountBBalance); 22 | 23 | const nonce = await provider.getTransactionCount(walletA.address); 24 | const feeData = await provider.getFeeData(); 25 | const gasLimit = await provider.estimateGas({from: walletA.address, value: ethers.parseEther("0.01")}); 26 | 27 | // send some eth from A to B 28 | const txn = { 29 | nonce: nonce, 30 | from: walletA.address, 31 | to: walletB.address, 32 | value: 0x10, //amount of eth to transfer 33 | gasPrice: feeData.gasPrice, //ETH per unit of gas 34 | gasLimit: gasLimit //max number of gas units the tx is allowed to use 35 | }; 36 | 37 | console.log("create and sign the txn") 38 | const signedTx = await walletA.sendTransaction(txn); 39 | await signedTx.wait(); 40 | console.log("tx transactionHash: " + signedTx.hash); 41 | 42 | //After the transaction there should be some ETH transferred 43 | accountABalance = await provider.getBalance(walletA.address); 44 | console.log("Account A has balance of: " + accountABalance); 45 | accountBBalance = await provider.getBalance(walletB.address); 46 | console.log("Account B has balance of: " + accountBBalance); 47 | 48 | } 49 | 50 | if (require.main === module) { 51 | main(); 52 | } 53 | 54 | module.exports = exports = main 55 | 56 | -------------------------------------------------------------------------------- /files/common/promtail/promtail.yml: -------------------------------------------------------------------------------- 1 | server: 2 | http_listen_port: 9080 3 | grpc_listen_port: 0 4 | 5 | positions: 6 | filename: /tmp/positions.yaml 7 | 8 | clients: 9 | - url: http://loki:3100/loki/api/v1/push 10 | 11 | scrape_configs: 12 | - job_name: besu 13 | pipeline_stages: 14 | - json: 15 | expressions: 16 | timestamp: timestamp 17 | container: container 18 | level: level 19 | class: class 20 | message: message 21 | throwable: throwable 22 | thread: thread 23 | logger: logger 24 | - labels: 25 | container: 26 | level: 27 | - timestamp: 28 | source: timestamp 29 | format: ISO8601 30 | # - template: 31 | # source: throwable 32 | # template: '{{if .Value }} {{- " | Stack Trace: " -}}{{- .Value -}} {{else}} {{- " " -}} {{end}}' 33 | static_configs: 34 | - targets: 35 | - localhost 36 | labels: 37 | job: besu 38 | __path__: /var/log/besu/*.log 39 | 40 | - job_name: tessera 41 | pipeline_stages: 42 | - json: 43 | expressions: 44 | timestamp: timestamp 45 | container: container 46 | level: level 47 | class: class 48 | message: message 49 | throwable: throwable 50 | thread: thread 51 | logger: logger 52 | - labels: 53 | container: 54 | level: 55 | - timestamp: 56 | source: timestamp 57 | format: ISO8601 58 | # - template: 59 | # source: throwable 60 | # template: '{{if .Value }} {{- " | Stack Trace: " -}}{{- .Value -}} {{else}} {{- " " -}} {{end}}' 61 | static_configs: 62 | - targets: 63 | - localhost 64 | labels: 65 | job: tessera 66 | __path__: /var/log/tessera/*.log 67 | 68 | - job_name: quorum 69 | static_configs: 70 | - targets: 71 | - localhost 72 | labels: 73 | job: quorum 74 | __path__: /var/log/quorum/*.log 75 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/scripts/public/hre_eth_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | var ethers = require('ethers'); 4 | 5 | // member1 details 6 | const { accounts, quorum } = require("../keys.js"); 7 | const host = quorum.rpcnode.url; 8 | // one of the seeded accounts 9 | const accountAPrivateKey = accounts.a.privateKey; 10 | 11 | async function main(){ 12 | const provider = new ethers.JsonRpcProvider(host); 13 | 14 | const walletA = new ethers.Wallet(accountAPrivateKey, provider); 15 | var accountABalance = await provider.getBalance(walletA.address); 16 | console.log("Account A has balance of: " + accountABalance); 17 | 18 | // create a new account to use to transfer eth to 19 | const walletB = ethers.Wallet.createRandom() 20 | var accountBBalance = await provider.getBalance(walletB.address); 21 | console.log("Account B has balance of: " + accountBBalance); 22 | 23 | const nonce = await provider.getTransactionCount(walletA.address); 24 | const feeData = await provider.getFeeData(); 25 | const gasLimit = await provider.estimateGas({from: walletA.address, value: ethers.parseEther("0.01")}); 26 | 27 | // send some eth from A to B 28 | const txn = { 29 | nonce: nonce, 30 | from: walletA.address, 31 | to: walletB.address, 32 | value: 0x10, //amount of eth to transfer 33 | gasPrice: feeData.gasPrice, //ETH per unit of gas 34 | gasLimit: gasLimit //max number of gas units the tx is allowed to use 35 | }; 36 | 37 | console.log("create and sign the txn") 38 | const signedTx = await walletA.sendTransaction(txn); 39 | await signedTx.wait(); 40 | console.log("tx transactionHash: " + signedTx.hash); 41 | 42 | //After the transaction there should be some ETH transferred 43 | accountABalance = await provider.getBalance(walletA.address); 44 | console.log("Account A has balance of: " + accountABalance); 45 | accountBBalance = await provider.getBalance(walletB.address); 46 | console.log("Account B has balance of: " + accountBBalance); 47 | 48 | } 49 | 50 | if (require.main === module) { 51 | main(); 52 | } 53 | 54 | module.exports = exports = main 55 | 56 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/test/QuorumToken.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | time, 3 | loadFixture, 4 | } from "@nomicfoundation/hardhat-toolbox/network-helpers"; 5 | import { expect } from "chai" 6 | import { ethers } from "hardhat" 7 | import { Signer } from "ethers" 8 | 9 | describe("QuorumToken", function () { 10 | const initialSupply = ethers.parseEther('10000.0') 11 | 12 | // We define a fixture to reuse the same setup in every test. 13 | // ie a fixture is a function that is only ran the first time it is invoked (& a snapshot is made of the hardhat network). 14 | // On all subsequent invocations our fixture won’t be invoked, but rather the snapshot state is reset and loaded 15 | async function deployQuorumTokenFixture() { 16 | // Contracts are deployed using the first signer/account by default 17 | const [owner, otherAccount] = await ethers.getSigners(); 18 | const QuorumToken = await ethers.getContractFactory("QuorumToken") 19 | const quorumToken = await QuorumToken.deploy(initialSupply); 20 | const address = await quorumToken.getAddress(); 21 | return { quorumToken, address, owner, otherAccount }; 22 | } 23 | 24 | describe("Deployment", function () { 25 | it("Should have the correct initial supply", async function () { 26 | const {quorumToken, address} = await loadFixture(deployQuorumTokenFixture); 27 | expect(await quorumToken.totalSupply()).to.equal(initialSupply); 28 | }); 29 | 30 | it("Should token transfer with correct balance", async function () { 31 | const {quorumToken, address, owner, otherAccount} = await loadFixture(deployQuorumTokenFixture); 32 | const amount = ethers.parseEther('200.0') 33 | const accountAddress = await otherAccount.getAddress(); 34 | await expect(async () => quorumToken.transfer(accountAddress,amount)) 35 | .to.changeTokenBalance(quorumToken, otherAccount, amount) 36 | await expect(async () => quorumToken.connect(otherAccount).transfer(await owner.getAddress(),amount)) 37 | .to.changeTokenBalance(quorumToken, owner, amount) 38 | }); 39 | 40 | }); 41 | 42 | }) 43 | -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/public/web3_eth_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | const Web3 = require('web3'); 4 | 5 | // member1 details 6 | const { tessera, besu, accounts } = require("../keys.js"); 7 | const host = besu.rpcnode.url; 8 | 9 | async function main(){ 10 | const web3 = new Web3(host); 11 | //pre seeded account - test account only 12 | 13 | const privateKeyA = accounts.a.privateKey; 14 | const accountA = web3.eth.accounts.privateKeyToAccount(privateKeyA); 15 | var accountABalance = web3.utils.fromWei(await web3.eth.getBalance(accountA.address)); 16 | console.log("Account A has balance of: " + accountABalance); 17 | 18 | // create a new account to use to transfer eth to 19 | var accountB = web3.eth.accounts.create(); 20 | var accountBBalance = web3.utils.fromWei(await web3.eth.getBalance(accountB.address)); 21 | console.log("Account B has balance of: " + accountBBalance); 22 | 23 | // send some eth from A to B 24 | const txn = { 25 | nonce: web3.utils.numberToHex(await web3.eth.getTransactionCount(accountA.address)), 26 | from: accountA.address, 27 | to: accountB.address, 28 | value: "0x100", //amount of eth to transfer 29 | gasPrice: "0x0", //ETH per unit of gas 30 | gasLimit: "0x24A22" //max number of gas units the tx is allowed to use 31 | }; 32 | 33 | console.log("create and sign the txn") 34 | const signedTx = await web3.eth.accounts.signTransaction(txn, accountA.privateKey); 35 | console.log("sending the txn") 36 | const txReceipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction); 37 | console.log("tx transactionHash: " + txReceipt.transactionHash); 38 | 39 | //After the transaction there should be some ETH transferred 40 | accountABalance = web3.utils.fromWei(await web3.eth.getBalance(accountA.address)); 41 | console.log("Account A has an updated balance of: " + accountABalance); 42 | accountBBalance = web3.utils.fromWei(await web3.eth.getBalance(accountB.address)); 43 | console.log("Account B has an updated balance of: " + accountBBalance); 44 | 45 | } 46 | 47 | if (require.main === module) { 48 | main(); 49 | } 50 | 51 | module.exports = exports = main 52 | 53 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/components/quorumToken/TransferQuorumToken.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { Text, Button, Input , NumberInput, NumberInputField, FormControl, FormLabel } from '@chakra-ui/react'; 3 | import {ethers, Contract} from 'ethers'; 4 | import {QuorumTokenABI as abi} from './QuorumTokenABI'; 5 | import { TransactionResponse,TransactionReceipt } from "@ethersproject/abstract-provider"; 6 | 7 | declare let window: any; 8 | 9 | interface Props { 10 | addressContract: string, 11 | currentAccount: string | undefined 12 | } 13 | 14 | export default function TransferQuorumToken(props:Props){ 15 | const addressContract = props.addressContract 16 | const currentAccount = props.currentAccount 17 | const [amount, setAmount]=useState('100') 18 | const [toAddress, setToAddress]=useState("") 19 | 20 | const handleChange = (value:string) => setAmount(value) 21 | 22 | // https://docs.ethers.org/v6/getting-started/#starting-contracts 23 | async function transfer(event:React.FormEvent) { 24 | event.preventDefault() 25 | // const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8545'); 26 | const provider = new ethers.BrowserProvider(window.ethereum); 27 | const signer = await provider.getSigner(); 28 | const erc20:Contract = new ethers.Contract(addressContract, abi, signer); 29 | 30 | erc20.transfer(toAddress, ethers.parseEther(amount)) 31 | .then((tr: TransactionResponse) => { 32 | console.log(`TransactionResponse TX hash: ${tr.hash}`) 33 | // todo: maybe put this in a modal thing? 34 | tr.wait().then((receipt:TransactionReceipt)=>{console.log("transfer receipt",receipt)}) 35 | }) 36 | .catch((e:Error)=>console.log(e)) 37 | 38 | } 39 | 40 | 41 | return ( 42 |
43 | 44 | Amount: 45 | 46 | 47 | 48 | To address: 49 | setToAddress(e.target.value)} my={3}/> 50 | 51 | 52 |
53 | ) 54 | } 55 | -------------------------------------------------------------------------------- /files/common/splunk/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${env:LOG_LEVEL:-INFO} 5 | ${env:LOGGER:-Console} 6 | ${env:HOST:-${docker:containerId:-${hostName:-locahost}}} 7 | ${env:SPLUNK_URL} 8 | ${env:SPLUNK_TOKEN} 9 | ${env:SPLUNK_INDEX} 10 | ${env:SPLUNK_SOURCE:-besu} 11 | ${env:SPLUNK_SOURCETYPE:-besu} 12 | ${env:SPLUNK_BATCH_SIZE_BYTES:-65536} 13 | ${env:SPLUNK_BATCH_SIZE_COUNT:-1000} 14 | ${env:SPLUNK_BATCH_INTERVAL:-500} 15 | ${env:SPLUNK_SKIPTLSVERIFY:-false} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /files/besu/config/besu/log-config-splunk.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${env:LOG_LEVEL:-INFO} 5 | ${env:LOGGER:-Console} 6 | ${env:HOST:-${docker:containerId:-${hostName:-locahost}}} 7 | ${env:SPLUNK_URL} 8 | ${env:SPLUNK_TOKEN} 9 | ${env:SPLUNK_INDEX} 10 | ${env:SPLUNK_SOURCE:-besu} 11 | ${env:SPLUNK_SOURCETYPE:-besu} 12 | ${env:SPLUNK_BATCH_SIZE_BYTES:-65536} 13 | ${env:SPLUNK_BATCH_SIZE_COUNT:-1000} 14 | ${env:SPLUNK_BATCH_INTERVAL:-500} 15 | ${env:SPLUNK_SKIPTLSVERIFY:-false} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /files/common/.common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | me=`basename "$0"` 4 | 5 | if [ "$me" = ".common.sh" ];then 6 | echo >&2 "This script is not expected to be run separately." 7 | exit 1 8 | fi 9 | 10 | bold=$(tput bold) 11 | normal=$(tput sgr0) 12 | 13 | hash docker 2>/dev/null || { 14 | echo >&2 "This script requires Docker but it's not installed." 15 | echo >&2 "Refer to documentation to fulfill requirements." 16 | exit 1 17 | } 18 | 19 | docker compose version &>/dev/null 20 | if [ "$?" -eq "1" ];then 21 | echo >&2 "This script requires Docker compose but it's not installed." 22 | echo >&2 "Refer to documentation to fulfill requirements." 23 | exit 1 24 | fi 25 | 26 | docker info &>/dev/null 27 | if [ "$?" -eq "1" ];then 28 | echo >&2 "This script requires Docker daemon to run. Start Docker and try again." 29 | echo >&2 "Refer to documentation to fulfill requirements." 30 | exit 1 31 | fi 32 | 33 | # We use "SI" measures here because the measurement in the UI and actual bytes 34 | # do not align exactly 35 | PRIVACY_MINIMUM=$(( 6 * 1000 * 1000 * 1000 )) 36 | NORMAL_MINIMUM=$(( 4 * 1000 * 1000 * 1000 )) 37 | dockermem=$(docker info --format '{{.MemTotal}}') 38 | 39 | case "$me" in 40 | *privacy* ) 41 | if [ $dockermem -lt $PRIVACY_MINIMUM ]; then 42 | echo >&2 "This script requires that docker has at least 6GB of memory available."; 43 | echo >&2 "Refer to documentation to fulfill requirements." 44 | exit 1 45 | fi; 46 | ;; 47 | * ) 48 | if [ $dockermem -lt $NORMAL_MINIMUM ]; then 49 | echo >&2 "This script requires that docker has at least 4GB of memory available." 50 | echo >&2 "Refer to documentation to fulfill requirements." 51 | exit 1 52 | fi 53 | ;; 54 | esac 55 | 56 | if [ "${NO_LOCK_REQUIRED}" = "true" ];then 57 | if [ -f ${LOCK_FILE} ];then 58 | echo "Network already in use (${LOCK_FILE} present)." >&2 59 | echo "Restart with ./resume.sh or remove with ./remove.sh before running again." >&2 60 | exit 1 61 | fi 62 | else 63 | composeFile="" 64 | if [ -f ${LOCK_FILE} ]; then 65 | #read the first line of the lock file and store the value as it's the compose file option 66 | composeFile=`sed '1q;d' ${LOCK_FILE}` 67 | else 68 | echo "Network is not running (${LOCK_FILE} not present)." >&2 69 | echo "Run it with ./run.sh first" >&2 70 | exit 1 71 | fi 72 | fi 73 | 74 | current_dir=${PWD##*/} 75 | 76 | -------------------------------------------------------------------------------- /src/networkBuilder.ts: -------------------------------------------------------------------------------- 1 | import {renderTemplateDir, validateDirectoryExists, copyFilesDir} from "./fileRendering"; 2 | import path from "path"; 3 | 4 | import {Spinner} from "./spinner"; 5 | 6 | export interface NetworkContext { 7 | clientType: "goquorum" | "besu"; 8 | nodeCount: number; 9 | privacy: boolean; 10 | monitoring: "splunk" | "elk" | "loki"; 11 | blockscout: boolean; 12 | chainlens: boolean; 13 | outputPath: string; 14 | } 15 | 16 | export async function buildNetwork(context: NetworkContext): Promise { 17 | const templatesDirPath = path.resolve(__dirname, "..", "templates"); 18 | const filesDirPath = path.resolve(__dirname, "..", "files"); 19 | const spinner = new Spinner(""); 20 | 21 | try { 22 | const blockchainClient = context.clientType === "besu" ? "Besu" : "GoQuorum" ; 23 | 24 | spinner.text = `Installing ${blockchainClient} quickstart to ${context.outputPath}`; 25 | spinner.start(); 26 | 27 | const commonTemplatePath = path.resolve(templatesDirPath, "common"); 28 | const clientTemplatePath = path.resolve(templatesDirPath, context.clientType); 29 | 30 | const commonFilesPath = path.resolve(filesDirPath, "common"); 31 | const clientFilesPath = path.resolve(filesDirPath, context.clientType); 32 | 33 | if (validateDirectoryExists(commonTemplatePath)) { 34 | renderTemplateDir(commonTemplatePath, context); 35 | } 36 | 37 | if (validateDirectoryExists(clientTemplatePath)) { 38 | renderTemplateDir(clientTemplatePath, context); 39 | } 40 | 41 | if (validateDirectoryExists(commonFilesPath)) { 42 | copyFilesDir(commonFilesPath, context); 43 | } 44 | 45 | if (validateDirectoryExists(clientFilesPath)) { 46 | copyFilesDir(clientFilesPath, context); 47 | } 48 | 49 | await spinner.succeed(`Installation complete.`); 50 | 51 | console.log(); 52 | console.log(`To start your test network, run 'run.sh' in the directory, '${context.outputPath}'`); 53 | console.log(`For more information on the test network, see 'README.md' in the directory, '${context.outputPath}'`); 54 | } catch (err) { 55 | if (spinner.isRunning) { 56 | await spinner.fail(`Installation failed. Error: ${(err as Error).message}`); 57 | } 58 | process.exit(1); 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /files/common/extra/generate_node_details.js: -------------------------------------------------------------------------------- 1 | const secp256k1 = require('secp256k1') 2 | const keccak = require('keccak') 3 | const { randomBytes } = require('crypto') 4 | const fs = require('fs') 5 | const Wallet = require('ethereumjs-wallet'); 6 | const yargs = require('yargs/yargs'); 7 | 8 | function generatePrivateKey() { 9 | let privKey 10 | do { 11 | privKey = randomBytes(32) 12 | } while (!secp256k1.privateKeyVerify(privKey)) 13 | return privKey 14 | } 15 | 16 | function derivePublicKey(privKey) { 17 | // slice on the end to remove the compression prefix ie. uncompressed use 04 prefix & compressed use 02 or 03 18 | // we generate the address, which wont work with the compression prefix 19 | let pubKey = secp256k1.publicKeyCreate(privKey, false).slice(1) 20 | return Buffer.from(pubKey) 21 | } 22 | 23 | function deriveAddress(pubKey) { 24 | if(!Buffer.isBuffer(pubKey)) { 25 | console.log("ERROR - pubKey is not a buffer") 26 | } 27 | let keyHash = keccak('keccak256').update(pubKey).digest() 28 | return keyHash.slice(Math.max(keyHash.length - 20, 1)) 29 | } 30 | 31 | function generateNodeData() { 32 | let privateKey = generatePrivateKey() 33 | let publicKey = derivePublicKey(privateKey) 34 | let address = deriveAddress(publicKey) 35 | console.log("keys created, writing to file...") 36 | fs.writeFileSync("nodekey", privateKey.toString('hex')); 37 | fs.writeFileSync("nodekey.pub", publicKey.toString('hex')); 38 | fs.writeFileSync("address", address.toString('hex')); 39 | } 40 | 41 | async function main(password) { 42 | 43 | // generate nodekeys 44 | generateNodeData(); 45 | 46 | // generate account 47 | const wallet = Wallet['default'].generate(); 48 | const v3keystore = await wallet.toV3(password); 49 | console.log("account created, writing to file...") 50 | fs.writeFileSync("accountKeystore", JSON.stringify(v3keystore)); 51 | fs.writeFileSync("accountPrivateKey", wallet.getPrivateKeyString()); 52 | fs.writeFileSync("accountPassword", password); 53 | return { 54 | privateKey: wallet.getPrivateKeyString(), 55 | keystore: JSON.stringify(v3keystore), 56 | password: password 57 | } 58 | } 59 | 60 | try { 61 | const args = yargs(process.argv.slice(2)).options({ 62 | password: { type: 'string', demandOption: false, default: '', describe: 'Password for the account' } 63 | }).argv; 64 | main(args.password); 65 | } catch { 66 | console.error(e) 67 | } 68 | 69 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | 21 | jobs: 22 | analyze: 23 | name: Analyze 24 | runs-on: ubuntu-latest 25 | permissions: 26 | actions: read 27 | contents: read 28 | security-events: write 29 | 30 | strategy: 31 | fail-fast: false 32 | matrix: 33 | language: [ 'javascript' ] 34 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 35 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 36 | 37 | steps: 38 | - name: Checkout repository 39 | uses: actions/checkout@v2 40 | 41 | # Initializes the CodeQL tools for scanning. 42 | - name: Initialize CodeQL 43 | uses: github/codeql-action/init@v1 44 | with: 45 | languages: ${{ matrix.language }} 46 | # If you wish to specify custom queries, you can do so here or in a config file. 47 | # By default, queries listed here will override any specified in a config file. 48 | # Prefix the list here with "+" to use these queries and those in the config file. 49 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 50 | 51 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 52 | # If this step fails, then you should remove it and run the build manually (see below) 53 | - name: Autobuild 54 | uses: github/codeql-action/autobuild@v1 55 | 56 | # ℹ️ Command-line programs to run using the OS shell. 57 | # 📚 https://git.io/JvXDl 58 | 59 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 60 | # and modify them (or add more) to build your code if your project 61 | # uses a compiled language 62 | 63 | #- run: | 64 | # make bootstrap 65 | # make release 66 | 67 | - name: Perform CodeQL Analysis 68 | uses: github/codeql-action/analyze@v1 69 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/scripts/deployEthers.js: -------------------------------------------------------------------------------- 1 | const ethers = require("ethers"); 2 | const fs = require("fs-extra"); 3 | const path = require("path"); 4 | 5 | // member1 details 6 | const { quorum } = require("./keys.js"); 7 | const host = quorum.member1.url; 8 | const guardianAddress = "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"; 9 | 10 | const provider = new ethers.providers.JsonRpcProvider(host); 11 | 12 | const privateKey = quorum.member1.accountPrivateKey; 13 | const wallet = new ethers.Wallet(privateKey, provider); 14 | 15 | async function contractDeployer(contractName, ...argumentss) { 16 | const abi = JSON.parse( 17 | fs.readFileSync( 18 | path.resolve( 19 | __dirname, 20 | "../", 21 | "contracts/v2/output", 22 | `${contractName}.abi` 23 | ) 24 | ) 25 | ); 26 | const bytecode = fs 27 | .readFileSync( 28 | path.resolve( 29 | __dirname, 30 | "../", 31 | "contracts/v2/output", 32 | `${contractName}.bin` 33 | ) 34 | ) 35 | .toString(); 36 | const factory = new ethers.ContractFactory(abi, bytecode, wallet); 37 | const contract = await factory.deploy(...argumentss); 38 | await contract.deployTransaction.wait(); 39 | console.log(`${contractName} Contract Address: ${contract.address}`); 40 | return contract.address; 41 | } 42 | 43 | (async function main() { 44 | const permissionUpgradableAddress = await contractDeployer( 45 | "PermissionsUpgradable", 46 | guardianAddress 47 | ); 48 | const orgManagerAddress = await contractDeployer( 49 | "OrgManager", 50 | permissionUpgradableAddress 51 | ); 52 | const roleManagerAddress = await contractDeployer( 53 | "RoleManager", 54 | permissionUpgradableAddress 55 | ); 56 | const accountManagerAddress = await contractDeployer( 57 | "AccountManager", 58 | permissionUpgradableAddress 59 | ); 60 | const voterManagerAddress = await contractDeployer( 61 | "VoterManager", 62 | permissionUpgradableAddress 63 | ); 64 | const nodeManagerAddress = await contractDeployer( 65 | "NodeManager", 66 | permissionUpgradableAddress 67 | ); 68 | const permissionsInterfaceAddress = await contractDeployer( 69 | "PermissionsInterface", 70 | permissionUpgradableAddress 71 | ); 72 | const permissionsImplementationAddress = await contractDeployer( 73 | "PermissionsImplementation", 74 | permissionUpgradableAddress, 75 | orgManagerAddress, 76 | roleManagerAddress, 77 | accountManagerAddress, 78 | voterManagerAddress, 79 | nodeManagerAddress 80 | ); 81 | })(); 82 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/README.md: -------------------------------------------------------------------------------- 1 | # Using a DApp to interact with the blockchain 2 | 3 | This DApp, uses Hardhat and Ethers.js in combination with a self custodial (also called a user controlled) wallet i.e. Metamask to interact with the chain. As such this process esentially comprises two parts: 4 | 5 | 1. Deploy the contract to the chain 6 | 2. Use the DApp's interface to send and transact on the chain 7 | 8 | The `dapps/quorumToken` folder is this structured in this manner (only relevant paths shown): 9 | 10 | ``` 11 | quorumToken 12 | ├── hardhat.config.ts // hardhat network config 13 | ├── contracts // sample contracts of which we use the QuorumToken.sol 14 | ├── scripts // handy scripts eg: to deploy to a chain 15 | ├── test // contract tests 16 | └── frontend // DApp done in next.js 17 | ├── README.md 18 | ├── public 19 | ├── src 20 | ├── styles 21 | ├── tsconfig.json 22 | ``` 23 | 24 | # Contracts 25 | 26 | Contracts are written in Solidity and we use the hardhat development environment for testing, deploying etc 27 | 28 | The `hardhat.config.js` specifies the networks, accounts, solidity version etc 29 | 30 | Install dependencies 31 | 32 | ``` 33 | npm i 34 | ``` 35 | 36 | Compile the contracts and run tests (optional): 37 | 38 | ``` 39 | npx run compile 40 | # As you develop contracts you are using the inbuilt `hardhat` network 41 | npx hardhat test 42 | ``` 43 | 44 | Deploy contracts with: 45 | 46 | ``` 47 | # we specify the network here so the DApp can use the contract, but you can use any network you wish to and remember to connect Metamask to the appropriate network for the DApp 48 | npx hardhat run ./scripts/deploy_quorumtoken.ts --network quickstart 49 | ``` 50 | 51 | _Please remember to save the address returned from the deploy as you will need it for the following steps_ 52 | 53 | # DApp 54 | 55 | We have a sample DApp created that uses Next.js, react and ethers to interact with the quickstart network 56 | 57 | ``` 58 | cd frontend 59 | npm i 60 | npm run dev 61 | ``` 62 | 63 | 1. Open up a tab on port 3001 and connect to Metamask. 64 | 2. To interact with the DApp you will need to import the test accounts from `hardhat.config.ts` 65 | 66 | For brevity they are the following: 67 | 68 | ``` 69 | 0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63 70 | 0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 71 | 0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f 72 | ``` 73 | 74 | 3. When you connect to Metamask, you are presented with a field to input the address of the deployed contract from the previous step. The app will then fetch the contract data and you can then transfer eth to a new another account. 75 | -------------------------------------------------------------------------------- /src/spinner.ts: -------------------------------------------------------------------------------- 1 | import cliSpinners, { Spinner as CLISpinner, SpinnerName } from "cli-spinners"; 2 | import logUpdate from "log-update"; 3 | 4 | export class Spinner { 5 | 6 | public text: string; 7 | private _spinner: CLISpinner; 8 | private _intervalHandle: NodeJS.Timeout | null; 9 | 10 | constructor(text: string, spinnerName: SpinnerName = "dots3") { 11 | this.text = text; 12 | if (!cliSpinners[spinnerName]) { 13 | const spinnerNames = Object.keys(cliSpinners).join(", "); 14 | throw new Error(`Invalid spinner name ${spinnerName} specified. Expected one of the following: ${spinnerNames}`); 15 | } 16 | 17 | this._spinner = cliSpinners[spinnerName]; 18 | this._intervalHandle = null; 19 | } 20 | 21 | get isRunning(): boolean { 22 | return this._intervalHandle !== null; 23 | } 24 | 25 | start(): Spinner { 26 | if (this._intervalHandle !== null) { 27 | return this; 28 | } 29 | 30 | let i = 0; 31 | 32 | this._intervalHandle = setInterval(() => { 33 | const spinnerFrame = this._spinner.frames[i = ++i % this._spinner.frames.length]; 34 | const line = `${spinnerFrame} ${this.text}`; 35 | logUpdate(line); 36 | }, this._spinner.interval); 37 | 38 | return this; 39 | } 40 | 41 | stop(finalText?: string): Promise { 42 | if (this._intervalHandle === null) { 43 | return Promise.resolve(); 44 | } 45 | 46 | const handle = this._intervalHandle; 47 | this._intervalHandle = null; 48 | clearInterval(handle); 49 | 50 | return new Promise((resolve, reject) => { 51 | setTimeout(() => { 52 | try { 53 | logUpdate.clear(); 54 | if (finalText) { 55 | logUpdate(finalText); 56 | } 57 | logUpdate.done(); 58 | resolve(); 59 | } catch (err) { 60 | reject(err); 61 | } 62 | }, this._spinner.interval); 63 | }); 64 | } 65 | 66 | succeed(finalText: string): Promise { 67 | return this.stop(`✅ ${finalText}`); 68 | } 69 | 70 | fail (finalText: string): Promise { 71 | return this.stop(`❌ ${finalText}`); 72 | } 73 | } 74 | 75 | if (require.main === module) { 76 | const spinner = new Spinner("This is a test").start(); 77 | setTimeout(() => { 78 | spinner.text = "the text changed!"; 79 | setTimeout(() => { 80 | void spinner.stop("Test complete"); 81 | const spinner2 = new Spinner("This is a test again").start(); 82 | setTimeout(() => { 83 | void spinner2.succeed("Test completed successfully"); 84 | const spinner3 = new Spinner("This is a test one last time").start(); 85 | setTimeout(() => { 86 | void spinner3.fail("Test failed (this is expected and desirable)"); 87 | }, 3000); 88 | }, 3000); 89 | }, 3000); 90 | }, 3000); 91 | 92 | } -------------------------------------------------------------------------------- /files/besu/config/besu/CLIQUEgenesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config":{ 3 | "chainId":1337, 4 | "londonBlock": 0, 5 | "zeroBaseFee": true, 6 | "clique":{ 7 | "blockperiodseconds":15, 8 | "epochlength":30000 9 | } 10 | }, 11 | "coinbase":"0x0000000000000000000000000000000000000000", 12 | "difficulty":"0x1", 13 | "extraData":"0x000000000000000000000000000000000000000000000000000000000000000093917cadbace5dfce132b991732c6cda9bcc5b8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 14 | "gasLimit":"0xa00000", 15 | "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000", 16 | "nonce":"0x0", 17 | "timestamp":"0x5c51a607", 18 | "alloc": { 19 | "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": { 20 | "privateKey": "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 21 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 22 | "balance": "0x130EE8E7179044400000" 23 | }, 24 | "0x627306090abaB3A6e1400e9345bC60c78a8BEf57": { 25 | "privateKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 26 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 27 | "balance": "90000000000000000000000" 28 | }, 29 | "0xf17f52151EbEF6C7334FAD080c5704D77216b732": { 30 | "privateKey": "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 31 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 32 | "balance": "90000000000000000000000" 33 | }, 34 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 35 | "balance": "1000000000000000000000000000" 36 | }, 37 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 38 | "balance": "1000000000000000000000000000" 39 | }, 40 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 41 | "balance": "1000000000000000000000000000" 42 | }, 43 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 44 | "balance": "1000000000000000000000000000" 45 | }, 46 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 47 | "balance": "1000000000000000000000000000" 48 | }, 49 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 50 | "balance": "1000000000000000000000000000" 51 | }, 52 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 53 | "balance": "1000000000000000000000000000" 54 | }, 55 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 56 | "balance": "1000000000000000000000000000" 57 | } 58 | }, 59 | "number":"0x0", 60 | "gasUsed":"0x0", 61 | "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000" 62 | } 63 | -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/keys.js: -------------------------------------------------------------------------------- 1 | // WARNING: the keys here are demo purposes ONLY. Please use a tool like EthSigner for production, rather than hard coding private keys 2 | 3 | module.exports = { 4 | tessera: { 5 | member1: { 6 | publicKey: "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=", 7 | }, 8 | member2: { 9 | publicKey: "QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc=", 10 | }, 11 | member3: { 12 | publicKey: "1iTZde/ndBHvzhcl7V68x44Vx7pl8nwx9LqnM/AfJUg=", 13 | }, 14 | }, 15 | besu: { 16 | rpcnode: { 17 | name: "rpcnode", 18 | url: "http://127.0.0.1:8545", 19 | wsUrl: "ws://127.0.0.1:8546", 20 | nodekey: 21 | "0e93a540518eeb673d94fb496b746008ab56605463cb9212493997f5755124d1", 22 | accountAddress: "c9c913c8c3c1cd416d80a0abf475db2062f161f6", 23 | accountPrivateKey: 24 | "0x60bbe10a196a4e71451c0f6e9ec9beab454c2a5ac0542aa5b8b733ff5719fec3", 25 | }, 26 | member1: { 27 | name: "member1", 28 | url: "http://127.0.0.1:20000", 29 | wsUrl: "ws://127.0.0.1:20001", 30 | privateUrl: "http://127.0.0.1:9081", 31 | nodekey: 32 | "0xb9a4bd1539c15bcc83fa9078fe89200b6e9e802ae992f13cd83c853f16e8bed4", 33 | accountAddress: "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5", 34 | accountPrivateKey: 35 | "8bbbb1b345af56b560a5b20bd4b0ed1cd8cc9958a16262bc75118453cb546df7", 36 | }, 37 | member2: { 38 | name: "member2", 39 | url: "http://127.0.0.1:20002", 40 | wsUrl: "ws://127.0.0.1:20003", 41 | privateUrl: "http://127.0.0.1:9082", 42 | nodekey: 43 | "f18166704e19b895c1e2698ebc82b4e007e6d2933f4b31be23662dd0ec602570", 44 | accountAddress: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", 45 | accountPrivateKey: 46 | "4762e04d10832808a0aebdaa79c12de54afbe006bfffd228b3abcc494fe986f9", 47 | }, 48 | member3: { 49 | name: "member3", 50 | url: "http://127.0.0.1:20004", 51 | wsUrl: "ws://127.0.0.1:20005", 52 | privateUrl: "http://127.0.0.1:9083", 53 | nodekey: 54 | "4107f0b6bf67a3bc679a15fe36f640415cf4da6a4820affaac89c8b280dfd1b3", 55 | accountAddress: "0x0fbdc686b912d7722dc86510934589e0aaf3b55a", 56 | accountPrivateKey: 57 | "61dced5af778942996880120b303fc11ee28cc8e5036d2fdff619b5675ded3f0", 58 | }, 59 | }, 60 | accounts: { 61 | a: { 62 | address: "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", 63 | privateKey: "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 64 | }, 65 | b: { 66 | address: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57", 67 | privateKey: "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 68 | }, 69 | c: { 70 | address: "0xf17f52151EbEF6C7334FAD080c5704D77216b732", 71 | privateKey: "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 72 | }, 73 | }, 74 | }; 75 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/scripts/keys.js: -------------------------------------------------------------------------------- 1 | // WARNING: the keys here are demo purposes ONLY. Please use a tool like EthSigner for production, rather than hard coding private keys 2 | 3 | module.exports = { 4 | tessera: { 5 | member1: { 6 | publicKey: "BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=", 7 | }, 8 | member2: { 9 | publicKey: "QfeDAys9MPDs2XHExtc84jKGHxZg/aj52DTh0vtA3Xc=", 10 | }, 11 | member3: { 12 | publicKey: "1iTZde/ndBHvzhcl7V68x44Vx7pl8nwx9LqnM/AfJUg=", 13 | }, 14 | }, 15 | quorum: { 16 | rpcnode: { 17 | name: "rpcnode", 18 | url: "http://127.0.0.1:8545", 19 | wsUrl: "ws://127.0.0.1:8546", 20 | nodekey: 21 | "0e93a540518eeb673d94fb496b746008ab56605463cb9212493997f5755124d1", 22 | accountAddress: "c9c913c8c3c1cd416d80a0abf475db2062f161f6", 23 | accountPrivateKey: 24 | "0x60bbe10a196a4e71451c0f6e9ec9beab454c2a5ac0542aa5b8b733ff5719fec3", 25 | }, 26 | member1: { 27 | name: "member1", 28 | url: "http://127.0.0.1:20000", 29 | wsUrl: "ws://127.0.0.1:20001", 30 | privateUrl: "http://127.0.0.1:9081", 31 | nodekey: 32 | "0xb9a4bd1539c15bcc83fa9078fe89200b6e9e802ae992f13cd83c853f16e8bed4", 33 | accountAddress: "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5", 34 | accountPrivateKey: 35 | "8bbbb1b345af56b560a5b20bd4b0ed1cd8cc9958a16262bc75118453cb546df7", 36 | }, 37 | member2: { 38 | name: "member2", 39 | url: "http://127.0.0.1:20002", 40 | wsUrl: "ws://127.0.0.1:20003", 41 | privateUrl: "http://127.0.0.1:9082", 42 | nodekey: 43 | "f18166704e19b895c1e2698ebc82b4e007e6d2933f4b31be23662dd0ec602570", 44 | accountAddress: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", 45 | accountPrivateKey: 46 | "4762e04d10832808a0aebdaa79c12de54afbe006bfffd228b3abcc494fe986f9", 47 | }, 48 | member3: { 49 | name: "member3", 50 | url: "http://127.0.0.1:20004", 51 | wsUrl: "ws://127.0.0.1:20005", 52 | privateUrl: "http://127.0.0.1:9083", 53 | nodekey: 54 | "4107f0b6bf67a3bc679a15fe36f640415cf4da6a4820affaac89c8b280dfd1b3", 55 | accountAddress: "0x0fbdc686b912d7722dc86510934589e0aaf3b55a", 56 | accountPrivateKey: 57 | "61dced5af778942996880120b303fc11ee28cc8e5036d2fdff619b5675ded3f0", 58 | }, 59 | }, 60 | accounts: { 61 | a: { 62 | address: "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73", 63 | privateKey: "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 64 | }, 65 | b: { 66 | address: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57", 67 | privateKey: "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 68 | }, 69 | c: { 70 | address: "0xf17f52151EbEF6C7334FAD080c5704D77216b732", 71 | privateKey: "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 72 | }, 73 | } 74 | }; 75 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/raft-standard-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "alloc": { 3 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73" : { 4 | "privateKey" : "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 5 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 6 | "balance" : "0x130EE8E7179044400000" 7 | }, 8 | "627306090abaB3A6e1400e9345bC60c78a8BEf57" : { 9 | "privateKey" : "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 10 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 11 | "balance" : "90000000000000000000000" 12 | }, 13 | "f17f52151EbEF6C7334FAD080c5704D77216b732" : { 14 | "privateKey" : "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 15 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 16 | "balance" : "90000000000000000000000" 17 | }, 18 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 19 | "balance": "1000000000000000000000000000" 20 | }, 21 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 22 | "balance": "1000000000000000000000000000" 23 | }, 24 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 25 | "balance": "1000000000000000000000000000" 26 | }, 27 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 28 | "balance": "1000000000000000000000000000" 29 | }, 30 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 31 | "balance": "1000000000000000000000000000" 32 | }, 33 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 34 | "balance": "1000000000000000000000000000" 35 | }, 36 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 37 | "balance": "1000000000000000000000000000" 38 | }, 39 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 40 | "balance": "1000000000000000000000000000" 41 | } 42 | }, 43 | "coinbase": "0x0000000000000000000000000000000000000000", 44 | "config": { 45 | "homesteadBlock": 0, 46 | "byzantiumBlock": 0, 47 | "constantinopleBlock": 0, 48 | "petersburgBlock": 0, 49 | "istanbulBlock": 0, 50 | "muirGlacierBlock": 0, 51 | "berlinBlock": 10000000, 52 | "londonBlock": 0, 53 | "arrowGlacierBlock": 0, 54 | "grayGlacierBlock": 0, 55 | "chainId": 1337, 56 | "eip150Block": 0, 57 | "eip155Block": 0, 58 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 59 | "eip158Block": 0, 60 | "isQuorum": true, 61 | "maxCodeSizeConfig" : [ 62 | { 63 | "block" : 0, 64 | "size" : 64 65 | } 66 | ] 67 | }, 68 | "difficulty": "0x0", 69 | "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", 70 | "gasLimit": "0xE0000000", 71 | "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", 72 | "nonce": "0x0", 73 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 74 | "timestamp": "0x00" 75 | } 76 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/raft-enhanced-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "alloc": { 3 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73" : { 4 | "privateKey" : "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 5 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 6 | "balance" : "0x130EE8E7179044400000" 7 | }, 8 | "627306090abaB3A6e1400e9345bC60c78a8BEf57" : { 9 | "privateKey" : "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 10 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 11 | "balance" : "90000000000000000000000" 12 | }, 13 | "f17f52151EbEF6C7334FAD080c5704D77216b732" : { 14 | "privateKey" : "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 15 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 16 | "balance" : "90000000000000000000000" 17 | }, 18 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 19 | "balance": "1000000000000000000000000000" 20 | }, 21 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 22 | "balance": "1000000000000000000000000000" 23 | }, 24 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 25 | "balance": "1000000000000000000000000000" 26 | }, 27 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 28 | "balance": "1000000000000000000000000000" 29 | }, 30 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 31 | "balance": "1000000000000000000000000000" 32 | }, 33 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 34 | "balance": "1000000000000000000000000000" 35 | }, 36 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 37 | "balance": "1000000000000000000000000000" 38 | }, 39 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 40 | "balance": "1000000000000000000000000000" 41 | } 42 | }, 43 | "coinbase": "0x0000000000000000000000000000000000000000", 44 | "config": { 45 | "homesteadBlock": 0, 46 | "byzantiumBlock": 0, 47 | "constantinopleBlock": 0, 48 | "petersburgBlock": 0, 49 | "istanbulBlock": 0, 50 | "muirGlacierBlock": 0, 51 | "berlinBlock": 10000000, 52 | "londonBlock": 0, 53 | "arrowGlacierBlock": 0, 54 | "grayGlacierBlock": 0, 55 | "chainId": 1337, 56 | "eip150Block": 0, 57 | "eip155Block": 0, 58 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 59 | "eip158Block": 0, 60 | "isQuorum": true, 61 | "privacyEnhancementsBlock": 0, 62 | "maxCodeSizeConfig" : [ 63 | { 64 | "block" : 0, 65 | "size" : 64 66 | } 67 | ] 68 | }, 69 | "difficulty": "0x0", 70 | "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000", 71 | "gasLimit": "0xE0000000", 72 | "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578", 73 | "nonce": "0x0", 74 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 75 | "timestamp": "0x00" 76 | } 77 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -o errexit 4 | set -o nounset 5 | set -o pipefail 6 | 7 | GOQUORUM_CONS_ALGO=`echo "${GOQUORUM_CONS_ALGO:-qbft}" | tr '[:lower:]'` 8 | GENESIS_FILE=${GENESIS_FILE:-"/data/${GOQUORUM_CONS_ALGO}-${GOQUORUM_GENESIS_MODE}-genesis.json"} 9 | 10 | cp -R /config/* /data 11 | mkdir -p /data/keystore/ 12 | 13 | echo "Applying ${GENESIS_FILE} ..." 14 | geth --nousb --verbosity 1 --datadir=/data init ${GENESIS_FILE}; 15 | 16 | cp /config/keys/accountKeystore /data/keystore/key; 17 | cp /config/keys/nodekey /data/geth/nodekey; 18 | 19 | if [ "istanbul" == "$GOQUORUM_CONS_ALGO" ]; 20 | then 21 | echo "Using istanbul for consensus algorithm..." 22 | export CONSENSUS_ARGS="--istanbul.blockperiod 5 --mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints" 23 | export QUORUM_API="istanbul" 24 | elif [ "qbft" == "$GOQUORUM_CONS_ALGO" ]; 25 | then 26 | echo "Using qbft for consensus algorithm..." 27 | export CONSENSUS_ARGS="--mine --miner.threads 1 --miner.gasprice 0 --emitcheckpoints" 28 | export QUORUM_API="istanbul" 29 | elif [ "raft" == "$GOQUORUM_CONS_ALGO" ]; 30 | then 31 | echo "Using raft for consensus algorithm..." 32 | export CONSENSUS_ARGS="--raft --raftblocktime 300 --raftport 53000" 33 | export QUORUM_API="raft" 34 | fi 35 | 36 | export ADDRESS=$(grep -o '"address": *"[^"]*"' /config/keys/accountKeystore | grep -o '"[^"]*"$' | sed 's/"//g') 37 | 38 | if [[ ! -z ${QUORUM_PTM:-} ]]; 39 | then 40 | echo -n "Checking tessera is up ... " 41 | 42 | curl \ 43 | --connect-timeout 5 \ 44 | --max-time 10 \ 45 | --retry 5 \ 46 | --retry-connrefused \ 47 | --retry-delay 0 \ 48 | --retry-max-time 60 \ 49 | --silent \ 50 | --fail \ 51 | "${QUORUM_PTM}:9000/upcheck" 52 | echo "" 53 | 54 | ADDITIONAL_ARGS="${ADDITIONAL_ARGS:-} --ptm.timeout 5 --ptm.url http://${QUORUM_PTM}:9101 --ptm.http.writebuffersize 4096 --ptm.http.readbuffersize 4096 --ptm.tls.mode off" 55 | fi 56 | 57 | touch /var/log/quorum/geth-$(hostname -i).log 58 | cat /proc/1/fd/2 /proc/1/fd/1 > /var/log/quorum/geth-$(hostname -i).log & 59 | 60 | if [ -f /permissions/permission-config.json ]; then 61 | echo "Using Enhanced Permissions: Copying permission-config.json exists to /data ..."; 62 | cp /permissions/permission-config.json /data/permission-config.json 63 | fi 64 | 65 | exec geth \ 66 | --datadir /data \ 67 | --nodiscover \ 68 | --permissioned \ 69 | --verbosity 3 \ 70 | $CONSENSUS_ARGS \ 71 | --syncmode full --revertreason \ 72 | --metrics --pprof --pprof.addr 0.0.0.0 --pprof.port 9545 \ 73 | --networkid ${QUORUM_NETWORK_ID:-1337} \ 74 | --http --http.addr 0.0.0.0 --http.port 8545 --http.corsdomain "*" --http.vhosts "*" --http.api admin,eth,debug,miner,net,txpool,personal,web3,$QUORUM_API \ 75 | --ws --ws.addr 0.0.0.0 --ws.port 8546 --ws.origins "*" --ws.api admin,eth,debug,miner,net,txpool,personal,web3,$QUORUM_API \ 76 | --port 30303 \ 77 | --identity ${HOSTNAME}-${GOQUORUM_CONS_ALGO} \ 78 | --unlock ${ADDRESS} \ 79 | --allow-insecure-unlock \ 80 | --password /data/passwords.txt \ 81 | ${ADDITIONAL_ARGS:-} \ 82 | 2>&1 -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/public/hre_public_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | var ethers = require('ethers'); 4 | 5 | // RPCNODE details 6 | const { tessera, besu } = require("../keys.js"); 7 | const host = besu.rpcnode.url; 8 | const accountPrivateKey = besu.rpcnode.accountPrivateKey; 9 | 10 | // abi and bytecode generated from simplestorage.sol: 11 | // > solcjs --bin --abi simplestorage.sol 12 | const contractJsonPath = path.resolve(__dirname, '../../','contracts','SimpleStorage.json'); 13 | const contractJson = JSON.parse(fs.readFileSync(contractJsonPath)); 14 | const contractAbi = contractJson.abi; 15 | const contractBytecode = contractJson.evm.bytecode.object 16 | 17 | async function getValueAtAddress(provider, deployedContractAbi, deployedContractAddress){ 18 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 19 | const res = await contract.get(); 20 | console.log("Obtained value at deployed contract is: "+ res); 21 | return res 22 | } 23 | 24 | // You need to use the accountAddress details provided to Quorum to send/interact with contracts 25 | async function setValueAtAddress(provider, wallet, deployedContractAbi, deployedContractAddress, value){ 26 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 27 | const contractWithSigner = contract.connect(wallet); 28 | const tx = await contractWithSigner.set(value); 29 | // verify the updated value 30 | await tx.wait(); 31 | // const res = await contract.get(); 32 | // console.log("Obtained value at deployed contract is: "+ res); 33 | return tx; 34 | } 35 | 36 | async function createContract(provider, wallet, contractAbi, contractByteCode, contractInit) { 37 | const factory = new ethers.ContractFactory(contractAbi, contractByteCode, wallet); 38 | const contract = await factory.deploy(contractInit); 39 | // The contract is NOT deployed yet; we must wait until it is mined 40 | const deployed = await contract.waitForDeployment(); 41 | //The contract is deployed now 42 | return contract 43 | }; 44 | 45 | async function main(){ 46 | const provider = new ethers.JsonRpcProvider(host); 47 | const wallet = new ethers.Wallet(accountPrivateKey, provider); 48 | 49 | createContract(provider, wallet, contractAbi, contractBytecode, 47) 50 | .then(async function(contract){ 51 | contractAddress = await contract.getAddress(); 52 | console.log("Contract deployed at address: " + contractAddress); 53 | console.log("Use the smart contracts 'get' function to read the contract's constructor initialized value .. " ) 54 | await getValueAtAddress(provider, contractAbi, contractAddress); 55 | console.log("Use the smart contracts 'set' function to update that value to 123 .. " ); 56 | await setValueAtAddress(provider, wallet, contractAbi, contractAddress, 123 ); 57 | console.log("Verify the updated value that was set .. " ) 58 | await getValueAtAddress(provider, contractAbi, contractAddress); 59 | // await getAllPastEvents(host, contractAbi, tx.contractAddress); 60 | }) 61 | .catch(console.error); 62 | 63 | } 64 | 65 | if (require.main === module) { 66 | main(); 67 | } 68 | 69 | module.exports = exports = main -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/scripts/public/hre_public_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | var ethers = require('ethers'); 4 | 5 | // RPCNODE details 6 | const { tessera, quorum } = require("../keys.js"); 7 | const host = quorum.rpcnode.url; 8 | const accountPrivateKey = quorum.rpcnode.accountPrivateKey; 9 | 10 | // abi and bytecode generated from simplestorage.sol: 11 | // > solcjs --bin --abi simplestorage.sol 12 | const contractJsonPath = path.resolve(__dirname, '../../','contracts','SimpleStorage.json'); 13 | const contractJson = JSON.parse(fs.readFileSync(contractJsonPath)); 14 | const contractAbi = contractJson.abi; 15 | const contractBytecode = contractJson.evm.bytecode.object 16 | 17 | async function getValueAtAddress(provider, deployedContractAbi, deployedContractAddress){ 18 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 19 | const res = await contract.get(); 20 | console.log("Obtained value at deployed contract is: "+ res); 21 | return res 22 | } 23 | 24 | // You need to use the accountAddress details provided to Quorum to send/interact with contracts 25 | async function setValueAtAddress(provider, wallet, deployedContractAbi, deployedContractAddress, value){ 26 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 27 | const contractWithSigner = contract.connect(wallet); 28 | const tx = await contractWithSigner.set(value); 29 | // verify the updated value 30 | await tx.wait(); 31 | // const res = await contract.get(); 32 | // console.log("Obtained value at deployed contract is: "+ res); 33 | return tx; 34 | } 35 | 36 | async function createContract(provider, wallet, contractAbi, contractByteCode, contractInit) { 37 | const factory = new ethers.ContractFactory(contractAbi, contractByteCode, wallet); 38 | const contract = await factory.deploy(contractInit); 39 | // The contract is NOT deployed yet; we must wait until it is mined 40 | const deployed = await contract.waitForDeployment(); 41 | //The contract is deployed now 42 | return contract 43 | }; 44 | 45 | async function main(){ 46 | const provider = new ethers.JsonRpcProvider(host); 47 | const wallet = new ethers.Wallet(accountPrivateKey, provider); 48 | 49 | createContract(provider, wallet, contractAbi, contractBytecode, 47) 50 | .then(async function(contract){ 51 | contractAddress = await contract.getAddress(); 52 | console.log("Contract deployed at address: " + contractAddress); 53 | console.log("Use the smart contracts 'get' function to read the contract's constructor initialized value .. " ) 54 | await getValueAtAddress(provider, contractAbi, contractAddress); 55 | console.log("Use the smart contracts 'set' function to update that value to 123 .. " ); 56 | await setValueAtAddress(provider, wallet, contractAbi, contractAddress, 123 ); 57 | console.log("Verify the updated value that was set .. " ) 58 | await getValueAtAddress(provider, contractAbi, contractAddress); 59 | // await getAllPastEvents(host, contractAbi, tx.contractAddress); 60 | }) 61 | .catch(console.error); 62 | } 63 | 64 | if (require.main === module) { 65 | main(); 66 | } 67 | 68 | module.exports = exports = main -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/components/quorumToken/ReadQuorumToken.tsx: -------------------------------------------------------------------------------- 1 | import React, {useEffect, useState } from 'react'; 2 | import {Text} from '@chakra-ui/react' 3 | import {QuorumTokenABI as abi} from './QuorumTokenABI' 4 | import {ethers, Contract} from 'ethers' 5 | 6 | declare let window: any; 7 | 8 | interface ReadQuorumTokenProps { 9 | addressContract: string, 10 | currentAccount: string | undefined 11 | } 12 | 13 | export default function ReadQuorumToken(props:ReadQuorumTokenProps){ 14 | const addressContract = props.addressContract 15 | const currentAccount = props.currentAccount 16 | const [totalSupply,setTotalSupply]=useState() 17 | const [symbol,setSymbol]= useState("") 18 | const [balance, setBalance] =useState(undefined) 19 | 20 | useEffect( () => { 21 | if(!window.ethereum) return; 22 | const provider = new ethers.BrowserProvider(window.ethereum); 23 | const erc20:Contract = new ethers.Contract(addressContract, abi, provider); 24 | 25 | provider.getCode(addressContract).then((result:string)=>{ 26 | //check whether it is a contract 27 | if(result === '0x') return 28 | 29 | erc20.symbol().then((result:string)=>{ 30 | setSymbol(result) 31 | }).catch('error', console.error) 32 | erc20.totalSupply().then((result:string)=>{ 33 | setTotalSupply(ethers.formatEther(result)) 34 | }).catch('error', console.error); 35 | 36 | }) 37 | },[]) 38 | 39 | // when currentAccount changes, we call this hook ie useEffect(()=>{ .... },[currentAccount] 40 | // 41 | useEffect(()=>{ 42 | if(!window.ethereum) return 43 | if(!currentAccount) return 44 | 45 | queryTokenBalance(window); 46 | const provider = new ethers.BrowserProvider(window.ethereum); 47 | const erc20:Contract = new ethers.Contract(addressContract, abi, provider); 48 | 49 | // listen for changes on an Ethereum address 50 | console.log(`listening for Transfer...`) 51 | const fromMe = erc20.filters.Transfer(currentAccount, null) 52 | erc20.on(fromMe, (from, to, amount, event) => { 53 | console.log('Transfer|sent', {from, to, amount, event} ) 54 | queryTokenBalance(window) 55 | }) 56 | 57 | const toMe = erc20.filters.Transfer(null, currentAccount) 58 | erc20.on(toMe, (from, to, amount, event) => { 59 | console.log('Transfer|received', {from, to, amount, event} ) 60 | queryTokenBalance(window) 61 | }) 62 | 63 | // remove listener when the component is unmounted 64 | return () => { 65 | erc20.removeAllListeners(toMe) 66 | erc20.removeAllListeners(fromMe) 67 | } 68 | }, [currentAccount]) 69 | 70 | 71 | async function queryTokenBalance(window:any){ 72 | const provider = new ethers.BrowserProvider(window.ethereum); 73 | const erc20:Contract = new ethers.Contract(addressContract, abi, provider); 74 | 75 | erc20.balanceOf(currentAccount) 76 | .then((result:string)=>{ 77 | setBalance(Number(ethers.formatEther(result))) 78 | }).catch((e:Error)=>console.log(e)) 79 | } 80 | 81 | return ( 82 |
83 | ERC20 Contract Address: {addressContract} 84 | QuorumToken totalSupply: {totalSupply} {symbol} 85 | QuorumToken in current account: {balance} {symbol} 86 |
87 | ) 88 | } 89 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/istanbul-standard-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 1337, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "istanbul": { 12 | "epoch": 30000, 13 | "policy": 0, 14 | "ceil2Nby3Block": 0 15 | }, 16 | "txnSizeLimit": 64, 17 | "maxCodeSizeConfig" : [ 18 | { 19 | "block" : 0, 20 | "size" : 64 21 | } 22 | ], 23 | "isQuorum": true 24 | }, 25 | "nonce": "0x0", 26 | "timestamp": "0x5f1663fc", 27 | "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f89af8549493917cadbace5dfce132b991732c6cda9bcc5b8a9427a97c9aaf04f18f3014c32e036dd0ac76da5f1894ce412f988377e31f4d0ff12d74df73b51c42d0ca9498c1334496614aed49d2e81526d089f7264fed9cb8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", 28 | "gasLimit" : "0xf7b760", 29 | "difficulty": "0x1", 30 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 31 | "coinbase": "0x0000000000000000000000000000000000000000", 32 | "alloc": { 33 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73" : { 34 | "privateKey" : "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 35 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 36 | "balance" : "0x130EE8E7179044400000" 37 | }, 38 | "627306090abaB3A6e1400e9345bC60c78a8BEf57" : { 39 | "privateKey" : "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 40 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 41 | "balance" : "90000000000000000000000" 42 | }, 43 | "f17f52151EbEF6C7334FAD080c5704D77216b732" : { 44 | "privateKey" : "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 45 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 46 | "balance" : "90000000000000000000000" 47 | }, 48 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 49 | "balance": "1000000000000000000000000000" 50 | }, 51 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 52 | "balance": "1000000000000000000000000000" 53 | }, 54 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 55 | "balance": "1000000000000000000000000000" 56 | }, 57 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 58 | "balance": "1000000000000000000000000000" 59 | }, 60 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 61 | "balance": "1000000000000000000000000000" 62 | }, 63 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 64 | "balance": "1000000000000000000000000000" 65 | }, 66 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 67 | "balance": "1000000000000000000000000000" 68 | }, 69 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 70 | "balance": "1000000000000000000000000000" 71 | } 72 | }, 73 | "number": "0x0", 74 | "gasUsed": "0x0", 75 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 76 | } 77 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/qbft-enhanced-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 1337, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "petersburgBlock": 0, 12 | "istanbulBlock": 0, 13 | "muirGlacierBlock": 0, 14 | "berlinBlock": 10000000, 15 | "londonBlock": 0, 16 | "arrowGlacierBlock": 0, 17 | "grayGlacierBlock": 0, 18 | "qbft": { 19 | "epochLength": 30000, 20 | "blockPeriodSeconds": 5 21 | }, 22 | "transitions": [ 23 | { 24 | "block": 0, 25 | "transactionSizeLimit": 64, 26 | "contractSizeLimit": 64, 27 | "privacyEnhancementsEnabled": true 28 | } 29 | ], 30 | "isQuorum": true 31 | }, 32 | "nonce": "0x0", 33 | "timestamp": "0x5f1663fc", 34 | "extraData": "0xf87aa00000000000000000000000000000000000000000000000000000000000000000f8549493917cadbace5dfce132b991732c6cda9bcc5b8a9427a97c9aaf04f18f3014c32e036dd0ac76da5f1894ce412f988377e31f4d0ff12d74df73b51c42d0ca9498c1334496614aed49d2e81526d089f7264fed9cc080c0", 35 | "gasLimit": "0xf7b760", 36 | "difficulty": "0x1", 37 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 38 | "coinbase": "0x0000000000000000000000000000000000000000", 39 | "alloc": { 40 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { 41 | "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 42 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 43 | "balance": "0x130EE8E7179044400000" 44 | }, 45 | "627306090abaB3A6e1400e9345bC60c78a8BEf57": { 46 | "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 47 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 48 | "balance": "90000000000000000000000" 49 | }, 50 | "f17f52151EbEF6C7334FAD080c5704D77216b732": { 51 | "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 52 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 53 | "balance": "90000000000000000000000" 54 | }, 55 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 56 | "balance": "1000000000000000000000000000" 57 | }, 58 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 59 | "balance": "1000000000000000000000000000" 60 | }, 61 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 62 | "balance": "1000000000000000000000000000" 63 | }, 64 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 65 | "balance": "1000000000000000000000000000" 66 | }, 67 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 68 | "balance": "1000000000000000000000000000" 69 | }, 70 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 71 | "balance": "1000000000000000000000000000" 72 | }, 73 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 74 | "balance": "1000000000000000000000000000" 75 | }, 76 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 77 | "balance": "1000000000000000000000000000" 78 | } 79 | }, 80 | "number": "0x0", 81 | "gasUsed": "0x0", 82 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 83 | } 84 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/qbft-standard-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 1337, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "petersburgBlock": 0, 12 | "istanbulBlock": 0, 13 | "muirGlacierBlock": 0, 14 | "berlinBlock": 10000000, 15 | "londonBlock": 0, 16 | "arrowGlacierBlock": 0, 17 | "grayGlacierBlock": 0, 18 | "qbft": { 19 | "epochLength": 30000, 20 | "blockPeriodSeconds": 5 21 | }, 22 | "transitions": [ 23 | { 24 | "block": 0, 25 | "transactionSizeLimit": 64, 26 | "contractSizeLimit": 64, 27 | "privacyEnhancementsEnabled": false 28 | } 29 | ], 30 | "isQuorum": true 31 | }, 32 | "nonce": "0x0", 33 | "timestamp": "0x5f1663fc", 34 | "extraData": "0xf87aa00000000000000000000000000000000000000000000000000000000000000000f8549493917cadbace5dfce132b991732c6cda9bcc5b8a9427a97c9aaf04f18f3014c32e036dd0ac76da5f1894ce412f988377e31f4d0ff12d74df73b51c42d0ca9498c1334496614aed49d2e81526d089f7264fed9cc080c0", 35 | "gasLimit": "0xf7b760", 36 | "difficulty": "0x1", 37 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 38 | "coinbase": "0x0000000000000000000000000000000000000000", 39 | "alloc": { 40 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73": { 41 | "privateKey": "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 42 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 43 | "balance": "0x130EE8E7179044400000" 44 | }, 45 | "627306090abaB3A6e1400e9345bC60c78a8BEf57": { 46 | "privateKey": "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 47 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 48 | "balance": "90000000000000000000000" 49 | }, 50 | "f17f52151EbEF6C7334FAD080c5704D77216b732": { 51 | "privateKey": "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 52 | "comment": "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 53 | "balance": "90000000000000000000000" 54 | }, 55 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 56 | "balance": "1000000000000000000000000000" 57 | }, 58 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 59 | "balance": "1000000000000000000000000000" 60 | }, 61 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 62 | "balance": "1000000000000000000000000000" 63 | }, 64 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 65 | "balance": "1000000000000000000000000000" 66 | }, 67 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 68 | "balance": "1000000000000000000000000000" 69 | }, 70 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 71 | "balance": "1000000000000000000000000000" 72 | }, 73 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 74 | "balance": "1000000000000000000000000000" 75 | }, 76 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 77 | "balance": "1000000000000000000000000000" 78 | } 79 | }, 80 | "number": "0x0", 81 | "gasUsed": "0x0", 82 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 83 | } 84 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { rootQuestion } from "./questions"; 2 | import { QuestionRenderer } from "./questionRenderer"; 3 | import { buildNetwork, NetworkContext } from "./networkBuilder"; 4 | import yargs = require('yargs/yargs'); 5 | import chalk from "chalk"; 6 | 7 | export async function main(): Promise { 8 | if (process.platform === "win32") { 9 | console.error(chalk.red( 10 | "Unfortunately this tool is not compatible with Windows at the moment.\n" + 11 | "We recommend running it under Windows Subsystem For Linux 2 with Docker Desktop.\n" + 12 | "Please visit the following pages for installation instructions.\n\n" + 13 | "https://docs.microsoft.com/en-us/windows/wsl/install-win10\n" + 14 | "https://docs.docker.com/docker-for-windows/wsl/" 15 | )); 16 | process.exit(1); 17 | } 18 | 19 | let answers = {}; 20 | 21 | if(process.argv.slice(2).length > 0){ 22 | const args = await yargs(process.argv.slice(2)).options({ 23 | clientType: { type: 'string', demandOption: true, choices:['besu','goquorum'], describe: 'Ethereum client to use.' }, 24 | privacy: { type: 'boolean', demandOption: true, default: false, describe: 'Enable support for private transactions' }, 25 | monitoring: { type: 'string', demandOption: false, default: 'loki', describe: 'Enable support for monitoring with Splunk or ELK.' }, 26 | blockscout: { type: 'boolean', demandOption: false, default: false, describe: 'Enable support for monitoring the network with Blockscout' }, 27 | chainlens: { type: 'boolean', demandOption: false, default: false, describe: 'Enable support for monitoring the network with Chainlens' }, 28 | outputPath: { type: 'string', demandOption: false, default: './quorum-test-network', describe: 'Location for config files.'} 29 | }).argv; 30 | 31 | answers = { 32 | clientType: args.clientType, 33 | outputPath: args.outputPath, 34 | monitoring: args.monitoring, 35 | blockscout: args.blockscout, 36 | chainlens: args.chainlens, 37 | privacy: args.privacy 38 | }; 39 | 40 | } else{ 41 | const qr = new QuestionRenderer(rootQuestion); 42 | answers = await qr.render(); 43 | } 44 | 45 | await buildNetwork(answers as NetworkContext); 46 | setTimeout(() => { 47 | process.exit(0); 48 | }, 500); 49 | } 50 | 51 | if (require.main === module) { 52 | // note: main returns a Promise, but we don't need to do anything 53 | // special with it, so we use the void operator to indicate to eslint that 54 | // we left this dangling intentionally... 55 | try { 56 | void main(); 57 | } catch (err) { 58 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 59 | if (err && err.stack && process.argv.length >= 3 && process.argv[2] === "--stackTraceOnError") { 60 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 61 | console.error(`Fatal error: ${err.stack as string}`); 62 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 63 | } else if (err && err.message) { 64 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 65 | console.error(`Fatal error: ${err.message as string}`); 66 | } else if (err) { 67 | console.error(`Fatal error: ${err as string}`); 68 | } else { 69 | console.error(`Fatal error: unknown`); 70 | } 71 | process.exit(1); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /files/goquorum/config/goquorum/data/istanbul-enhanced-genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 1337, 4 | "homesteadBlock": 0, 5 | "eip150Block": 0, 6 | "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", 7 | "eip155Block": 0, 8 | "eip158Block": 0, 9 | "byzantiumBlock": 0, 10 | "constantinopleBlock": 0, 11 | "istanbul": { 12 | "epoch": 30000, 13 | "policy": 0, 14 | "ceil2Nby3Block": 0 15 | }, 16 | "txnSizeLimit": 64, 17 | "maxCodeSizeConfig" : [ 18 | { 19 | "block" : 0, 20 | "size" : 64 21 | } 22 | ], 23 | "isQuorum": true, 24 | "privacyEnhancementsBlock": 0 25 | }, 26 | "nonce": "0x0", 27 | "timestamp": "0x5f1663fc", 28 | "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000f89af8549493917cadbace5dfce132b991732c6cda9bcc5b8a9427a97c9aaf04f18f3014c32e036dd0ac76da5f1894ce412f988377e31f4d0ff12d74df73b51c42d0ca9498c1334496614aed49d2e81526d089f7264fed9cb8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0", 29 | "gasLimit" : "0xf7b760", 30 | "difficulty": "0x1", 31 | "mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365", 32 | "coinbase": "0x0000000000000000000000000000000000000000", 33 | "alloc": { 34 | "fe3b557e8fb62b89f4916b721be55ceb828dbd73" : { 35 | "privateKey" : "8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 36 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 37 | "balance" : "0x130EE8E7179044400000" 38 | }, 39 | "627306090abaB3A6e1400e9345bC60c78a8BEf57" : { 40 | "privateKey" : "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 41 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 42 | "balance" : "90000000000000000000000" 43 | }, 44 | "f17f52151EbEF6C7334FAD080c5704D77216b732" : { 45 | "privateKey" : "ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 46 | "comment" : "private key and this comment are ignored. In a real chain, the private key should NOT be stored", 47 | "balance" : "90000000000000000000000" 48 | }, 49 | "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5": { 50 | "balance": "1000000000000000000000000000" 51 | }, 52 | "0xca843569e3427144cead5e4d5999a3d0ccf92b8e": { 53 | "balance": "1000000000000000000000000000" 54 | }, 55 | "0x0fbdc686b912d7722dc86510934589e0aaf3b55a": { 56 | "balance": "1000000000000000000000000000" 57 | }, 58 | "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6": { 59 | "balance": "1000000000000000000000000000" 60 | }, 61 | "0xed9d02e382b34818e88b88a309c7fe71e65f419d": { 62 | "balance": "1000000000000000000000000000" 63 | }, 64 | "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca": { 65 | "balance": "1000000000000000000000000000" 66 | }, 67 | "0x0886328869e4e1f401e1052a5f4aae8b45f42610": { 68 | "balance": "1000000000000000000000000000" 69 | }, 70 | "0xf48de4a0c2939e62891f3c6aca68982975477e45": { 71 | "balance": "1000000000000000000000000000" 72 | } 73 | }, 74 | "number": "0x0", 75 | "gasUsed": "0x0", 76 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 77 | } 78 | -------------------------------------------------------------------------------- /files/common/chainlens/5xx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chainlens | Blockchain Explorer 6 | 7 | 8 | 9 | 10 | 69 | 70 | 71 |
72 |
73 |
74 | 75 | 79 | 80 |
81 |
82 |
83 |

Your environment is being created

84 |

Give us a few minutes

85 | 86 | Chainlens — web3labs.com 87 | 88 |
89 |
90 | 91 | 92 | -------------------------------------------------------------------------------- /files/goquorum/config/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 4 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Alertmanager configuration 8 | alerting: 9 | # alertmanagers: 10 | # - static_configs: 11 | # - targets: 12 | # - alertmanager:9093 13 | 14 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 15 | rule_files: 16 | # - "first_rules.yml" 17 | # - "second_rules.yml" 18 | 19 | # A scrape configuration containing exactly one endpoint to scrape: 20 | # Here it's Prometheus itself. 21 | scrape_configs: 22 | - job_name: validator1 23 | scrape_interval: 15s 24 | scrape_timeout: 10s 25 | metrics_path: /debug/metrics/prometheus 26 | scheme: http 27 | static_configs: 28 | - targets: [ validator1:9545 ] 29 | 30 | - job_name: validator2 31 | scrape_interval: 15s 32 | scrape_timeout: 10s 33 | metrics_path: /debug/metrics/prometheus 34 | scheme: http 35 | static_configs: 36 | - targets: [ validator2:9545 ] 37 | 38 | - job_name: validator3 39 | scrape_interval: 15s 40 | scrape_timeout: 10s 41 | metrics_path: /debug/metrics/prometheus 42 | scheme: http 43 | static_configs: 44 | - targets: [ validator3:9545 ] 45 | 46 | - job_name: validator4 47 | scrape_interval: 15s 48 | scrape_timeout: 10s 49 | metrics_path: /debug/metrics/prometheus 50 | scheme: http 51 | static_configs: 52 | - targets: [ validator4:9545 ] 53 | 54 | - job_name: rpcnode 55 | scrape_interval: 15s 56 | scrape_timeout: 10s 57 | metrics_path: /debug/metrics/prometheus 58 | scheme: http 59 | static_configs: 60 | - targets: [ rpcnode:9545 ] 61 | 62 | - job_name: newnode 63 | scrape_interval: 15s 64 | scrape_timeout: 10s 65 | metrics_path: /debug/metrics/prometheus 66 | scheme: http 67 | static_configs: 68 | - targets: [ newnode:9545 ] 69 | 70 | - job_name: member1quorum 71 | scrape_interval: 15s 72 | scrape_timeout: 10s 73 | metrics_path: /debug/metrics/prometheus 74 | scheme: http 75 | static_configs: 76 | - targets: [ member1quorum:9545 ] 77 | 78 | - job_name: member2quorum 79 | scrape_interval: 15s 80 | scrape_timeout: 10s 81 | metrics_path: /debug/metrics/prometheus 82 | scheme: http 83 | static_configs: 84 | - targets: [ member2quorum:9545 ] 85 | 86 | - job_name: member3quorum 87 | scrape_interval: 15s 88 | scrape_timeout: 10s 89 | metrics_path: /debug/metrics/prometheus 90 | scheme: http 91 | static_configs: 92 | - targets: [ member3quorum:9545 ] 93 | 94 | - job_name: member1tessera 95 | scrape_interval: 15s 96 | scrape_timeout: 10s 97 | metrics_path: /metrics 98 | scheme: http 99 | static_configs: 100 | - targets: [ member1tessera:9000 ] 101 | 102 | - job_name: member2tessera 103 | scrape_interval: 15s 104 | scrape_timeout: 10s 105 | metrics_path: /metrics 106 | scheme: http 107 | static_configs: 108 | - targets: [ member2tessera:9000 ] 109 | 110 | - job_name: member3tessera 111 | scrape_interval: 15s 112 | scrape_timeout: 10s 113 | metrics_path: /metrics 114 | scheme: http 115 | static_configs: 116 | - targets: [ member3tessera:9000 ] 117 | 118 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/scripts/keys.js: -------------------------------------------------------------------------------- 1 | 2 | // WARNING: the keys here are demo purposes ONLY. Please use a tool like EthSigner for production, rather than hard coding private keys 3 | 4 | module.exports = { 5 | quorum: { 6 | validator1: { 7 | name: "validator1", 8 | url: "http://127.0.0.1:21001", 9 | nodekey: "0x1a2c4ff0f1b38e2322658dba692816138eb22d002515df1fffca21278f406aa9", 10 | accountAddress: "0xed9d02e382b34818e88b88a309c7fe71e65f419d", 11 | accountPrivateKey: "0xe6181caaffff94a09d7e332fc8da9884d99902c7874eb74354bdcadf411929f1" 12 | }, 13 | validator2: { 14 | name: "validator1", 15 | url: "http://127.0.0.1:21002", 16 | nodekey: "7f9af699dd2bb1af76c90b3f67183dd48abae509c315eb8f2c55301ad90ba978", 17 | accountAddress: "0xb30f304642de3fee4365ed5cd06ea2e69d3fd0ca", 18 | accountPrivateKey: "0x5ad8b28507578c429dfa9f178d7f742f4861716ee956eb75648a7dbc5ffe915d" 19 | }, 20 | validator3: { 21 | name: "validator1", 22 | url: "http://127.0.0.1:21003", 23 | nodekey: "fe006b00c738e7e5af7f7623290ffc83f394741ae6fb6afc6081cab49e1e1a70", 24 | accountAddress: "0x0886328869e4e1f401e1052a5f4aae8b45f42610", 25 | accountPrivateKey: "0xf23f92ed543046498d7616807b18a8f304855cb644df25bc7d0b0b37d8a66019" 26 | }, 27 | validator4: { 28 | name: "validator1", 29 | url: "http://127.0.0.1:21004", 30 | nodekey: "8f6ae009cdbbf6e6fa739b91a4483f251bbe89f6570d34856554533b36c93c55", 31 | accountAddress: "0xf48de4a0c2939e62891f3c6aca68982975477e45", 32 | accountPrivateKey: "0x7f012b2a11fc651c9a73ac13f0a298d89186c23c2c9a0e83206ad6e274ba3fc7" 33 | }, 34 | rpcnode: { 35 | name: "rpcnode", 36 | url: "http://127.0.0.1:8545", 37 | wsUrl: "ws://127.0.0.1:8546", 38 | nodekey: "0e93a540518eeb673d94fb496b746008ab56605463cb9212493997f5755124d1", 39 | accountAddress: "0xc9c913c8c3c1cd416d80a0abf475db2062f161f6", 40 | accountPrivateKey: "0x60bbe10a196a4e71451c0f6e9ec9beab454c2a5ac0542aa5b8b733ff5719fec3" 41 | }, 42 | member1: { 43 | name: "member1", 44 | url: "http://127.0.0.1:20000", 45 | wsUrl: "ws://127.0.0.1:20001", 46 | privateUrl: "http://127.0.0.1:9081", 47 | nodekey: "0xb9a4bd1539c15bcc83fa9078fe89200b6e9e802ae992f13cd83c853f16e8bed4", 48 | accountAddress: "0xf0e2db6c8dc6c681bb5d6ad121a107f300e9b2b5", 49 | accountPrivateKey: "0x8bbbb1b345af56b560a5b20bd4b0ed1cd8cc9958a16262bc75118453cb546df7" 50 | }, 51 | member2: { 52 | name: "member2", 53 | url: "http://127.0.0.1:20002", 54 | wsUrl: "ws://127.0.0.1:20003", 55 | privateUrl: "http://127.0.0.1:9082", 56 | nodekey: "f18166704e19b895c1e2698ebc82b4e007e6d2933f4b31be23662dd0ec602570", 57 | accountAddress: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", 58 | accountPrivateKey: "0x4762e04d10832808a0aebdaa79c12de54afbe006bfffd228b3abcc494fe986f9" 59 | }, 60 | member3: { 61 | name: "member3", 62 | url: "http://127.0.0.1:20004", 63 | wsUrl: "ws://127.0.0.1:20005", 64 | privateUrl: "http://127.0.0.1:9083", 65 | nodekey: "4107f0b6bf67a3bc679a15fe36f640415cf4da6a4820affaac89c8b280dfd1b3", 66 | accountAddress: "0x0fbdc686b912d7722dc86510934589e0aaf3b55a", 67 | accountPrivateKey: "0x61dced5af778942996880120b303fc11ee28cc8e5036d2fdff619b5675ded3f0" 68 | } 69 | }, 70 | accounts: { 71 | "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73" : { 72 | "privateKey" : "0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63", 73 | }, 74 | "0x627306090abaB3A6e1400e9345bC60c78a8BEf57" : { 75 | "privateKey" : "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3", 76 | }, 77 | "0xf17f52151EbEF6C7334FAD080c5704D77216b732" : { 78 | "privateKey" : "0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f", 79 | }, 80 | } 81 | }; 82 | -------------------------------------------------------------------------------- /files/common/dapps/quorumToken/frontend/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import type { NextPage } from 'next' 2 | import { Heading, Text, VStack, Box, Button, Input, Spacer, Flex } from '@chakra-ui/react' 3 | import { useState, useEffect} from 'react' 4 | import {ethers} from "ethers" 5 | import ReadQuorumToken from "../components/quorumToken/ReadQuorumToken" 6 | import TransferQuorumToken from "../components/quorumToken/TransferQuorumToken" 7 | import MMAccount from "../components/MMAccount" 8 | 9 | declare let window:any 10 | 11 | export default function Home() { 12 | 13 | const [balance, setBalance] = useState(); 14 | const [currentAccount, setCurrentAccount] = useState(); 15 | const [erc20ContractAddress, setErc20ContractAddress] = useState("0x"); 16 | const [chainId, setChainId] = useState(); 17 | 18 | useEffect( () => { 19 | if(!currentAccount || !ethers.isAddress(currentAccount)) return; 20 | if(!window.ethereum) return; 21 | const provider = new ethers.BrowserProvider(window.ethereum); 22 | provider.getBalance(currentAccount).then((result)=> { 23 | setBalance(ethers.formatEther(result)); 24 | }) 25 | provider.getNetwork().then((result)=>{ 26 | setChainId(ethers.toNumber(result.chainId)); 27 | }) 28 | 29 | },[currentAccount]) 30 | 31 | const onClickConnect = () => { 32 | if(!window.ethereum) { 33 | console.log("please install MetaMask"); 34 | return; 35 | } 36 | 37 | const provider = new ethers.BrowserProvider(window.ethereum); 38 | // MetaMask requires requesting permission to connect users accounts 39 | provider.send("eth_requestAccounts", []) 40 | .then((accounts)=>{ 41 | if(accounts.length>0) setCurrentAccount(accounts[0]) 42 | }) 43 | .catch((e)=>console.log(e)) 44 | } 45 | 46 | const onClickDisconnect = () => { 47 | setBalance(undefined) 48 | setCurrentAccount(undefined) 49 | } 50 | 51 | const deployedAddressHandler = (e: any) => { 52 | setErc20ContractAddress(e.target.value); 53 | } 54 | 55 | return ( 56 | <> 57 | QuorumToken 58 | 59 | 60 | {currentAccount 61 | ? 64 | : 67 | } 68 | 69 | {currentAccount 70 | ? 75 | :<> 76 | } 77 | 78 | {(erc20ContractAddress!="0x") 79 | ? 80 | Read QuorumToken 81 | Query the smart contract info at address provided 82 | 83 | 87 | 88 | :<> 89 | } 90 | 91 | {(erc20ContractAddress!="0x") 92 | ? 93 | Transfer QuorumToken 94 | Interact with the token 95 | 99 | 100 | :<> 101 | } 102 | 103 | 104 | 105 | ) 106 | } 107 | -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/public/hre_1559_public_tx.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs-extra'); 3 | var ethers = require('ethers'); 4 | 5 | // RPCNODE details 6 | const { tessera, besu } = require("../keys.js"); 7 | const host = besu.rpcnode.url; 8 | const accountPrivateKey = besu.rpcnode.accountPrivateKey; 9 | 10 | // abi and bytecode generated from simplestorage.sol: 11 | // > solcjs --bin --abi simplestorage.sol 12 | const contractJsonPath = path.resolve(__dirname, '../../','contracts','Counter.json'); 13 | const contractJson = JSON.parse(fs.readFileSync(contractJsonPath)); 14 | const contractAbi = contractJson.abi; 15 | const contractBytecode = contractJson.evm.bytecode.object 16 | 17 | async function getValueAtAddress(provider, deployedContractAbi, deployedContractAddress){ 18 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 19 | const res = await contract.getCount(); 20 | console.log("Obtained value at deployed contract is: "+ res); 21 | return res 22 | } 23 | 24 | // You need to use the accountAddress details provided to Quorum to send/interact with contracts 25 | async function incrementValueAtAddress(provider, wallet, deployedContractAbi, deployedContractAddress){ 26 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 27 | const contractWithSigner = contract.connect(wallet); 28 | const tx = await contractWithSigner.incrementCounter(); 29 | // verify the updated value 30 | await tx.wait(); 31 | // const res = await contract.get(); 32 | // console.log("Obtained value at deployed contract is: "+ res); 33 | return tx; 34 | } 35 | 36 | async function decrementValueAtAddress(provider, wallet, deployedContractAbi, deployedContractAddress){ 37 | const contract = new ethers.Contract(deployedContractAddress, deployedContractAbi, provider); 38 | const contractWithSigner = contract.connect(wallet); 39 | const tx = await contractWithSigner.decrementCounter(); 40 | // verify the updated value 41 | await tx.wait(); 42 | // const res = await contract.get(); 43 | // console.log("Obtained value at deployed contract is: "+ res); 44 | return tx; 45 | } 46 | 47 | async function createContract(provider, wallet, contractAbi, contractByteCode) { 48 | const feeData = await provider.getFeeData(); 49 | const factory = new ethers.ContractFactory(contractAbi, contractByteCode, wallet); 50 | const contract = await factory.deploy({ 51 | chainId: 1337, 52 | type: 2, 53 | maxPriorityFeePerGas: feeData["maxPriorityFeePerGas"], 54 | maxFeePerGas: feeData["maxFeePerGas"], 55 | }); 56 | // The contract is NOT deployed yet; we must wait until it is mined 57 | const deployed = await contract.waitForDeployment(); 58 | //The contract is deployed now 59 | return contract 60 | }; 61 | 62 | async function main(){ 63 | const provider = new ethers.JsonRpcProvider(host); 64 | const wallet = new ethers.Wallet(accountPrivateKey, provider); 65 | 66 | createContract(provider, wallet, contractAbi, contractBytecode) 67 | .then(async function(contract){ 68 | console.log(contract); 69 | contractAddress = await contract.getAddress(); 70 | console.log("Use the smart contracts 'get' function to read the contract's initialized value .. " ) 71 | await getValueAtAddress(provider, contractAbi, contractAddress); 72 | console.log("Use the smart contracts 'increment' function to update that value .. " ); 73 | await incrementValueAtAddress(provider, wallet, contractAbi, contractAddress ); 74 | console.log("Verify the updated value that was set .. " ) 75 | await getValueAtAddress(provider, contractAbi, contractAddress); 76 | console.log("Use the smart contracts 'decrement' function to update that value .. " ); 77 | await decrementValueAtAddress(provider, wallet, contractAbi, contractAddress ); 78 | console.log("Verify the updated value that was set .. " ) 79 | await getValueAtAddress(provider, contractAbi, contractAddress); 80 | }) 81 | .catch(console.error); 82 | } 83 | 84 | if (require.main === module) { 85 | main(); 86 | } 87 | 88 | module.exports = exports = main 89 | -------------------------------------------------------------------------------- /files/besu/config/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. 4 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Alertmanager configuration 8 | alerting: 9 | # alertmanagers: 10 | # - static_configs: 11 | # - targets: 12 | # - alertmanager:9093 13 | 14 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 15 | rule_files: 16 | # - "first_rules.yml" 17 | # - "second_rules.yml" 18 | 19 | # A scrape configuration containing exactly one endpoint to scrape: 20 | # Here it's Prometheus itself. 21 | scrape_configs: 22 | - job_name: validator1 23 | scrape_interval: 15s 24 | scrape_timeout: 10s 25 | metrics_path: /metrics 26 | scheme: http 27 | static_configs: 28 | - targets: [ validator1:9545 ] 29 | 30 | - job_name: validator2 31 | scrape_interval: 15s 32 | scrape_timeout: 10s 33 | metrics_path: /metrics 34 | scheme: http 35 | static_configs: 36 | - targets: [ validator2:9545 ] 37 | 38 | - job_name: validator3 39 | scrape_interval: 15s 40 | scrape_timeout: 10s 41 | metrics_path: /metrics 42 | scheme: http 43 | static_configs: 44 | - targets: [ validator3:9545 ] 45 | 46 | - job_name: validator4 47 | scrape_interval: 15s 48 | scrape_timeout: 10s 49 | metrics_path: /metrics 50 | scheme: http 51 | static_configs: 52 | - targets: [ validator4:9545 ] 53 | 54 | - job_name: rpcnode 55 | scrape_interval: 15s 56 | scrape_timeout: 10s 57 | metrics_path: /metrics 58 | scheme: http 59 | static_configs: 60 | - targets: [ rpcnode:9545 ] 61 | 62 | - job_name: newnode 63 | scrape_interval: 15s 64 | scrape_timeout: 10s 65 | metrics_path: /metrics 66 | scheme: http 67 | static_configs: 68 | - targets: [ newnode:9545 ] 69 | 70 | - job_name: member1besu 71 | scrape_interval: 15s 72 | scrape_timeout: 10s 73 | metrics_path: /metrics 74 | scheme: http 75 | static_configs: 76 | - targets: [ member1besu:9545 ] 77 | 78 | - job_name: member2besu 79 | scrape_interval: 15s 80 | scrape_timeout: 10s 81 | metrics_path: /metrics 82 | scheme: http 83 | static_configs: 84 | - targets: [ member2besu:9545 ] 85 | 86 | - job_name: member3besu 87 | scrape_interval: 15s 88 | scrape_timeout: 10s 89 | metrics_path: /metrics 90 | scheme: http 91 | static_configs: 92 | - targets: [ member3besu:9545 ] 93 | 94 | - job_name: member1tessera 95 | scrape_interval: 15s 96 | scrape_timeout: 10s 97 | metrics_path: /metrics 98 | scheme: http 99 | static_configs: 100 | - targets: [ member1tessera:9545 ] 101 | 102 | - job_name: member2tessera 103 | scrape_interval: 15s 104 | scrape_timeout: 10s 105 | metrics_path: /metrics 106 | scheme: http 107 | static_configs: 108 | - targets: [ member2tessera:9545 ] 109 | 110 | - job_name: member3tessera 111 | scrape_interval: 15s 112 | scrape_timeout: 10s 113 | metrics_path: /metrics 114 | scheme: http 115 | static_configs: 116 | - targets: [ member3tessera:9545 ] 117 | 118 | # all the nodes override themselves if given the same name 119 | # so we use dns based lookup and, replace labels to 120 | # alter the address from 192.168.x.y:9545 to node:192.168.x.y:9545 so they are easier to see in grafana 121 | - job_name: node 122 | scrape_interval: 15s 123 | scrape_timeout: 10s 124 | metrics_path: /metrics 125 | scheme: http 126 | dns_sd_configs: 127 | - names: 128 | - node 129 | type: 'A' 130 | port: 9545 131 | relabel_configs: 132 | - source_labels: [__address__] 133 | regex: '(.*)' 134 | target_label: instance 135 | replacement: "node:$1" 136 | 137 | -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/contracts/v1/PermissionsUpgradable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.3; 2 | 3 | import "./PermissionsInterface.sol"; 4 | 5 | /** @title Permissions Upgradable Contract 6 | * @notice This contract holds the address of current permissions implementation 7 | contract. The contract is owned by a guardian account. Only the 8 | guardian account can change the implementation contract address as 9 | business needs. 10 | */ 11 | contract PermissionsUpgradable { 12 | 13 | address private guardian; 14 | address private permImpl; 15 | address private permInterface; 16 | // initDone ensures that init can be called only once 17 | bool private initDone; 18 | 19 | /** @notice constructor 20 | * @param _guardian account address 21 | */ 22 | constructor (address _guardian) public{ 23 | guardian = _guardian; 24 | initDone = false; 25 | } 26 | 27 | /** @notice confirms that the caller is the guardian account 28 | */ 29 | modifier onlyGuardian { 30 | require(msg.sender == guardian, "invalid caller"); 31 | _; 32 | } 33 | 34 | /** @notice executed by guardian. Links interface and implementation contract 35 | addresses. Can be executed by guardian account only 36 | * @param _permInterface permissions interface contract address 37 | * @param _permImpl implementation contract address 38 | */ 39 | function init(address _permInterface, address _permImpl) external 40 | onlyGuardian { 41 | require(!initDone, "can be executed only once"); 42 | permImpl = _permImpl; 43 | permInterface = _permInterface; 44 | _setImpl(permImpl); 45 | initDone = true; 46 | } 47 | 48 | /** @notice changes the implementation contract address to the new address 49 | address passed. Can be executed by guardian account only 50 | * @param _proposedImpl address of the new permissions implementation contract 51 | */ 52 | function confirmImplChange(address _proposedImpl) public 53 | onlyGuardian { 54 | // The policy details needs to be carried forward from existing 55 | // implementation to new. So first these are read from existing 56 | // implementation and then updated in new implementation 57 | (string memory adminOrg, string memory adminRole, string memory orgAdminRole, bool bootStatus) = PermissionsImplementation(permImpl).getPolicyDetails(); 58 | _setPolicy(_proposedImpl, adminOrg, adminRole, orgAdminRole, bootStatus); 59 | permImpl = _proposedImpl; 60 | _setImpl(permImpl); 61 | } 62 | 63 | /** @notice function to fetch the guardian account address 64 | * @return _guardian guardian account address 65 | */ 66 | function getGuardian() public view returns (address) { 67 | return guardian; 68 | } 69 | 70 | /** @notice function to fetch the current implementation address 71 | * @return permissions implementation contract address 72 | */ 73 | function getPermImpl() public view returns (address) { 74 | return permImpl; 75 | } 76 | /** @notice function to fetch the interface address 77 | * @return permissions interface contract address 78 | */ 79 | function getPermInterface() public view returns (address) { 80 | return permInterface; 81 | } 82 | 83 | /** @notice function to set the permissions policy details in the 84 | permissions implementation contract 85 | * @param _permImpl permissions implementation contract address 86 | * @param _adminOrg name of admin organization 87 | * @param _adminRole name of the admin role 88 | * @param _orgAdminRole name of default organization admin role 89 | * @param _bootStatus network boot status 90 | */ 91 | function _setPolicy(address _permImpl, string memory _adminOrg, string memory _adminRole, string memory _orgAdminRole, bool _bootStatus) private { 92 | PermissionsImplementation(_permImpl).setMigrationPolicy(_adminOrg, _adminRole, _orgAdminRole, _bootStatus); 93 | } 94 | 95 | /** @notice function to set the permissions implementation contract address 96 | in the permissions interface contract 97 | * @param _permImpl permissions implementation contract address 98 | */ 99 | function _setImpl(address _permImpl) private { 100 | PermissionsInterface(permInterface).setPermImplementation(_permImpl); 101 | } 102 | 103 | } -------------------------------------------------------------------------------- /files/goquorum/smart_contracts/permissioning/contracts/v2/PermissionsUpgradable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.3; 2 | 3 | import "./PermissionsInterface.sol"; 4 | 5 | /** @title Permissions Upgradable Contract 6 | * @notice This contract holds the address of current permissions implementation 7 | contract. The contract is owned by a guardian account. Only the 8 | guardian account can change the implementation contract address as 9 | business needs. 10 | */ 11 | contract PermissionsUpgradable { 12 | 13 | address private guardian; 14 | address private permImpl; 15 | address private permInterface; 16 | // initDone ensures that init can be called only once 17 | bool private initDone; 18 | 19 | /** @notice constructor 20 | * @param _guardian account address 21 | */ 22 | constructor (address _guardian) public{ 23 | guardian = _guardian; 24 | initDone = false; 25 | } 26 | 27 | /** @notice confirms that the caller is the guardian account 28 | */ 29 | modifier onlyGuardian { 30 | require(msg.sender == guardian, "invalid caller"); 31 | _; 32 | } 33 | 34 | /** @notice executed by guardian. Links interface and implementation contract 35 | addresses. Can be executed by guardian account only 36 | * @param _permInterface permissions interface contract address 37 | * @param _permImpl implementation contract address 38 | */ 39 | function init(address _permInterface, address _permImpl) external 40 | onlyGuardian { 41 | require(!initDone, "can be executed only once"); 42 | permImpl = _permImpl; 43 | permInterface = _permInterface; 44 | _setImpl(permImpl); 45 | initDone = true; 46 | } 47 | 48 | /** @notice changes the implementation contract address to the new address 49 | address passed. Can be executed by guardian account only 50 | * @param _proposedImpl address of the new permissions implementation contract 51 | */ 52 | function confirmImplChange(address _proposedImpl) public 53 | onlyGuardian { 54 | // The policy details needs to be carried forward from existing 55 | // implementation to new. So first these are read from existing 56 | // implementation and then updated in new implementation 57 | (string memory adminOrg, string memory adminRole, string memory orgAdminRole, bool bootStatus) = PermissionsImplementation(permImpl).getPolicyDetails(); 58 | _setPolicy(_proposedImpl, adminOrg, adminRole, orgAdminRole, bootStatus); 59 | permImpl = _proposedImpl; 60 | _setImpl(permImpl); 61 | } 62 | 63 | /** @notice function to fetch the guardian account address 64 | * @return _guardian guardian account address 65 | */ 66 | function getGuardian() public view returns (address) { 67 | return guardian; 68 | } 69 | 70 | /** @notice function to fetch the current implementation address 71 | * @return permissions implementation contract address 72 | */ 73 | function getPermImpl() public view returns (address) { 74 | return permImpl; 75 | } 76 | /** @notice function to fetch the interface address 77 | * @return permissions interface contract address 78 | */ 79 | function getPermInterface() public view returns (address) { 80 | return permInterface; 81 | } 82 | 83 | /** @notice function to set the permissions policy details in the 84 | permissions implementation contract 85 | * @param _permImpl permissions implementation contract address 86 | * @param _adminOrg name of admin organization 87 | * @param _adminRole name of the admin role 88 | * @param _orgAdminRole name of default organization admin role 89 | * @param _bootStatus network boot status 90 | */ 91 | function _setPolicy(address _permImpl, string memory _adminOrg, string memory _adminRole, string memory _orgAdminRole, bool _bootStatus) private { 92 | PermissionsImplementation(_permImpl).setMigrationPolicy(_adminOrg, _adminRole, _orgAdminRole, _bootStatus); 93 | } 94 | 95 | /** @notice function to set the permissions implementation contract address 96 | in the permissions interface contract 97 | * @param _permImpl permissions implementation contract address 98 | */ 99 | function _setImpl(address _permImpl) private { 100 | PermissionsInterface(permInterface).setPermImplementation(_permImpl); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/fileRendering.ts: -------------------------------------------------------------------------------- 1 | import { renderString } from "nunjucks"; 2 | import { isBinaryFileSync } from "isbinaryfile"; 3 | import { resolve as resolvePath, join as joinPath, dirname } from "path"; 4 | import fs from "fs"; 5 | import os from "os"; 6 | import { NetworkContext } from "./networkBuilder"; 7 | 8 | export function renderTemplateDir(templateBasePath: string, context: NetworkContext): void { 9 | const skipDirName = context.clientType === "besu" ? "goquorum" : "besu"; 10 | for (const filePath of _walkDir(templateBasePath, skipDirName)) { 11 | renderFileToDir(templateBasePath, filePath, context); 12 | } 13 | } 14 | 15 | export function copyFilesDir(filesBasePath: string, context: NetworkContext): void { 16 | const skipDirName = context.clientType === "besu" ? "goquorum" : "besu"; 17 | for (const filePath of _walkDir(filesBasePath, skipDirName)) { 18 | const outputPath = resolvePath(context.outputPath, filePath); 19 | const outputDirname = dirname(outputPath); 20 | 21 | const { mode, size } = fs.statSync(resolvePath(filesBasePath, filePath)); 22 | 23 | if (!validateDirectoryExists(outputDirname)) { 24 | fs.mkdirSync(outputDirname, { recursive: true }); 25 | } 26 | 27 | if (isBinaryFileSync(resolvePath(filesBasePath, filePath), size)) { 28 | fs.createReadStream(resolvePath(filesBasePath, filePath)).pipe(fs.createWriteStream(outputPath, { 29 | mode, 30 | })); 31 | continue; 32 | } 33 | 34 | const fileSrc = fs.readFileSync(resolvePath(filesBasePath, filePath), "utf-8"); 35 | const output = fileSrc.replace(/(\r\n|\n|\r)/gm, os.EOL); 36 | fs.writeFileSync(outputPath, output, { encoding: "utf-8", flag: "w", mode }); 37 | } 38 | } 39 | 40 | export function renderFileToDir(basePath: string, filePath: string, context: NetworkContext): void { 41 | if (!validateDirectoryExists(resolvePath(basePath))) { 42 | throw new Error(`The template base path '${basePath}' does not exist.`); 43 | } 44 | 45 | const templatePath = resolvePath(basePath, filePath); 46 | const outputPath = resolvePath(context.outputPath, filePath); 47 | 48 | if (!_validateFileExists(templatePath)) { 49 | throw new Error(`The template does not exist at '${templatePath}'.`); 50 | } 51 | 52 | if (_validateFileExists(outputPath)) { 53 | throw new Error(`It appears that an output file already exists at '${outputPath}'. Aborting.`); 54 | } 55 | 56 | const mode = fs.statSync(templatePath).mode; 57 | const templateSrc = fs.readFileSync(templatePath, "utf-8"); 58 | const output = renderString(templateSrc, context).replace(/(\r\n|\n|\r)/gm, os.EOL); 59 | 60 | const outputDirname = dirname(outputPath); 61 | 62 | if (!validateDirectoryExists(outputDirname)) { 63 | fs.mkdirSync(outputDirname, { recursive: true }); 64 | } 65 | 66 | fs.writeFileSync(outputPath, output, { encoding: "utf-8", flag: "w", mode }); 67 | } 68 | 69 | export function validateDirectoryExists(path: string): boolean { 70 | let stat; 71 | 72 | try { 73 | stat = fs.statSync(path); 74 | } catch (err) { 75 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 76 | if (err.code === "ENOENT") { 77 | return false; 78 | } 79 | throw err; 80 | } 81 | 82 | if (!stat.isDirectory()) { 83 | throw new Error(`Path ${path} exists, but is not a directory.`); 84 | } 85 | 86 | return true; 87 | } 88 | 89 | 90 | function _validateFileExists(path: string): boolean { 91 | let stat; 92 | 93 | try { 94 | stat = fs.statSync(path); 95 | } catch (err) { 96 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access 97 | if (err.code === "ENOENT") { 98 | return false; 99 | } 100 | throw err; 101 | } 102 | 103 | if (!stat.isFile()) { 104 | throw new Error(`Path ${path} exists, but is not a plain file.`); 105 | } 106 | 107 | return true; 108 | } 109 | 110 | function* _walkDir(dir: string, skipDirName?: string, basePath = ""): Iterable { 111 | const files = fs.readdirSync(resolvePath(dir)); 112 | for (const f of files) { 113 | const dirPath = resolvePath(dir, f); 114 | const isDirectory = fs.statSync(dirPath).isDirectory(); 115 | if (isDirectory) { 116 | yield *_walkDir(dirPath, skipDirName, joinPath(basePath, f)); 117 | } else { 118 | yield joinPath(basePath, f); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /files/besu/smart_contracts/scripts/privacy/concurrent_private_txs.js: -------------------------------------------------------------------------------- 1 | const Web3 = require("web3"); 2 | const Web3Quorum = require("web3js-quorum"); 3 | const Tx = require("ethereumjs-tx"); 4 | const PromisePool = require("async-promise-pool"); 5 | const { tessera, besu } = require("../keys.js"); 6 | 7 | const chainId = 1337; 8 | const web3 = new Web3Quorum(new Web3(besu.member1.url), chainId); 9 | 10 | /* 11 | Transactions are sent in batches. 12 | TX_COUNT defines the total of transactions 13 | BATCH_SIZE defines how many transactions will be sent at once 14 | */ 15 | const TX_COUNT = 100; 16 | const BATCH_SIZE = 5; 17 | 18 | // options used to create a privacy group with only one member 19 | const privacyOptions = { 20 | privateFrom: tessera.member1.publicKey, 21 | privateFor: [tessera.member1.publicKey], 22 | privateKey: besu.member1.accountPrivateKey, 23 | }; 24 | 25 | const deployContractData = 26 | "0x608060405234801561001057600080fd5b5060405161018e38038061018e8339818101604052602081101561003357600080fd5b8101908080519060200190929190505050806000819055507f85bea11d86cefb165374e0f727bacf21dc2f4ea816493981ecf72dcfb212a410816040518082815260200191505060405180910390a15060fd806100916000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050607e565b005b606860bf565b6040518082815260200191505060405180910390f35b806000819055507f85bea11d86cefb165374e0f727bacf21dc2f4ea816493981ecf72dcfb212a410816040518082815260200191505060405180910390a150565b6000805490509056fea265627a7a723158207735a32daa767059dd230ee7718eb7f09ff35ca8ba54249b53ea1c2e12b98f8564736f6c634300051100320000000000000000000000000000000000000000000000000000000000000001"; 27 | 28 | // get nonce of account in the privacy group 29 | function getPrivateNonce(account) { 30 | return web3.priv.getTransactionCount( 31 | account, 32 | web3.utils.generatePrivacyGroup(privacyOptions) 33 | ); 34 | } 35 | 36 | // get public nonce of account 37 | function getPublicNonce(account) { 38 | return web3.eth.getTransactionCount(account, "pending"); 39 | } 40 | 41 | // distribute payload to participants 42 | function distributePayload(payload, nonce) { 43 | return web3.priv.generateAndDistributeRawTransaction({ 44 | ...privacyOptions, 45 | data: payload, 46 | nonce, 47 | }); 48 | } 49 | 50 | // create and sign PMT 51 | function sendPMT(sender, enclaveKey, nonce) { 52 | const rawTx = { 53 | nonce: web3.utils.numberToHex(nonce), // PMT nonce 54 | from: sender, 55 | to: "0x000000000000000000000000000000000000007e", // privacy precompile address 56 | data: enclaveKey, 57 | gasLimit: "0x5a88", 58 | }; 59 | 60 | const tx = new Tx(rawTx); 61 | tx.sign(Buffer.from(besu.member1.accountPrivateKey, "hex")); 62 | 63 | const hexTx = `0x${tx.serialize().toString("hex")}`; 64 | 65 | // eslint-disable-next-line promise/avoid-new 66 | return new Promise((resolve, reject) => { 67 | web3.eth 68 | .sendSignedTransaction(hexTx) 69 | .once("receipt", (rcpt) => { 70 | resolve(rcpt); 71 | }) 72 | .on("error", (error) => { 73 | reject(error); 74 | }); 75 | }); 76 | } 77 | 78 | function printPrivTxDetails(pmtRcpt) { 79 | return web3.priv 80 | .waitForTransactionReceipt(pmtRcpt.transactionHash) 81 | .then((privTxRcpt) => { 82 | console.log( 83 | `=== Private TX ${privTxRcpt.transactionHash}\n` + 84 | ` > Status ${privTxRcpt.status}\n` + 85 | ` > Block #${pmtRcpt.blockNumber}\n` + 86 | ` > PMT Index #${pmtRcpt.transactionIndex}\n` + 87 | ` > PMT Hash ${pmtRcpt.transactionHash}\n` 88 | ); 89 | return Promise.resolve(); 90 | }); 91 | } 92 | 93 | /* 94 | Example of sending private transactions in batch. 95 | 96 | The basic steps are: 97 | 98 | 1. Find the expected public and private nonce for the sender account 99 | 2. Ditribute the private transaction (incrementing the private nonce) 100 | 3. Create a PMT for each private transaction (incrementing the public nonce) 101 | */ 102 | module.exports = async () => { 103 | const sender = "0xfe3b557e8fb62b89f4916b721be55ceb828dbd73"; 104 | 105 | const privateNonce = await getPrivateNonce(sender); 106 | const publicNonce = await getPublicNonce(sender); 107 | 108 | const pool = new PromisePool({ concurrency: BATCH_SIZE }); 109 | 110 | for (let i = 0; i < TX_COUNT; i += 1) { 111 | pool.add(() => { 112 | return distributePayload(deployContractData, privateNonce + i) 113 | .then((enclaveKey) => { 114 | return sendPMT(sender, enclaveKey, publicNonce + i); 115 | }) 116 | .then(printPrivTxDetails); 117 | }); 118 | } 119 | 120 | await pool.all(); 121 | }; 122 | 123 | if (require.main === module) { 124 | module.exports().catch((error) => { 125 | console.log(error); 126 | console.log( 127 | "\nThis example requires ONCHAIN privacy to be DISABLED. \nCheck config for ONCHAIN privacy groups." 128 | ); 129 | }); 130 | } 131 | --------------------------------------------------------------------------------