Giter Site home page Giter Site logo

utxo-workshop's Introduction

UTXO on Substrate

Note: this workshop is presently not actively maintained and is using older versions of all dependancies than presently used in substrate.

A UTXO chain implementation on Substrate, with two self-guided workshops. Original UXTO inspiration by Dmitriy Kashitsyn.

Substrate Version: 2.0.0-rc6. For educational purposes only.

Table of Contents

  • Installation: Setting up Rust & Substrate dependencies

  • UI Demo: Demo of UTXO implementation in a simple UI

  • Beginner Workshop: A self guided, 1 hour workshop that familiarizes you with Substrate.

  • Advanced Workshop: A self guided, 2 hour video tutorial, that teaches you how to build a UTXO blockchain from scratch.

  • Helpful Resources: Additional supporting documentation and references for troubleshooting.

Installation

1. Install or update Rust

curl https://sh.rustup.rs -sSf | sh

# On Windows, download and run rustup-init.exe
# from https://rustup.rs instead

rustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
rustup update stable

2. Clone this workshop

Clone your copy of the workshop codebase

git clone https://github.com/substrate-developer-hub/utxo-workshop.git

UI Demo

In this UI demo, you will interact with the UTXO blockchain via the Polkadot UI.

The following example takes you through a scenario where:

  • Alice already owns a UTXO of value 100 upon genesis
  • Alice sends Bob a UTXO with value 50, tipping the remainder to validators
  1. Compile and build a release node
cargo build --release
  1. Start a node. The --dev flag will start a single mining node, and the --tmp flag will start it in a new temporary directory.
./target/release/utxo-workshop --dev --tmp
  1. In the console note the helper printouts. In particular, notice the default account Alice already has 100 UTXO within the genesis block.

  2. Open Polkadot JS making sure the client is connected to your local node by going to Settings > General and selecting Local Node in the remote node dropdown.

  3. Declare custom datatypes in PolkadotJS as the frontend cannot automatically detect this information. To do this, go to Settings > Developer tab and paste in the following JSON:

{
  "Address": "AccountId",
  "LookupSource": "AccountId",
  "Value": "u128",
  "TransactionInput": {
    "outpoint": "Hash",
    "sigscript": "H512"
  },
  "TransactionOutput": {
    "value": "Value",
    "pubkey": "Hash"
  },
  "Transaction": {
    "inputs": "Vec<TransactionInput>",
    "outputs": "Vec<TransactionOutput>"
  },
  "Difficulty": "U256",
  "DifficultyAndTimestamp": {
    "difficulty": "Difficulty",
    "timestamp": "Moment"
  },
  "Public": "H256"
}
  1. Confirm that Alice already has 100 UTXO at genesis. In Chain State > Storage, select utxo. Input the hash 0x76584168d10a20084082ed80ec71e2a783abbb8dd6eb9d4893b089228498e9ff. Click the + notation to query blockchain state.

    Notice that:

    • This UTXO has a value of 100
    • This UTXO belongs to Alice's pubkey. You use the subkey tool to confirm that the pubkey indeed belongs to Alice
  2. 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:

    • outpoint: 0x76584168d10a20084082ed80ec71e2a783abbb8dd6eb9d4893b089228498e9ff
    • sigscript: 0x6ceab99702c60b111c12c2867679c5555c00dcd4d6ab40efa01e3a65083bfb6c6f5c1ed3356d7141ec61894153b8ba7fb413bf1e990ed99ff6dee5da1b24fd83
    • value: 50
    • pubkey: 0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48

    Send as an unsigned transaction. With UTXO blockchains, the proof is already in the sigscript input.

  3. 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.

Coming soon: A video walkthrough of the above demo.

Beginner Workshop

Estimated time: 2 hours

In this workshop you will:

  • Get familiar with basic Rust and Substrate functionality
  • Prevent malicious users from sending bad UTXO transactions

Your challenge is to fix the code such that:

  1. The Rust compiler compiles without any errors
  2. All tests in utxo.rs pass, ensuring secure transactions

Directions

  1. Checkout the workshop branch. The Master branch has the solutions, so don't peek!
