trustchain 0.2.0

Trustchain decentralised PKI reference implementation.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
# ION

The [Identity Overlay Network](https://identity.foundation/ion/) (ION) is an open source [DID method](https://www.w3.org/TR/did-core/#methods) implementation developed by the Decentralized Identity Foundation.

In other words, ION is a software tool that can be used to perform DID operations, such as creating and publishing new DIDs and DID documents, and resolving existing ones. It does this by reading and writing data to the [Bitcoin](https://bitcoin.org/en/) blockchain and to the [IPFS](https://ipfs.tech/) distributed file system. As such, every ION instance is a node on these two peer-to-peer networks.

Trustchain delegates the execution of DID operations to an ION node. Therefore to use Trustchain you must first install and run ION, either on the same machine or a connected one.

!!! warning "ION resource requirements"

    An ION installation includes a full node on the Bitcoin network, which must download and store the entire Bitcoin blockchain. This is a large amount of data that typically takes several hours, or even days, to download.

    The recommended system requirements for an ION installation are:

    - 6GB of RAM
    - 1TB of storage (or 256GB for [Testnet](#bitcoin-mainnet-vs-testnet)).

Note, however, that **Trustchain makes no assumptions about the trustworthiness of the ION system** and the Trustchain security model does not rely on the correct functioning of the ION software. Trustchain independently verifies all of the data it receives from ION, so a faulty or compromised ION node would not represent a security vulnerability in Trustchain (although it could cause a loss of service).

This page explains how to install and run ION.

<!-- TODO: insert the architecture schematic diagram here? (from the paper). -->

## Preliminaries

Before beginning the installation, a few decisions must be made that will determine exactly what steps should be taken.

### Docker Container vs. Full Installation

The simplest way to run ION is using Docker, and it can be a useful way to experiment with the system before performing a full installation. However, this method provides a **read-only ION node**. This means that it provides access to existing DIDs, but cannot be used to create and publish new ones.

If you would like to be able to use Trustchain to create and publish your own DIDs, follow the full installation instructions below (and ignore the [ION with Docker](#ion-using-docker) section).

If you want to run ION using Docker, you can skip most of this page and just follow the instructions in the [ION with Docker](#ion-with-docker) section.

### Bitcoin Mainnet vs. Testnet

The Bitcoin client wrapped inside an ION node can be configured either for **Mainnet** (the main Bitcoin network) or **Testnet** (an alternative blockchain designed for testing and software development).

Mainnet should be used for a production deployment of Trustchain because DID operations published on the Bitcoin blockchain have extremely strong immutability, persistence and discoverability properties. When testing Trustchain, however, it is sensible to configure the ION Bitcoin client for Testnet, since coins on the test network have no monetary value and therefore "test" DID operations can be executed at zero cost.

Testnet coins can be requested from a Testnet "faucet", such as [this one](https://coinfaucet.eu/en/btc-testnet/).

In this guide, commands and configuration settings may depend on which network is in use. In those cases, choose the appropriate tab (Mainnet or Testnet) for your setup.

### Local vs. Remote Installation

You can install ION on your local machine or a remote one, e.g. a virtual machine in the Cloud. If you are using a remote machine, connect to it using SSH and follow the instructions below.

Once installed, follow the port forwarding instructions in the [SSH config](#ssh-config) section to produce a setup that is indistinguishable from running an ION node locally.

## ION Installation Guide

These instructions are based on the official [ION Install Guide](https://identity.foundation/ion/install-guide/) but contain additional details, several minor corrections and a workaround to support the latest versions of Bitcoin Core.

Both Linux and macOS are supported and tested. For Linux, our instructions assume a Debian-based distribution, such as Ubuntu. Some minor changes will be needed for other distributions. Instructions for installing on Windows are given in the official [ION guide](https://identity.foundation/ion/install-guide/).

In all cases, administrator privileges are required.

### Prerequisites

!!! info "Create the `SHELL_CONFIG` environment variable"

    Before continuing, make sure you have created the `SHELL_CONFIG` environment variable by following the instructions on the [Getting Started](getting-started.md#environment-variables) page.

Run the following commands to set up your environment.

=== "Linux"

    Update the package lists on your machine and install essential build tools:
    ```console
    $ sudo apt update && sudo apt install build-essential
    ```
    Install Git:
    ```console
    $ sudo apt install git
    ```
    Install Node.js:
    ```console
    $ sudo apt install nodejs
    ```
    and the Node package manager:
    ```console
    $ sudo apt install npm
    ```

=== "macOS"

    Install Xcode [command line tools](https://developer.apple.com/download/all/):
    ```console
    $ xcode-select --install
    ```
    Install the [Homebrew](https://brew.sh/#install) package manager:
    ```console
    $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    ```

### Install IPFS

IPFS is the InterPlanetary File System, a peer-to-peer protocol and network used by ION for storing and sharing data.

=== "Linux"

    Follow the official IPFS [installation instructions](https://docs.ipfs.tech/install/command-line/#install-kubo-linux) for Linux.

=== "macOS"

    Install IPFS:
    ```console
    $ brew install ipfs
    ```

Then initialise your IPFS node:
```console
$ ipfs init
```
To check the installation was successful, open a new Terminal window and start the IPFS daemon:
```console
$ ipfs daemon
```
Then (back in the original Terminal window) run:
```console
$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
```
which should output a welcome message.

### Install MongoDB

=== "Linux"

    Follow [these instructions](https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/) to install MongoDB on Linux


=== "macOS"

    Following [these instructions](https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-os-x/):
    ```console
    $ brew tap mongodb/brew
    ```
    then:
    ```console
    $ brew install mongodb-community
    ```

### Install Bitcoin Core

Trustchain has been tested with Bitcoin Core v24.0.1 and therefore the instructions below assume that version. More recent versions of Bitcoin Core are [available](https://bitcoincore.org/en/releases/) and can be used, but will require some minor changes to the commands in the following steps.

=== "Linux"

    Begin by downloading the [Bitcoin Core release](https://bitcoincore.org/bin/bitcoin-core-24.0.1/) for your system:

     - [Download link](https://bitcoincore.org/bin/bitcoin-core-24.0.1/bitcoin-24.0.1-x86_64-linux-gnu.tar.gz) for Linux with x86-64 processor.
     - [Download link](https://bitcoincore.org/bin/bitcoin-core-24.0.1/bitcoin-24.0.1-arm-linux-gnueabihf.tar.gz) for Linux with ARM processor.

    Verify the download by comparing the [published hash](https://bitcoincore.org/bin/bitcoin-core-24.0.1/SHA256SUMS) with the result of this command:
    ```console
    $ shasum -a 256 ~/Downloads/bitcoin-24.0.1-*.tar.gz
    ```

    Unzip the archive:
    ```console
    $ (cd ~/Downloads && tar xvzf bitcoin-24.0.1-*.tar.gz)
    ```
    and install Bitcoin Core:
    ```console
    $ sudo install -m 0755 -t /usr/local/bin ~/Downloads/bitcoin-24.0.1/bin/*
    ```
    The installation includes an executable file named `bitcoind` which we will run to start Bitcoin Core.

=== "macOS"

    Begin by downloading the [Bitcoin Core release](https://bitcoincore.org/bin/bitcoin-core-24.0.1/) for your system:

     - [Download link](https://bitcoincore.org/bin/bitcoin-core-24.0.1/bitcoin-24.0.1-x86_64-apple-darwin.tar.gz) for Mac with x86-64 processor.
     - [Download link](https://bitcoincore.org/bin/bitcoin-core-24.0.1/bitcoin-24.0.1-arm64-apple-darwin.tar.gz) for Mac with Apple M1 processor.

    Verify the download by comparing the [published hash](https://bitcoincore.org/bin/bitcoin-core-24.0.1/SHA256SUMS) with the result of this command:
    ```console
    $ shasum -a 256 ~/Downloads/bitcoin-24.0.1-*.tar.gz
    ```

    Unzip the archive:
    ```console
    $ (cd ~/Downloads && tar xvzf bitcoin-24.0.1-*.tar.gz)
    ```
    and move the contents to the `/Applications` folder:
    ```console
    $ mv ~/Downloads/bitcoin-24.0.1 /Applications
    ```
    The download contains an executable file named `bitcoind` which we will run to start Bitcoin Core.

    !!! info "Sign the Bitcoin Core executable files"

        Newer macOS systems will refuse to run an executable file unless it is signed. Run the following command to check whether this is a requirement on your machine:
        ```console
        $ codesign -d -vvv --entitlements :- /Applications/bitcoin-24.0.1/bin/bitcoind
        > /Applications/bitcoin-24.0.1/bin/bitcoind: code object is not signed at all
        ```
        If you see the message "code object is not signed at all" (as in the example above), you will need to create a [self-signed certificate](https://support.apple.com/en-gb/guide/keychain-access/kyca8916/mac) for the executable file. Do this by running:
        ```console
        $ codesign -s - /Applications/bitcoin-24.0.1/bin/bitcoind
        ```
        And do the same for the Bitcoin CLI executable:
        ```console
        $ codesign -s - /Applications/bitcoin-24.0.1/bin/bitcoin-cli
        ```

### Configure Bitcoin Core

We shall need to specify a folder to store the Bitcoin blockchain data.

!!! warning "Bitcoin data storage requirements"

    The Bitcoin data folder will store the entire Bitcoin blockchain, which is >580GB for Mainnet and >75GB for Testnet.

For convenience, we create an environment variable for the Bitcoin data folder.

!!! tip "Create the `BITCOIN_DATA` environment variable"

    Our convention is to use the folder `~/.bitcoin` for Bitcoin Core data. If you want to use a different folder, just change the path in the following command:
    ```console
    $ echo "export BITCOIN_DATA=~/.bitcoin" >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

Having defined the `BITCOIN_DATA` environment variable, use it to create the data folder itself:
```console
$ mkdir $BITCOIN_DATA
```

=== "Mainnet"

    Bitcoin configuration parameters will be stored in a file named `bitcoin.conf` inside the `$BITCOIN_DATA` folder.
    The following command creates that file with the required parameters and user permissions:
    ```console
    $ printf "server=1\ndaemon=1\ntxindex=1\ndatadir=$BITCOIN_DATA\n" > $BITCOIN_DATA/bitcoin.conf && chmod 640 $BITCOIN_DATA/bitcoin.conf
    ```

    To confirm these changes were made correctly, check the first three lines in the `bitcoin.conf` file by running:
    ```console
    $ head -n 4 $BITCOIN_DATA/bitcoin.conf
    ```
    You should see lines like these printed to the Terminal:
    ```
    server=1
    daemon=1
    txindex=1
    datadir=<YOUR_BITCOIN_DATA_DIRECTORY>
    ```

=== "Testnet"

    Bitcoin configuration parameters will be stored in a file named `bitcoin.conf` inside the `$BITCOIN_DATA` folder.
    The following command creates that file with the required parameters and user permissions:
    ```console
    $ printf "testnet=1\nserver=1\ndaemon=1\ntxindex=1\ndatadir=$BITCOIN_DATA\n" > $BITCOIN_DATA/bitcoin.conf && chmod 640 $BITCOIN_DATA/bitcoin.conf
    ```

    To confirm these changes were made correctly, check the first three lines in the `bitcoin.conf` file by running:
    ```console
    $ head -n 5 $BITCOIN_DATA/bitcoin.conf
    ```
    You should see lines like these printed to the Terminal:
    ```
    testnet=1
    server=1
    daemon=1
    txindex=1
    datadir=<YOUR_BITCOIN_DATA_DIRECTORY>
    ```

!!! warning "Note: Do not use the `~` shorthand in the `datadir` parameter"

    The directory path in the `datadir` parameter must not contain the `~` character as a shorthand for the user's home directory.

    The example given in the official [ION install guide](https://identity.foundation/ion/install-guide/) does use this shorthand, which causes an error, so beware of this issue if you are following that guide and/or editing the `bitcoin.conf` file manually.

### Configure Bitcoin CLI

When your Bitcoin Core node is up and running, you will want to be able to communicate with it. Bitcoin Core provides a command line interface (CLI) for this purpose.

Run the following command to create an alias, making to easy to access the CLI:

=== "Linux"

    ```console
    $ echo 'alias bitcoin-cli="/usr/local/bin/bitcoin-cli -conf=$BITCOIN_DATA/bitcoin.conf"' >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

=== "macOS"

    ```console
    $ echo 'alias bitcoin-cli="/Applications/bitcoin-24.0.1/bin/bitcoin-cli -conf=$BITCOIN_DATA/bitcoin.conf"' >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

!!! info "Bitcoin RPC username and password"

    Before you can make use of the CLI you will need to add a username and password to the Bitcoin configuration file. These same parameters will also be used for authentication when ION interacts with Bitcoin Core. In both cases, the interaction is possible because Bitcoin Core provides access via a Remote Procedure Call (RPC) interface.

    We shall use `admin` for the RPC username. To set up the RPC password, copy and paste the following command into the Terminal and then change `<password>` to something of your choice before hitting the ++return++ key:
    ```console
    $ RPC_PASSWORD="<password>"
    ```
    Now run the following command to add the username and password to the `bitcoin.conf` file:

    === "Linux"
        ```console
        $ sed -i "1s|^|rpcuser=admin\nrpcpassword=$RPC_PASSWORD\n|" $BITCOIN_DATA/bitcoin.conf
        ```
    === "macOS"
        ```console
        $ sed -i '' "1s|^|rpcuser=admin\nrpcpassword=$RPC_PASSWORD\n|" $BITCOIN_DATA/bitcoin.conf
        ```

    To confirm these changes were made correctly, check the first two lines in the `bitcoin.conf` file by running:
    ```console
    $ head -n 2 $BITCOIN_DATA/bitcoin.conf
    ```
    You should see these lines printed to the Terminal (with your chosen password):
    ```
    rpcuser=admin
    rpcpassword=<password>
    ```

### Start Bitcoin Core

Before we start Bitcoin Core, we need to make sure it can find the correct configuration file that was created above. To make this convenient, let's create an alias in our `SHELL_CONFIG` file:

=== "Linux"

    ```console
    $ echo 'alias bitcoind="/usr/local/bin/bitcoind -conf=$BITCOIN_DATA/bitcoin.conf"' >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

    Now, use the following simple command to start Bitcoin Core:
    ```console
    $ bitcoind
    ```

=== "macOS"

    ```console
    $ echo 'alias bitcoind="/Applications/bitcoin-24.0.1/bin/bitcoind -conf=$BITCOIN_DATA/bitcoin.conf"' >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

    Now, use the following simple command to start Bitcoin Core:
    ```console
    $ bitcoind
    ```
    The first time your run this command, you will see the following pop-up message:

    ![bitcoind macOS pop-up](assets/bitcoind-macOS-pop-up.png){: style="height:250px"}

    You need to tell macOS that this is not malicious software. To do this, open the "Security & Privacy" settings in System Preferences, choose the "General" tab, and click the button on the right-hand side that says "Allow Anyway":

    ![bitcoind macOS pop-up](assets/bitcoind-allow-anyway.png){: style="height:350px"}

    Now re-run the command to start Bitcoin Core:
    ```console
    $ bitcoind
    ```
    Another pop-up message will appear, similar to the first one, but this time there will be an option to allow the program to run by clicking the "Open" button.

You should now see the message "Bitcoin Core starting" in the Terminal.

!!! warning "Bitcoin synchronisation"

    When Bitcoin Core starts for the first time, it will begin synchronising with the rest of the Bitcoin network. This means downloading all of the blocks in the Bitcoin blockchain, which is a large data structure containing every Bitcoion transaction that has ever been processed.

    **The synchronisation process may take several hours, or even days, to complete.** You can continue with the installation steps below while it is in progress, but you will not be able to use Trustchain until your Bitcoin node has finished synchronising.

Whenever Bitcoin Core is running, you can invoke the Bitcoin CLI with commands beginning `bitcoin-cli`. A full list of commands available via the Bitcoin CLI can be found [here](https://developer.bitcoin.org/reference/rpc/).

One useful example is the following `-getinfo` command. It reports information about the state of your Bitcoin node, including whether it is fully synchronised:
```console
$ bitcoin-cli -getinfo
```

!!! info "Create a Bitcoin wallet for ION"

    Before using ION you must create a Bitcoin wallet by running the following CLI command:
    ```console
    $ bitcoin-cli -named createwallet wallet_name="sidetreeDefaultWallet" descriptors=false
    ```
    Expected output:
    ```json
    {
      "name": "sidetreeDefaultWallet",
      "warnings": [
        "Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future."
      ]
    }
    ```
    Note that we have chosen to create a "legacy" Bitcoin wallet, for compatibility with ION.


### Configure ION

Choose a directory in which you want to store the ION software and change to that directory using the command `$ cd <DIRECTORY_NAME>`. For instance, to change to your home directory run the `cd` command without any arguments:
```console
$ cd
```
Now clone the ION code repository from GitHub:
```console
$ git clone https://github.com/decentralized-identity/ion
```
and change into the newly-created `ion` subfolder:
```console
$ cd ion
```

!!! tip "Create the `ION_REPO` environment variable"

    Since we will need to refer to this folder in future, let's create an [environment variable](getting-started.md#environment-variables) containing its file path:
    ```console
    $ echo "export ION_REPO=" $(pwd) | sed 's/= /=/g' >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

We will need a folder for storing ION configuration files. For convenience, we'll also create an environment variable for that folder.

!!! tip "Create the `ION_CONFIG` environment variables"

    Our convention is to use the folder `~/.ion` for ION configuration files. If you want to use a different folder, just change the path in the following command:
    ```console
    $ echo "export ION_CONFIG=~/.ion" >> $SHELL_CONFIG; source $SHELL_CONFIG
    ```

    We also need environment variables for each of the four files that will be stored in the ION config folder, so ION can find them when it starts up. The following command creates all four environment variables:

    === "Mainnet"
        ```console
        $ printf "export ION_BITCOIN_CONFIG_FILE_PATH=$ION_CONFIG/mainnet-bitcoin-config.json\nexport ION_BITCOIN_VERSIONING_CONFIG_FILE_PATH=$ION_CONFIG/mainnet-bitcoin-versioning.json\nexport ION_CORE_CONFIG_FILE_PATH=$ION_CONFIG/mainnet-core-config.json\nexport ION_CORE_VERSIONING_CONFIG_FILE_PATH=$ION_CONFIG/mainnet-core-versioning.json" >> $SHELL_CONFIG; source $SHELL_CONFIG
        ```
    === "Testnet"
        ```console
        $ printf "export ION_BITCOIN_CONFIG_FILE_PATH=$ION_CONFIG/testnet-bitcoin-config.json\nexport ION_BITCOIN_VERSIONING_CONFIG_FILE_PATH=$ION_CONFIG/testnet-bitcoin-versioning.json\nexport ION_CORE_CONFIG_FILE_PATH=$ION_CONFIG/testnet-core-config.json\nexport ION_CORE_VERSIONING_CONFIG_FILE_PATH=$ION_CONFIG/testnet-core-versioning.json" >> $SHELL_CONFIG; source $SHELL_CONFIG
        ```

Having defined the `ION_CONFIG` environment variable (above), use it to create the folder itself:
```console
$ mkdir $ION_CONFIG
```

Next, copy the template ION configuration files to your `ION_CONFIG` directory:

=== "Mainnet"
    ```console
    $ cp $ION_REPO/config/mainnet-bitcoin-config.json $ION_REPO/config/mainnet-bitcoin-versioning.json $ION_REPO/config/mainnet-core-config.json $ION_REPO/config/mainnet-core-versioning.json $ION_CONFIG
    ```
=== "Testnet"
    ```console
    $ cp $ION_REPO/config/testnet-bitcoin-config.json $ION_REPO/config/testnet-bitcoin-versioning.json $ION_REPO/config/testnet-core-config.json $ION_REPO/config/testnet-core-versioning.json $ION_CONFIG
    ```

and set appropriate user permissions:
```console
$ chmod 640 $ION_BITCOIN_CONFIG_FILE_PATH $ION_BITCOIN_VERSIONING_CONFIG_FILE_PATH $ION_CORE_CONFIG_FILE_PATH $ION_CORE_VERSIONING_CONFIG_FILE_PATH
```

Having made copies of the template configuration files, we now edit some of their parameters to match our Bitcoin Core configuration.

=== "Mainnet"

    Set the `bitcoinDataDirectory` parameter (skip this step if your `BITCOIN_DATA` directory is on a network drive):

    === "Linux"
        ```console
        $ sed -i 's|"bitcoinDataDirectory": ".*"|"bitcoinDataDirectory": "'$BITCOIN_DATA'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```
    === "macOS"
        ```console
        $ sed -i '' 's|"bitcoinDataDirectory": ".*"|"bitcoinDataDirectory": "'$BITCOIN_DATA'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```

=== "Testnet"

    Set the `bitcoinDataDirectory` parameter (skip this step if your `BITCOIN_DATA` directory is on a network drive):

    === "Linux"
        ```console
        $ sed -i 's|"bitcoinDataDirectory": ".*"|"bitcoinDataDirectory": "'$BITCOIN_DATA'/testnet3"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```
    === "macOS"
        ```console
        $ sed -i '' 's|"bitcoinDataDirectory": ".*"|"bitcoinDataDirectory": "'$BITCOIN_DATA'/testnet3"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```

Next we shall set the `bitcoinRpcUsername` and `bitcoinRpcPassword` parameters. These must match the username and password chosen in the [Bitcoin CLI](#bitcoin-cli) section above.

We chose `admin` for the RPC username. The following command sets this same value inside the ION config file:

=== "Linux"
    ```console
    $ sed -i 's|"bitcoinRpcUsername": ".*"|"bitcoinRpcUsername": "admin"|g' $ION_BITCOIN_CONFIG_FILE_PATH
    ```
=== "macOS"
    ```console
    $ sed -i '' 's|"bitcoinRpcUsername": ".*"|"bitcoinRpcUsername": "admin"|g' $ION_BITCOIN_CONFIG_FILE_PATH
    ```

For the RPC password, copy and paste the following command into the Terminal and then change `<password>` to the **same password** you chose when setting up the [Bitcoin CLI](#bitcoin-cli):
```console
$ RPC_PASSWORD="<password>"
```

Then run this command to update the `bitcoinRpcPassword` parameter in the ION config file:

=== "Linux"
    ```console
    $ sed -i 's|"bitcoinRpcPassword": ".*"|"bitcoinRpcPassword": "'$RPC_PASSWORD'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
    ```
=== "macOS"
    ```console
    $ sed -i '' 's|"bitcoinRpcPassword": ".*"|"bitcoinRpcPassword": "'$RPC_PASSWORD'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
    ```

The final configuration step is to set the `bitcoinWalletOrImportString` parameter.

=== "Mainnet"

    This must be a mainnet-compatible private key in wallet import format (WIF).

    If you do **not** intend to use Trustchain to write your own DID operations, you can use [this tool](https://learnmeabitcoin.com/technical/wif) to randomly generate a WIF string without any bitcoin.

    If you are intending to use Trustchain to write your own DID operations, this parameter must be populated with your private key in the appropriate format. To do this, first check that `sidetreeDefaultWallet` (that was created [earlier](#configure-bitcoin-core)) is loaded. You should see the following output when running this command:
    ```console
    $ bitcoin-cli listwallets
    [
      "sidetreeDefaultWallet"
    ]
    ```
    Next create a wallet address with this command:
    ```console
    $ bitcoin-cli getnewaddress
    bc1qr5f53xkgfehq3tr0rjg478kvxdjfkc5tatma3u
    ```
    This command will output a new address (similar to the example above, but a different string of characters).

    Now, to get the private key for this Bitcoin address, run the following command but with `<address>` replaced with the output from the previous step:
    ```console
    $ bitcoin-cli dumpprivkey <address>
    L1eokPoQRzBXEddxWAyejiR49FopMj5iKyEZNSMaQKMqcZWFVLR5
    ```
    Once again, the output will look similar to the above, but with different characters. This is the WIF string to be used in the following command.

    !!! warning "Never share your Bitcoin private keys"

        The output from the previous command is the Bitcoin private key corresponding to your wallet address. Anyone who has access to this private key can spend the bitcoins in that address, so you should be careful to keep it secret.

        In the following step we will copy the private key into an ION configuration file, to enable ION to execute the Bitcoin transactions necessary to create and update DIDs. The permissions on this configuration file have already been set (above) so that only the user and their group can read the file contents.

    Copy and paste this command into the Terminal and then change `<wif>` to your WIF string:
    ```console
    $ WIF="<wif>"
    ```

    Then run this command to update the `bitcoinWalletOrImportString` parameter in the ION config file:

    === "Linux"
        ```console
        $ sed -i 's|"bitcoinWalletOrImportString": ".*"|"bitcoinWalletOrImportString": "'$WIF'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```
    === "macOS"
        ```console
        $ sed -i '' 's|"bitcoinWalletOrImportString": ".*"|"bitcoinWalletOrImportString": "'$WIF'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```

=== "Testnet"

    On Testnet, a key will be automatically generated when ION runs for the first time which can be used for the `bitcoinWalletOrImportString` parameter, so you don't need to do anything in this step.

### Build ION

Change directory into the ION repository:
```console
$ cd $ION_REPO
```
Now install the ION dependencies:
```console
$ npm i
```
make sure Typescript is installed:
```console
$ npm install typescript
```
and then build the ION package:
```console
$ npm run build
```

!!! info "Note: Rebuild ION whenever a configuration file is modified"

    You must rerun the command `npm run build` if changes are made to the JSON configuration files in the `ION_CONFIG` folder.

### Test ION

Before running ION for the first time, **make sure that you have started IPFS, MongoDB and Bitcoin Core** (by following the instructions above or using the command summary in the [Running ION](#running-ion) section). Also make sure that Bitcoin Core is fully synchronised by running:
```console
$ bitcoin-cli -getinfo
```

You should see output similar to the following. Bitcoin Core is synchronised if the number of `Blocks` is equal to the number of `Headers`:

=== "Mainnet"
    ```sh
    Chain: main
    Blocks: 852429
    Headers: 852429
    Verification progress: 99.9997%
    Difficulty: 82047728459932.75

    Network: in 0, out 10, total 10
    Version: 240001
    Time offset (s): 0
    Proxies: n/a
    Min tx relay fee rate (BTC/kvB): 0.00001000

    Warnings: (none)
    ```

    In a new Terminal, start the ION Bitcoin microservice with:
    ```console
    $ (cd $ION_REPO && npm run bitcoin)
    ```

=== "Testnet"
    ```sh
    Chain: test
    Blocks: 2868427
    Headers: 2868427
    Verification progress: 99.9997%
    Difficulty: 205023102.4598488

    Network: in 0, out 10, total 10
    Version: 240001
    Time offset (s): 0
    Proxies: n/a
    Min tx relay fee rate (BTC/kvB): 0.00001000

    Warnings: (none)
    ```

    In a new Terminal, start the ION Bitcoin microservice with:
    ```console
    $ (cd $ION_REPO && npm run bitcoin)
    ```

    When running this command for the first time, expect the error:
    ```
    Non-base58 character
    Is bitcoinWalletImportString valid? Consider using <testnet> key generated below:
    ```
    followed by a base58 string. In this case, copy the base58 string and paste it into the following command in place of `<wif>`:
    ```console
    $ WIF="<wif>"
    ```

    Then run this command to update the `bitcoinWalletOrImportString` parameter in the ION config file:

    === "Linux"
        ```console
        $ sed -i 's|"bitcoinWalletOrImportString": ".*"|"bitcoinWalletOrImportString": "'$WIF'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```
    === "macOS"
        ```console
        $ sed -i '' 's|"bitcoinWalletOrImportString": ".*"|"bitcoinWalletOrImportString": "'$WIF'"|g' $ION_BITCOIN_CONFIG_FILE_PATH
        ```

    Now repeat the attempt to start the ION Bitcoin microservice:
    ```console
    $ (cd $ION_REPO && npm run bitcoin)
    ```

!!! warning "ION synchronisation"

    When the ION Bitcoin microservice starts for the first time, it will begin scanning the Bitcoin blockchain for ION DID operations, by making calls to the Bitcoin Core RPC interface.

    **The synchronisation process may take >1 hour to complete.** Wait until it has finished before running the ION Core microservice in the following step.

??? tip "Troubleshooting Tip"

    - If you see an `ECONNREFUSED` error message when starting the ION Bitcoin microservice, this indicates that it has failed to communicate with Bitcoin Core. In this case, make sure that Bitcoin Core started successfully.

In another new Terminal, start the ION Core microservice with:
```console
$ (cd $ION_REPO && npm run core)
```

??? tip "Troubleshooting Tip"

    If you see an `ECONNREFUSED` error message when starting the ION Core microservice, this indicates that it has failed to communicate with the ION Bitcoin microservice. In this case, make sure that the ION Bitcoin microservice started successfully and is fully synchronised.

Finally, to confirm that ION is working properly, open yet another new Terminal and resolve a sample DID:

=== "Mainnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w | json_pp
    ```

=== "Testnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:test:EiClWZ1MnE8PHjH6y4e4nCKgtKnI1DK1foZiP61I86b6pw | json_pp
    ```

If ION is working properly, the command above will return a JSON data structure containing the resolved DID document and document metadata for the sample DID.

Congratulations! Your ION installation is now complete.

## Running ION

The following commands must be run each time you start your ION node, e.g. after restarting your computer. Some of them will keep control of the Terminal, so you will need to open a new Terminal window to continue.

!!! tip "Tip: Use tmux"

    A convenient way to start all of the following processes is to use [tmux](https://github.com/tmux/tmux/wiki) (the terminal multiplexer). Once installed, open a tmux session with the command:
    ```console
    $ tmux new -s ion
    ```
    and hit ++ctrl+b++ followed by ++c++ each time you need to open a new window.

    When all of the processes are started, detach the tmux session with ++ctrl+b++ followed by ++d++. To reattach the session later, run:
    ```console
    $ tmux a -t ion
    ```

Follow these steps to start your ION node:

**1. Start IPFS**

```console
$ ipfs daemon
```

??? info "Other IPFS commands"

    Stop:
    ```console
    $ ipfs shutdown
    ```

**2. Start MongoDB**

=== "Linux"

    ```console
    $ sudo systemctl start mongod
    ```

    ??? info "Other MongoDB commands"

        Stop MongoDB:
        ```
        sudo systemctl stop mongod
        ```
        Restart:
        ```
        sudo systemctl restart mongod
        ```
        Check status:
        ```
        sudo systemctl status mongod
        ```

=== "macOS"

    ```console
    $ brew services start mongodb-community
    ```

    ??? info "Other MongoDB commands"

        Stop:
        ```console
        $ brew services stop mongodb-community
        ```
        Restart:
        ```console
        $ brew services restart mongodb-community
        ```


**3. Start Bitcoin Core**
```console
$ bitcoind
```

??? info "Other Bitcoin Core commands"

    === "Mainnet"

        Check status:
        ```console
        $ bitcoin-cli -getinfo
        ```

        Stop Bitcoin Core:
        ```console
        $ bitcoin-cli stop
        ```

        Print the log file to the Terminal (hit ++ctrl+c++ to exit):
        ```console
        $ tail -f $BITCOIN_DATA/debug.log
        ```

        Reindex the chain (may take >1 hour):
        ```console
        $ bitcoind -reindex-chainstate
        ```

        Check which port bitcoind is listening on (should be 8333 for Mainnet):
        ```console
        $ netstat -tulpn | grep 'bitcoind'
        ```

    === "Testnet"

        Check status:
        ```console
        $ bitcoin-cli -getinfo
        ```

        Stop Bitcoin Core:
        ```console
        $ bitcoin-cli stop
        ```

        Print the log file to the Terminal (hit ++ctrl+c++ to exit):
        ```console
        $ tail -f $BITCOIN_DATA/testnet3/debug.log
        ```

        Reindex the chain (may take >1 hour):
        ```console
        $ bitcoind -reindex-chainstate
        ```

        Check which port bitcoind is listening on (should be 18333 for Testnet):
        ```console
        $ netstat -tulpn | grep 'bitcoind'
        ```

**4. Start the ION bitcoin service.**
```console
$ (cd $ION_REPO && npm run bitcoin)
```

**5. Start the ION core service.**
```console
$ (cd $ION_REPO && npm run core)
```

**6. Test ION.** To confirm that ION is working properly, resolve a sample DID:

=== "Mainnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w | json_pp
    ```

=== "Testnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:test:EiClWZ1MnE8PHjH6y4e4nCKgtKnI1DK1foZiP61I86b6pw | json_pp
    ```

This command should print the contents of the resolved DID document and document metadata to the Terminal. If it does not, see the Troubleshoot tips [above](#test-ion).

## Funding your Bitcoin wallet

ION can be used to resolve existing DIDs and to publish new ones. New DIDs are published by writing the DID document content to IPFS and inserting an identifier for that content inside a Bitcoin transaction. This has the effect of timestamping the DID document and also making it easily discoverable (by scanning the Bitcoin blockchain).

Every Bitcoin transaction must include a processing fee, and therefore some funds must be available in your ION Bitcoin wallet before it can be used to publish any new DIDs. No funds are needed to resolve existing DIDs.

First check that `sidetreeDefaultWallet`, that was created [earlier](#configure-bitcoin-core), is loaded. You should see the following output when running this command:
```console
$ bitcoin-cli listwallets
[
  "sidetreeDefaultWallet"
]
```
Then use this command to list the receiving addresses for this wallet (with their balances):
```console
$ bitcoin-cli -rpcwallet="sidetreeDefaultWallet" listreceivedbyaddress 1 true
```

To fund your wallet, send Bitcoins to the **first** receive address in this list.

=== "Mainnet"

    !!! tip "Purchase BTC on a Bitcoin exchange"

        If you do not already own any bitcoins, they can be purchased on a [Bitcoin exchange](https://bitcoin.org/en/exchanges). Make sure that you acquire genuine bitcoins, which are identified by the ticker symbol `BTC`. When withdrawing your coins from the exchange, enter the receive address obtained in the preceding step to send them to your ION wallet.

    After sending bitcoins to your wallet, you will need to wait for the transaction to be confirmed by the Bitcoin network. This should take around 10 minutes on average, but may take longer depending on the size of the transaction fee paid. To check the status of your transaction, paste the transaction ID into a Bitcoin blockchain explorer such as [blockstream.info](https://blockstream.info/).


=== "Testnet"

    !!! tip "Request tBTC from a Testnet faucet"

        Testnet bitcoins are identified by the ticker symbol tBTC, to distinguish them from the Mainnet bitcoins which have the symbol BTC.

        Since coins on the Bitcoin Testnet have no monetary value they can be obtained free of charge from a "faucet", which is an automated service that will dispense a small quantity of tBTC on request.

        Visit a Bitcoin Testnet faucet, such as [coinfaucet.eu](https://coinfaucet.eu/en/btc-testnet/), and enter the recieve address obtained in the preceding step to send them to your ION wallet.

    After sending bitcoins to your wallet, you will need to wait for the transaction to be confirmed by the Bitcoin network. To check the status of your transaction, paste the transaction ID into a Bitcoin Testnet explorer such as [blockstream.info](https://blockstream.info/testnet/).

When the transaction is confirmed, check your wallet balance with:
```console
$ bitcoin-cli getbalances
```
The output should look something like this, with a non-zero balance for the `watchonly` wallet:
```json
{
  "mine": {
    "trusted": 0.00000000,
    "untrusted_pending": 0.00000000,
    "immature": 0.00000000
  },
  "watchonly": {
    "trusted": 0.00017612,
    "untrusted_pending": 0.00000000,
    "immature": 0.00000000
  }
}
```


## SSH config

When running a remote ION node, it can be convenient to open an SSH connection (with port forwarding) from your local machine. This produces a setup that is indistinguishable from running ION locally.

!!! warning "Allow incoming connections on the remote machine"

    The remote machine must be configured to accept incoming connections on all of the ports listed below. If you are using a Virtual Machine from a cloud provider, this can be done from the Network Settings page in the management portal.

We recommend adding the following lines to your SSH configuration file at `~/.ssh/config`:

=== "Mainnet"

    ```bash
    Host ion
        HostName <IP_ADDRESS>
        User <USERNAME>
        IdentityFile ~/.ssh/<KEY_FILE>
        LocalForward 3000 localhost:3000
        LocalForward 5001 localhost:5001
        LocalForward 8332 localhost:8332
        LocalForward 27017 localhost:27017
    ```

=== "Testnet"

    ```bash
    Host ion
        HostName <IP_ADDRESS>
        User <USERNAME>
        IdentityFile ~/.ssh/<KEY_FILE>
        LocalForward 3000 localhost:3000
        LocalForward 5001 localhost:5001
        LocalForward 18332 localhost:18332
        LocalForward 27017 localhost:27017
    ```

where `<IP_ADDRESS>` is the public IP address of the remote machine, `<USERNAME>` is the login username, and `<KEY_FILE>` is the name of the SSH key file used for key pair authentication.

The port forwarding rules in the above configuration assume that the default ports are used for the following processes. These ports are shown in the following table. If you wish, you can change any of these ports by editing the ION configuration files as described [earlier](#configure-ion).

=== "Mainnet"

    | Port        | Process           |
    | ----------- | ----------------- |
    | 3000        | ION               |
    | 5001        | IPFS              |
    | 8332        | Bitcoin           |
    | 27017       | MongoDB           |

=== "Testnet"

    | Port        | Process           |
    | ----------- | ----------------- |
    | 3000        | ION               |
    | 5001        | IPFS              |
    | 18332       | Bitcoin           |
    | 27017       | MongoDB           |

With this configuration in place, connect to the remote machine with the following command:
```console
$ ssh ion
```

As long as this connection is active, data sent to the ports specified in the SSH configuration (above) will be relayed to the same ports on the remote machine, producing a setup equivalent to running ION and its related processes locally.

## ION using Docker

!!! warning "ION using Docker is read-only"

    The simplest way to run ION is using Docker, and it can be a useful way to experiment with the system before performing a full installation. However, **this method provides a read-only ION node**. This means that it provides access to existing DIDs, but cannot be used to create and publish new ones.


These instructions are based on the [guide](https://github.com/decentralized-identity/ion/tree/master/docker) available on the ION GitHub repository.

**Step 1: Install Docker**

=== "Linux"

    Install Docker:
    ```
    sudo apt-get update
    sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

    curl -fsSL --max-time 10 --retry 3 --retry-delay 3 --retry-max-time 60 https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

    sudo apt-get install -y docker-ce
    sudo systemctl enable docker
    ```

    Install Docker Compose:
    ```
    sudo curl -L --max-time 60 --retry 3 --retry-delay 3 --retry-max-time 100 "https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    ```

=== "macOS"

    Install [Docker Desktop](https://www.docker.com/products/docker-desktop/).

**Step 2: Run the ION Docker container**

To obtain the required `docker-compose.*` files, clone the ION repository and enter the `docker` directory:
```
git clone https://github.com/decentralized-identity/ion.git
cd ion/docker
```

Now run the ION container. This command depends on whether you wish to run a Mainnet or a Testnet ION node.

=== "Mainnet"

    ```
    docker-compose up -d
    ```

=== "Testnet"

    ```
    docker-compose -f docker-compose.yml -f docker-compose.testnet-override.yml up -d
    ```

!!! warning "Bitcoin and ION synchronisation"

    When the ION container starts for the first time, it will begin synchronising with the Bitcoin network. This means downloading all of the blocks in the Bitcoin blockchain, which is a large data structure containing every Bitcoion transaction that has ever been processed. Once this has finished, ION itself will then scan the entire blockchain for ION DID operations, which is also a lengthy process.

    **In total, the synchronisation process may take several hours, or even days, to complete.** You will not be able to use Trustchain until your ION node has finished synchronising.


<!-- TODO: screenshots! -->

When the synchronisation process has finished, confirm that ION is working properly by running the following command to resolve a sample DID:

=== "Mainnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:EiClkZMDxPKqC9c-umQfTkR8vvZ9JPhl_xLDI9Nfk38w5w | json_pp
    ```

=== "Testnet"

    ```console
    $ curl http://localhost:3000/identifiers/did:ion:test:EiClWZ1MnE8PHjH6y4e4nCKgtKnI1DK1foZiP61I86b6pw | json_pp
    ```

If ION is working properly, the command above will return a JSON data structure containing the resolved DID document and document metadata for the sample DID.


&nbsp;