|
| 1 | +# zcash-devtool Tutorial |
| 2 | + |
| 3 | +This tutorial explaining how to use FROST to sign a Zcash transaction using |
| 4 | +[zcash-devtool](https://github.com/zcash/zcash-devtool). |
| 5 | + |
| 6 | + |
| 7 | +## Setting up |
| 8 | + |
| 9 | +Install `cargo` and `git`. |
| 10 | + |
| 11 | +Install the `zcash-devtool`: |
| 12 | + |
| 13 | +``` |
| 14 | +cargo install --git https://github.com/zcash/zcash-devtool.git --locked |
| 15 | +``` |
| 16 | + |
| 17 | +Install the `frost-client` tool: |
| 18 | + |
| 19 | +``` |
| 20 | +cargo install --git https://github.com/ZcashFoundation/frost-zcash-demo.git --locked frost-client |
| 21 | +``` |
| 22 | + |
| 23 | +Install the `zcash-sign` tool: |
| 24 | + |
| 25 | +``` |
| 26 | +cargo install --git https://github.com/ZcashFoundation/frost-zcash-demo.git --locked zcash-sign |
| 27 | +``` |
| 28 | + |
| 29 | +Switch to an empty folder which will store the files generated in the demo. |
| 30 | +For example: |
| 31 | + |
| 32 | +``` |
| 33 | +mkdir frost-demo |
| 34 | +cd frost-demo/ |
| 35 | +``` |
| 36 | + |
| 37 | + |
| 38 | +### Running the server |
| 39 | + |
| 40 | +This demo uses the ZF FROST server (frostd) to help participants communicate. |
| 41 | +While in practice users would use an existing online server, for the demo you |
| 42 | +can run a local server by following [these instructions](./server.md) (the |
| 43 | +"Compiling, Running and Deploying" and "Local Testing" sections). |
| 44 | + |
| 45 | +The rest of the tutorial assumes the server is up and running. |
| 46 | + |
| 47 | + |
| 48 | +### Initializing the users |
| 49 | + |
| 50 | +Run the following command to initialize three users (in practice, each user |
| 51 | +would run a similar command, but for demo purposes we're assuming |
| 52 | +you will simulate all of them in the same machine, so run these |
| 53 | +commands in your machine): |
| 54 | + |
| 55 | +``` |
| 56 | +frost-client init -c alice.toml |
| 57 | +frost-client init -c bob.toml |
| 58 | +frost-client init -c eve.toml |
| 59 | +``` |
| 60 | + |
| 61 | +This will create a config file for three users; Alice, Bob and Eve. |
| 62 | + |
| 63 | +```admonish note |
| 64 | +If you really want to run the demo in separate machines, then you can omit the |
| 65 | +`-c alice.toml` part of the command (i.e. run `frost-client init`); it will |
| 66 | +save to a default location in the user's home directory. |
| 67 | +``` |
| 68 | + |
| 69 | + |
| 70 | +## Generating FROST key shares |
| 71 | + |
| 72 | +First we will generate the FROST key shares. For simplicity we'll use trusted |
| 73 | +dealer; if you want to use Distributed Key Generation, skip to the next section. |
| 74 | + |
| 75 | +In a new terminal (in case the previous terminal is running the server), run the |
| 76 | +following: |
| 77 | + |
| 78 | +``` |
| 79 | +frost-client trusted-dealer -d "Alice, Bob and Eve's group" --names Alice,Bob,Eve -c alice.toml -c bob.toml -c eve.toml -C redpallas |
| 80 | +``` |
| 81 | + |
| 82 | +This will by default generate a 2-of-3 key shares. The key shares will be |
| 83 | +written into each participant's config file. You can change the threhsold, |
| 84 | +number of shares and file names using the command line; append `-h` to the |
| 85 | +commend above for the command line help. |
| 86 | + |
| 87 | + |
| 88 | +## Generating FROST key shares using DKG |
| 89 | + |
| 90 | +For real-word usage we commend generating key shares using Distributed Key |
| 91 | +Generation. If you did the previous section, skip to "Generating the Full |
| 92 | +Viewing Key for the wallet". |
| 93 | + |
| 94 | + |
| 95 | +```admonish note |
| 96 | +This section assumes each participant is running the commands in their own |
| 97 | +machine. If you want to simulate all of them in a single machine, |
| 98 | +specify the config file for the user (e.g. `-c alice.toml`) accordingly. |
| 99 | +``` |
| 100 | + |
| 101 | + |
| 102 | +### Initializing config files |
| 103 | + |
| 104 | +If they haven't yet, each participant should run: |
| 105 | + |
| 106 | +``` |
| 107 | +frost-client init |
| 108 | +``` |
| 109 | + |
| 110 | + |
| 111 | +### Sharing contacts |
| 112 | + |
| 113 | +Each participant must now generate a contact string that they will need to share |
| 114 | +with the other participants. This contact string will include a name, which they |
| 115 | +can choose when exporting and will be shown to whoever they send the contact to. |
| 116 | + |
| 117 | +Run the following, substituting the name accordingly: |
| 118 | + |
| 119 | +``` |
| 120 | +frost-client export --name 'Alice' |
| 121 | +``` |
| 122 | + |
| 123 | +The command will print an encoded contact string such as |
| 124 | +`zffrost1qyqq2stvd93k2g84hudcr98zp67a9rnx9v00euw9e5424hjathvre7ymy344fynjdvxmwxfg`. |
| 125 | +Send it to the other participants using some trusted communication channel |
| 126 | +(instant messaging, etc.). |
| 127 | + |
| 128 | +The other participants will send you their contacts. Import them by running the |
| 129 | +following command for each contact (replace `<contact-string>` with the contact |
| 130 | +string accordingly): |
| 131 | + |
| 132 | +``` |
| 133 | +frost-client import <contact-string> |
| 134 | +``` |
| 135 | + |
| 136 | + |
| 137 | +### Generating shares |
| 138 | + |
| 139 | +Finally, to generate the shares, one of the participants will need to initiate |
| 140 | +the process. They will need to public key of each participant, so they need to |
| 141 | +first list them with the following command: |
| 142 | + |
| 143 | +``` |
| 144 | +frost-client contacts |
| 145 | +``` |
| 146 | + |
| 147 | +Then run the following command, replacing the `<pubkey1>` and `<pubkey2>` hex |
| 148 | +strings with the public keys of the contacts which will participate (along with |
| 149 | +the user running the command): |
| 150 | + |
| 151 | +``` |
| 152 | +frost-client dkg -d "Alice, Bob and Eve's group" -s localhost:2744 -S <pubkey1>,<pubkey2> -t 2 -C redpallas -c alice.toml |
| 153 | +``` |
| 154 | + |
| 155 | +The user should then notify the others that a signing session has started (e.g. |
| 156 | +via instant messaging again), and also share the threshold number that was used. |
| 157 | +They should then run the following, replacing the name of the group if they wish |
| 158 | +and the threshold number with the one given by the first participant. |
| 159 | + |
| 160 | +``` |
| 161 | +frost-client dkg -d "Alice, Bob and Eve's group" -s localhost:2744 -t 2 -C redpallas |
| 162 | +``` |
| 163 | + |
| 164 | +```admonish note |
| 165 | +A future version might not require specifying the threshold and group name. |
| 166 | +``` |
| 167 | + |
| 168 | + |
| 169 | +## Generating the Full Viewing Key for the wallet |
| 170 | + |
| 171 | +Next, we will need to generate a Zcash Full Viewing Key from the FROST group |
| 172 | +material we have just generated; this address will then be imported into a wallet |
| 173 | +so that we'll be able to create Zcash transactions for it. |
| 174 | + |
| 175 | +Run the following command: |
| 176 | + |
| 177 | +``` |
| 178 | +frost-client groups |
| 179 | +``` |
| 180 | + |
| 181 | +It will list all groups you're in - at this point it should list the only one |
| 182 | +you have just created. Copy the Public Key it shows (it will look like e.g. |
| 183 | +`79d6bcee79c88ad9ba259067772b97f5de12f1435b474d03bc98f255be08a610`) |
| 184 | + |
| 185 | +The run the following command, replacing `<ak>` with the value you copied, |
| 186 | +and `test` with `main` if you're using Mainnet. |
| 187 | + |
| 188 | +``` |
| 189 | +zcash-sign generate --net test --ak <ak> |
| 190 | +``` |
| 191 | + |
| 192 | +It will print an Orchard address, and a Unified Full Viewing Key. Copy and |
| 193 | +paste both somewhere to use them later. |
| 194 | + |
| 195 | + |
| 196 | +## Importing the Full Viewing Key into zcash-devtool |
| 197 | + |
| 198 | +In the zcash-devtool folder, run the following, replacing `<UFVK>` with the |
| 199 | +UFVK printed in the last step: |
| 200 | + |
| 201 | +``` |
| 202 | +zcash-devtool wallet -w ./.frost.view/ init-fvk --name FROST_wallet --fvk <UFVK> --birthday 3720000 -s zecrocks |
| 203 | +``` |
| 204 | + |
| 205 | +(Change `./.frost-view` or `FROST_wallet` if you want to change the folder or |
| 206 | +name of the wallet.) |
| 207 | + |
| 208 | + |
| 209 | +## Funding the wallet |
| 210 | + |
| 211 | +Now you will need to fund this wallet with some ZEC. Send ZEC to that address |
| 212 | +using another account (or try [ZecFaucet](https://zecfaucet.com/)). |
| 213 | + |
| 214 | +## Creating the transaction |
| 215 | + |
| 216 | +Run the following, replacing `<DEST_ADDR>` with the address you want to ZEC to, |
| 217 | +`<VALUE>` with the value you want to send in Zatoshis, `<MEMO>` with the |
| 218 | +memo you want to send: |
| 219 | + |
| 220 | +``` |
| 221 | +zcash-devtool pczt -w ./.frost.view/ create --address <DEST_ADDR> --value <VALUE> --memo <MEMO> > frost_pczt.created |
| 222 | +``` |
| 223 | + |
| 224 | + |
| 225 | +## Signing the transaction |
| 226 | + |
| 227 | +Now you will need to simulate two participants and a Coordinator to sign the |
| 228 | +transaction, and you should still have the FROST server running which will |
| 229 | +handle communications between them. It's probably easier to open three new |
| 230 | +terminals. |
| 231 | + |
| 232 | +Go back to the signer terminal and run the following, replacing `<pczt_path>` |
| 233 | +with the path to the file you saved in the previous step, and `<pczt_signed_path>` |
| 234 | +with the path where you want to write the signed transaction (e.g. |
| 235 | +`frost_pczt.signed`). |
| 236 | + |
| 237 | +``` |
| 238 | +zcash-sign sign -n test --tx-plan frost_pczt.created -o frost_pczt.signed |
| 239 | +``` |
| 240 | + |
| 241 | +(Replace `test` with `main` if you're using Mainnet.) |
| 242 | + |
| 243 | +The program will print a SIGHASH and a Randomizer, and will prompt for a |
| 244 | +signature. This is what you will get after running FROST, so let's do that; |
| 245 | +leave the prompt there without typing anything. |
| 246 | + |
| 247 | + |
| 248 | +### Coordinator |
| 249 | + |
| 250 | +In the second terminal, the Coordinator, run (in the same folder where you |
| 251 | +initialized the users and ran the key generation) the following: |
| 252 | + |
| 253 | +``` |
| 254 | +frost-client groups -c alice.toml |
| 255 | +``` |
| 256 | + |
| 257 | +This will list the groups Alice is in; it should only list the one you created |
| 258 | +earlier. You will need to copy some values in the command. Run the following, |
| 259 | +replacing the value after `<group>` with the "Public key" listed for the group; |
| 260 | +replacing `<pubkey1>` and `<pubkey2>` with the public keys of Alice and Bob (the |
| 261 | +hexadecimal values printed next to their names; Alice's name will be empty to |
| 262 | +indicate it's her own). |
| 263 | + |
| 264 | +``` |
| 265 | +frost-client coordinator -c alice.toml --server-url localhost:2744 --group <group> -S <pubkey1>,<pubkey2> -m - -r - |
| 266 | +``` |
| 267 | + |
| 268 | +It will prompt you for a message. Paste the SIGHASH generated with the |
| 269 | +`zcash-sign` tool and press enter. It will then prompt for a randomizer. Paste |
| 270 | +the one generated with the `zcash-sign` tool and press enter. |
| 271 | + |
| 272 | +The tool will connect to the server and wait for the other participants. |
| 273 | + |
| 274 | +```admonish warning |
| 275 | +If you prefer to pass the message (SIGHASH) or randomizer as files by using |
| 276 | +the `-m` and `-r` arguments, you will need to convert them to binary format. |
| 277 | +``` |
| 278 | + |
| 279 | + |
| 280 | +### Participant 1 (Alice) |
| 281 | + |
| 282 | +In the third terminal, Participant 1, run the following (replacing `<group>` |
| 283 | +with the same group public key used in the previous command): |
| 284 | + |
| 285 | +``` |
| 286 | +frost-client participant -c alice.toml --server-url localhost:2744 --group <group> |
| 287 | +``` |
| 288 | + |
| 289 | +(We are using "Alice" again. There's nothing stopping a Coordinator from being a |
| 290 | +Partcipant too!) |
| 291 | + |
| 292 | + |
| 293 | +### Participant 2 (Bob) |
| 294 | + |
| 295 | +In the fourth terminal, for Participant 2, run the following (replacing `<group>` |
| 296 | +again): |
| 297 | + |
| 298 | +``` |
| 299 | +frost-client participant -c bob.toml --server-url localhost:2744 --group <group> |
| 300 | +``` |
| 301 | + |
| 302 | + |
| 303 | +### Coordinator |
| 304 | + |
| 305 | +Go back to the Coordinator CLI. The protocol should run and complete |
| 306 | +successfully. It will print the final FROST-generated signature. Hurrah! Copy it |
| 307 | +(just the hex value). |
| 308 | + |
| 309 | +Go back to the signer and paste the signature. It will write the signed |
| 310 | +transaction to the file you specified. |
| 311 | + |
| 312 | +## Proving the transaction |
| 313 | + |
| 314 | +You will need to prove the transaction separately: |
| 315 | + |
| 316 | +``` |
| 317 | +cargo run -p zcash-sign -- sign -n test --tx-plan frost_pczt.created -o frost_pczt.signed |
| 318 | +``` |
| 319 | + |
| 320 | +And then combine signed and proven into a final transaction: |
| 321 | + |
| 322 | +``` |
| 323 | +zcash-devtool pczt combine -i frost_pczt.signed -i frost_pczt.proven > frost_pczt.combined |
| 324 | +``` |
| 325 | + |
| 326 | + |
| 327 | +## Broadcasting the transaction |
| 328 | + |
| 329 | +Run: |
| 330 | + |
| 331 | +``` |
| 332 | +zcash-devtool pczt -w ./.frost.view/ send -s zecrocks < test_pczt.combined |
| 333 | +``` |
0 commit comments