├── pool_setup
├── images
│ ├── private_ip.png
│ ├── reserved_ips.png
│ ├── server_list.png
│ ├── take_snapshot.png
│ ├── server_details.png
│ ├── deploy_new_server.png
│ ├── linked_instances.png
│ ├── new_firewall_group.png
│ └── restore_snapshot.png
├── send_simple_payment.md
├── topology_updater.md
├── scripts
│ └── getDelegators.sh
├── block_node_setup.md
└── base_setup.md
├── .github
└── FUNDING.yml
├── README.md
├── .gitignore
├── LICENSE
└── cardano-addresses.md
/pool_setup/images/private_ip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/private_ip.png
--------------------------------------------------------------------------------
/pool_setup/images/reserved_ips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/reserved_ips.png
--------------------------------------------------------------------------------
/pool_setup/images/server_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/server_list.png
--------------------------------------------------------------------------------
/pool_setup/images/take_snapshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/take_snapshot.png
--------------------------------------------------------------------------------
/pool_setup/images/server_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/server_details.png
--------------------------------------------------------------------------------
/pool_setup/images/deploy_new_server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/deploy_new_server.png
--------------------------------------------------------------------------------
/pool_setup/images/linked_instances.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/linked_instances.png
--------------------------------------------------------------------------------
/pool_setup/images/new_firewall_group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/new_firewall_group.png
--------------------------------------------------------------------------------
/pool_setup/images/restore_snapshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uniVocity/cardano-tutorials/HEAD/pool_setup/images/restore_snapshot.png
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | github: [jbax]
3 | patreon: # Replace with a single Patreon username
4 | open_collective: # Replace with a single Open Collective username
5 | ko_fi: # Replace with a single Ko-fi username
6 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
7 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
8 | liberapay: # Replace with a single Liberapay username
9 | issuehunt: # Replace with a single IssueHunt username
10 | otechie: # Replace with a single Otechie username
11 | custom: [paypal.me/jeronimobackes]
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The cardano tutorials.
2 |
3 | This repository contains tutorials and guides on how to use the APIs and SDKs
4 | created by IOG to allow easy integration with the cardano blockchain.
5 |
6 | I started this work due to the lack of readily available and easy to follow
7 | instructions to guide new developers. My purpose is to make the learning curve
8 | from using these tools less steep.
9 |
10 | All instructions are based on what I found out from what I could gather from
11 | the official documentation, trial and error, and by annoying the hell of most
12 | developers from IOG on telegram. If you find any incorrect assumption or
13 | instruction, please submit a pull request with amendments/clarification.
14 |
15 | Feel free to submit pull requests with your guides and tutorials too.
16 |
17 | ## Tutorials
18 |
19 | * [cardano-addresses](./cardano-addresses.md): create seed phrases, wallet keys
20 | payment addresses, etc.
21 |
22 | * [stake pool setup](./pool_setup/base_setup.md): how to create, secure and run your own stake pool.
23 |
24 | ## Support this project
25 |
26 | This is an open-source, not for profit initiative, aiming to help poor
27 | developers in need.
28 |
29 | If you want to help me somehow, consider delegating to the **SHOP** stake pool.
30 |
31 | You can also:
32 |
33 | * **Sponsor** me here on github.
34 |
35 | * **Donate**, via:
36 |
37 | * **Paypal** - just click [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JKH3JNHLL4Y42&source=url)
38 |
39 | * **ADA**: on `addr1qy77cfgccmcfe9h936qunl4u36hyrwryrmzj6duug9sm73tdd0sqyslnjxvce9syyw4ktnrh0n7ct60zrs29wnef3jqq202748`
40 |
41 | * **Bitcoin**: on `3BcmUPTPfLDuYWWSBxGKkChkq5WMzC94J6`
42 |
43 | Every little bit helps. Thank you for your support!
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### OSX template
2 | .DS_Store
3 | .AppleDouble
4 | .LSOverride
5 |
6 | # Icon must end with two \r
7 | Icon
8 |
9 | # Thumbnails
10 | ._*
11 |
12 | # Files that might appear in the root of a volume
13 | .DocumentRevisions-V100
14 | .fseventsd
15 | .Spotlight-V100
16 | .TemporaryItems
17 | .Trashes
18 | .VolumeIcon.icns
19 |
20 | # Directories potentially created on remote AFP share
21 | .AppleDB
22 | .AppleDesktop
23 | Network Trash Folder
24 | Temporary Items
25 | .apdisk
26 | ### Java template
27 | *.class
28 |
29 | # Mobile Tools for Java (J2ME)
30 | .mtj.tmp/
31 |
32 | # Package Files #
33 | *.jar
34 | *.war
35 | *.ear
36 |
37 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
38 | hs_err_pid*
39 | ### Eclipse template
40 |
41 | .metadata
42 | bin/
43 | tmp/
44 | *.tmp
45 | *.bak
46 | *.swp
47 | *~.nib
48 | local.properties
49 | .settings/
50 | .loadpath
51 | .recommenders
52 |
53 | # Eclipse Core
54 | .project
55 |
56 | # External tool builders
57 | .externalToolBuilders/
58 |
59 | # Locally stored "Eclipse launch configurations"
60 | *.launch
61 |
62 | # PyDev specific (Python IDE for Eclipse)
63 | *.pydevproject
64 |
65 | # CDT-specific (C/C++ Development Tooling)
66 | .cproject
67 |
68 | # JDT-specific (Eclipse Java Development Tools)
69 | .classpath
70 |
71 | # Java annotation processor (APT)
72 | .factorypath
73 |
74 | # PDT-specific (PHP Development Tools)
75 | .buildpath
76 |
77 | # sbteclipse plugin
78 | .target
79 |
80 | # Tern plugin
81 | .tern-project
82 |
83 | # TeXlipse plugin
84 | .texlipse
85 |
86 | # STS (Spring Tool Suite)
87 | .springBeans
88 |
89 | # Code Recommenders
90 | .recommenders/
91 | ### JetBrains template
92 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
93 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
94 |
95 | # User-specific stuff:
96 | .idea/workspace.xml
97 | .idea/tasks.xml
98 | .idea/dictionaries
99 | .idea/vcs.xml
100 | .idea/jsLibraryMappings.xml
101 |
102 | # Sensitive or high-churn files:
103 | .idea/dataSources.ids
104 | .idea/dataSources.xml
105 | .idea/dataSources.local.xml
106 | .idea/sqlDataSources.xml
107 | .idea/dynamic.xml
108 | .idea/uiDesigner.xml
109 |
110 | # Gradle:
111 | .idea/gradle.xml
112 | .idea/libraries
113 |
114 | # Mongo Explorer plugin:
115 | .idea/mongoSettings.xml
116 |
117 | ## File-based project format:
118 | *.iws
119 | *.ipr
120 | *.iml
121 |
122 | ## Plugin-specific files:
123 |
124 | # IntelliJ
125 | /out/
126 |
127 | # mpeltonen/sbt-idea plugin
128 | .idea_modules/
129 |
130 | # JIRA plugin
131 | atlassian-ide-plugin.xml
132 |
133 | # Crashlytics plugin (for Android Studio and IntelliJ)
134 | com_crashlytics_export_strings.xml
135 | crashlytics.properties
136 | crashlytics-build.properties
137 | fabric.properties
138 | # Created by .ignore support plugin (hsz.mobi)
139 |
140 | /target
141 | /log/
142 | /db/
143 | /.idea/
--------------------------------------------------------------------------------
/pool_setup/send_simple_payment.md:
--------------------------------------------------------------------------------
1 | ```
2 | cd ~/pool-keys/
3 |
4 | #paste wallet address in this file:
5 | nano target-wallet.addr
6 |
7 | # AS ALWAYS, MAKE A TEST TRANSACTION FIRST BEFORE MOVING A LOT OF CASH
8 |
9 | # Get protocol params:
10 | cardano-cli shelley query protocol-parameters \
11 | --mainnet \
12 | --out-file /tmp/params.json
13 |
14 | #Find your balance and UTXOs:
15 | cardano-cli shelley query utxo \
16 | --address $(cat payment.addr) \
17 | --mainnet \
18 | > /tmp/fullUtxo.out
19 |
20 | tail -n +3 /tmp/fullUtxo.out | sort -k3 -nr > /tmp/balance.out
21 |
22 | # Here is your balance
23 | cat /tmp/balance.out
24 |
25 | tx_in=""
26 | total_balance=0
27 | while read -r utxo; do
28 | in_addr=$(awk '{ print $1 }' <<< "${utxo}")
29 | idx=$(awk '{ print $2 }' <<< "${utxo}")
30 | utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
31 | total_balance=$((${total_balance}+${utxo_balance}))
32 | echo TxHash: ${in_addr}#${idx}
33 | echo ADA: ${utxo_balance}
34 | tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
35 | done < /tmp/balance.out
36 | txcnt=$(cat /tmp/balance.out | wc -l)
37 | echo Total ADA balance: ${total_balance}
38 | echo Number of UTXOs: ${txcnt}
39 |
40 | # deposit 10000000 lovelace (10 ADA)
41 | amount=10000000
42 |
43 | #Draft the transaction
44 | cardano-cli shelley transaction build-raw \
45 | ${tx_in} \
46 | --tx-out $(cat target-wallet.addr)+0 \
47 | --tx-out $(cat payment.addr)+0 \
48 | --ttl 0 \
49 | --fee 0 \
50 | --out-file /tmp/tx.draft
51 |
52 | #Calculate the current minimum fee:
53 | fee=$(cardano-cli shelley transaction calculate-min-fee \
54 | --tx-body-file /tmp/tx.draft \
55 | --tx-in-count 1 \
56 | --tx-out-count 2 \
57 | --witness-count 1 \
58 | --byron-witness-count 0 \
59 | --mainnet \
60 | --protocol-params-file /tmp/params.json | awk '{ print $1 }')
61 | echo fee: $fee
62 |
63 |
64 | #Calculate your change output.
65 | txOut=$((${total_balance}-${amount}-${fee}))
66 | echo Change Output: ${txOut}
67 |
68 | # Find the tip of the blockchain:
69 | currentSlot=$(cardano-cli shelley query tip --mainnet | jq -r '.slotNo')
70 | echo Current Slot: $currentSlot
71 |
72 | # Build the transaction
73 | cardano-cli shelley transaction build-raw \
74 | ${tx_in} \
75 | --tx-out $(cat target-wallet.addr)+${amount} \
76 | --tx-out $(cat payment.addr)+${txOut} \
77 | --ttl $((${currentSlot} + 10000)) \
78 | --fee ${fee} \
79 | --out-file /tmp/tx.raw
80 |
81 | #Sign the transaction
82 | cardano-cli shelley transaction sign \
83 | --tx-body-file /tmp/tx.raw \
84 | --signing-key-file payment.skey \
85 | --mainnet \
86 | --out-file /tmp/tx.signed
87 |
88 | #Send the signed transaction.
89 | cardano-cli shelley transaction submit \
90 | --tx-file /tmp/tx.signed \
91 | --mainnet
92 |
93 |
94 | #Check balance of wallet that sent the amount
95 | cardano-cli shelley query utxo \
96 | --address $(cat payment.addr) \
97 | --mainnet
98 |
99 | #Check balance of target wallet
100 | cardano-cli shelley query utxo \
101 | --address $(cat target-wallet.addr) \
102 | --mainnet
103 |
104 | ```
105 |
--------------------------------------------------------------------------------
/pool_setup/topology_updater.md:
--------------------------------------------------------------------------------
1 | ## Using the topologyUpdater.sh
2 |
3 | Once again, save this file locally on your computer and from your favorite editor run a Search+Replace on it:
4 |
5 | ```
6 |
7 |
8 |
9 | # Here replace the IPs with either the private network IP of your block node and/or relays
10 |
11 |
12 | ```
13 |
14 | Do this for each relay node you want to run.
15 |
16 | Then log into your relay nodes.
17 | ```
18 | ssh -A @
19 | ```
20 |
21 | Create the script:
22 |
23 | ```
24 | cat > ~/topologyUpdater.sh << EOF
25 | #!/bin/bash
26 | # shellcheck disable=SC2086,SC2034
27 |
28 | USERNAME="\$(whoami)"
29 | CNODE_PORT=3001 # must match your relay node port as set in the startup command
30 | CNODE_HOSTNAME="" # must resolve to the public IP of the relay
31 | CNODE_BIN="\$/usr/local/bin/"
32 | CNODE_HOME=/home//cardano-node
33 | CNODE_LOG_DIR="\${CNODE_HOME}/logs/"
34 | GENESIS_JSON="/home//config/mainnet-shelley-genesis.json"
35 | NETWORKID=\$(jq -r .networkId \$GENESIS_JSON)
36 | CNODE_VALENCY=1 # optional for multi-IP hostnames
37 | NWMAGIC=\$(jq -r .networkMagic < \$GENESIS_JSON)
38 | [[ "\${NETWORKID}" = "Mainnet" ]] && HASH_IDENTIFIER="--mainnet" || HASH_IDENTIFIER="--testnet-magic \${NWMAGIC}"
39 | [[ "\${NWMAGIC}" = "764824073" ]] && NETWORK_IDENTIFIER="--mainnet" || NETWORK_IDENTIFIER="--testnet-magic \${NWMAGIC}"
40 |
41 | export PATH="\${CNODE_BIN}:\${PATH}"
42 | export CARDANO_NODE_SOCKET_PATH="\${CNODE_HOME}/db/node.socket"
43 |
44 | blockNo=\$(cardano-cli shelley query tip --mainnet | jq -r .blockNo )
45 |
46 | # Note:
47 | # if you run your node in IPv4/IPv6 dual stack network configuration and want announced the
48 | # IPv4 address only please add the -4 parameter to the curl command below (curl -4 -s ...)
49 | if [ "\${CNODE_HOSTNAME}" != "CHANGE ME" ]; then
50 | T_HOSTNAME="&hostname=\${CNODE_HOSTNAME}"
51 | else
52 | T_HOSTNAME=''
53 | fi
54 |
55 | if [ ! -d \${CNODE_LOG_DIR} ]; then
56 | mkdir -p \${CNODE_LOG_DIR};
57 | fi
58 |
59 | curl -4 -s "https://api.clio.one/htopology/v1/?port=\${CNODE_PORT}&blockNo=\${blockNo}&valency=\${CNODE_VALENCY}&magic=\${NWMAGIC}\${T_HOSTNAME}" | tee -a \$CNODE_LOG_DIR/topologyUpdater_lastresult.json
60 | EOF
61 |
62 | ```
63 |
64 | Add permissions and run the updater script.
65 | ```
66 | chmod +x ~/topologyUpdater.sh
67 | ~/topologyUpdater.sh
68 | ```
69 |
70 |
71 | When the topologyUpdater.sh runs successfully, you will see
72 | ```
73 | { "resultcode": "201", "datetime":"2020-07-28 01:23:45", "clientIp": "1.2.3.4", "iptype": 4, "msg": "nice to meet you" }
74 | ```
75 |
76 | Add a crontab job to automatically run topologyUpdater.sh every hour on the 22nd minute. You can change the 22 value to your own preference:
77 |
78 | ```
79 | cat > /home//crontab-fragment.txt << EOF
80 | 22 * * * * . $HOME/.profile; /home//topologyUpdater.sh
81 | EOF
82 | crontab -l | cat - crontab-fragment.txt > crontab.txt && crontab crontab.txt
83 |
84 | # you might get a "no crontab for [user]". In this case run:
85 | crontab -e
86 |
87 | rm crontab-fragment.txt
88 |
89 | # Check if the crontab rule is active:
90 | crontab -l
91 |
92 | ```
93 |
94 |
95 | ## Update relay node topology files:
96 |
97 | After **four hours** since you execute the steps in the previous section:
98 |
99 | ```
100 | # Check if the topology updater ran OK with crontab:
101 | less ~/cardano-node/logs/topologyUpdater_lastresult.json
102 | ```
103 |
104 | When your relay node IP is properly registered, run this:
105 |
106 | RELAY1 (assuming block node is in the same private network than relay 1)
107 | ```
108 | cat > ~/relay-topology_pull.sh << EOF
109 | #!/bin/bash
110 | cp ~/config/mainnet-topology.json ~/config/old_mainnet-topology.json
111 | curl -4 -s -o ~/config/new-mainnet-topology.json "https://api.clio.one/htopology/v1/fetch/?max=20&customPeers=:3001:2|:3001:2|relays-new.cardano-mainnet.iohk.io:3001:2"
112 | EOF
113 | ```
114 |
115 | Add permissions and pull new topology files.
116 | ```
117 | chmod +x ~/relay-topology_pull.sh
118 | ~/relay-topology_pull.sh
119 |
120 | # Grab the suggested topology from here and update the current topology manually. I
121 | # suggest you to checking if you can connect to the IPs in this file.
122 | less ~/config/new-mainnet-topology.json
123 |
124 | #If you changed the topology (in ~/config/mainnet-topology.json), these modifications only
125 | take effect after restarting your stake pool.
126 | sudo systemctl restart cardano
127 | ```
128 |
--------------------------------------------------------------------------------
/pool_setup/scripts/getDelegators.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # All credit for this script goes to the awesome team behind CNTools
4 | # I merely extracted this logic from their scripts so operators who
5 | # didn't want to install the full library could still check their
6 | # delegation.
7 | # Adam - Crypto2099, Corp. - [BUFFY] [SPIKE]
8 | # @therealadamdean - Telegram
9 |
10 | # To call this script, save it on your system as something like
11 | # ~/getDelegators.sh and make sure to make it executable via
12 | # chmod 750 getDelegators.sh
13 | # then call the script like so: ./getDelegators.sh
14 |
15 |
16 | # Change the following lines to match the configuration on your
17 | # local system.
18 | CCLI=/home/jbax/.local/bin/cardano-cli
19 | CNODE_HOME=/home/jbax/cardano-node
20 | CONFIG=/home/jbax/config/mainnet-config.json
21 | GENESIS_JSON=/home/jbax/config/mainnet-shelley-genesis.json
22 | BYRON_GENESIS_JSON=/home/jbax/config/mainnet-byron-genesis.json
23 | TMP_FOLDER=/tmp
24 |
25 | PROTOCOL=$(jq -r .Protocol "$CONFIG")
26 | [[ "${PROTOCOL}" = "Cardano" ]] && PROTOCOL_IDENTIFIER="--cardano-mode" || PROTOCOL_IDENTIFIER="--shelley-mode"
27 | NETWORKID=$(jq -r .networkId $GENESIS_JSON)
28 | MAGIC=$(jq -r .protocolMagicId < $GENESIS_JSON)
29 | NWMAGIC=$(jq -r .networkMagic < $GENESIS_JSON)
30 | [[ "${NETWORKID}" = "Mainnet" ]] && HASH_IDENTIFIER="--mainnet" || HASH_IDENTIFIER="--testnet-magic ${NWMAGIC}"
31 | [[ "${NWMAGIC}" = "764824073" ]] && NETWORK_IDENTIFIER="--mainnet" || NETWORK_IDENTIFIER="--testnet-magic ${NWMAGIC}"
32 |
33 | pool_id=$1
34 |
35 | function removeEmptyLines() {
36 | local -r content="${1}"
37 | echo -e "${content}" | sed '/^\s*$/d'
38 | }
39 |
40 | function repeatString() {
41 | local -r string="${1}"
42 | local -r numberToRepeat="${2}"
43 | if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]; then
44 | local -r result="$(printf "%${numberToRepeat}s")"
45 | echo -e "${result// /${string}}"
46 | fi
47 | }
48 |
49 | function isEmptyString() {
50 | local -r string="${1}"
51 | if [[ "$(trimString "${string}")" = '' ]]; then
52 | echo 'true' && return 0
53 | fi
54 | echo 'false' && return 1
55 | }
56 |
57 | function trimString() {
58 | local -r string="${1}"
59 | sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,'
60 | }
61 |
62 | say() {
63 | if [[ -z $2 || $2 = "log" || $2 -le ${VERBOSITY} ]]; then
64 | echo -e "$1"
65 | fi
66 | # if [[ $2 = "log" || $3 = "log" ]]; then
67 | # log "$1"
68 | # fi
69 | }
70 |
71 | formatLovelace() {
72 | re_int_nbr='^[0-9]+$'
73 | if [[ $1 =~ ${re_int_nbr} ]]; then
74 | printf "%'.6f" ${1}e-6
75 | else
76 | say "${RED}ERROR${NC}: must be a valid integer number"
77 | return 1
78 | fi
79 | }
80 |
81 | function printTable() {
82 | local -r delimiter="${1}"
83 | local -r data="$(removeEmptyLines "${2}")"
84 | if [[ "${delimiter}" != '' && "$(isEmptyString "${data}")" = 'false' ]]; then
85 | local -r numberOfLines="$(wc -l <<< "${data}")"
86 | if [[ "${numberOfLines}" -gt '0' ]]; then
87 | local table=''
88 | local i=1
89 | for ((i = 1; i <= "${numberOfLines}"; i = i + 1)); do
90 | local line=''
91 | line="$(sed "${i}q;d" <<< "${data}")"
92 | local numberOfColumns='0'
93 | numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")"
94 | # Add Line Delimiter
95 | if [[ "${i}" -eq '1' ]]; then
96 | table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
97 | fi
98 | # Add Header Or Body
99 | table="${table}\n"
100 | local j=1
101 | for ((j = 1; j <= "${numberOfColumns}"; j = j + 1)); do
102 | table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")"
103 | done
104 | table="${table}#|\n"
105 | # Add Line Delimiter
106 | if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]]; then
107 | table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
108 | fi
109 | done
110 | if [[ "$(isEmptyString "${table}")" = 'false' ]]; then
111 | echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1'
112 | fi
113 | fi
114 | fi
115 | }
116 |
117 | touch "${TMP_FOLDER}"/ledger-state.json
118 |
119 | timeout -k 5 60 ${CCLI} shelley query ledger-state ${PROTOCOL_IDENTIFIER} ${NETWORK_IDENTIFIER} --out-file "${TMP_FOLDER}"/ledger-state.json
120 | say "\nLedger state dumped, parsing data..."
121 | non_myopic_delegators=$(jq -r -c ".esNonMyopic.snapNM._delegations | .[] | select(.[1] == \"${pool_id}\") | .[0][\"key hash\"]" "${TMP_FOLDER}"/ledger-state.json)
122 | snapshot_delegators=$(jq -r -c ".esSnapshots._pstakeSet._delegations | .[] | select(.[1] == \"${pool_id}\") | .[0][\"key hash\"]" "${TMP_FOLDER}"/ledger-state.json)
123 | lstate=$(jq -r -c ".esLState" "${TMP_FOLDER}"/ledger-state.json)
124 | lstate_dstate=$(jq -r -c "._delegationState._dstate" <<< "${lstate}")
125 | ledger_pool_state=$(jq -r -c '._delegationState._pstate._pParams."'"${pool_id}"'" // empty' <<< "${lstate}")
126 | lstate_rewards=$(jq -r -c "._rewards" <<< "${lstate_dstate}")
127 | lstate_utxo=$(jq -r -c "._utxoState._utxo" <<< "${lstate}")
128 | lstate_delegators=$(jq -r -c "._delegations | .[] | select(.[1] == \"${pool_id}\") | .[0][\"key hash\"]" <<< "${lstate_dstate}")
129 | delegators=$(echo "${non_myopic_delegators}" "${snapshot_delegators}" "${lstate_delegators}" | tr ' ' '\n' | sort -u)
130 | say "\n$(wc -w <<< "${delegators}") delegators found, gathering data for each:"
131 | pledge="$(jq -c -r '.pledge // 0' <<< "${ledger_pool_state}" | tr '\n' ' ')"
132 | owners="$(jq -c -r '.owners[] // empty' <<< "${ledger_pool_state}" | tr '\n' ' ')"
133 | owner_nbr=$(jq -r '(.owners | length) // 0' <<< "${ledger_pool_state}")
134 | delegators_array=()
135 | delegator_nbr=0
136 | total_stake=0
137 | total_pledged=0
138 | for key in ${delegators}; do
139 | stake=$(jq -r -c ".[] | select(.address | contains(\"${key}\")) | .amount" <<< "${lstate_utxo}" | awk 'BEGIN{total = 0} {total = total + $1} END{printf "%.0f", total}')
140 | rewards=$(jq -r -c ".[] | select(.[0][\"key hash\"] == \"${key}\") | .[1]" <<< "${lstate_rewards}")
141 | total_stake=$((total_stake + stake + reward))
142 | say "Delegator $((++delegator_nbr)) processed"
143 | if echo "${owners}" | grep -q "${key}"; then
144 | key="${key} (owner)"
145 | total_pledged=$((total_pledged + stake + reward))
146 | fi
147 | delegators_array+=( "hex_key" "${key}" "stake" "$(formatLovelace ${stake})" "rewards" "$(formatLovelace ${rewards})" )
148 | done
149 |
150 | # Construct delegator json array
151 | delegators_json=$({
152 | say '['
153 | printf '{"%s":"%s","%s":"%s","%s":"%s"},\n' "${delegators_array[@]}" | sed '$s/,$//'
154 | say ']'
155 | } | jq -c .)
156 |
157 | clear
158 | say " >> POOL >> DELEGATORS" "log"
159 | say "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
160 | say ""
161 | say "${BLUE}${delegator_nbr}${NC} wallet(s) delegated to ${GREEN}${pool_name}${NC} of which ${ORANGE}${owner_nbr}${NC} are owner(s)\n"
162 | say "Total Stake: $(formatLovelace ${total_stake}) ADA [ owners pledge: $(formatLovelace ${total_pledged}) | delegators: $(formatLovelace $((total_stake-total_pledged))) ]\n"
163 |
164 | if [[ ${total_pledged} -lt ${pledge} ]]; then
165 | say "${ORANGE}WARN${NC}: Owners pledge does not cover registered pledge of $(formatLovelace ${pledge}) ADA\n"
166 | fi
167 |
168 | printTable ';' "$(say 'Hex Key;Stake;Rewards' | cat - <(jq -r -c '.[] | "\(.hex_key);\(.stake);\(.rewards)"' <<< "${delegators_json}"))"
169 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/cardano-addresses.md:
--------------------------------------------------------------------------------
1 | # cardano-addresses
2 |
3 | The `cardano-addresses` utility is a command line tool for manipulating - guess
4 | what - addresses.
5 |
6 | You can find its source code in the following repository:
7 | https://github.com/input-output-hk/cardano-addresses,
8 | but most users would simply want the compiled binaries from the
9 | [release page](https://github.com/input-output-hk/cardano-addresses/releases)
10 |
11 | > **IMPORTANT** All of the steps described here apply to linux. You will have to
12 | > adapt the commands to make things work on Windows, but the sequence of steps
13 | > is the same.
14 |
15 | ## Installation
16 |
17 | Simply download the latest released file for your operating system for the
18 | [release page](https://github.com/input-output-hk/cardano-addresses/releases)
19 |
20 | Unzip the file and you should get a `cardano-address` binary.
21 |
22 | For the sake of simplicity, create a `dev/cardano` folder under your home
23 | directory, then move the binary into it:
24 |
25 | ```shell script
26 | mkdir ~/dev
27 | mkdir ~/dev/cardano
28 | mv ~/Downloads/cardano-address ~/dev/cardano
29 | ```
30 |
31 | Make it executable:
32 | ```shell script
33 | cd ~/dev/cardano
34 | chmod +x cardano-address
35 | ```
36 |
37 | See if it works
38 | ```shell script
39 | ./cardano-address --version
40 | ```
41 |
42 | This should output something like:
43 |
44 | ```
45 | 2.0.0 @ 9a64226fd749513ad0ed2e43e663f7132c92faa7
46 | ```
47 |
48 | Once you get there, you are ready to move on to learning how to use this tool.
49 |
50 | ## The command line interface
51 |
52 | IOG did a pretty good job with their command line tools: every command is
53 | organized as "sub-menus" and every time you type in a command you'll get the
54 | options available from the path you took.
55 |
56 | For example, from `cardano-address` you'll get the top "menu" options:
57 |
58 | ```shell script
59 | ./cardano-address
60 |
61 | >Available commands:
62 | version Show the software current version and build revision.
63 | recovery-phrase About recovery phrases
64 | key About public/private keys
65 | address About addresses
66 | ```
67 |
68 | Let's try out the `recovery-phrase` option:
69 |
70 | ```shell script
71 | ./cardano-address recovery-phrase
72 |
73 | >Available commands:
74 | generate Generate an English recovery phrase
75 | ```
76 |
77 | So it looks like we only have the `generate` option from there, let's see what
78 | it does:
79 | ```shell script
80 | ./cardano-address recovery-phrase generate
81 |
82 | >return arrest letter ready seat weird news you wave profit ritual grace cream lawsuit lend alone crisp foil joy gas caught vintage fresh modify
83 | ```
84 |
85 | Amazing, we got a random 24 words seed phrase for a wallet! That was super easy.
86 |
87 | ### Making it even easier
88 |
89 | You can enable bash to auto-complete the available commands for you with this
90 | command:
91 |
92 | ```shell script
93 | source <( ./cardano-address --bash-completion-script `which ./cardano-address`)
94 | ```
95 |
96 | Now, you can type `./cardano-address` followed by a tab key press to get the
97 | list of available commands and their arguments:
98 |
99 | ```shell script
100 | ./cardano-address recovery-phrase
101 |
102 | > generate -h --help
103 |
104 |
105 | ./cardano-address recovery-phrase generate
106 | ./cardano-address recovery-phrase generate -
107 |
108 | > -h --help --size
109 | ```
110 |
111 | Hm so it looks like the `generate` option allows for a `--size` parameter, let's
112 | try this out:
113 |
114 | ```
115 | ./cardano-address recovery-phrase generate --size 9
116 |
117 | >work swim render cart amazing valve funny tomato drink
118 | ```
119 |
120 | Et voila, a 9 word long seed phrase. Easy as pie.
121 |
122 | So now that you got the hang of it, let's dive deeper into it.
123 |
124 | ## Generating seed phrases
125 |
126 | To generate a seed phrase, simply run
127 | `./cardano-address recovery-phrase generate --size `
128 |
129 | Where the word count is one of 9, 12, 15, 18, 21 or 24 words, eg:
130 |
131 | ```shell script
132 | ./cardano-address recovery-phrase generate --size 12
133 | >zebra dinosaur galaxy valve kangaroo image omit mystery faith crime normal omit
134 |
135 | ./cardano-address recovery-phrase generate --size 21
136 | >sentence sail donate pioneer theory suspect mammal dove impulse second narrow animal concert bless design flag glow area blame noble forget
137 | ```
138 |
139 | ### Selecting the appropriate word count to restore the seed in your wallet of choice
140 |
141 | * *Shelley* addresses:
142 |
143 | * For daedalus, use `--size 24`.
144 |
145 | * For yoroi, use `--size 15`.
146 |
147 | * Byron legacy wallet
148 |
149 | * For daedalus, use `--size 12`.
150 |
151 | * For yoroi use `--size 15`.
152 |
153 | > **NOTE:** There is no support for the legacy Byron paper wallet format, which used 27 words.
154 |
155 | To make the upcoming instructions easier to follow and reproduce, store the
156 | seed phrase in a text file. We'll be using `--size 24` from now on.
157 |
158 | ```
159 | ./cardano-address recovery-phrase generate --size 24 > seed.txt
160 | cat seed.txt
161 | >intact engine crumble rotate umbrella flee wire talk creek employ rural state wreck pluck settle later okay foot assault general type mutual excuse valid
162 | ```
163 |
164 | With the command above your seed phrase will be *insecurely* stored in a plain
165 | text file named `seed.txt`. With this we can proceed to the next steps.
166 |
167 | ## Generating private keys
168 |
169 | The private key is the actual identifier of a wallet. You can derive a private
170 | key from a seed phrase with:
171 |
172 | `./cardano-address key from-recovery-phrase