{"id":13341176,"url":"https://github.com/lambdaclass/ethereum_war_game_tooling","last_synced_at":"2025-07-04T09:07:01.164Z","repository":{"id":38085597,"uuid":"460438708","full_name":"lambdaclass/ethereum_war_game_tooling","owner":"lambdaclass","description":"We are slow while using the UI/UX of crypto wallets so we created our CLI version","archived":false,"fork":false,"pushed_at":"2022-07-21T17:30:36.000Z","size":653,"stargazers_count":5,"open_issues_count":35,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-09T23:38:30.952Z","etag":null,"topics":["ctf-challenges","distributed-systems","ethereum","wargame"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lambdaclass.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-17T13:04:48.000Z","updated_at":"2023-08-09T23:21:12.000Z","dependencies_parsed_at":"2022-07-14T02:10:40.758Z","dependency_job_id":null,"html_url":"https://github.com/lambdaclass/ethereum_war_game_tooling","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lambdaclass/ethereum_war_game_tooling","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fethereum_war_game_tooling","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fethereum_war_game_tooling/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fethereum_war_game_tooling/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fethereum_war_game_tooling/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lambdaclass","download_url":"https://codeload.github.com/lambdaclass/ethereum_war_game_tooling/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lambdaclass%2Fethereum_war_game_tooling/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263480867,"owners_count":23473164,"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","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":["ctf-challenges","distributed-systems","ethereum","wargame"],"created_at":"2024-07-29T19:25:13.630Z","updated_at":"2025-07-04T09:07:01.138Z","avatar_url":"https://github.com/lambdaclass.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ethereum War Game and CTF Tooling\n\n## EthClient\n\nSimple elixir client to interact with the ethereum blockchain, deploying and calling smart contracts.\n\n## Requirements\n- Erlang/OTP 24\n- Elixir 1.13.0\n- Rust 1.58.0\n- [Geth](https://geth.ethereum.org/docs/install-and-build/installing-geth)\n\n## Quick Start with Tilt\n\n*\"I just want to try it right now!!\"*\n\nRun the following commands to get started. This will configure and start both Ethereum nodes, the Livebook server and the EthClient Elixir application. \n\n```bash\ngit clone git@github.com:lambdaclass/ethereum_war_game_tooling.git\ncd ethereum_war_game_tooling\ntilt up\n```\nNow that you have everything ready you can start playing with the tool in **one of two ways**. \n\n#### \u003cins\u003eLivebook\u003c/ins\u003e\nAccesing to the Application running at http://localhost:8080 and creating a new notebook.\n\n#### \u003cins\u003eElixir IEx terminal\u003c/ins\u003e\n\n```bash\ncd eth_client\nmake tilt.up\n```  \n\n### Configuration\n\nAll global configuration is kept in the `EthClient.Context` module, which holds the following values:\n\n- `rpc_host`: The hostname needed to interact with the ethereum Json RPC API. This can be an infura-type url or just the hostname of an actual node.\n- `chain_id`: The id of the chain currently in use (`1` for mainnet, `4` for Rinkeby, etc).\n- `user_account`: A value of type `EthClient.Account`, which holds two fields, `address` and `private_key`. This is the account used to sign and send all transactions.\n- `contract`: A value of type `EthClient.Contract`, which holds two fields, `address` and `functions`.\n\nYou can change any of these config values at runtime by using the functions exposed by the `EthClient.Context` module.\n\nThe default config assumes you're running the local ethereum network this repo provides.\n\nIf you want to use infura-type host this are the setps you must follow:\n\nFirst set your infura api key\n\n```\nContext.set_infura_api_key(\"your_infura_api_key\")\n```\n\nThen set the your etherscan api key\n\n```\nContext.set_etherscan_api_key(\"your_eth_scan_api_key\")\n```\n\nAnd finally set the name of the chain you want to use, for now this are the supported chains: eht mainnet, rinkeby and ropsten.\n\n```\nEthClient.set_chain(\"chain_name\")\n```\n\n### Interacting with smart contracts\n\n#### \u003ca name=\"without_an_abi\"\u003e\u003c/a\u003eWithout an ABI file\nCurrently there are three functions in the `EthClient` module that form the main API:\n\n- `EthClient.deploy(bin_path)` deploys a compiled smart contract given a path to its `.bin` file, generated by compiling said contract (i.e. by running something like `solc --bin contract.sol`). After a successful deployment, the context will be updated to use it.\n\n- `EthClient.call(method, arguments)` calls any read-only public method of a contract.\n\n- `EthClient.invoke(method, arguments, amount)` calls any public method of a contract that requires a transaction (usually to write stuff to the blockchain). The `amount` parameter controls how much `eth` is sent to the contract.\n\n#### With an ABI file\nWhen there is an `.abi` file with the ABI of the contract, user can interact with API in a different way:\n\n- `EthClient.deploy(bin_path, abi_path)` deploys a compiled smart contract (as it is explained in [Without an ABI file](#without_an_abi) section) but it also add contract functions to the context when deploying it.\n\n- Then, user can interact with contract functions by calling `Context.contract.functions.contract_function_name.(parameters)`, either if it is a read-only method or not.\n\n### Example\n\nWhen running `iex -S mix`, there will be a default `bin_path` variable loaded with the path to a compiled `Storage` contract and a default `abi_path` variable with the path to contract's ABI. You can then immediately deploy it with\n\n```\nEthClient.deploy(bin_path)\n```\n\nand then call each of its functions. If you're running the local ethereum network, you should see something like the following:\n\n```\niex(1)\u003e EthClient.deploy(bin_path)\n19:53:26.918 [info]  Deployment transaction accepted by the network, tx_hash: 0x14765466533a85c90ce45dd966854dc5fb95543ba97f343f389872c64ed9597b\n19:53:26.922 [info]  Waiting for confirmation...\n19:53:28.931 [info]  Contract deployed, address: 0x69148897094941cfad7fd3d52c5e1a810ba4e123 Current contract updated\n:ok\n```\n\n```\niex(2)\u003e EthClient.call(\"test_function()\", [])\n{:ok, \"0x0000000000000000000000000000000000000000000000000000000000000001\"}\n```\n\n```\niex(3)\u003e EthClient.invoke(\"store(uint256)\", [20], 0)\n19:55:28.127 [info]  Transaction accepted by the network, tx_hash: 0x137320dcfb61055313f73aafa799670a4d172936bc91200ebf7a95092f77c297\n19:55:28.127 [info]  Waiting for confirmation...\n19:55:41.177 [info]  Transaction confirmed!\n{:ok, \"0x137320dcfb61055313f73aafa799670a4d172936bc91200ebf7a95092f77c297\"}\n```\n\n```\niex(4)\u003e EthClient.call(\"retrieve()\", [])\n{:ok, \"0x0000000000000000000000000000000000000000000000000000000000000014\"}\n```\n\n## Local nodes\nInstall dependencies with\n\n```\nmake init\n```\n\nthen source your `.bashrc`, `.zshrc` or similar files to add foundry to your `PATH`, then run `foundryup` to install `forge` and `cast`.\n\nTo run two local Ethereum nodes:\n\n```\ncd geth_nodes\nmake setup\nmake up\n```\n\n## Accounts\nYou can use the miner accounts to pay for transactions.\n\nNode 1 miner account\n\n- Address: `0xafb72ccaeb7e22c8a7640f605824b0898424b3da`\n- Private key: `e90d75baafee04b3d9941bd8d76abe799b391aec596515dee11a9bd55f05709c`\n\nNode 2 miner account:\n\n- Address: `0x77b648683cde1d69544ed6f4f7204e8d51c324db`\n- Private key: `f71d3dd32649f9bdfc8e4a5232d3f245860243756f96fbe070c31fc44c9293f4`\n\n\n## Test contract\n\nYou can then deploy the test contract with\n\n```\nmake deploy_test_contract\n```\n\nunder the root directory.\n\nThe code for this contract is in `contracts/src/Storage.sol`; it has 3 functions: `test_function` will always return `1`, `store(uint256)` stores the given number and `retrieve()` returns said number.\n\nThe output should look like this\n\n```\nforge create --rpc-url http://127.0.0.1:8545 Storage --root contracts/ --private-key df57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e\ncompiling...\nCompiling 1 files with 0.8.10\nCompilation finished successfully\nCompiler run successful\nsuccess.\nDeployer: 0x8626f6940e2eb28930efb4cef49b2d1f2c9c1199\nDeployed to: 0xb581c9264f59bf0289fa76d61b2d0746dce3c30d\nTransaction hash: 0xe2c19a2f0766c0e00c416433a8cf53c9993fc918e2b321f348d8de421c195416\n```\n\nTake note of the address you are given after `Deployed to:`, as that is the contract's address in the local chain.\nWith it, you can now call its test function using `cast` like this:\n\n```\ncast call \u003ccontract_address\u003e \"test_function()(uint256)\" --rpc-url http://localhost:8545\n```\n\nwhich should return `1`.\n\n\nYou can also send a transaction to call the `store` function\n\n```\ncast send \u003ccontract_address\u003e --private-key \u003cprivate_key\u003e \"store(uint256)\" 5 --rpc-url http://localhost:8545\n```\n\nwhere the private key needs to have some funds to pay for the transaction (for this you can use one of the miner accounts). Output should look like this\n\n```\nblockHash            \"0xd2f9afae4ef28c63ceccd7575c4370c17ead74448567ca651ec82a7051434e01\"\nblockNumber          \"0x5\"\ncontractAddress      null\ncumulativeGasUsed    \"0x6746\"\neffectiveGasPrice    \"0xd1790ced\"\ngasUsed              \"0x6746\"\nlogs                 []\nlogsBloom            \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"\nroot                 null\nstatus               \"0x1\"\ntransactionHash      \"0x0bc2448d1f7ee4be24bae1201e687d937d5f094af5e64f09ca0b279d62bf0b81\"\ntransactionIndex     \"0x0\"\ntype                 \"0x2\"\n```\n\nAfter storing a number, you can retrieve it with\n\n```\ncast call \u003ccontract_address\u003e \"retrieve()(uint256)\" --rpc-url http://localhost:8545\n```\n### Code\n\nApart from EthClient calls, other modules can be called.\n\n- RPC module handles RPC calls to the node.\n- ABI module is a helper used to get the ABI of the desired contract, either calling to etherscan or locally.\n- The Contract module uses the ABI module to generate elixir functions that invoke/call the said methods in the contract.\n- The Account module defines a struct for accounts\n- The Context module saves the current context, ie. contract ABI and address, and is updated as used. It is maintained with a Supervisor process.\n- The RawTransaction module handles encoding of transactions for sending. (via RPC module)\n- The Application module handles environment\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Fethereum_war_game_tooling","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flambdaclass%2Fethereum_war_game_tooling","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flambdaclass%2Fethereum_war_game_tooling/lists"}