{"id":30508897,"url":"https://github.com/thykof/tuto-private-eth","last_synced_at":"2025-08-25T23:18:55.085Z","repository":{"id":201449800,"uuid":"366149663","full_name":"Thykof/tuto-private-eth","owner":"Thykof","description":"How to set up your own private Ethereum blockchain?","archived":false,"fork":false,"pushed_at":"2021-05-10T19:32:50.000Z","size":54,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-10-19T20:31:01.677Z","etag":null,"topics":["blockchain","ethereum-blockchain","geth-node","tutorial","web3"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Thykof.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-05-10T19:08:47.000Z","updated_at":"2023-10-19T21:32:07.294Z","dependencies_parsed_at":null,"dependency_job_id":"bf884441-2f07-4dd0-ab1f-39155fdcdcec","html_url":"https://github.com/Thykof/tuto-private-eth","commit_stats":null,"previous_names":["thykof/tuto-private-eth"],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/Thykof/tuto-private-eth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thykof%2Ftuto-private-eth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thykof%2Ftuto-private-eth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thykof%2Ftuto-private-eth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thykof%2Ftuto-private-eth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Thykof","download_url":"https://codeload.github.com/Thykof/tuto-private-eth/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thykof%2Ftuto-private-eth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272144769,"owners_count":24881166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-25T02:00:12.092Z","response_time":1107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","ethereum-blockchain","geth-node","tutorial","web3"],"created_at":"2025-08-25T23:18:53.619Z","updated_at":"2025-08-25T23:18:55.078Z","avatar_url":"https://github.com/Thykof.png","language":"JavaScript","readme":"# Private Ethereum Blockchain\n\nIn this tutorial, we build a network of 2 Ethereum nodes.\n\nAs it is a private blockchain, we don't need to create blocks with proof of work.\nInstead, we use the Proof of Authority consensus algorithm. The miner node is not called a miner but rather a signer.\n\n*Why do we need two nodes?*\n\nThis is because the signer node must run with an unlocked account. This account is the account that will receive mining rewards. If we open the AIPs of the node, the account is insecure. So, we need a node that communicates with the signer node and that opens some APIs to the external world.\n\n## Ressources\n - [Geth command line documentation](https://geth.ethereum.org/docs/interface/command-line-options)\n - geth private networks documentation: https://geth.ethereum.org/docs/interface/private-network\n - good tutorial for 2 nodes deployed on AWS: https://blockgeeks.com/two-node-setup-of-a-private-ethereum/\n - good tutorial for private Ethereum blockchain: https://www.edureka.co/blog/ethereum-private-network-tutorial\n - [Web3 documentation](https://web3js.readthedocs.io)\n\n## Sensitive data\n**WARNING:** Do not use any data from this repo, it contains private keys that anybody can read.\n\n## Install requirements\n\n\tsudo apt-get install software-properties-common\n\tsudo add-apt-repository -y ppa:ethereum/ethereum\n\tsudo apt-get update\n\tsudo apt-get install ethereum\n\n\tnpm install\n\n## Generate accounts\n### For the signer\nChange the password in the file `./secrets/password-signer.secret`\n\nRun this command:\n\n\tgeth account new --datadir ./datadir-signer --password ./secrets/password-signer.secret\n\n`--datadir ./datadir-signer` specifies the data directory for our blockchain.\n\n`--password ./secrets/password-signer.secret` specifies the file where the account password is stored\n\n### For the API\nDo the same thing for the API node: change the password in the file `./secrets/password-api.secret` and run:\n\n\tgeth account new --datadir ./datadir-api --password ./secrets/password-api.secret\n\n### Generate key pair\nIf you want, you can generate a key pair with this command:\n\n\tnode ./scripts/generate-keypair.js\n\nIt will generate a key pair and save it in a file.\n\n**Warning:** the file contains the private key.\n\n*Note*: this is not really useful for our blockchain.\n\n## Signer node (Miner)\nThe signer node is the node that computes transactions.\n\nTo initialize a network with POA consensus algorithm, we need to specify a `clique` and `extradata` in the genesis file.\n\n## API node\nThe API node is the node that receives RPC calls from clients and shares submitted transactions to the signer node.\n\nIt needs to open an API and be synchronized with the signer node.\n\n## Initialization: the genesis file\nAll nodes of the network must have the same genesis file.\n\nThe first step is defining a chain ID.\n\nOpen the file `./common/genesis.json` and change the value of the `chainId` field.\n\nChange the `alloc` section with the generated addresses, remove `0x` prefix.\n\nIn the `extradata` field, replace the address with the account generate in the `datadir-signer` folder (signer's address). This field must start with `0x`, then 64 `0`, the signer address (without the `0x`), and finish with 130 `0`.\n\n## Initialize\n### Initialize Signer node\nRun:\n\n\tgeth init --datadir ./datadir-signer ./common/genesis.json\n\n### Initialize API node\nRun:\n\n\tgeth init --datadir ./datadir-api ./common/genesis.json\n\nThe two nodes are now initialized with the same genesis file.\n\n## Run\n### Run the signer node\nIn the command bellow, replace the signer's address and the network id:\n\n\tgeth --networkid 2363 --datadir ./datadir-signer --nodiscover --port 30304 --mine --miner.threads=1 --miner.etherbase 0x815bd60b39e32d23793410c928e4d8a5459d2c2f --unlock 0x815bd60b39e32d23793410c928e4d8a5459d2c2f --password ./secrets/password-signer.secret\n\n### Run the API node\nFor local host, run this command:\n\n\tgeth --networkid 2363 --datadir ./datadir-api --nodiscover --http --http.addr 127.0.0.1 --http.api eth,net,web3\n\nAgain, don't forget to replace de network id.\n\nOr, run this one for specifing networking options:\n\n\tgeth --networkid 2363 --datadir ./datadir-api --nodiscover --netrestrict=\"10.0.0.0/28\" --http --http.addr 10.0.0.11 --http.api eth,net,web3\n\n - `--netrestrict`: Restricts network communication to the given IP networks (CIDR masks)\n - `--http.addr`: HTTP-RPC server listening interface\n\n#### Check the API node\nThis command shows the version of the web3 API of the node.\nIt can be used to know if the node is running and if we can communicate with it through web3.\n\nRun this in a new terminal:\n\n    curl -X POST -H \"Content-Type: application/json\" --data '{\"jsonrpc\":\"2.0\",\"method\":\"web3_clientVersion\",\"params\":[],\"id\":67}' http://localhost:8545\n\nIt should output something like `{\"jsonrpc\":\"2.0\",\"id\":67,\"result\":\"Geth/v1.10.2-stable-97d11b01/linux-amd64/go1.16\"}`.\n\n## Synchronize nodes\nThe API node needs to be synchronized with the signer node.\nTo make them communicate with each other, we simply add a file named `static-nodes.json` in the `geth` folder of the datadir of the API node.\n\nIn a new terminal, run the console of the signer node :\n\n\tgeth attach --datadir ./datadir-signer\n\nIn the console, run:\n\n\tadmin.nodeInfo.enode\n\nIt should output something like `\"enode://79d6921e66fb9865e941555733124930c6394586ade5efb9a1ac8bebc25ac6dec6bebb725d00cb193c228f12d1adcd38d754e4c5bbdd1982079a380a74b2a008@10.0.0.12:30304?discport=0\"`.\n\nYou can see that `10.0.0.12` is the IP address of the signer node.\n\nThen, in the folder `./datadir-api/geth`, create a file `static-nodes.json` with this content:\n\n    [\n        \u003cput here the output of the previous command\u003e\n    ]\n\nReplace with the output and replace the IP address with the signer node's private IP address.\n\nIf you run both nodes on the same computer, the IP address is `127.0.0.1`.\n\nAt startup, the API node will try to connect to the signer node and will start to synchronize.\n\nRestart the API node.\n\n### Check the synchronization\nGo back to the console of the signer node:\n\nType:\n\n\tadmin.peers\n\nIt should output something like:\n\n```\n[{\n    caps: [\"eth/64\", \"eth/65\", \"eth/66\", \"snap/1\"],\n    enode: \"enode://396c1447f79d164153641e2791034333ee6f75f4f757ed1e2d69e205dd021e44a72b1ecb726172b6a6537fe124b1cf0a206641e84d9a0cdbbb6ab6cda1aea050@127.0.0.1:60390\",\n    id: \"d71ed1495f6616be0350bde4f1ffb219e93c568c389ba7e7f93d0d2845d1df98\",\n    name: \"Geth/v1.10.2-stable-97d11b01/linux-amd64/go1.16\",\n    network: {\n      inbound: true,\n      localAddress: \"127.0.0.1:30304\",\n      remoteAddress: \"127.0.0.1:60390\",\n      static: false,\n      trusted: false\n    },\n    protocols: {\n      eth: {\n        difficulty: 1,\n        head: \"0x74eaa02b8d78ff17130fbf524c1774d14a85ae770badcd4ef1b9707b84f3fb36\",\n        version: 66\n      },\n      snap: {\n        version: 1\n      }\n    }\n}]\n```\n\nYou can see that it is a JSON object. If you see multiple JSON objects, this means that your miner node is connected with several other nodes. In this JSON object, the `enode` field is the node information of the API node.\n\nThe logs of the signer node should output some messages like `mined potential block`.\n\nThe logs of the API node should output some messages like `Imported new chain segment`.\n\n## Interact\n### Send ether\nOpen the file `./scripts/constants.js` and change the values of `addressSigner` and `addressAPI` with the one generated in the *Generate key pair* step.\n\nIn the `scripts` folder, you will find two different ways to send a transaction.\n\n#### API node send ether to signer node\nRun:\n\n\tnode ./scripts/api-send-to-signer.js\n\nWhen a transaction is broadcasted, API node should output `Submitted transaction`.\n\n#### Check balances\nIn a new terminal window, open a console of the signer node by typing:\n\n\tgeth attach --datadir ./datadir-signer\n\nAnd type:\n\n\tweb3.fromWei(eth.getBalance(eth.coinbase));\n\nThe output should be like `4000000000.000042000000000006`. The script sends 6 WEI, so the amount ends with 6.\n\nTo check the balance of the API node, you can do the same as previous: open a console of the API node.\nHowever, you can run is any console node:\n\n\tweb3.fromWei(eth.getBalance(\"0xf6eed716dd9a86a36b5be105dc45d4e74abbd775\"));\n\nAnd of course, replace the address with the one of the API node.\n\nAs the API node sends the transaction, it pays fees, so the output would look like `2999999999.999936999999999982`.\n\n### Deploy contract\nNow that we can submit simple transfer transactions, it is possible to use a framework to make some more complex actions, like deploy a smart contract and interact with it.\n\nTo do that, we just need the host of the API node, for example, `http://localhost:8545`. We can use Truffle: https://www.trufflesuite.com/docs/truffle/overview.\n\n## Deploy the stack\nNow that we have our network running, we can deploy both notes on separate servers, for example in VMs in a cloud provider.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthykof%2Ftuto-private-eth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthykof%2Ftuto-private-eth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthykof%2Ftuto-private-eth/lists"}