Title | Status | Authors | Usefull links | Created | License | |
---|---|---|---|---|---|---|
SanchoNet - Geek Speak Made Fun |
In progress |
|
2025-02-28 |
CC-BY-4.0 |
- Initial Environment Configuration
- Sancho Wallet
- Stake Pools
- Delegated Representative
- Constitutional Committee Consortium
- Download and install Nix
- Install the Credential Manager tools
- Generate Cardano keys and Openssl certificate signing request
- The Head of security role and Certificate authority
- Mint the cold credential NFT
- Mint the hot credential NFT
- Authorize the Constitutional Committee hot credential
- Vote on governance actions as a consortium
- Build a governance action
- Usefull Commands
mkdir ~/sancho-src ~/keys ~/sancho-src/db ~/sancho-src/socket
cd sancho-src
2. Grab the binary files of the last node version release. (Yes, because on SanchoNet, we test the latest)
wget https://github.com/IntersectMBO/cardano-node/releases/download/10.2.1/cardano-node-10.2.1-linux.tar.gz
tar -xvf cardano-node-10.2.1-linux.tar.gz
rm cardano-node-10.2.1-linux.tar.gz
cd bin
sudo mv cardano-node /usr/local/bin
sudo mv cardano-cli /usr/local/bin
This should allow you to write cardano-cli commands and queries without having to specify the socket path and network ID options everytime.
echo 'export CARDANO_NODE_SOCKET_PATH=${HOME}/sancho-src/socket/node.socket' >> ~/.bashrc
echo 'export CARDANO_NODE_NETWORK_ID=4' >> ~/.bashrc
source ~/.bashrc
cardano-cli conway address key-gen \
--verification-key-file payment.vkey \
--signing-key-file payment.skey
cardano-cli conway stake-address key-gen \
--verification-key-file stake.vkey \
--signing-key-file stake.skey
cardano-cli conway address build \
--payment-verification-key-file payment.vkey \
--stake-verification-key-file stake.vkey \
--out-file payment.addr
cardano-cli conway stake-address build \
--stake-verification-key-file stake.vkey \
--out-file stake.addr
Martin Lang is a very well known Cardano Developer and a great Stake pool operator. So shout out to him for his great scripts.
The following command will get the cardano-signer
binary file, extract it and move it to /usr/local/bin
so you can use it globaly:
cd ~/sancho-src
wget https://github.com/gitmachtl/cardano-signer/releases/download/v1.23.0/cardano-signer-1.23.0_linux-x64.tar.gz
tar -xvf https://github.com/gitmachtl/cardano-signer/releases/download/v1.23.0/cardano-signer-1.23.0_linux-x64.tar.gz
sudo mv cardano-signer /usr/local/bin
cardano-signer keygen \
--path payment \
--json-extended \
--out-skey payment.xskey \
--out-vkey payment.vkey \
--out-file secret.json
While we don't prioritize security for SanchoNet, it's definitely worth protecting it for Mainnet use. (Yes that involve the use of a cold environment to generate these)
cat secret.json | jq .mnemonics
cardano-signer keygen \
--path stake \
--mnemonics "$(cat secret.json | jq -r .mnemonics)" \
--json-extended \
--out-skey stake.xskey \
--out-vkey stake.vkey | jq '.'
Make sure the mnemonic phrase in the output of this command matches the one you generated for your payment keys.
cardano-cli conway address build \
--payment-verification-key-file payment.vkey \
--stake-verification-key-file stake.vkey \
--out-file payment.addr
cardano-cli conway stake-address build \
--stake-verification-key-file stake.vkey \
--out-file stake.addr
1. Get the cardano-signer script from Martin Lang(ATADA)'s github repository. (If you don't already have it)
The following command will get the cardano-signer
binary file, extract it and move it to /usr/local/bin
so you can use it globaly:
cd ~/sancho-src
wget https://github.com/gitmachtl/cardano-signer/releases/download/v1.23.0/cardano-signer-1.23.0_linux-x64.tar.gz
tar -xvf https://github.com/gitmachtl/cardano-signer/releases/download/v1.23.0/cardano-signer-1.23.0_linux-x64.tar.gz
sudo mv cardano-signer /usr/local/bin
cardano-signer keygen \
--path payment \
--mnemonics "WRITE DOWN YOUR SEED PHRASE HERE" \
--json-extended \
--out-skey payment.xskey \
--out-vkey payment.vkey \
--out-file secret.json
3. Double-check the contents of your secret.json
file to ensure your payment keys have been properly restored.
cat secret.json | jq '.'
cardano-signer keygen \
--path stake \
--mnemonics "$(cat secret.json | jq -r .mnemonics)" \
--json-extended \
--out-skey stake.xskey \
--out-vkey stake.vkey | jq '.'
cardano-cli conway address build \
--payment-verification-key-file payment.vkey \
--stake-verification-key-file stake.vkey \
--out-file payment.addr
cardano-cli conway stake-address build \
--stake-verification-key-file stake.vkey \
--out-file stake.addr
cardano-cli conway query utxo \
--address $(cat payment.addr)
Now when you are finally ready to get some SanchoBucks to build on SanchoNet, you can ask our beloved King Big Joe the Don or Mike Hornan directly. It is highly recommended to join the ABLE pool Discord to hang out with us, or if you want to test or possibly break something. You might be surprised by how willing we are to test anything that could potentially damage the chain. Then Mike will send SanchoBucks directly to your wallet address. (Yes, he always answers his DMs.)
cardano-cli conway stake-address registration-certificate \
--stake-verification-key-file stake.vkey \
--key-reg-deposit-amt 2000000 \
--out-file registration.cert
cardano-cli conway transaction build \
--witness-override 2 \
--tx-in $(cardano-cli query utxo --address $(cat payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--certificate-file registration.cert \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway stake-address stake-delegation-certificate \
--stake-verification-key-file stake.vkey \
--stake-pool-id "THE ID OF THE STAKE POOL YOU ARE DELEGATING TO" \
--out-file delegation.cert
cardano-cli conway transaction build \
--witness-override 2 \
--tx-in $(cardano-cli query utxo --address $(cat payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--certificate-file delegation.cert \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
Note that when delegating the voting power of your wallet, you can opt to delegate to --always-abstain
or --always-no-confidence
. However, in the example below, we will delegate to a specific DRep ID.
cardano-cli conway stake-address vote-delegation-certificate \
--stake-verification-key-file stake.vkey \
--drep-key-hash "PUT YOUR DREP ID HERE" \
--out-file vote-deleg.cert
cardano-cli conway transaction build \
--witness-override 2 \
--tx-in $(cardano-cli query utxo --address $(cat payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--certificate-file vote-deleg.cert \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cd ~
echo '#!/bin/bash
# Configuration variables
TOPOLOGY_FILE="${HOME}/sancho-src/share/sanchonet/topology.json"
CONFIG_FILE="${HOME}/sancho-src/share/sanchonet/config.json"
DATABASE_PATH="${HOME}/sancho-src/db"
SOCKET_PATH="${HOME}/sancho-src/socket/node.socket"
KES_PATH="keys/kes.skey"
VRF_PATH="keys/vrf.skey"
OPCERT_PATH="keys/opcert.cert"
HOST_ADDR="0.0.0.0"
PORT="6002"
cardano-node run \
--topology "${TOPOLOGY_FILE}" \
--database-path "${DATABASE_PATH}" \
--socket-path "${SOCKET_PATH}" \
--host-addr "${HOST_ADDR}" \
--shelley-kes-key "${KES_PATH}" \
--shelley-vrf-key "${VRF_PATH}" \
--shelley-operational-certificate "${OPCERT_PATH}" \
--port "${PORT}" \
--config "${CONFIG_FILE}" ' >> startnode.sh
sudo chmod 755 startnode.sh
sudo cat > sancho-node.service << EOF
[Unit]
Description = Cardano Node Service
Wants = network-online.target
After = network-online.target
[Service]
User=$(whoami)
Type=simple
WorkingDirectory=/home/$(whoami)
ExecStart=/home/$(whoami)/startnode.sh
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=300
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-node
[Install]
WantedBy = multi-user.target
EOF
sudo mv sancho-node.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable sancho-node.service
cd ~/keys
cardano-cli conway node key-gen \
--cold-verification-key-file cold.vkey \
--cold-signing-key-file cold.skey \
--operational-certificate-issue-counter-file opcert.counter
sudo chmod 400 cold.skey cold.vkey
cardano-cli conway node key-gen-KES \
--verification-key-file kes.vkey \
--signing-key-file kes.skey
sudo chmod 400 kes.skey kes.vkey
cardano-cli conway node key-gen-VRF \
--verification-key-file vrf.vkey \
--signing-key-file vrf.skey
sudo chmod 400 vrf.skey vrf.vkey
cd ~/sancho-src/share/sanchonet
echo '{
"bootstrapPeers": [
{
"address": "sancho-testnet.able-pool.io",
"port": 6002
}
],
"localRoots": [
{
"accessPoints": [],
"advertise": false,
"trustable": false,
"valency": 1
}
],
"publicRoots": [
{
"accessPoints": [],
"advertise": false
}
],
"useLedgerAfterSlot": 33695977
}' > topology.json
kesPeriod=416
cardano-cli conway node issue-op-cert \
--kes-verification-key-file ~/keys/kes.vkey \
--cold-signing-key-file ~/keys/cold.skey \
--operational-certificate-issue-counter-file ~/keys/opcert.counter \
--kes-period ${kesPeriod} \
--out-file ~/keys/opcert.cert
sudo chmod 400 ~/keys/opcert.cert
sudo systemctl start sancho-node.service
Create your pool metadata following the example below, and upload it to a URL that you control (e.g., your GitHub repository).
{
"name": "Able Stake Pool",
"description": "Able Pool On Sancho Testnet",
"ticker": "ABLE",
"homepage": "https://able-pool.io"
}
cardano-cli hash anchor-data \
--url <THE URL LINK TO YOUR METADATA>
cardano-cli conway stake-pool registration-certificate \
--cold-verification-key-file cold.vkey \
--vrf-verification-key-file vrf.vkey \
--pool-pledge 9000000000 \
--pool-cost 340000000 \
--pool-margin 0.05 \
--pool-reward-account-verification-key-file stake.vkey \
--pool-owner-stake-verification-key-file stake.vkey \
--pool-relay-ipv4 <RELAY NODE PUBLIC IP> \
--pool-relay-port <RELAY NODE PORT> \
--metadata-url <POOL METADATA URL LINK> \
--metadata-hash <THE HASH OF YOUR METADATA FILE> \
--out-file pool-registration.cert
cardano-cli conway transaction build \
--witness-override 3 \
--tx-in $(cardano-cli query utxo --address $(cat payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--certificate-file pool-registration.cert \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file stake.skey \
--signing-key-file cold.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway stake-pool id \ \
--cold-verification-key-file cold.vkey \
--output-format bech32 \
--out-file pool.id
cardano-cli conway query pool-params \
--stake-pool-id $(cat pool.id)
cd ~
echo '#!/bin/bash
# Configuration variables
TOPOLOGY_FILE="${HOME}/sancho-src/share/sanchonet/topology.json"
CONFIG_FILE="${HOME}/sancho-src/share/sanchonet/config.json"
DATABASE_PATH="${HOME}/sancho-src/db"
SOCKET_PATH="${HOME}/sancho-src/socket/node.socket"
HOST_ADDR="0.0.0.0"
PORT="6002"
cardano-node run \
--topology "${TOPOLOGY_FILE}" \
--database-path "${DATABASE_PATH}" \
--socket-path "${SOCKET_PATH}" \
--host-addr "${HOST_ADDR}" \
--port "${PORT}" \
--config "${CONFIG_FILE}" ' >> startnode.sh
sudo chmod 755 startnode.sh
sudo cat > sancho-node.service << EOF
[Unit]
Description = Cardano Node Service
Wants = network-online.target
After = network-online.target
[Service]
User=$(whoami)
Type=simple
WorkingDirectory=/home/$(whoami)
ExecStart=/home/$(whoami)/startnode.sh
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=300
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-node
[Install]
WantedBy = multi-user.target
EOF
sudo mv sancho-node.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable sancho-node.service
cd ~/sancho-src/share/sanchonet
echo '{
"bootstrapPeers": [
{
"address": "sancho-testnet.able-pool.io",
"port": 6002
}
],
"localRoots": [
{
"accessPoints": [],
"advertise": false,
"trustable": false,
"valency": 1
}
],
"publicRoots": [
{
"accessPoints": [],
"advertise": false
}
],
"useLedgerAfterSlot": 33695977
}' > topology.json
sudo systemctl start sancho-node.service
cardano-cli conway governance drep key-gen \
--verification-key-file drep.vkey \
--signing-key-file drep.skey
Note that in the example below, we are generating a bech32-encoded ID. However, if you want to validate a vote in the future by querying the governance state of the ledger, your DRep ID will be displayed in hex format.
You can always obtain your hex-encoded ID by setting the output option to --output-hex
.
cardano-cli conway governance drep id \
--drep-verification-key-file drep.vkey \
--output-bech32 \
--out-file drep.id
cardano-cli conway governance drep registration-certificate \
--drep-verification-key-file drep.vkey \
--key-reg-deposit-amt $(cardano-cli conway query gov-state | jq -r .currentPParams.dRepDeposit) \
--out-file drep-register.cert
cardano-cli conway transaction build \
--witness-override 2 \
--tx-in $(cardano-cli query utxo --address $(cat payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--certificate-file drep-register.cert \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--signing-key-file drep.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance drep key-gen \
--verification-key-file drep.vkey \
--signing-key-file drep.skey
cardano-cli conway governance drep id \
--drep-verification-key-file drep.vkey \
--output-format hex \
--out-file name-drep.hash
Note that you can replace the atLeast
value with all
and remove the required
key-value pair if you want to require all signatures to vote on a governance action.
Name the file drep-script.json
and save it.
{
"type": "atLeast",
"required": 2,
"scripts": [
{
"type": "sig",
"keyHash": "PUT MEMBER'S VERIFICATION KEY HASH HERE"
},
{
"type": "sig",
"keyHash": "5ab00e8cd1142fcffc5f7a2c2e3549874afd89e26995d7686c2714d4"
},
{
"type": "sig",
"keyHash": "db5a8cbb0df0359c36541727229993b21371f834202733c9bbabc1fd"
}
]
}
cardano-cli hash script \
--script-file drep-script.json \
--out-file drep-script.hash
cardano-cli conway governance drep registration-certificate \
--drep-script-hash "$(cat drep-script.hash)" \
--key-reg-deposit-amt $(cardano-cli conway query gov-state | jq -r .currentPParams.dRepDeposit) \
--out-file drep-multisig-reg.cert
Note that the --witness-override
value should be the number of members plus one, which accounts for both the members' signatures and the payment wallet signature for the transaction.
cardano-cli conway transaction build \
--tx-in $(cardano-cli conway query utxo --address $(cat payment.addr) --output-json | jq -r 'keys[0]') \
--change-address $(cat payment.addr) \
--witness-override 4 \
--certificate-file drep-multisig-reg.cert \
--certificate-script-file drep-script.json \
--out-file tx.raw
Share the transaction body file tx.raw
with all members so they can sign it using the following command:
cardano-cli conway transaction witness \
--tx-body-file tx.raw \
--signing-key-file drep.skey \
--out-file name-drep.witness
cardano-cli conway transaction witness \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file payment.witness
cardano-cli conway transaction assemble \
--tx-body-file tx.raw \
--witness-file payment.witness \
--witness-file name1-drep.witness \
--witness-file name2-drep.witness \
--witness-file name3-drep.witness \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway query drep-state \
--drep-script-hash $(cat drep-script.hash)
sh <(curl -L https://nixos.org/nix/install) --no-daemon
sudo mkdir -p /etc/nix/
sudo cat > nix.conf << EOF
experimental-features = nix-command flakes fetch-closure
trusted-users = $(whoami)
substituters = https://cache.iog.io https://cache.nixos.org/
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
EOF
sudo mv nix.conf /etc/nix/
sudo reboot
mkdir ~/repos
cd ~/repos
git clone [email protected]:IntersectMBO/credential-manager.git
Ensure that your system or device has a minimum of 8GB of memory before entering the shell. The first time you access it, the shell may take some time to build.
cd credential-manager
nix upgrade-nix
nix develop
After entering the shell for the first time, you’ll need to compile the orchestrator-cli
. However, before doing so, make sure to update Haskell Cabal first:
cabal update
orchestrator-cli --help
Replace the NAME
variable with your name and the ROLE
variable with your assigned role.
NAME="changeMe"
ROLE="changeMe"
cardano-cli conway address key-gen \
--verification-key-file ${ROLE}.vkey \
--signing-key-file ${ROLE}.skey
cat ${ROLE}.skey | jq -r ".cborHex" | cut -c 5- | (echo -n "302e020100300506032b657004220420" && cat) | xxd -r -p | base64 \
| (echo "-----BEGIN PRIVATE KEY-----" && cat) | (cat && echo "-----END PRIVATE KEY-----") > ${ROLE}-private.pem
openssl req -new -key ${ROLE}-priv.pem -out ${NAME}-${ROLE}.csr
4. After completing all prompts, check the CSR file content before sending it to the Head of Security.
openssl req -in ${NAME}-${ROLE}.csr -text -noout
This section will guide you through creating your self-signed certificate (certificate authority) to help you assume the role of Head of Security.
cardano-cli address key-gen --signing-key-file ca.skey --verification-key-file ca.vkey
cat ca.skey | jq -r ".cborHex" | cut -c 5- | (echo -n "302e020100300506032b657004220420" && cat) | xxd -r -p | base64 | (echo "-----BEGIN PRIVATE KEY-----" && cat) | (cat && echo "-----END PRIVATE KEY-----") > ca-priv.pem
You will be asked to provide some basic attribute information for the CA.
openssl req -x509 -new -key ca-priv.pem -days 3650 -out ca.cert
openssl x509 -in ca.cert -text -noout
Assume that name
and role
refer to the respective name and role of the consortium member requesting the signature.
openssl req -in name-role.csr -text -noout
Of course, you need to provide the CA private key, the CA certificate, and the certificate signing request. The name and role on the signed certificate should correspond to those of the CSR file.
openssl x509 -days 365 -req -in name-role.csr -CA ca.cert -CAkey ca-priv.pem -out name-role.cert
Once the Head of Security has signed all the certificate signing requests, they will be sent to the orchestrator to mint the Cold Credential NFT.
The token name will be derived from the transaction input that you are going to use.
cardano-cli conway query utxo \
--address $(cat payment.addr)
cd ~/repos/credential-manager
nix develop
Please note that you may receive an error message if you have only one --membership-cert
or one --delegation-cert
, but this should not prevent you from proceeding.
orchestrator-cli init-cold \
--seed-input "YOUR WALLET UTXO WITH ITS INDEX" \
--testnet \
--ca-cert example-certificates/ca-cert.pem \
--membership-cert name1-membership.cert \
--membership-cert name2-membership.cert \
--membership-cert name3-membership.cert \
--delegation-cert name4-delegation.cert \
--delegation-cert name5-delegation.cert \
--delegation-cert name6-delegation.cert \
-o init-cold
cardano-cli conway transaction build \
--change-address $(cat payment.addr) \
--tx-in "THE UTXO YOU USED AS THE SEED INPUT" \
--tx-in-collateral "ANOTHER UTXO AS COLLATERAL" \
--tx-out "$(cat init-cold/nft.addr) + 9000000 + 1 $(cat init-cold/minting.plutus.hash).$(cat init-cold/nft-token-name)" \
--tx-out-inline-datum-file init-cold/nft.datum.json \
--mint "1 $(cat init-cold/minting.plutus.hash).$(cat init-cold/nft-token-name)" \
--mint-script-file init-cold/minting.plutus \
--mint-redeemer-file init-cold/mint.redeemer.json \
--out-file init-cold/body.json
cardano-cli conway transaction sign \
--signing-key-file payment.skey \
--tx-body-file init-cold/body.json \
--out-file init-cold/tx.json
cardano-cli conway transaction submit \
--tx-file init-cold/tx.json
cardano-cli conway query utxo \
--address $(cat init-cold/nft.addr) \
--output-json \
Now that your cold NFT is minted, you have to get elected through an Update Committee and/or threshold governance action. Here is how to get your script hash:
cat init-cold/credential.plutus.hash
You can mint the Hot NFT in advance, but you will only be able to authorize it after being officially elected as a Constitutional Committee Member.
The token name will be derived from the transaction input that you are going to use.
cardano-cli conway query utxo \
--address $(cat payment.addr)
cd ~/repos/credential-manager
nix develop
orchestrator-cli init-hot \
--seed-input "YOUR WALLET UTXO WITH ITS INDEX" \
--testnet \
--cold-nft-policy-id "$(cat init-cold/minting.plutus.hash)" \
--cold-nft-token-name "$(cat init-cold/nft-token-name)" \
--voting-cert name1-voter.cert \
--voting-cert name2-voter.cert \
--voting-cert name3-voter.cert \
-o init-hot
cardano-cli conway transaction build \
--change-address $(cat payment.addr) \
--tx-in "THE UTXO YOU USED AS THE SEED INPUT" \
--tx-in-collateral "ANOTHER UTXO AS COLLATERAL" \
--tx-out "$(cat init-hot/nft.addr) + 9000000 + 1 $(cat init-hot/minting.plutus.hash).$(cat init-hot/nft-token-name)" \
--tx-out-inline-datum-file init-hot/nft.datum.json \
--mint "1 $(cat init-hot/minting.plutus.hash).$(cat init-hot/nft-token-name)" \
--mint-script-file init-hot/minting.plutus \
--mint-redeemer-file init-hot/mint.redeemer.json \
--out-file init-hot/body.json
cardano-cli conway transaction sign \
--signing-key-file orchestrator.skey \
--tx-body-file init-hot/body.json \
--out-file init-hot/tx.json
cardano-cli conway transaction submit \
--tx-file init-hot/tx.json
cardano-cli conway query utxo \
--address $(cat init-hot/nft.addr) \
--output-json \
This may seem unusual at first, but you need to spend the Cold NFT UTXO to trigger the authorization of the Hot NFT. First, let's retrieve the Cold NFT UTXO that will be used as one of our transaction inputs.
cardano-cli conway query utxo \
--address $(cat init-cold/nft.addr) \
--output-json \
--out-file cold-nft.utxo
cd ~/repos/credential-manager
nix develop
orchestrator-cli authorize \
-u cold-nft.utxo \
--cold-credential-script-file init-cold/credential.plutus \
--hot-credential-script-file init-hot/credential.plutus \
--out-dir authorize
Fortunately, as the orchestrator, you don’t need to request them directly—you can retrieve them from their certificates using the orchestrator-cli
.
orchestrator-cli extract-pub-key-hash name1-delegation.cert
cardano-cli conway transaction build \
--tx-in "YOUR WALLET UTXO WITH ITS INDEX" \
--tx-in-collateral "ANOTHER UTXO AS COLLATERAL" \
--tx-in $(cardano-cli query utxo --address $(cat init-cold/nft.addr) --output-json | jq -r 'keys[0]') \
--tx-in-script-file init-cold/nft.plutus \
--tx-in-inline-datum-present \
--tx-in-redeemer-file authorize/redeemer.json \
--tx-out "$(cat authorize/value)" \
--tx-out-inline-datum-file authorize/datum.json \
--required-signer-hash "DELEGATER HASH 1" \
--required-signer-hash "DELEGATER HASH 1" \
--required-signer-hash "DELEGATER HASH 1" \
--certificate-file authorize/authorizeHot.cert \
--certificate-script-file init-cold/credential.plutus \
--certificate-redeemer-value {} \
--change-address $(cat payment.addr) \
--out-file authorize/body.json
cardano-cli conway debug transaction view \
--tx-body-file body.json
As the orchestrator, you can send the body.json
file to all those who hold the delegation role and will witness the transaction. They will have to sign using the following command:
cardano-cli conway transaction witness \
--tx-body-file body.json \
--signing-key-file name-delegation.skey \
--out-file name-delegation.witness
Note If you are the orchestrator, don't forget to sign it as well with your payment signing key.
cardano-cli conway transaction witness \
--tx-body-file body.json \
--signing-key-file payment.skey \
--out-file payment.witness
After receiving the signed witness files from everyone, you can proceed with assembling the final transaction.
cardano-cli conway transaction assemble \
--tx-body-file body.json \
--witness-file payment.witness \
--witness-file name1-delegation.witness \
--witness-file name2-delegation.witness \
--witness-file name3-delegation.witness \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
This is the command to get all active proposals on chain:
cardano-cli conway query gov-state \
| jq '.proposals[]'
Note Each proposal should follow this general structure, though specific details may vary depending on the type of governance action. Select the ones you want to vote on and get the
actionId
s.
{
"actionId": {
"govActionIx": 0,
"txId": "ecda75ee2a80c93f8cbde6ba208ac25d62e37e46389a2d3125168f2a1b0472be"
},
"committeeVotes": {
"scriptHash-b568833ad1bd9ea5a2aaa552c4d386cc2af14eade1c92573fdb7432c": "VoteNo"
},
"dRepVotes": {
"keyHash-ddb7316d7f4ff1d69084f2352e4613284381f17474fd133dfb4bb6ed": "VoteNo",
"keyHash-fd1e9fb13ef9a4bdd0c7e47aef0bfc065eca6c4ac9b613861ccf20cb": "VoteYes"
},
"expiresAfter": 652,
"proposalProcedure": {
"anchor": {
"dataHash": "1805dc601b3b6fe259c646a94edb14d52534c09a0ee51e5ac502fa823b6a510c",
"url": "https://raw.githubusercontent.com/Ryun1/metadata/main/cip100/ga.jsonld"
},
"deposit": 100000000000,
"govAction": {
"tag": "InfoAction"
},
"returnAddr": {
"credential": {
"keyHash": "b5f97564c79d450ab5bc2cda0794c31de0676e168798f0d50eda0e6f"
},
"network": "Testnet"
}
},
"proposedIn": 592,
"stakePoolVotes": {}
}
To trigger the vote, you need to spend the hot NFT UTXO, which is why we must query its UTXO first.
cardano-cli conway query utxo \
--address $(cat init-hot/nft.addr) \
--output-json \
--out-file hot-nft.utxo
cardano-cli hash anchor-data \
--url <THE URL LINK TO YOUR METADATA> \
--out-file anchor.hash
cd ~/repos/credential-manager
nix develop
orchestrator-cli vote \
--utxo-file hot-nft.utxo \
--hot-credential-script-file init-hot/credential.plutus \
--governance-action-tx-id "ecda75ee2a80c93f8cbde6ba208ac25d62e37e46389a2d3125168f2a1b0472be" \
--governance-action-index 0 \
--yes \
--metadata-url <THE URL LINK TO YOUR METADATA> \
--metadata-hash $(cat anchor.hash) \
--out-dir vote
orchestrator-cli extract-pub-key-hash name1-voter.cert
cardano-cli conway transaction build \
--tx-in "PAYMENT UTXO FROM THE ORCHESTRATOR WALLET" \
--tx-in-collateral "ANOTHER UTXO FOR THE COLLATERAL" \
--tx-in $(jq -r 'keys[0]' hot-nft.utxo) \
--tx-in-script-file init-hot/nft.plutus \
--tx-in-inline-datum-present \
--tx-in-redeemer-file vote/redeemer.json \
--tx-out "$(cat vote/value)" \
--tx-out-inline-datum-file vote/datum.json \
--required-signer-hash "VOTER HASH 1" \
--required-signer-hash "VOTER HASH 2" \
--required-signer-hash "VOTER HASH 3" \
--vote-file vote/vote \
--vote-script-file init-hot/credential.plutus \
--vote-redeemer-value {} \
--change-address $(cat payment.addr) \
--out-file vote/body.json
cardano-cli conway transaction witness \
--tx-body-file body.json \
--signing-key-file name-voter.skey \
--out-file name-voter.witness
After receiving the signed witness files from everyone, you can proceed with assembling the final transaction.
cardano-cli conway transaction assemble \
--tx-body-file body.json \
--witness-file payment.witness \
--witness-file name1-voter.witness \
--witness-file name2-voter.witness \
--witness-file name3-voter.witness \
--out-file vote-tx.signed
cardano-cli conway transaction submit \
--tx-file vote-tx.signed
cardano-cli conway query gov-state \
| jq '.proposals[]'
This section will cover governance actions, including building the action file, specifying and executing the guardrail script smart contract if needed, and constructing the transaction to submit it on-chain.
cardano-cli conway governance action create-no-confidence \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--prev-governance-action-tx-id <PREVIOUS UPDATE COMMITEE GOVERNANCE ACTION ID> \
--prev-governance-action-index <PREVIOUS UPDATE COMMITEE GOVERNANCE ACTION INDEX> \
--out-file no-confidence.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file no-confidence.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
The Update Committee governance actions enable you to add or remove any number of members and adjust their voting threshold. The example command below adds two new members, removes one existing member, and sets their voting threshold to 2/3, or 67%.
cardano-cli conway governance action update-committee \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--add-cc-cold-verification-key-hash 89181f26b47c3d3b6b127df163b15b74b45bba7c3b7a1d185c05c2de \
--epoch 100 \
--add-cc-cold-verification-key-hash ea8738081fca0726f4e781f5e55fda05f8745432a5f8a8d09eb0b34b \
--epoch 95 \
--remove-cc-cold-verification-key-hash 89181f26b47c3d3b6b127df163b15b74b45bba7c3b7a1d185c05c2de \
--threshold 2/3 \
--prev-governance-action-tx-id <PREVIOUS UPDATE COMMITEE GOVERNANCE ACTION ID> \
--prev-governance-action-index <PREVIOUS UPDATE COMMITEE GOVERNANCE ACTION INDEX> \
--out-file update-committee.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file update-committee.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance action create-constitution \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--constitution-url <THE URL LINK TO THE NEW CONSTITUTION> \
--constitution-hash <THE HASH OF THE NEW CONSTITUION FILE> \
--constitution-script-hash <THE SCRIPT HASH OF THE GUARDRAIL SCRIPT> \
--prev-governance-action-tx-id <PREVIOUS CONSTITUTION ACTION ID> \
--prev-governance-action-index <PREVIOUS CONSTITUTION ACTION INDEX> \
--out-file constitution.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file constitution.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance action create-hardfork \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--prev-governance-action-tx-id <PREVIOUS HARDFORK ACTION ID> \
--prev-governance-action-index <PREVIOUS HARDFORK ACTION INDEX> \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--protocol-major-version 11 \
--out-file hardfork.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file hardfork.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance action create-protocol-parameters-update \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--constitution-script-hash <THE SCRIPT HASH OF THE CONSTITUTION GUARDRAIL SCRIPT> \
--key-reg-deposit-amt 1000000 \
--out-file pp-update.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file pp-update.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance action create-treasury-withdrawal \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--funds-receiving-stake-verification-key-file stake.vkey \
--constitution-script-hash <THE SCRIPT HASH OF THE CONSTITUTION GUARDRAIL SCRIPT> \
--transfer 50000000000 \
--out-file treasury.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file treasury.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway governance action create-info \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file stake.vkey \
--anchor-url <THE URL LINK TO YOUR RATIONAL> \
--anchor-data-hash <THE HASH OF YOUR RATIONAL FILE> \
--out-file info.action
Ensure that your UTXO has sufficient funds to cover both the deposit and transaction fees, or you will receive an error message. You can always include additional UTXOs to spend if necessary.
cardano-cli conway transaction build \
--tx-in "$(cardano-cli query utxo --address "$(cat payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \
--change-address $(cat payment.addr) \
--proposal-file info.action \
--out-file tx.raw
cardano-cli conway transaction sign \
--tx-body-file tx.raw \
--signing-key-file payment.skey \
--out-file tx.signed
cardano-cli conway transaction submit \
--tx-file tx.signed
cardano-cli conway query gov-state | jq -r '.nextRatifyState.nextEnactState.prevGovActionIds'
cardano-cli conway query gov-state | jq '.proposals'
cardano-cli conway query constitution