<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: smith@mcf.rocks</title>
    <description>The latest articles on Forem by smith@mcf.rocks (@dusktastic).</description>
    <link>https://forem.com/dusktastic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1242732%2F2bb7504c-783a-452a-8773-fce6836323bc.png</url>
      <title>Forem: smith@mcf.rocks</title>
      <link>https://forem.com/dusktastic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dusktastic"/>
    <language>en</language>
    <item>
      <title>Dusk - Tiny Net with Staking</title>
      <dc:creator>smith@mcf.rocks</dc:creator>
      <pubDate>Thu, 15 Feb 2024 18:31:18 +0000</pubDate>
      <link>https://forem.com/dusktastic/dusk-tiny-net-with-staking-3351</link>
      <guid>https://forem.com/dusktastic/dusk-tiny-net-with-staking-3351</guid>
      <description>&lt;p&gt;I will make a network with one genesis staked provisioner, then add a second staked provisioner later.&lt;/p&gt;

&lt;p&gt;We will use TWO machines, both Ubuntu 22.04 installed.&lt;/p&gt;

&lt;p&gt;M1 - Digital Ocean Basic/Regular 4GB/2CPU - Frankfurt - 142.XX.XX.240&lt;br&gt;
M2 - Digital Ocean Basic/Regular 4GB/2CPU - London - 167.XX.XX.102&lt;/p&gt;

&lt;p&gt;// NB: I could not build Dusk with less than 4GB&lt;/p&gt;

&lt;p&gt;I will setup M1 first...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build Prerequisites&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# update packages
apt update 
apt upgrade  -y 

# packages we need
apt install make pkg-config libssl-dev npm unzip libclang-dev build-essential -y

# rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh  # select opt 1
source "$HOME/.cargo/env"
rustup toolchain install nightly
rustup default nightly

# rust extras
cargo install wasm-pack

# nvm and node
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
exit
# and login again :-)
nvm list-remote
nvm install v20.11.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build Dusk - Everything&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/dusk-network/rusk.git
cd rusk
make

# check it built
./target/release/rusk -V
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Consensus keys (wallet generated) for node:
mkdir -p ~/.dusk/rusk
cp examples/consensus.keys ~/.dusk/rusk/consensus.keys

# the example genesis.toml starts a staked provisioner
# note the two addresses...
cat examples/genesis.toml

# edit the file as follows -- give wallet 300k:
[[balance]]
address = '4ZH3oyfTuMHyWD1Rp4e7QKp5yK6wLrWvxHneufAiYBAjvereFvfjtDvTbBcZN5ZCsaoMo49s1LKPTwGpowik6QJG'
seed = 0xdead_beef
notes = [300_000_000_000_000]

[[stake]]
address = 'oCqYsUMRqpRn2kSabH52Gt6FQCwH5JXj5MtRdYVtjMSJ73AFvdbPf98p3gz98fQwNy9ZBiDem6m9BivzURKFSKLYWP3N9JahSPZs9PnZ996P18rTGAjQTNFsxtbrKx79yWu'
amount = 1_000_000_000_000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Launch M1 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Generate genesis state
cargo r --release -p rusk -- recovery-state --init examples/genesis.toml -o /tmp/example.state

# Launch node
cargo r --release -p rusk -- -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-public-address 167.99.241.102:9000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Make Wallet&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/dusk-network/wallet-cli.git
cd wallet-cli/
make build
./target/release/rusk-wallet -V

# the wallet makes / looks for a wallet.dat file in this location
# /root/.dusk/rusk-wallet/wallet.dat
# the genesis addresses are from the .dat file in the examples directory of the repo
# copy it in-place
cp ~/rusk/examples/wallet.dat /root/.dusk/rusk-wallet/

# if there is a cache in /root/.dusk/rusk-wallet/ (from some previous wallet) delete it
# run the wallet
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321

# nb: password of the example.dat is "password"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the 4ZH3oy... address from the genesis toml, it should have 300k Dusk on it.&lt;/p&gt;

&lt;p&gt;If you "Check existing stake" there should be 1000 Dusk on staking address oCqYsUM...&lt;/p&gt;

&lt;p&gt;With this node still running, we will join a second node to the network....&lt;/p&gt;

&lt;p&gt;on M2:&lt;/p&gt;

