├── Dockerfile ├── keystore ├── UTC--2018-01-18T01-05-42.637024000Z--1f7402f55e142820ea3812106d0657103fc1709e ├── UTC--2018-01-18T01-06-50.619577000Z--cb409caa43e385288d6bff2c3a0635688c7b3294 ├── UTC--2018-01-18T01-07-44.712525000Z--5963e46cf9f9700e70d4d1bc09210711ab4a20b4 ├── UTC--2018-01-18T01-08-02.793570000Z--75e912af38888643829380fa9f2c4019f5710ff5 ├── UTC--2018-01-18T01-08-34.712007000Z--83a930a41a1fbc65d65203f9477ca6d1293a4d23 ├── UTC--2018-01-18T01-39-33.381836000Z--830ad8ef8b5b1c7f22fde94ddb30a19b2c34c2c8 ├── UTC--2018-01-18T01-39-50.916986000Z--d00c280f175a5935b3237b8504c5a8340c5a9fd0 ├── UTC--2018-01-18T01-40-08.561062000Z--4e8463ae7fcd8472357ceebecf20d44635a23873 ├── UTC--2018-01-18T01-40-39.367202000Z--140725c8fafc5b59d93db9a3c86717a2bc365b2d └── UTC--2018-01-18T01-41-10.283422000Z--61d3fa79ba54f08dcb850c3dc802b83e3d970552 ├── LICENSE ├── .circleci └── config.yml ├── run-dev-node.js ├── run-poa-node.js ├── start-node.sh ├── genesis.json └── README.md /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ethereum/client-go:v1.7.3 2 | MAINTAINER Chris Purta 3 | 4 | ARG DEV_CHAIN 5 | ENV DEV_CHAIN_ENABLED=${DEV_CHAIN} 6 | 7 | RUN apk update && \ 8 | apk add bash curl 9 | 10 | RUN mkdir -p /ethereum/data 11 | 12 | ADD . /ethereum/ 13 | 14 | EXPOSE 8545 8555 8080 6060 15 | 16 | WORKDIR /ethereum 17 | 18 | ENTRYPOINT ["./start-node.sh"] 19 | -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-05-42.637024000Z--1f7402f55e142820ea3812106d0657103fc1709e: -------------------------------------------------------------------------------- 1 | {"address":"1f7402f55e142820ea3812106d0657103fc1709e","crypto":{"cipher":"aes-128-ctr","ciphertext":"c52ed24d0f17ec20d7d2fd786d107e8da20d44045ea67741a76756e0c73cb598","cipherparams":{"iv":"0519fe619a25eb1bc2427f88609196a8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e2568068492ffee009047d57b50acfdf3d882fb21d1311b9513af7397b338c4b"},"mac":"2650905dcd2ddd9545810e97e74719731bccdddd9937e97fc1a8409cff231757"},"id":"42649555-cb85-4cca-a09c-a488d92eab5f","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-06-50.619577000Z--cb409caa43e385288d6bff2c3a0635688c7b3294: -------------------------------------------------------------------------------- 1 | {"address":"cb409caa43e385288d6bff2c3a0635688c7b3294","crypto":{"cipher":"aes-128-ctr","ciphertext":"ecb4d7c405e901682d372b36997d5d07cb75737249be35b37a4095adb2fad0b4","cipherparams":{"iv":"782854ae47e215d0269c441360a17ac5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e903a0648f895278fc41df76659ba3e27da2f49371f4f8629cd4fa4f831b759a"},"mac":"fcad6aef1c5242fbb49746542de83985d7afda284da16239923a7c1cf353e048"},"id":"76cf105d-06c6-4d3c-b0cc-645749a43973","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-07-44.712525000Z--5963e46cf9f9700e70d4d1bc09210711ab4a20b4: -------------------------------------------------------------------------------- 1 | {"address":"5963e46cf9f9700e70d4d1bc09210711ab4a20b4","crypto":{"cipher":"aes-128-ctr","ciphertext":"2e89247d0803b4b93d1b3ce16c3ed6c1a3e728624863090dcbaee7cccfb0a992","cipherparams":{"iv":"4fb7ad0b4657197a21b6b6e57dbe8258"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"95e6718afe699f1cccdb1b903631be544a35682f81277e2de648770756f2d4ba"},"mac":"4ca4be160247a2983aa9599e33d3730bb691f82e2d8576c95ae0c7916d441158"},"id":"584acd04-c8ba-47a0-8c9a-b17403638ae6","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-08-02.793570000Z--75e912af38888643829380fa9f2c4019f5710ff5: -------------------------------------------------------------------------------- 1 | {"address":"75e912af38888643829380fa9f2c4019f5710ff5","crypto":{"cipher":"aes-128-ctr","ciphertext":"8aa1de1bc802c9f39dc8e30e7df500edb2b68786e45a3772435ecbcbb9189118","cipherparams":{"iv":"82ad5660ef0293ea1202d2f02c748cc9"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"74a6be11f8c95e31a11eea54637c050387ccc81b84ad42a96e03a0fd1ffbd9f7"},"mac":"1b78fe6e23f99e48a6d4e9839a1c9c6fa3e2175743ec95d852e9d97537fc94fd"},"id":"ee5b247f-6614-4927-8682-a9f9f2b3b455","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-08-34.712007000Z--83a930a41a1fbc65d65203f9477ca6d1293a4d23: -------------------------------------------------------------------------------- 1 | {"address":"83a930a41a1fbc65d65203f9477ca6d1293a4d23","crypto":{"cipher":"aes-128-ctr","ciphertext":"df44983d3fabab1f8a2d6a079b6634a63db652b305a1cb4ee61f42fce325b529","cipherparams":{"iv":"c9ef74ad5b4b56a9946c6b9190a53bec"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"90e02f86ba65429b52a19d231e5e0111a17213c7ce8aa5e27ae0ada7505d6116"},"mac":"c098547a2e9915b3a7b56c49b6aa5842fb3050454f0a36584e340365a9f5efae"},"id":"4ca6033e-659e-4e94-a944-6eea172f30b2","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-39-33.381836000Z--830ad8ef8b5b1c7f22fde94ddb30a19b2c34c2c8: -------------------------------------------------------------------------------- 1 | {"address":"830ad8ef8b5b1c7f22fde94ddb30a19b2c34c2c8","crypto":{"cipher":"aes-128-ctr","ciphertext":"c979106393939c1892fdfc5de282c5d52805c59b487a861e6d881af424158e9e","cipherparams":{"iv":"64dad40a990ac0e3753bf44e6c80dfc2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"9fdfcf2c7fd89343034185f01d9f6261019d1370e8d77cfd3d71294954f58a49"},"mac":"52d818c59a76761a6a557f9572bbfab20b7cbb2abec53a4f816ad5355b1f88d6"},"id":"4ea2170d-f167-4084-8cc2-6ccd79e34a6e","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-39-50.916986000Z--d00c280f175a5935b3237b8504c5a8340c5a9fd0: -------------------------------------------------------------------------------- 1 | {"address":"d00c280f175a5935b3237b8504c5a8340c5a9fd0","crypto":{"cipher":"aes-128-ctr","ciphertext":"978f6a1546afedbdc160ab41ccff122240581dcbc10b3a3c11198807e221eb33","cipherparams":{"iv":"cea77503d7765efc8e8410a3478465ff"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"cf7822347c416d63d82aa2a6953905999335411d2b2fb7350908999a351182d7"},"mac":"6c2d0114aad97913af71cafd1acfa1401ac04b882b9e9f04127e88a827267bb3"},"id":"acb8a63e-d2b7-4db6-8d69-543a9dc3e4e4","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-40-08.561062000Z--4e8463ae7fcd8472357ceebecf20d44635a23873: -------------------------------------------------------------------------------- 1 | {"address":"4e8463ae7fcd8472357ceebecf20d44635a23873","crypto":{"cipher":"aes-128-ctr","ciphertext":"0aa7562633be60924d766366efcdb6bb5ebe5e7dbb50db91128a7ad2d2c498ed","cipherparams":{"iv":"9a26a4ca4f5483791f6389abcb00cfa5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b5b96e3bc2dc79c89dd4d69c85abdfeb79fcccba3b2b98054133602ddcb7a16f"},"mac":"1ed63920cc736efe4f3d3d7c7b362c1eeae30ab4e3c714d5defce06bb8da231f"},"id":"7c7e2432-50d2-4815-8e9a-fd2538637104","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-40-39.367202000Z--140725c8fafc5b59d93db9a3c86717a2bc365b2d: -------------------------------------------------------------------------------- 1 | {"address":"140725c8fafc5b59d93db9a3c86717a2bc365b2d","crypto":{"cipher":"aes-128-ctr","ciphertext":"8ca55ef5f73074f5a48bf85de100dd076f13d290defab7dfbdde5bb867eff377","cipherparams":{"iv":"d9ce251bc303e9a22e3e3241e2f981f8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"a3707eb4e294a7d68dbd6c2b75363108105cb5b6d8135641fc8708b7e5bd5501"},"mac":"8ee158cc4d9eaffbfdf494c5883d984b8ad3ceb6619eec52dc31d0ef8f9a565a"},"id":"7c70ae4a-a7b8-4b00-920c-d4450baf1015","version":3} -------------------------------------------------------------------------------- /keystore/UTC--2018-01-18T01-41-10.283422000Z--61d3fa79ba54f08dcb850c3dc802b83e3d970552: -------------------------------------------------------------------------------- 1 | {"address":"61d3fa79ba54f08dcb850c3dc802b83e3d970552","crypto":{"cipher":"aes-128-ctr","ciphertext":"0d4287c33f879ff19c60b4b7828945abd8c27cd76c4ec55ebdd5e78b934a7f2a","cipherparams":{"iv":"3c055629f5c9a4feab54615379a9556d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"25cb21926d915f55640315476075345937792bef6b2ab3355f6f3f95d908dc8e"},"mac":"f5c2a973f9d9ae7947c20e2d82771ce8b6565da3d8b370d35e7c1baef8daa4e6"},"id":"19b5204e-030b-4ee2-8417-7d5e680e1d5d","version":3} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Chris Purta 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | filters: 5 | tags: 6 | only: /^v.*/ 7 | branches: 8 | ignore: /.*/ 9 | machine: true 10 | steps: 11 | - checkout 12 | # build all docker images for tags 13 | - run: 14 | name: Creating image artifacts 15 | command: | 16 | docker build --build-arg DEV_CHAIN=false -f Dockerfile -t purta/geth-devnet:${CIRCLE_TAG:-latest} . 17 | docker build --build-arg DEV_CHAIN=true -f Dockerfile -t purta/geth-devnet:${CIRCLE_TAG:-latest}-instantseal . 18 | 19 | deploy: 20 | requires: 21 | - build 22 | filters: 23 | tags: 24 | only: /^v.*/ 25 | branches: 26 | ignore: /.*/ 27 | machine: true 28 | steps: 29 | # publish all docker images to docker hub 30 | - run: 31 | name: Publish images 32 | command: | 33 | docker login -u $DOCKER_USER -p $DOCKER_PASSWORD 34 | docker push purta/geth-devnet:${CIRCLE_TAG:-latest} 35 | docker push purta/geth-devnet:${CIRCLE_TAG:-latest}-instantseal 36 | -------------------------------------------------------------------------------- /run-dev-node.js: -------------------------------------------------------------------------------- 1 | function createAccounts() { 2 | for (var i = 0; i < 10; i++) { 3 | console.log('creating new account...') 4 | acc = personal.newAccount(""); 5 | personal.unlockAccount(acc, ""); 6 | eth.sendTransaction({from: eth.accounts[0], to: acc, value: web3.toWei(1000, "ether")}); 7 | } 8 | } 9 | 10 | function unlockAccounts() { 11 | eth.accounts.forEach(function (account) { 12 | console.log('Unlocking ' + account + '...'); 13 | personal.unlockAccount(account, '', 86400); 14 | }); 15 | } 16 | 17 | function pendingTransactions() { 18 | if (web3.eth.pendingTransactions === undefined || web3.eth.pendingTransactions === null) { 19 | return txpool.status.pending || txpool.status.queued; 20 | } 21 | else if (typeof web3.eth.pendingTransactions === "function") { 22 | return web3.eth.pendingTransactions().length > 0; 23 | } 24 | else { 25 | return web3.eth.pendingTransactions.length > 0 || web3.eth.getBlock('pending').transactions.length > 0; 26 | } 27 | } 28 | 29 | function setupDevNode() { 30 | // keep accounts unlocked 31 | while (true) { 32 | unlockAccounts() 33 | } 34 | } 35 | 36 | createAccounts(); 37 | setupDevNode(); 38 | -------------------------------------------------------------------------------- /run-poa-node.js: -------------------------------------------------------------------------------- 1 | function unlockAccounts() { 2 | eth.accounts.forEach(function (account) { 3 | console.log('Unlocking ' + account + '...'); 4 | personal.unlockAccount(account, '', 86400); 5 | }); 6 | } 7 | 8 | function pendingTransactions() { 9 | if (web3.eth.pendingTransactions === undefined || web3.eth.pendingTransactions === null) { 10 | return txpool.status.pending || txpool.status.queued; 11 | } 12 | else if (typeof web3.eth.pendingTransactions === "function") { 13 | return web3.eth.pendingTransactions().length > 0; 14 | } 15 | else { 16 | return web3.eth.pendingTransactions.length > 0 || web3.eth.getBlock('pending').transactions.length > 0; 17 | } 18 | } 19 | 20 | function setupDevNode() { 21 | web3.eth.filter("pending").watch(function () { 22 | if (miner.hashrate > 0) 23 | return; 24 | console.log("== Pending transactions! Looking for next block..."); 25 | miner.start(8); 26 | }); 27 | 28 | web3.eth.filter("latest").watch(function () { 29 | if (!pendingTransactions()) { 30 | console.log("== No transactions left. Stopping miner..."); 31 | miner.stop(); 32 | } 33 | }); 34 | } 35 | 36 | unlockAccounts(); 37 | setupDevNode(); 38 | -------------------------------------------------------------------------------- /start-node.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | start_poa_network() { 4 | echo "Starting PoA network" 5 | 6 | # hardcoded address of first account in keystore 7 | ETHERBASE='0x1f7402f55e142820ea3812106d0657103fc1709e' 8 | DATADIR="$HOME/.ethdata" 9 | 10 | # Generate and store a wallet password 11 | if [ ! -f $DATADIR ]; then 12 | echo "Making data directory '$HOME/.ethdata'..." 13 | mkdir -p $DATADIR 14 | cp -R ./keystore $DATADIR 15 | fi 16 | # initialize our private network 17 | geth \ 18 | --datadir $DATADIR \ 19 | --networkid 454545 \ 20 | --etherbase $ETHERBASE \ 21 | --targetgaslimit '6500000' \ 22 | init ./genesis.json 23 | 24 | geth \ 25 | --rpc \ 26 | --rpcaddr '0.0.0.0' \ 27 | --rpcport 8545 \ 28 | --rpccorsdomain '*' \ 29 | --datadir $DATADIR \ 30 | --networkid 454545 \ 31 | --etherbase $ETHERBASE \ 32 | --targetgaslimit '6500000' \ 33 | js ./run-poa-node.js 34 | } 35 | 36 | start_instantseal_network() { 37 | echo "Starting dev chain" 38 | 39 | # start geth network with dev chain 40 | geth \ 41 | --rpc \ 42 | --rpcaddr '0.0.0.0' \ 43 | --rpcport 8545 \ 44 | --rpccorsdomain '*' \ 45 | --dev \ 46 | --dev.period 1 \ 47 | --targetgaslimit '6500000' \ 48 | --nodiscover \ 49 | js ./run-dev-node.js 50 | } 51 | 52 | echo $DEV_CHAIN_ENABLED 53 | if [ $DEV_CHAIN_ENABLED == true ]; then 54 | start_instantseal_network 55 | else 56 | start_poa_network 57 | fi 58 | -------------------------------------------------------------------------------- /genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "chainId": 454545, 4 | "homesteadBlock": 0, 5 | "eip155Block": 0, 6 | "eip158Block": 0, 7 | "ByzantiumBlock": 0 8 | }, 9 | "difficulty": "0x00", 10 | "gasLimit": "6500000", 11 | "alloc": { 12 | "0x1f7402f55e142820ea3812106d0657103fc1709e": { 13 | "balance": "100000000000000000000" 14 | }, 15 | "0xcb409caa43e385288d6bff2c3a0635688c7b3294": { 16 | "balance": "100000000000000000000" 17 | }, 18 | "0x5963e46cf9f9700e70d4d1bc09210711ab4a20b4": { 19 | "balance": "100000000000000000000" 20 | }, 21 | "0x75e912af38888643829380fa9f2c4019f5710ff5": { 22 | "balance": "100000000000000000000" 23 | }, 24 | "0x83a930a41a1fbc65d65203f9477ca6d1293a4d23": { 25 | "balance": "100000000000000000000" 26 | }, 27 | "0x830ad8ef8b5b1c7f22fde94ddb30a19b2c34c2c8": { 28 | "balance": "100000000000000000000" 29 | }, 30 | "0xd00c280f175a5935b3237b8504c5a8340c5a9fd0": { 31 | "balance": "100000000000000000000" 32 | }, 33 | "0x4e8463ae7fcd8472357ceebecf20d44635a23873": { 34 | "balance": "100000000000000000000" 35 | }, 36 | "0x140725c8fafc5b59d93db9a3c86717a2bc365b2d": { 37 | "balance": "100000000000000000000" 38 | }, 39 | "0x61d3fa79ba54f08dcb850c3dc802b83e3d970552": { 40 | "balance": "100000000000000000000" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # geth-devnet 2 | 3 | [![CircleCI](https://circleci.com/gh/cpurta/geth-devnet/tree/master.svg?style=svg)](https://circleci.com/gh/cpurta/geth-devnet/tree/master) 4 | 5 | This is simple repo to create a geth node running private development network to 6 | be used for testing dApps. This holds all the needed code and Dockerfile(s) to 7 | create the base image. 8 | 9 | This will by default create a geth node that has an account unlocked, is mining and 10 | has the jsonrpc api enabled, should not be discoverable by other nodes, and has a 11 | high `targetgaslimit`. This allows for contracts that have high gas prices to still 12 | be run by the network. 13 | 14 | There are two "flavors" of images, one using the geth instant sealing development network 15 | and another using Proof of Authority (PoA) network. The instant sealing network allows 16 | for faster mining times and if you are testing contracts this will usually allow 17 | for your test to be completed faster. 18 | 19 | ## Building 20 | 21 | When building the images, the default will use 22 | a PoA network. In order to use the instant seal dev network you will need to set a 23 | docker argument when building the image. 24 | 25 | ### Proof of Authority network 26 | 27 | To build the image just run the following command: 28 | ``` 29 | $ docker build --build-arg DEV_CHAIN=false -f Dockerfile -t geth-devnet: . 30 | ``` 31 | 32 | ### Instant seal development network 33 | 34 | ``` 35 | $ docker build --build-arg DEV_CHAIN=true -f Dockerfile -t geth-devnet: . 36 | ``` 37 | 38 | ## Running 39 | 40 | Once you have built the image you should be able to run the image by using: 41 | ``` 42 | $ docker run -d -p 8545:8545 geth-devnet: 43 | ``` 44 | 45 | You can add any other geth flags that you need by appending them as a part of the 46 | docker run command. 47 | 48 | ## LICENSE 49 | MIT 50 | --------------------------------------------------------------------------------