git fetch origin workshop:workshop
git checkout workshop
  1. Cd into the base directory. Run the test using: cargo test -p utxo-runtime.
compiling utxo-runtime v2.0.0 (/Users/nicole/Desktop/utxo-workshop/runtime)
error[E0433]: failed to resolve: use of undeclared type or module `H512`
   --> /Users/nicole/Desktop/utxo-workshop/runtime/src/utxo.rs:236:31
    |
236 |             input.sigscript = H512::zero();
    |                               ^^^^ use of undeclared type or module `H512`

...
  1. Your first task: fix all the compiler errors! Hint: Look for the TODO comments in utxo.rs to see where to fix errors.

  2. Once your code compiles, it's now time to fix the 8 failing tests!

failures:
    utxo::tests::attack_by_double_counting_input
    utxo::tests::attack_by_double_generating_output
    utxo::tests::attack_by_over_spending
    utxo::tests::attack_by_overflowing_value
    utxo::tests::attack_by_permanently_sinking_outputs
    utxo::tests::attack_with_empty_transactions
    utxo::tests::attack_with_invalid_signature
    utxo::tests::test_simple_transaction
  1. In utxo.rs, edit the logic in validate_transaction() function to make all tests pass.
running 8 tests
test utxo::tests::attack_by_overflowing_value ... ok
test utxo::tests::attack_by_double_counting_input ... ok
test utxo::tests::attack_by_double_generating_output ... ok
test utxo::tests::attack_by_over_spending ... ok
test utxo::tests::attack_with_empty_transactions ... ok
test utxo::tests::attack_with_invalid_signature ... ok
test utxo::tests::attack_by_permanently_sinking_outputs ... ok
test utxo::tests::test_simple_transaction ... ok

Advanced Workshop

VIDEO TUTORIALS COMING SOON

Estimated time: 2 hours

In this workshop, you will implement this UTXO project from scratch using Substrate.

You will learn:

  • How to implement the UTXO ledger model on Substrate
  • How to secure UTXO transactions against attacks
  • How to seed genesis block with UTXOs
  • How to reward block validators in this environment
  • How to customize transaction pool logic on Substrate
  • Good coding patterns for working with Substrate & Rust, including testing and refactoring

Checkout the startercode branch to get the boilerplate for this workshop.

git fetch origin startercode:startercode
git checkout startercode

Helpful Resources

utxo-workshop's People

Contributors

nczhu avatar joshorndorff avatar cecton avatar ltfschoen avatar nuke-web3 avatar 4meta5 avatar laboon avatar arikan avatar

Stargazers

三角兽 avatar Christian Kessler avatar Meharab avatar cdesch avatar yaya avatar Leeco avatar James Aman avatar Chen22 avatar Vijayendra Gaur avatar Ratin Kumar avatar  avatar  avatar ShunpeIII avatar Pep avatar  avatar Nicholas Raphael avatar  avatar mizojp2001 y-mizomoto avatar 盧露 avatar 0x3N3jVhPUV avatar Lucid avatar Zach Forrest avatar Peter C avatar Sebastian Mandrean avatar MOZGIII avatar Alan Fernandez avatar Joshua W avatar  avatar Harry Ha avatar F35X avatar  avatar whgreate avatar Mutalisk avatar 莫莫大船长 avatar Hossein Mayboudi avatar Franky Lau avatar Mayowa Yakub avatar Vasiliy Yorkin avatar Kang avatar  avatar  avatar  avatar laps avatar  avatar Saurav  Kanchan avatar Steve Huguenin avatar 曾涛 avatar  avatar Natan avatar  avatar Ezequiel Moreno avatar Brandon Behbahani avatar  avatar BenWhiteJam avatar Matthias Seitz avatar longcpp avatar WakiyamaP avatar  avatar Edison avatar Nicolas Marshall avatar Ha DANG  avatar Clayon avatar  avatar  avatar JimmyLv_吕立青 avatar yorozunouchu avatar Obi avatar  avatar NITOBE-MANEI=PENGUIN avatar allen avatar Rust Mann avatar Lee Raj avatar Natanael Mojica avatar Steve Degosserie avatar Mike Tang avatar HAOYUatHZ avatar Runchao Han avatar owen05 avatar Jessica avatar Chester Lee avatar B avatar Shooter avatar Elder Ryan avatar Caos avatar sekiseki avatar  avatar Tresdin avatar holaworld avatar Sher avatar Fabian Raetz avatar Vitaliy Yermolenko avatar Johannes avatar Kian Paimani avatar  avatar Zhuang Zhong avatar Aten Jin avatar Alessio Delmonti avatar Osuke avatar Hyungsuk Kang avatar ZXX avatar