&lt;p&gt;1) &lt;em&gt;repeat all the build steps for rusk and wallet from M1&lt;/em&gt;&lt;br&gt;
2) &lt;em&gt;edit the genesis.toml file to be the same&lt;/em&gt;&lt;br&gt;
3) &lt;em&gt;do NOT copy example.dat file, this is new wallet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run Wallet&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd wallet-cli
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a new wallet, or recover to get same addresses;&lt;br&gt;
my 12 words were: tag tide chef like history submit field minor hub ridge prepare pause&lt;br&gt;
password: "password"&lt;/p&gt;

&lt;p&gt;Export provisioner keys &amp;gt; will write consensus.keys to /root/.dusk/rusk-wallet&lt;br&gt;
Exit Wallet&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup M2 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd rusk
mkdir -p ~/.dusk/rusk

# previously we used the consensus.keys from example directory, which corresponded to the example wallet, but here we use the consensus keys for this wallet

cp /root/.dusk/rusk-wallet/*.keys ~/.dusk/rusk/

# I renamed the file to con.keys to make it simpler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run M2 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# run the node, specifying the first node as bootstrap node
# note that it is the Kadcast port (9000) that must be referenced
# nb: port needs to be open, check using telnet

./target/release/rusk -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-bootstrap "&amp;lt;M2-IP&amp;gt;:9000" --consensus-keys-path="$HOME/.dusk/rusk/&amp;lt;filename.keys&amp;gt;" --kadcast-public-address &amp;lt;THIS-IP&amp;gt;:9000

eg:

export DUSK_CONSENSUS_KEYS_PASS=password
./target/release/rusk -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-bootstrap "167.XX.XX.102:9000" --consensus-keys-path="/$HOME/.dusk/rusk/con.keys" --kadcast-public-address 142.XX.XX.240:9000

# note: Kadcast uses UDP, you can check the port is listening with netstat -ulpn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a new session start the M2 wallet and fund from M1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd wallet-cli
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321

# address1 is 4oPWfmo... with a balance of zero.

# on the M1 wallet, transfer 200k to this address1 

after a short while (if node and wallet is fully synced) M2 - 4oPWfmo... should have 200k balance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point both nodes are on the same network, with the respective wallets connected to their nodes. We will now stake M2 node.&lt;/p&gt;

&lt;p&gt;If you observe the logs of both running nodes, you will see that M1 node has "Proposal" in the log output, whereas the M2 node does not, immediately after "Proposal" you will see pk="oCqYsUMR..." which is the public staking key from the wallet. M2 node does not propose blocks, as it is not yet staked.&lt;/p&gt;

&lt;p&gt;From the M2 wallet stake 100k.&lt;/p&gt;

&lt;p&gt;After doing that, in the wallet do "Check existing stake", this will tell you that the stake becomes eligible from some future block number and epoch. Stake becomes active at the next epoch boundary. You will see the current block height of the node in the log output, so you will know how long you have to wait. &lt;/p&gt;

&lt;p&gt;Once the block height is reached, you will see "Proposal" messages in the M2 node log, as the node is now making blocks. Indeed, as the staked amount on the M2 node is 100k and the staked amount on the M1 node is 1k, almost ALL blocks are made on the M2 node. &lt;/p&gt;

&lt;p&gt;If you "Check existing stake" in the wallet, you will see the stake is now active and rewards are accumulating.&lt;/p&gt;

&lt;p&gt;Until next time.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dusk - Tiny Net with Staking.</title>
      <dc:creator>smith@mcf.rocks</dc:creator>
      <pubDate>Thu, 15 Feb 2024 18:30:23 +0000</pubDate>
      <link>https://forem.com/dusktastic/dusk-tiny-net-with-staking-2c6g</link>
      <guid>https://forem.com/dusktastic/dusk-tiny-net-with-staking-2c6g</guid>
      <description>&lt;p&gt;I will make a network with one genesis staked provisioner, then add a second staked provisioner later.&lt;/p&gt;

&lt;p&gt;We will use TWO machines, both Ubuntu 22.04 installed.&lt;/p&gt;

&lt;p&gt;M1 - Digital Ocean Basic/Regular 4GB/2CPU - Frankfurt - 142.XX.XX.240&lt;br&gt;
M2 - Digital Ocean Basic/Regular 4GB/2CPU - London - 167.XX.XX.102&lt;/p&gt;
&lt;h1&gt;
  
  
  NB: I could not build Dusk with less than 4GB
&lt;/h1&gt;

&lt;p&gt;I will setup M1 first...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build Prerequisites&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# update packages
apt update 
apt upgrade  -y 

# packages we need
apt install make pkg-config libssl-dev npm unzip libclang-dev build-essential -y

# rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh  # select opt 1
source "$HOME/.cargo/env"
rustup toolchain install nightly
rustup default nightly

# rust extras
cargo install wasm-pack

# nvm and node
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
exit
# and login again :-)
nvm list-remote
nvm install v20.11.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build Dusk - Everything&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/dusk-network/rusk.git
cd rusk
make

# check it built
./target/release/rusk -V
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Consensus keys (wallet generated) for node:
mkdir -p ~/.dusk/rusk
cp examples/consensus.keys ~/.dusk/rusk/consensus.keys

# the example genesis.toml starts a staked provisioner
# note the two addresses...
cat examples/genesis.toml

# edit the file as follows -- give wallet 300k:
[[balance]]
address = '4ZH3oyfTuMHyWD1Rp4e7QKp5yK6wLrWvxHneufAiYBAjvereFvfjtDvTbBcZN5ZCsaoMo49s1LKPTwGpowik6QJG'
seed = 0xdead_beef
notes = [300_000_000_000_000]

[[stake]]
address = 'oCqYsUMRqpRn2kSabH52Gt6FQCwH5JXj5MtRdYVtjMSJ73AFvdbPf98p3gz98fQwNy9ZBiDem6m9BivzURKFSKLYWP3N9JahSPZs9PnZ996P18rTGAjQTNFsxtbrKx79yWu'
amount = 1_000_000_000_000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Launch M1 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Generate genesis state
cargo r --release -p rusk -- recovery-state --init examples/genesis.toml -o /tmp/example.state

# Launch node
cargo r --release -p rusk -- -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-public-address 167.99.241.102:9000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Make Wallet&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/dusk-network/wallet-cli.git
cd wallet-cli/
make build
./target/release/rusk-wallet -V

# the wallet makes / looks for a wallet.dat file in this location
# /root/.dusk/rusk-wallet/wallet.dat
# the genesis addresses are from the .dat file in the examples directory of the repo
# copy it in-place
cp ~/rusk/examples/wallet.dat /root/.dusk/rusk-wallet/

# if there is a cache in /root/.dusk/rusk-wallet/ (from some previous wallet) delete it
# run the wallet
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321

# nb: password of the example.dat is "password"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the 4ZH3oy... address from the genesis toml, it should have 300k Dusk on it&lt;br&gt;
If you "Check existing stake" there should be 1000 Dusk on staking address oCqYsUM...&lt;/p&gt;

&lt;p&gt;With this node still running, we will join a second node to the network....&lt;/p&gt;

&lt;p&gt;on M2:&lt;/p&gt;

&lt;p&gt;1) &lt;em&gt;repeat all the build steps for rusk and wallet from M1&lt;/em&gt;&lt;br&gt;
2) &lt;em&gt;edit the genesis.toml file to be the same&lt;/em&gt;&lt;br&gt;
3) &lt;em&gt;do NOT copy example.dat file, this is new wallet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Run Wallet&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd wallet-cli
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a new wallet, or recover to get same addresses;&lt;br&gt;
my 12 words were: tag tide chef like history submit field minor hub ridge prepare pause&lt;br&gt;
password: "password"&lt;/p&gt;

&lt;p&gt;Export provisioner keys &amp;gt; will write consensus.keys to /root/.dusk/rusk-wallet&lt;br&gt;
Exit Wallet&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup M2 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd rusk
mkdir -p ~/.dusk/rusk

# previously we used the consensus.keys from example directory, which corresponded to the example wallet, but here we use the consensus keys for this wallet

cp /root/.dusk/rusk-wallet/*.keys ~/.dusk/rusk/

# I renamed the file to con.keys to make it simpler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run M2 node&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# run the node, specifying the first node as bootstrap node
# note that it is the Kadcast port (9000) that must be referenced
# nb: port needs to be open, check using telnet

./target/release/rusk -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-bootstrap "&amp;lt;M2-IP&amp;gt;:9000" --consensus-keys-path="$HOME/.dusk/rusk/&amp;lt;filename.keys&amp;gt;" --kadcast-public-address &amp;lt;THIS-IP&amp;gt;:9000

eg:

export DUSK_CONSENSUS_KEYS_PASS=password
./target/release/rusk -s /tmp/example.state --http-listen-addr 0.0.0.0:4321 --kadcast-bootstrap "167.XX.XX.102:9000" --consensus-keys-path="/$HOME/.dusk/rusk/con.keys" --kadcast-public-address 142.XX.XX.240:9000

# note: Kadcast uses UDP, you can check the port is listening with netstat -ulpn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a new session start the M2 wallet and fund from M1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd wallet-cli
./target/release/rusk-wallet --state http://127.0.0.1:4321 --prover http://127.0.0.1:4321

# address1 is 4oPWfmo... with a balance of zero.

# on the M1 wallet, transfer 200k to this address1 

after a short while (if node and wallet is fully synced) M2 - 4oPWfmo... should have 200k balance.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point both nodes are on the same network, with the respective wallets connected to their nodes. We will now stake M2 node.&lt;/p&gt;

&lt;p&gt;If you observe the logs of both running nodes, you will see that M1 node has "Proposal" in the log output, whereas the M2 node does not, immediately after "Proposal" you will see pk="oCqYsUMR..." which is the public staking key from the wallet. M2 node does not propose blocks, as it is not yet staked.&lt;/p&gt;

&lt;p&gt;From the M2 wallet stake 100k.&lt;/p&gt;

&lt;p&gt;After doing that, in the wallet do "Check existing stake", this will tell you that the stake becomes eligible from some future block number and epoch. Stake becomes active at the next epoch boundary. You will see the current block height of the node in the log output, so you will know how long you have to wait. &lt;/p&gt;

&lt;p&gt;Once the block height is reached, you will see "Proposal" messages in the M2 node log, as the node is now making blocks. Indeed, as the staked amount on the M2 node is 100k and the staked amount on the M1 node is 1k, almost ALL blocks are made on the M2 node. &lt;/p&gt;

&lt;p&gt;If you "Check existing stake" in the wallet, you will see the stake is now active and rewards are accumulating.&lt;/p&gt;

&lt;p&gt;Until next time.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dusk - Standalone Prover</title>
      <dc:creator>smith@mcf.rocks</dc:creator>
      <pubDate>Mon, 01 Jan 2024 18:23:40 +0000</pubDate>
      <link>https://forem.com/dusktastic/dusk-standalone-prover-35k2</link>
      <guid>https://forem.com/dusktastic/dusk-standalone-prover-35k2</guid>
      <description>&lt;p&gt;Dusk uses ZKPs (Zero-Knowledge-Proofs) to maintain transaction privacy; for example, when doing a simple transfer, a proof must be constructed by the wallet demonstrating the notes involved belong to that wallet and are nullified, later the proof is verified on-chain by the consensus nodes. &lt;/p&gt;

&lt;p&gt;So there are two parts 1) proof creation 2) proof verification. Each contract (in this example, the genesis Transfer contract) contains both prover and verification circuits. Verification is fast with constant time. Proof creation can take longer depending on how many notes are involved, in some cases on slower hardware it can be really quite lengthy (&amp;gt;20s) leading to poor UX in the wallet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ONe7HnBn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6qg0uwr9szac1wssi09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ONe7HnBn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n6qg0uwr9szac1wssi09.png" alt="Dusk proof creation times" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, proof creation is trustless and can therefore be done by a third party. Dusk allows a node to run in "Prover" mode, where it only does proof creation.&lt;/p&gt;

&lt;p&gt;Right now the web-wallet is hard coded to use Dusk Foundation provers. In the wallet-core code, an UnprovenTransaction structure is converted and sent as bytes to a prover in ./src/compat/tx.rs unproven_tx_to_bytes(), the prover returns the proof, which is checked in prove_tx() -- however, right now, the web-wallet code is in a private repo, so we can't mess with that.&lt;/p&gt;

&lt;p&gt;On the other hand, the CLI Wallet allows specification of two endpoints, one for state and one for prover. In our previous tutorials, both point at the local node, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./wallet-cli/target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However they can be different... We will use the same setup as &lt;a href="https://dev.to/dusktastic/dusk-running-a-local-node-1723"&gt;before&lt;/a&gt; with a local node and wallet. &lt;/p&gt;

&lt;p&gt;On another server, we will make a Prover node, listening on 4322:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# git clone https://github.com/dusk-network/rusk.git
# cd rusk
# make
# ./target/release/rusk -V
rusk 0.7.0 (16cd2d58 2023-12-31)
# cp examples/consensus.keys ~/.dusk/rusk/consensus.keys
# export DUSK_CONSENSUS_KEYS_PASS=password
# ./target/release/rusk --http-listen-addr 0.0.0.0:4322
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB: remember to allow the machine with the state node and wallet access to port 4322 on this machine.&lt;/p&gt;

&lt;p&gt;Run the CLI wallet referencing the prover on the other machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./wallet-cli/target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://&amp;lt;myOtherServerIP&amp;gt;:4322
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do a transfer from the wallet:&lt;/p&gt;

&lt;p&gt;Send 50 Dusk to 3uVEjrfzdhjN1a5o48SpiVU9AFzF5o9FZ9mFR9GfeV7U3nfDpDGfVrLJveFPokHsQiXUjjrQHYZSWNz4PY2UQ4xU&lt;/p&gt;

&lt;p&gt;Observe the log output of our Prover node, you will see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024-01-01T15:50:18.664338Z  INFO rusk::http: Received Host("rusk"):prove_execute request
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proof creation has taken place on the Prover node, not the local state node.&lt;/p&gt;

&lt;p&gt;The action takes place in ./rusk-prover/src/prover/execute.rs&lt;/p&gt;

&lt;p&gt;If you look, you will notice there are 4 different proving circuits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub static EXEC_1_2_PROVER: Lazy&amp;lt;PlonkProver&amp;gt; =
    Lazy::new(|| fetch_prover("ExecuteCircuitOneTwo"));

pub static EXEC_2_2_PROVER: Lazy&amp;lt;PlonkProver&amp;gt; =
    Lazy::new(|| fetch_prover("ExecuteCircuitTwoTwo"));

pub static EXEC_3_2_PROVER: Lazy&amp;lt;PlonkProver&amp;gt; =
    Lazy::new(|| fetch_prover("ExecuteCircuitThreeTwo"));

pub static EXEC_4_2_PROVER: Lazy&amp;lt;PlonkProver&amp;gt; =
    Lazy::new(|| fetch_prover("ExecuteCircuitFourTwo"));

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        match utx.inputs().len() {
            1 =&amp;gt; local_prove_exec_1_2(&amp;amp;utx, rng),
            2 =&amp;gt; local_prove_exec_2_2(&amp;amp;utx, rng),
            3 =&amp;gt; local_prove_exec_3_2(&amp;amp;utx, rng),
            4 =&amp;gt; local_prove_exec_4_2(&amp;amp;utx, rng),
            _ =&amp;gt; Err
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The circuit used depends on the number of inputs (notes from the user's wallet); the output is always 2 notes (a new note owned by someone else &amp;amp; the change). The maximum number of notes that can be used is 4, I have no idea what happens if the wallet needs to use more than 4 input notes. &lt;/p&gt;

&lt;p&gt;The log output from the node does not really tell us much. I want to know a) which circuit was used, and b) how long the operation took. Let's make some code changes to add this to the log.&lt;/p&gt;

&lt;p&gt;In ./rusk/src/lib/http/prover.rs handle() function I amend as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        // smith 
        let utx = UnprovenTransaction::from_slice(request.event_data()).unwrap();
        info!("LocalProver Start inputs:{:?}",utx.inputs().len());

        let response = match topic {
            "prove_execute" =&amp;gt; self.prove_execute(request.event_data())?,
            "prove_stct" =&amp;gt; self.prove_stct(request.event_data())?,
            "prove_stco" =&amp;gt; self.prove_stco(request.event_data())?,
            "prove_wfct" =&amp;gt; self.prove_wfct(request.event_data())?,
            "prove_wfco" =&amp;gt; self.prove_wfco(request.event_data())?,
            _ =&amp;gt; anyhow::bail!("Unsupported"),
        };

        info!("LocalProver End");  // smith
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then recompile and run the modified node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# make
# ./target/release/rusk \
  --http-listen-addr 0.0.0.0:4322 \
  | grep rusk::http::prover
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the wallet:&lt;/p&gt;

&lt;p&gt;Send 1 Dusk to 3uVEjrfzdhjN1a5o48SpiVU9AFzF5o9FZ9mFR9GfeV7U3nfDpDGfVrLJveFPokHsQiXUjjrQHYZSWNz4PY2UQ4xU&lt;/p&gt;

&lt;p&gt;For me, the log reported the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024-01-01T17:26:24.444775Z  INFO rusk::http::prover: LocalProver Start inputs:2
2024-01-01T17:26:30.191910Z  INFO rusk::http::prover: LocalProver End
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see the proof creation took 6s for a Transfer using 2 input notes.&lt;/p&gt;

&lt;p&gt;Although the server I am running the Prover on is decent (AMD EPYC 9374F 32-Core) proof creation cannot be multithreaded, so a single fast core is what matters, something like an Intel Core i9-14900K maybe, or perhaps some kind of FPGA solution, who knows.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dusk - GraphQL RPC</title>
      <dc:creator>smith@mcf.rocks</dc:creator>
      <pubDate>Sun, 31 Dec 2023 17:56:42 +0000</pubDate>
      <link>https://forem.com/dusktastic/dusk-graphql-rpc-c6</link>
      <guid>https://forem.com/dusktastic/dusk-graphql-rpc-c6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Explore the Dusk node's RPC capabilities, especially GraphQL... in under 10 minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the setup as described previously &lt;a href="https://dev.to/dusktastic/dusk-running-a-local-node-1723"&gt;to run a local node&lt;/a&gt;, regenerate the initial state, the file examples/genesis.toml  has been edited to give 100,000 coins to our wallet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cd rusk
# rm /tmp/example.state
# cargo r --release -p rusk -- recovery-state \
  --init examples/genesis.toml \
  -o /tmp/example.state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# export DUSK_CONSENSUS_KEYS_PASS=password
# ./rusk/target/release/rusk \
  -s /tmp/example.state \
  --http-listen-addr 0.0.0.0:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use the &lt;a href="https://dev.to/dusktastic/dusk-running-a-local-node-1723"&gt;same wallet as before&lt;/a&gt;, but the wallet software has local caching, so after resetting state we need to clear that cache and restart the wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# rm ~/.dusk/rusk-wallet/cache
# ./wallet-cli/target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When restarting the wallet there will be some delay while it reads the chain to find the notes associated with the wallet.&lt;/p&gt;

&lt;p&gt;Make an RPC call to the node, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# curl -X POST http://127.0.0.1:4321/2/Chain \
  -H 'Content-Type: application/json' \
  -d '{"topic":"info","data":""}'
&amp;gt; {"bootstrapping_nodes":[],"chain_id":null,"kadcast_address":"127.0.0.1:9000","version":"0.7.0","version_build":"0.7.0 (16cd2d58 2023-12-31)"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This call returns some basic information including version and build. There are some parts that are noteworthy; the digit in the url (in this case 2) can be 1, 2, or 3 (contract, host, debugger); the final part of the url, in the event the digit is 2 can be "chain" or "rusk". If "chain" then the topic passed can be any of "info", "gas", "alive_nodes", "propagate_tx", or "gql". The data field contains arguments required for the call (for "info", there are no arguments)...&lt;/p&gt;

&lt;p&gt;Where the topic is "gql" we are passing a Graph Query Language call. This is what we are interested in.&lt;/p&gt;

&lt;p&gt;Passing the topic without data returns the schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# curl -s -X POST http://127.0.0.1:4321/2/Chain \
  -d '{"topic":"gql","data":""}' \
  -H 'Content-Type: application/json'

type Block {
    header: Header!
    transactions: [SpentTransaction!]!
    reward: Int!
    fees: Int!
    gasSpent: Int!
}

type CallData {
    contractId: String!
    fnName: String!
    data: String!
}

type Header {
    version: Int!
    height: Int!
    prevBlockHash: String!
    timestamp: Int!
    hash: String!
    stateHash: String!
    generatorBlsPubkey: String!
    txRoot: String!
    gasLimit: Int!
    seed: String!
    iteration: Int!
}

type Query {
    block(height: Float, hash: String): Block
    tx(hash: String!): SpentTransaction
    transactions(last: Int!): [SpentTransaction!]!
    blockTxs(last: Int, range: [Int!], contract: String): [SpentTransaction!]!
    blocks(last: Int, range: [Int!]): [Block!]!
    mempoolTxs: [Transaction!]!
    mempoolTx(hash: String!): Transaction
}

type SpentTransaction {
    tx: Transaction!
    err: String
    gasSpent: Int!
    blockHash: String!
    blockHeight: Int!
    blockTimestamp: Int!
    id: String!
    raw: String!
}

type Transaction {
    raw: String!
    id: String!
    gasLimit: Int!
    gasPrice: Int!
    callData: CallData
}

schema {
    query: Query
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the queries that are available. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transactions(last: Int!): [SpentTransaction!]!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query returns the last N transactions. We can test this by running the query before any transactions are made:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# curl -X POST http://127.0.0.1:4321/2/Chain \
  -d '{"topic":"gql","data":"query {transactions(last: 10){id}} "}' \
  -H 'Content-Type: application/json'
&amp;gt; {"transactions":[]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now do two transfers from the wallet to some other address, for example 3uVEjrfzdhjN1a5o48SpiVU9AFzF5o9FZ9mFR9GfeV7U3nfDpDGfVrLJveFPokHsQiXUjjrQHYZSWNz4PY2UQ4xU, note the transaction hashes:&lt;/p&gt;

&lt;p&gt;Transfer 100 - txid 8ffa359e732ccad500b16996662a6edb2033d3ecfa868cf68cbadc4ca4e7760d&lt;/p&gt;

&lt;p&gt;Transfer 200 - txid&lt;br&gt;
95f58e4b8e7fc5658540cd01064ae93ab07d34c1a91d5a848d32384a3951b100&lt;/p&gt;

&lt;p&gt;And finally, execute the query again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# curl -X POST http://127.0.0.1:4321/2/Chain \
  -d '{"topic":"gql","data":"query {transactions(last: 10){id}} "}' \
  -H 'Content-Type: application/json'
&amp;gt; {"transactions":[{"id":"95f58e4b8e7fc5658540cd01064ae93ab07d34c1a91d5a848d32384a3951b100"},{"id":"8ffa359e732ccad500b16996662a6edb2033d3ecfa868cf68cbadc4ca4e7760d"}]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transactions can be seen, newest first.&lt;/p&gt;

&lt;p&gt;At this time the node is ephemeral, so if it is restarted, this information is no longer available. The node should soon be runnable in "persistent" mode, in which case this would not apply.&lt;/p&gt;

&lt;p&gt;You can see the query part of the curl call, this string is in Graph Query Language, I have hidden the rest of the curl call using a small script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cat ./run_query

#!/usr/bin/perl -w
my $cmd = q#curl -s -X POST http://127.0.0.1:4321/2/Chain -d '{"topic":"gql","data":"#;
$cmd .= $ARGV[0];
$cmd .= q#"}' -H 'Content-Type: application/json'#;
print `$cmd`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this point on, I just give that string, not the entire call, which remains constant. Also we can use the Linux command &lt;strong&gt;jq&lt;/strong&gt; to format the json output.&lt;/p&gt;

&lt;p&gt;The query just executed returns "SpentTransaction" objects, we returned only the "id" field. It is only allowed to return fields, not objects.&lt;/p&gt;

&lt;p&gt;Here we return the Block Height and Block hash that the most recent transaction was mined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query "query {transactions(last: 1){blockHeight, blockHash}}"  | jq
{
  "transactions": [
    {
      "blockHash": "0925fc9ff94d445ffecead0e0bfeda70ca184e74d101fbc41a7cc4e5d4412060",
      "blockHeight": 184
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the schema, we see objects can include nested objects. Here we return attributes from the enclosed Transaction object; the Gas Limit and Gas Price:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query "query {transactions(last: 1){tx{gasLimit, gasPrice}}}"  | jq
{
  "transactions": [
    {
      "tx": {
        "gasLimit": 500000000,
        "gasPrice": 1
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NB: the Gas Price is not in Dusk, but in the smallest fraction of the token, called Lux.&lt;/p&gt;

&lt;p&gt;Let's try a different query. Plugging in the Block Height returned previously, we know what Block Hash to expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query "query {block(height: 184){header{hash}}}" | jq
{
  "block": {
    "header": {
      "hash": "0925fc9ff94d445ffecead0e0bfeda70ca184e74d101fbc41a7cc4e5d4412060"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or using the Block Hash to get the block reward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query 'query {block(hash: \"0925fc9ff94d445ffecead0e0bfeda70ca184e74d101fbc41a7cc4e5d4412060\"){reward}}' | jq
{
  "block": {
    "reward": 16000000000
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or fees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query 'query {block(hash: \"0925fc9ff94d445ffecead0e0bfeda70ca184e74d101fbc41a7cc4e5d4412060\"){fees}}' | jq
{
  "block": {
    "fees": 283239
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or the Ids of transactions in a block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./run_query "query {block(height: 184){transactions{id}}}" | jq
{
  "block": {
    "transactions": [
      {
        "id": "95f58e4b8e7fc5658540cd01064ae93ab07d34c1a91d5a848d32384a3951b100"
      }
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all folks.&lt;/p&gt;

</description>
      <category>dusk</category>
      <category>rpc</category>
      <category>graphql</category>
      <category>rwa</category>
    </item>
    <item>
      <title>Dusk - Running a Local Node</title>
      <dc:creator>smith@mcf.rocks</dc:creator>
      <pubDate>Wed, 27 Dec 2023 16:15:42 +0000</pubDate>
      <link>https://forem.com/dusktastic/dusk-running-a-local-node-1723</link>
      <guid>https://forem.com/dusktastic/dusk-running-a-local-node-1723</guid>
      <description>&lt;p&gt;&lt;strong&gt;Run a local node on your machine, give yourself some coins, create two wallets and transfer coins... in under 10 minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You will need Ubuntu 22.04 LTS (20.04 doesn't have the required libraries) and then clone the &lt;em&gt;rusk&lt;/em&gt; github repo and build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# git clone https://github.com/dusk-network/rusk.git
# cd rusk
# make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There will now be a binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./target/release/rusk -V
rusk 0.7.0-rc.0 (cbd5c504 2023-12-22)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy consensus keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cp examples/consensus.keys ~/.dusk/rusk/consensus.keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate the genesis state. It uses the .toml file to create the binary .state file, we will do this again with coins in a moment, but for now just to show how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cargo r --release -p rusk -- recovery-state \
  --init examples/genesis.toml -o /tmp/example.state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run the node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# export DUSK_CONSENSUS_KEYS_PASS=password 
# cargo r --release -p rusk -- -s /tmp/example.state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see a bunch of output on the console, and if you check in another session, you will see port 8080 listening.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# netstat -tlpn | grep target
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      77261/target/releas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;note&lt;/em&gt;: the 127.0.0.1 means the port (8080) will only accept connections from that server.&lt;/p&gt;

&lt;p&gt;Stop the process and have it listen on a specific port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# export DUSK_CONSENSUS_KEYS_PASS=password 
# ./target/release/rusk -s /tmp/example.state \
  --http-listen-addr 0.0.0.0:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# netstat -tlpn | grep target
tcp        0      0 0.0.0.0:4321            0.0.0.0:*               LISTEN      114057/./target/rel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;note&lt;/em&gt;: the 0.0.0.0 indicates the port accepts connections from anywhere (firewall permitting).&lt;/p&gt;

&lt;p&gt;Can't do much without a wallet. Go back to home directory, clone the &lt;em&gt;wallet-cli&lt;/em&gt; github repo and build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# git clone https://github.com/dusk-network/wallet-cli.git
# cd wallet-cli/
# make build
# cd target
# cd release
# ./rusk-wallet -V
Dusk Wallet CLI 0.20.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to connect the wallet to a running node, in this case our local node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ./target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select the recover wallet option and enter the 12 words:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cost hungry lounge anger hint cheap buddy across road excuse vendor area&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;it's deterministic, so the first address will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;471s2wnF6e5rEv3d6DgSmRHR5mjJGvXTitueNSMGDRV2U9WzhZHRHLJZNbNPZeVAoaGvtwoxRc4R8urC7oNeAueY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will note the balance is zero.&lt;/p&gt;

&lt;p&gt;We need to fund the wallet, to do that we stop the node and generate the initial state again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# rm /tmp/example.state
# cd ~/rusk
# vi examples/genesis.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add these lines to give initial balance of 100,000:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[balance]]
address = '471s2wnF6e5rEv3d6DgSmRHR5mjJGvXTitueNSMGDRV2U9WzhZHRHLJZNbNPZeVAoaGvtwoxRc4R8urC7oNeAueY'
seed = 0xdead_beef
notes = [100_000_000_000_000]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;note&lt;/em&gt;: the last 9 zeros are decimals&lt;/p&gt;

&lt;p&gt;Then regenerate the state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cargo r --release -p rusk -- recovery-state \
  --init examples/genesis.toml \
  -o /tmp/example.state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# export DUSK_CONSENSUS_KEYS_PASS=password 
# ./target/release/rusk -s /tmp/example.state \
  --http-listen-addr 0.0.0.0:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a second session, start the wallet as before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cd ~/wallet-cli
# ./target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://127.0.0.1:4321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recover the wallet, with our words:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;cost hungry lounge anger hint cheap buddy across road excuse vendor area&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You will see a balance of 100,000&lt;/p&gt;

&lt;p&gt;We now need to fake a second wallet, open a third session and create another linux user account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# sudo useradd -m testdusk
# sudo usermod --shell /bin/bash testdusk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the wallet directory to the new user and chown it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# cp -R wallet-cli /home/testdusk/
# chown -R testdusk:testdusk /home/testdusk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new wallet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# su - testdusk
# cd wallet-cli
# ./target/release/rusk-wallet \
  --state http://127.0.0.1:4321 \
  --prover http://127.0.0.1:4321
&amp;gt; Create a new wallet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you some new wallet with an address, with zero balance.&lt;/p&gt;

&lt;p&gt;Copy the new address, and on the original wallet, send 100 coins to the new address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Transfer Dusk
// use suggested gas limit and price and proceed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the balance is less by 100 plus a very small amount for gas. Switching to the new wallet, you should see a balance of 100.&lt;/p&gt;

</description>
      <category>dusk</category>
      <category>node</category>
      <category>crypto</category>
      <category>rwa</category>
    </item>
  </channel>
</rss>
