{"id":15448700,"url":"https://github.com/JoshOrndorff/utxo-workshop","last_synced_at":"2025-10-11T12:31:51.432Z","repository":{"id":49981280,"uuid":"182056574","full_name":"JoshOrndorff/utxo-workshop","owner":"JoshOrndorff","description":"A Substrate UTXO workshop","archived":true,"fork":false,"pushed_at":"2021-06-10T16:21:39.000Z","size":1573,"stargazers_count":118,"open_issues_count":15,"forks_count":81,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-10-04T10:03:38.695Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoshOrndorff.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":"2019-04-18T09:18:37.000Z","updated_at":"2025-07-25T20:15:55.000Z","dependencies_parsed_at":"2022-08-30T05:04:28.059Z","dependency_job_id":null,"html_url":"https://github.com/JoshOrndorff/utxo-workshop","commit_stats":null,"previous_names":["polkadot-developers/utxo-workshop","joshorndorff/utxo-workshop","substrate-developer-hub/utxo-workshop"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/JoshOrndorff/utxo-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoshOrndorff%2Futxo-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoshOrndorff%2Futxo-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoshOrndorff%2Futxo-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoshOrndorff%2Futxo-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoshOrndorff","download_url":"https://codeload.github.com/JoshOrndorff/utxo-workshop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoshOrndorff%2Futxo-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279007167,"owners_count":26084247,"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-10-11T02:00:06.511Z","response_time":55,"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":[],"created_at":"2024-10-01T20:29:13.970Z","updated_at":"2025-10-11T12:31:51.427Z","avatar_url":"https://github.com/JoshOrndorff.png","language":"Rust","funding_links":[],"categories":["Tutorial Repositories"],"sub_categories":[],"readme":"# UTXO on Substrate\n\n### _Note: this workshop is presently not actively maintained and is using older versions of all dependancies than presently used in substrate._\n\nA UTXO chain implementation on Substrate, with two self-guided workshops. Original [UXTO inspiration](https://github.com/0x7CFE/substrate-node-template/tree/utxo) by [Dmitriy Kashitsyn](https://github.com/0x7CFE).\n\nSubstrate Version: `2.0.0-rc6`. For educational purposes only.\n\n## Table of Contents\n- [Installation](#Installation): Setting up Rust \u0026 Substrate dependencies\n\n- [UI Demo](#UI-Demo): Demo of UTXO implementation in a simple UI\n\n- [Beginner Workshop](#Beginner-Workshop): A self guided, 1 hour workshop that familiarizes you with Substrate.\n\n- [Advanced Workshop](#Advanced-Workshop): A self guided, 2 hour video tutorial, that teaches you how to build a UTXO blockchain from scratch.\n\n- [Helpful Resources](#Helpful-Resources): Additional supporting documentation and references for troubleshooting.\n\n\n## Installation\n\n### 1. Install or update Rust\n```bash\ncurl https://sh.rustup.rs -sSf | sh\n\n# On Windows, download and run rustup-init.exe\n# from https://rustup.rs instead\n\nrustup update nightly\nrustup target add wasm32-unknown-unknown --toolchain nightly\nrustup update stable\n```\n\n### 2. Clone this workshop\n\nClone your copy of the workshop codebase\n\n```bash\ngit clone https://github.com/substrate-developer-hub/utxo-workshop.git\n```\n\n## UI Demo\n\nIn this UI demo, you will interact with the UTXO blockchain via the [Polkadot UI](https://polkadot.js.org/apps/).\n\nThe following example takes you through a scenario where:\n- Alice already owns a UTXO of value 100 upon genesis\n- Alice sends Bob a UTXO with value 50, tipping the remainder to validators\n\n1. Compile and build a release node\n```bash\ncargo build --release\n```\n\n2. Start a node. The `--dev` flag will start a single mining node, and the `--tmp` flag will start it in a new temporary directory.\n```bash\n./target/release/utxo-workshop --dev --tmp\n```\n\n3. In the console note the helper printouts. In particular, notice the default account `Alice` already has `100 UTXO` within the genesis block.\n\n4. Open [Polkadot JS](https://polkadot.js.org/apps/#/settings) making sure the client is connected to your local node by going to Settings \u003e General and selecting `Local Node` in the `remote node` dropdown.\n\n5. **Declare custom datatypes in PolkadotJS** as the frontend cannot automatically detect this information. To do this, go to Settings \u003e Developer tab and paste in the following JSON:\n\n```json\n{\n  \"Address\": \"AccountId\",\n  \"LookupSource\": \"AccountId\",\n  \"Value\": \"u128\",\n  \"TransactionInput\": {\n    \"outpoint\": \"Hash\",\n    \"sigscript\": \"H512\"\n  },\n  \"TransactionOutput\": {\n    \"value\": \"Value\",\n    \"pubkey\": \"Hash\"\n  },\n  \"Transaction\": {\n    \"inputs\": \"Vec\u003cTransactionInput\u003e\",\n    \"outputs\": \"Vec\u003cTransactionOutput\u003e\"\n  },\n  \"Difficulty\": \"U256\",\n  \"DifficultyAndTimestamp\": {\n    \"difficulty\": \"Difficulty\",\n    \"timestamp\": \"Moment\"\n  },\n  \"Public\": \"H256\"\n}\n```\n\n6. **Confirm that Alice already has 100 UTXO at genesis**. In `Chain State` \u003e `Storage`, select `utxo`. Input the hash `0x76584168d10a20084082ed80ec71e2a783abbb8dd6eb9d4893b089228498e9ff`. Click the `+` notation to query blockchain state.\n\n    Notice that:\n    - This UTXO has a value of `100`\n    - This UTXO belongs to Alice's pubkey. You use the [subkey](https://substrate.dev/docs/en/next/development/tools/subkey#well-known-keys) tool to confirm that the pubkey indeed belongs to Alice\n\n7. **Spend Alice's UTXO, giving 50 to Bob.** In the `Extrinsics` tab, invoke the `spend` function from the `utxo` pallet, using Alice as the transaction sender. Use the following input parameters:\n\n    - outpoint: `0x76584168d10a20084082ed80ec71e2a783abbb8dd6eb9d4893b089228498e9ff`\n    - sigscript: `0x6ceab99702c60b111c12c2867679c5555c00dcd4d6ab40efa01e3a65083bfb6c6f5c1ed3356d7141ec61894153b8ba7fb413bf1e990ed99ff6dee5da1b24fd83`\n    - value: `50`\n    - pubkey: `0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48`\n\n    Send as an `unsigned` transaction. With UTXO blockchains, the proof is already in the `sigscript` input.\n\n8. **Verify that your transaction succeeded**. In `Chain State`, look up the newly created UTXO hash: `0xdbc75ab8ee9b83dcbcea4695f9c42754d94e92c3c397d63b1bc627c2a2ef94e6` to verify that a new UTXO of 50, belonging to Bob, now exists! Also you can verify that Alice's original UTXO has been spent and no longer exists in UtxoStore.\n\n*Coming soon: A video walkthrough of the above demo.*\n\n## Beginner Workshop\n**Estimated time**: 2 hours\n\nIn this workshop you will:\n- Get familiar with basic Rust and Substrate functionality\n- Prevent malicious users from sending bad UTXO transactions\n\nYour challenge is to fix the code such that:\n1. The Rust compiler compiles without any errors\n2. All tests in `utxo.rs` pass, ensuring secure transactions\n\n### Directions\n1. Checkout the `workshop` branch. The `Master` branch has the solutions, so don't peek!\n\n```zsh\ngit fetch origin workshop:workshop\ngit checkout workshop\n```\n\n2. Cd into the base directory. Run the test using: `cargo test -p utxo-runtime`.\n\n```zsh\ncompiling utxo-runtime v2.0.0 (/Users/nicole/Desktop/utxo-workshop/runtime)\nerror[E0433]: failed to resolve: use of undeclared type or module `H512`\n   --\u003e /Users/nicole/Desktop/utxo-workshop/runtime/src/utxo.rs:236:31\n    |\n236 |             input.sigscript = H512::zero();\n    |                               ^^^^ use of undeclared type or module `H512`\n\n...\n```\n\n3. Your first task: fix all the compiler errors! Hint: Look for the `TODO` comments in `utxo.rs` to see where to fix errors.\n\n4. Once your code compiles, it's now time to fix the `8` failing tests!\n\n```zsh\nfailures:\n    utxo::tests::attack_by_double_counting_input\n    utxo::tests::attack_by_double_generating_output\n    utxo::tests::attack_by_over_spending\n    utxo::tests::attack_by_overflowing_value\n    utxo::tests::attack_by_permanently_sinking_outputs\n    utxo::tests::attack_with_empty_transactions\n    utxo::tests::attack_with_invalid_signature\n    utxo::tests::test_simple_transaction\n```\n\n5. In `utxo.rs`, edit the logic in `validate_transaction()` function to make all tests pass.\n\n```zsh\nrunning 8 tests\ntest utxo::tests::attack_by_overflowing_value ... ok\ntest utxo::tests::attack_by_double_counting_input ... ok\ntest utxo::tests::attack_by_double_generating_output ... ok\ntest utxo::tests::attack_by_over_spending ... ok\ntest utxo::tests::attack_with_empty_transactions ... ok\ntest utxo::tests::attack_with_invalid_signature ... ok\ntest utxo::tests::attack_by_permanently_sinking_outputs ... ok\ntest utxo::tests::test_simple_transaction ... ok\n```\n\n## Advanced Workshop\n**VIDEO TUTORIALS COMING SOON**\n\n**Estimated time**: 2 hours\n\nIn this workshop, you will implement this UTXO project from scratch using Substrate.\n\nYou will learn:\n- How to implement the UTXO ledger model on Substrate\n- How to secure UTXO transactions against attacks\n- How to seed genesis block with UTXOs\n- How to reward block validators in this environment\n- How to customize transaction pool logic on Substrate\n- Good coding patterns for working with Substrate \u0026 Rust, including testing and refactoring\n\nCheckout the `startercode` branch to get the boilerplate for this workshop.\n```zsh\ngit fetch origin startercode:startercode\ngit checkout startercode\n```\n\n## Helpful Resources\n- [Substrate documentation](http://crates.parity.io)\n- [bytes to Vec\u003cu8\u003e converter](https://cryptii.com/pipes/integer-encoder)\n- [Polkadot UI](https://polkadot.js.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJoshOrndorff%2Futxo-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJoshOrndorff%2Futxo-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJoshOrndorff%2Futxo-workshop/lists"}