Watchers

James Cloos avatar  avatar  avatar David Ballarin Prunera avatar 0xyjkim avatar Muhammad-Jibril B.A. (Khalifa MBA) avatar

utxo-workshop's Issues

Decide support model for tutorials

This repo contains working code for a bitcoin-like node built on Substrate. It also contains materials related to a workshop and video tutorial. It is ideal to keep the code up to date with recent versions of Substrate. However, the video tutorials reference a specific commit in the past. A final complication is that the UTXO videos refer to a branch, not a commit or a tag, as their starting point, so pushing additional commits to that branch will be confusing for video watchers.

This issue is to decide how to maintain the code and also the workshop including starter code, non-repo assets like videos, etc. Some options:

  • One repo for the updated code, another for the workshop code
  • Switch to using folders for starting points rather than separate branches, they are both updated together.

Refactor trx_pool to only check for race condition, not other transaction errors to improve i) computation optimization ii) code readibility

I'm gonna make the following optimization to improve both i) code readability for beginners and ii) handle transaction logic checking a bit more elegantly.

check_transaction is currently being called in the execute extrinsic and the transaction pools internal validate_trx step.

So this means for every valid transaction, check_transaction actually runs twice, iterating over inputs & outputs twice. Once during trx pool stage, and once during actual extrinsic execution.

This seems inefficient && the code is confusing code for the learner.

Specifically:

Current implementation:
Pro: Efficient for cases where trx are invalid, transactions are invalidated at the first trx_pool validate_transaction step before runtime even executes the extrinsic. We only iterate through inputs vec once! But this seems not elegant since we want most of the UTXO validation to happen during the execution of the extrinsic.
Con:

  • Check_transaction implementation is difficult for beginners to understand
  • Inefficient for cases where transactions ARE valid. We iterate through inputs/outputs vec twice!

Refactoring will:
Have trx pool check for only missinginput case, refactor it out from check_transaction.
Pro: Efficient for valid cases where trx are VALID
Con:

  • We're catching invalid trx during runtime execution of extrinsic, not during trx_pool.

Security improvement: Generate salt on behalf of the user

AT the moment, users have to construct their own salt variables to avoid utxo hash collision...
Users most likely wont do it correctly, so it means our UX is still highly vulnerable to replay attacks.

We should take out Salt from the user input, and construct it for the user ourselves.

The new salt with be a hash of the following combo:

  • transaction encoding: which contains input-utxo hash, which can't be doublespent. The resulting utxo hash will definitely be different than the original-utxo hash, thus 0 chance of future collisions down the line.
  • output index: to avoid collision among utxo in the same transaction

startercode cargo check utxo-runtime error

cargo check -p utxo-runtime
Compiling utxo-runtime v2.0.0-alpha.5 (C:\Users\Mwaki\utxo-workshop\runtime)
Checking parity-util-mem v0.6.0
error[E0308]: mismatched types
--> C:\Users\Mwaki.cargo\registry\src\github.com-1ecc6299db9ec823\parity-util-m\allocators.rs:76:30
|
76 | if HeapValidate(heap, 0, ptr) == 0 {
| ^^^ expected enum winapi::ctypes::cd enum std::ffi::c_void| = note: expected raw pointer*const winapi::ctypes::c_voidfound raw pointer*const std::ffi::c_void`

error[E0308]: mismatched types
--> C:\Users\Mwaki.cargo\registry\src\github.com-1ecc6299db9ec823\parity-util-m\allocators.rs:80:23
|
80 | HeapSize(heap, 0, ptr) as usize
| ^^^ expected enum winapi::ctypes::c_void,std::ffi::c_void
|
= note: expected raw pointer *const winapi::ctypes::c_void
found raw pointer *const std::ffi::c_void

error: aborting due to 2 previous errors

For more information about this error, try rustc --explain E0308.
error: could not compile parity-util-mem

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

any help to solve the above error would be highly appreciated.

use `decl_error!`

The code was originally written before decl_error! existed. While it has been updated to still work and compile, it is not following the standard practice of declaring errors explicitly.

Create `Substrate Bitcoin` repo to be a Git Submodules for this workshop repo

Create a separate repo called "Substrate Bitcoin" which contains your latest PR and the full PoW implementation. I feel like keeping this repo as a "workshop" devalues how functional and comprehensive it is, for teams that want to implement Bitcoin chains.

This way, workshop version control becomes a bit easier. Specifically, the following branches:

  • Workshop: can point to the latest commit, ex UTXO.rs file which contains the exercises
  • Startercode: points to Nicole's commit before the PoW changes.

@JoshOrndorff I think this will make this repo less confusing to navigate. thoughts?

Can we support substrate v2.0?

I've been working to tweak the repo and make it compatible against substrate master branch, I don't know if you have any plan to support the new api

Slide 22 example does not have description

It doesn't say what's going on in the Slide 22 example.
I can only based on looking at the pictures that Alice
is sending half her balance to Clair, and the other half to Dave,
whilst Bob is sending half his balance to Eve.

Slide 25 does not explain how to interpret the code shown

For this workshop to be 'self guided' I think the slide with title "UTXO is stored in UnspentOutputs" should be updated as follows:

decl_storage! {
    trait Store for Module<T: Trait> as Utxo {
        UnspentOutputs build(|config: &GenesisConfig<T>| {
            config.initial_utxo
                .iter()
                .cloned()
                .map(|u| (BlakeTwo256::hash_of(&u), u))
                .collect::<Vec<_>>()
        }): map H256 => Option<TransactionOutput>;

Implement Currency Trait

Occasionally the idea of implementing the Currency Trait for the UTXO pallet pops into my head. HAven't looked at it very concretely, but it would be cool because it would allow using the UTXO pallet in lots of places where the Balances pallet is currently the standard (staking, transaction fees, democracy).

Refactor hardcoded values out of tests

Currently the test setup is really hacky

Refactor out the hard coded values like:

// Alice's Public Key: Pair::from_seed(*b"12345678901234567890123456789012");
    const ALICE_KEY: [u8; 32] = [68, 169, 150, 190, 177, 238, 247, 189, 202, 185, 118, 171, 109, 44, 162, 97, 4, 131, 65, 100, 236, 242, 143, 179, 117, 96, 5, 118, 252, 198, 235, 15];

Ensure tests are still passing

Slide 41-42 add more context

...
use runtime_primitives::{
    ...
    transaction_validity::TransactionValidity,
    ...
};

...

// Reference: https://docs.substrate.dev/docs/construct_runtime
construct_runtime!(
   ...
);

// Implement our runtime API endpoints. This is just a bunch of proxying.
impl_runtime_apis! {
    ...

    impl runtime_api::TaggedTransactionQueue<Block> for Runtime {
        fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
            ...
        }
    }
...
}

`build-spec` subcommand broken

The helper information that prints the genesis UTXOs and sigs interferes with the build-spec sub command. Specifically that helper information is printed at the top of the resulting json file making it invalid.

To reproduce:

./target/release/node-template build-spec > spec.json
./target/release/node-template --chain=spec.json # Error invalid json
vim spec.json #Observe the printed lines at the top

These lines
https://github.com/substrate-developer-hub/utxo-workshop/blob/3a59a31b55c2b09fa9507c3ac69b13fa2f91648a/node/src/chain_spec.rs#L139-L144

Priority ordering logic feels out of place

There is a lot of custom logic for calculating priority of UTXO transactions in the tagged transaction queue runtime api https://github.com/substrate-developer-hub/utxo-workshop/blob/master/runtime/src/lib.rs#L339

This logic is specific to the utxo pallet, and it would feel more at home in the utxo pallet. One option would be to reduce the code in that runtime api to simply test whether the extrinsic is for UTXO pallet or not and either delegate to utxo pallet itself or to executive accordingly.

Slide 37 show more context in code snippet

...
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Encode, Decode, Hash)]
pub enum LockStatus<BlockNumber> {
    Locked,
    LockedUntil(BlockNumber),
}

// References: https://crates.parity.io/srml_support_procedural/macro.decl_storage.html
decl_storage! {
    trait Store for Module<T: Trait> as Utxo {
        ...
        LockedOutputs: map H256 => Option<LockStatus<T::BlockNumber>>;
    }
    ...
}
...

Critical front-running issue where nodes can listen to valid transaction and then claim the utxo

To repro:

  1. Malicious node can listen to valid trxs on the network
  2. She can then change any attributes in TransactionOutput in the input Transaction, e.g. changing the pubkey recipient to herself, lowering the value to recipient, changing te salt, etc.
  3. She then changes total value of new utxos to be lower, thus increasing leftover value. This prioritizes her new malicious trx above the original trx, thus frontrunning!

Bitcoin users sign the entire trx, whereas we're only asking users to sign the trx input. So we can adopt a similar approach and have the spender sign recipient addr...

Not great solutions

  1. Have the user sign/submit a hash (output (the input utxo address), vec<TransactionOutput> (which contains recipient pubkeys and values) ) using the same private key that owns the utxo input. Thus we guarantee that the new UTXOs will not be tampered by whoever doesn't own at least one of the output keys. But this means if I run a node and one of my utxos is input, then i can still frontrun.

  2. Do (1) and limit functionality for the user s.t. all input utxo need to be signed by the same private key. This means removing the proof field from Transaction inputs, which doesn't necessarily break the utxo ledger model... This is a design decision on who gets to decide/sign who the actual utxo recipients are ... the input-utxo owners, the extrinsic sender...

  3. Like in Bitcoin, save and reference the entire (prev)transaction hash rather than just the utxo hash. So the ScriptSig of each utxo input is a signed message of the entire transaction, including the output recipients. Basically:

TransactionInput {
    Prev Trx hash, 
    SigScript (signed over the entire message containing output)
}

Option 4 - Serialize and sign the entire trx

I think I'm going to go with the following:

  1. For each trx input, user signs the entire Transaction without script field, basically:
TransactionInput {
    output
    script: INITIALLY EMPTY
} ...
TransactionOutput {
   value
   pubkey
   salt
} ...
  1. User repopulates trx inputs to contain the corresponding scripts. i.e.:
TransactionInput {
    output
    script: private key signing entire Trx including TrxOutput parameters, thus tamper-proofing them
} ...
TransactionOutput {
   value
   pubkey
   salt
} ...
  1. In check_transaction we verify that each utxo-input's script is indeed signed over entire transaction and also itself && that the key still matches the pubkey of the utxo.

On a UX/feature level, this means all input-utxo key owners need to agree on the entire transaction & output outcome... which is fine i guess...

Remove tight coupling to Aura

Transaction fees are paid out to authorities in on_finalize. This is good. The authorities are read directly from the Aura pallet which is bad because it means this pallet won't work with Babe, PoW etc.

Instead the pallet should be loosely coupled via a trait bound in its own configuration trait.

error: failed to run custom build command for `utxo-runtime v2.0.0-alpha.5 `

At around the 15 minute mark of the tutorial video, we were asked to run

cargo check -p utxo-runtime

However, an error occurs half way through the compilation process:

error: failed to run custom build command for `utxo-runtime v2.0.0-alpha.5 (/home/athena/utxo-workshop/runtime)`

Caused by:
  process didn't exit successfully: `/home/athena/utxo-workshop/target/debug/build/utxo-runtime-770daab2e5a3b297/build-script-build` (exit code: 1)
  --- stdout
  Executing build command: "rustup" "run" "nightly" "cargo" "rustc" "--target=wasm32-unknown-unknown" "--manifest-path=/home/athena/utxo-workshop/target/debug/wbuild/utxo-runtime/Cargo.toml" "--color=always" "--release"

  --- stderr
     Compiling wasm-build-runner-impl v1.0.0 (/home/athena/utxo-workshop/target/debug/wbuild-runner/utxo-runtime13178774267024377957)
      Finished dev [unoptimized + debuginfo] target(s) in 0.47s
       Running `/home/athena/utxo-workshop/target/debug/wbuild-runner/utxo-runtime13178774267024377957/target/debug/wasm-build-runner-impl`
     Compiling frame-support v2.0.0-alpha.5
  error[E0424]: expected value, found module `self`
     --> /home/athena/.cargo/registry/src/github.com-1ecc6299db9ec823/frame-support-2.0.0-alpha.5/src/traits.rs:835:11
      |
  833 | / bitmask! {
  834 | |     /// Reasons for moving funds out of an account.
  835 | |     #[derive(Encode, Decode)]
      | |              ^^^^^^ `self` value is a keyword only available in methods with a `self` parameter
  836 | |     pub mask WithdrawReasons: i8 where
  ...   |
  851 | |     }
  852 | | }
      | |_- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
      |
      = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

  error: aborting due to previous error

  For more information about this error, try `rustc --explain E0424`.
  error: could not compile `frame-support`

  To learn more, run the command again with --verbose.

Tried running

rustup toolchain install nightly-2020-07-12
cargo +nightly-2020-07-12 build --release

but the error did not go away.

What should we do to fix this?

$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/athena/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-2020-07-12-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.46.0 (04488afe3 2020-08-24)

Simple refactoring, renaming things to be clearer

Renaming the following:

UnspentOutputs -> UtxoStore: map of hash and transactionOutputs

TransactionInput (s):

  • outpoint : UTXO hash corresponding to tOutputs in utxoStore
  • sigScript : Signature of current Transaction, by the corresponding key as the outpoint; The script contains two components, a signature and a public key. The public key must match the hash given in the script of the redeemed output. The public key is used to verify the redeemers signature, which is the second component. More precisely, the second component is an ECDSA signature over a hash of a simplified version of the transaction.

TransactionOutput (s):

  • value : no change
  • pubKeyScript : the publickey condition in order to spend this utxo

Type names:

  • Un-alias confusing typenames, just use the H512, H256 original naming
  • leftover -> reward
  • initial_utxo -> genesis_utxo

Slide 28-29 should show they are part of `decl_module` and the main module implementation block respectively with more circles around relevant parts of the code

Slide 28 should show link to relevant part of Example SRML https://github.com/paritytech/substrate/blob/master/srml/example/src/lib.rs#L346, and code snippet like below with circles around relevant methods like has already been done.

It should also include a link to decl_module in the Substrate Dev Hub https://docs.substrate.dev/docs/decl_module & https://crates.parity.io/srml_support/macro.decl_module.html

decl_module! {
        ...

        /// Dispatch a single transaction and update UTXO set accordingly
        pub fn execute(origin, transaction: Transaction) -> Result {
                ...
                let leftover = match Self::check_transaction(&transaction)? {
                        ...
                }
                ...
                Self::update_storage(&transaction, leftover)?;
                ...
        }
        
        ...
}

Slide 29 should show link to relevant part of Example SRML https://github.com/paritytech/substrate/blob/master/srml/example/src/lib.rs#L464, and code snippet like below with circles around relevant methods like has already been done.

impl<T: Trait> Module<T> {
    pub fn check_transaction(transaction: &Transaction) -> CheckResult<'_> {
        ...
    }

    ...

    fn update_storage(transaction: &Transaction, leftover: Value) -> Result {
        ...
    }
    
    ...
}

Unable to run ./target/release/utxo-workshop --dev --tmp on terminal

I am getting the following error:

./target/release/utxo-workshop : The term './target/release/utxo-workshop' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1

  • ./target/release/utxo-workshop --dev --tmp
  •   + CategoryInfo          : ObjectNotFound: (./target/release/utxo-workshop:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    
    

Please Help

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.