Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.idea
.DS_Store
node_modules/
2 changes: 1 addition & 1 deletion cardano/mainnet/00_common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ convert_actionUTXO2Bech() {
local govActionID="${1}"
# local govActionUTXO=$(trimString "${1%%#*}"); govActionUTXO=${govActionUTXO,,} #takes the part before the # separator
# local govActionIdx=$(trimString "${1#*#}"); #takes the part after the # separator
if [[ "${govActionID}" =~ ^([[:xdigit:]]{64}+#[[:digit:]]{1,})$ ]]; then
if [[ "${govActionID}" =~ ^([[:xdigit:]]{64}#[[:digit:]]{1,})$ ]]; then
local govActionUTXO=${govActionID:0:64}; govActionUTXO=${govActionUTXO,,} #make sure its lower case
local govActionIdx=$(( ${govActionID:65} + 0 )) #make sure to have single digits if provided like #00 #01 #02...
local govActionIdxHex="00$(bc <<< "obase=16;ibase=10;${govActionIdx}")"; govActionIdxHex=${govActionIdxHex: -$(( (${#govActionIdxHex}-1)/2*2 ))} #make sure its with a leading zero and always in pairs like 03, 04af
Expand Down
38 changes: 37 additions & 1 deletion cardano/mainnet/24a_genVote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ if [[ "${govActionID:0:11}" == "gov_action1" ]]; then #parameter is most likely
if [ $? -ne 0 ]; then echo -e "\n\n\e[91mERROR - \"${2,,}\" is not a valid Bech32 ACTION-ID.\e[0m"; exit 1; fi
govActionUTXO=${govActionID:0:64}
govActionIdx=$(( ${govActionID:65} + 0 )) #make sure to have single digits if provided like #00 #01 #02...
elif [[ "${govActionID}" =~ ^([[:xdigit:]]{64}+#[[:digit:]]{1,})$ ]]; then
elif [[ "${govActionID}" =~ ^([[:xdigit:]]{64}#[[:digit:]]{1,})$ ]]; then
govActionUTXO=${govActionID:0:64}
govActionIdx=$(( ${govActionID:65} + 0 )) #make sure to have single digits if provided like #00 #01 #02...
elif [[ "${govActionID}" == "all" ]]; then #do the voting on all current gov-actions
Expand Down Expand Up @@ -559,6 +559,7 @@ do
dRepAcceptIcon=""; poolAcceptIcon=""; committeeAcceptIcon="";
dRepPowerThreshold="N/A"; poolPowerThreshold="N/A"; #N/A -> not available
govActionTitle="";
cip179SurveyTxId=""; cip179SurveyIndex="";

echo
echo -e "\e[36m--- Entry $((${tmpCnt}+1)) of ${actionStateEntryCnt} --- Action-ID ${actionUTXO}#${actionIdx}\e[0m"
Expand Down Expand Up @@ -629,6 +630,22 @@ do
errorMsg=$(jq -r .errorMsg <<< ${signerJSON} 2> /dev/null)
echo -e "\e[0m Anchor-Data: ${iconYes}\e[32m JSONLD structure is ok\e[0m";
{ read govActionTitle; read proofDepositReturnAddr; read proofWithdrawalAddr; } <<< $(jq -r '.body.title // "-", .body.onChain.depositReturnAddress // "-", if (.body.onChain.withdrawals[0]) then ([.body.onChain.withdrawals[].withdrawalAddress] | add) else "-" end' ${tmpAnchorContent} 2> /dev/null)
if jq -e '
.body.cip179 as $link |
($link.specVersion == 5 and $link.kind == "survey-link" and
($link.surveyTxId | test("^[0-9a-fA-F]{64}$")) and
($link.surveyIndex | type == "number" and . >= 0 and . <= 65535 and floor == .) and
."@context".CIP179 == "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0179/README.md#" and
."@context".body."@context".cip179."@id" == "CIP179:link" and
."@context".body."@context".cip179."@context".specVersion == "CIP179:specVersion" and
."@context".body."@context".cip179."@context".kind == "CIP179:kind" and
."@context".body."@context".cip179."@context".surveyTxId == "CIP179:surveyTxId" and
."@context".body."@context".cip179."@context".surveyIndex == "CIP179:surveyIndex")' "${tmpAnchorContent}" >/dev/null 2>&1; then
{ read cip179SurveyTxId; read cip179SurveyIndex; } <<< $(jq -r '.body.cip179.surveyTxId, .body.cip179.surveyIndex' "${tmpAnchorContent}")
echo -e "\e[0m CIP-179: ${iconYes}\e[32m linked survey ${cip179SurveyTxId}#${cip179SurveyIndex}\e[0m";
elif jq -e '.body.cip179 != null' "${tmpAnchorContent}" >/dev/null 2>&1; then
echo -e "\e[0m CIP-179: ${iconNo}\e[35m malformed v5 survey link or @context; survey ignored\e[0m";
fi
if [[ "${errorMsg}" != "" ]]; then echo -e "\e[0m Notice: ${iconNo} ${errorMsg}\e[0m"; fi
authors=$(jq -r --arg iconYes "${iconYes}" --arg iconNo "${iconNo}" '.authors[] | "\\e[0m Signature: \(if .valid then $iconYes else $iconNo end) \(.name) (PubKey \(.publicKey))\\e[0m"' <<< ${signerJSON} 2> /dev/null)
if [[ "${authors}" != "" ]]; then echo -e "${authors}\e[0m"; fi
Expand Down Expand Up @@ -1167,12 +1184,31 @@ if [[ "${voteParam}" != "" ]]; then
esac

#Generate the vote file depending on the choice made above
cip179ResponseFile=""
if [[ "${cip179SurveyTxId}" != "" ]] && ask "\nThis action links a CIP-179 survey. Answer it with this governance vote?" N; then
if ! exists node || [[ ! -f "${scriptDir}/cip179-vote.mjs" ]]; then
echo -e "\n\e[35mCIP-179 survey voting needs cip179-vote.mjs, Node.js 20+, and cip-179@0.2.0.\nInstall the helper beside these scripts, then run 'npm install --no-save --no-package-lock cip-179@0.2.0' there.\e[0m\n"; exit 1
fi
case ${voterType} in "DRep") cip179Role=0;; "Pool") cip179Role=1;; "Committee-Hot") cip179Role=2;; esac
cip179ResponseFile="${votingFile}.cip179.json"
CIP179_KOIOS_API="${koiosAPI}" CIP179_KOIOS_AUTH="${koiosAuthorizationHeader}" \
node "${scriptDir}/cip179-vote.mjs" respond "${cip179SurveyTxId}" "${cip179SurveyIndex}" "${cip179Role}" "${voterHash}" "${actionExpiresAfterEpoch}" "${cip179ResponseFile}" <${termTTY}
cip179Result=$?
if [[ ${cip179Result} -eq 10 ]]; then cip179ResponseFile="";
elif [[ ${cip179Result} -ne 0 ]]; then
if ask "Continue with the governance vote without a survey response?" N; then cip179ResponseFile=""; else exit 1; fi
fi
fi

voteJSON=$(${cardanocli} ${cliEra} governance vote create ${voteParam} --governance-action-tx-id "${actionUTXO}" --governance-action-index "${actionIdx}" ${vkeyParam} "${voterVkeyFile}" ${anchorPARAM} --out-file /dev/stdout 2> /dev/stdout)
checkError "$?"; if [ $? -ne 0 ]; then echo -e "\e[35mERROR - ${voteJSON}\e[0m\n"; exit 1; fi

#Inject the GovActionTitle into the voting file
voteJSON=$(jq -r ". += { \"description\": \"${govActionTitle//[^[:alnum:][:space:]-_\/\!§$%&()?<>@|.,:;=*\']}\" }" <<< ${voteJSON} 2> /dev/null)
checkError "$?"; if [ $? -ne 0 ]; then echo -e "\e[35mERROR - ${voteJSON}\e[0m\n"; exit 1; fi
if [[ "${cip179ResponseFile}" != "" ]]; then
voteJSON=$(jq --arg responseFile "$(basename "${cip179ResponseFile}")" '.cip179Response = $responseFile' <<< "${voteJSON}")
fi
echo "${voteJSON}" > "${votingFile}"; checkError "$?"; if [ $? -ne 0 ]; then exit $?; fi

echo -e "\e[0mCreated the Vote-Certificate file: \e[32m${votingFile}\e[90m"
Expand Down
30 changes: 27 additions & 3 deletions cardano/mainnet/24b_regVote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ echo


#Setting default variables
metafileParameter=""; metafile=""; transactionMessage="{}"; enc=""; passphrase="cardano";
metafileParameter=""; metafile=""; transactionMessage="{}"; enc=""; passphrase="cardano"; metadataJsonFile=""; metadataCborFile="";
votefileParameter=""; actionIdCollector=""; voterHashCollector=""; voteCounter=0;
cip179ResponseFiles=()

#Check all optional parameters about there types and set the corresponding variables
#Starting with the 3th parameter (index=2) up to the last parameter
Expand All @@ -175,11 +176,13 @@ for (( tmpCnt=2; tmpCnt<${paramCnt}; tmpCnt++ ))
metadatum=$(jq -r "keys_unsorted[0]" "${metafile}" 2> /dev/null)
if [[ $? -ne 0 ]]; then echo -e "\n\e[35mERROR - '${metafile}' is not a valid JSON file!\n\e[0m"; exit 1; fi
#Check if it is null, a number, lower then zero, higher then 65535, otherwise exit with an error
if [ "${metadatum}" == null ] || [ -z "${metadatum##*[!0-9]*}" ] || [ "${metadatum}" -lt 0 ] || [ "${metadatum}" -gt 65535 ]; then
if [ "${metadatum}" == null ] || [ -z "${metadatum##*[!0-9]*}" ] || [ "${metadatum}" -lt 0 ] || [ "${metadatum}" -gt 65535 ]; then
echo -e "\n\e[35mERROR - MetaDatum Value '${metadatum}' in '${metafile}' must be in the range of 0..65535!\n\e[0m"; exit 1; fi
metafileParameter+="--metadata-json-file ${metafile} "; metafileList+="'${metafile}' "
metadataJsonFile="${metafile}"
metafileParameter+="--metadata-json-file ${metafile} "; metafileList+="'${metafile}' "

elif [[ -f "${metafile}" && "${metafileExt^^}" == "CBOR" ]]; then #its a cbor file
metadataCborFile="${metafile}"
metafileParameter+="--metadata-cbor-file ${metafile} "; metafileList+="'${metafile}' "

elif [[ -f "${metafile}" && "${metafileExt^^}" == "VOTE" ]]; then #its a vote file
Expand All @@ -199,6 +202,12 @@ for (( tmpCnt=2; tmpCnt<${paramCnt}; tmpCnt++ ))

#Additionally read the description from the voting file
voteActionDescription=$(jq -r '.description // "-"' 2> /dev/null "${metafile}");
cip179ResponseFile=$(jq -r '.cip179Response // empty' 2> /dev/null "${metafile}")
if [[ "${cip179ResponseFile}" != "" ]]; then
if [[ "${cip179ResponseFile}" != /* ]]; then cip179ResponseFile="$(dirname "${metafile}")/${cip179ResponseFile}"; fi
if [[ ! -f "${cip179ResponseFile}" ]]; then echo -e "\n\e[35mERROR - CIP-179 response file '${cip179ResponseFile}' referenced by '${metafile}' does not exist.\e[0m\n"; exit 1; fi
cip179ResponseFiles+=("${cip179ResponseFile}")
fi

#Show the Description
echo -e "\e[0m Description: \e[33m${voteActionDescription}\e[0m";
Expand Down Expand Up @@ -286,6 +295,16 @@ for (( tmpCnt=2; tmpCnt<${paramCnt}; tmpCnt++ ))

done

if [[ ${#cip179ResponseFiles[@]} -gt 0 ]]; then
if [[ "${metadataJsonFile}" != "" ]]; then echo -e "\n\e[35mERROR - JSON metadata '${metadataJsonFile}' cannot be combined with CIP-179 response sidecars because they use different cardano-cli JSON schemas.\e[0m\n"; exit 1; fi
if [[ "${metadataCborFile}" != "" ]]; then echo -e "\n\e[35mERROR - CBOR metadata '${metadataCborFile}' cannot be safely checked for a label 17 collision with CIP-179 response sidecars.\e[0m\n"; exit 1; fi
if ! exists node || [[ ! -f "${scriptDir}/cip179-vote.mjs" ]]; then echo -e "\n\e[35mERROR - Node.js and '${scriptDir}/cip179-vote.mjs' are required to merge CIP-179 responses.\e[0m\n"; exit 1; fi
cip179MetadataFile="${tempDir}/cip179-responses.json"
node "${scriptDir}/cip179-vote.mjs" merge "${cip179MetadataFile}" "${cip179ResponseFiles[@]}"
checkError "$?"; if [ $? -ne 0 ]; then exit $?; fi
metafileParameter="--json-metadata-detailed-schema --metadata-json-file ${cip179MetadataFile} "; metafileList+="'${cip179MetadataFile}' "
fi

#Check if there is only one vote included if also a hardware wallet is used (limitation by the hardware wallet firmware)
if [[ ${voteCounter} -gt 1 ]] && [[ -f "${fromAddr}.hwsfile" || "${voterSigningFile}" == *".hwsfile" ]]; then echo -e "\n\e[91mPlease include only one vote-file in case a hardware-wallet is involved in the transaction.\nThis is a limitation of the hardware-wallet firmware!\n\e[0m"; exit 1; fi

Expand All @@ -312,6 +331,11 @@ if [[ ! "${transactionMessage}" == "{}" ]]; then
echo -e "\n\e[35mERROR - The given encryption mode '${encryption,,}' is not on the supported list of encryption methods. Only 'basic' from CIP-0083 is currently supported\n\n\e[0m"; exit 1;
fi

if [[ ${#cip179ResponseFiles[@]} -gt 0 ]]; then
tmp=$(jq 'with_entries(.value |= {map: [to_entries[] | {k: {string: .key}, v: (if (.value | type) == "array" then {list: [.value[] | {string: .}]} else {string: .value} end)}]})' <<< "${tmp}")
checkError "$?"; if [ $? -ne 0 ]; then exit $?; fi
fi

echo "${tmp}" > ${transactionMessageMetadataFile}; metafileParameter="${metafileParameter}--metadata-json-file ${transactionMessageMetadataFile} "; #add it to the list of metadata.jsons to attach

else
Expand Down
2 changes: 1 addition & 1 deletion cardano/mainnet/24c_queryVote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ for (( tmpCnt=0; tmpCnt<${paramCnt}; tmpCnt++ ))
paramValue=${allParameters[$tmpCnt]}

#Check if its a Governance Action-ID
if [[ "${paramValue,,}" =~ ^([[:xdigit:]]{64}+#[[:digit:]]{1,})$ ]]; then
if [[ "${paramValue,,}" =~ ^([[:xdigit:]]{64}#[[:digit:]]{1,})$ ]]; then
if [[ "${govActionID}" != "" ]]; then echo -e "\n\e[91mERROR - Only one Action-ID is allowed as parameter!\e[0m\n"; exit 1; fi
govActionID="${paramValue,,}"
echo -e "\e[0mUsing Governance Action-ID:\e[32m ${govActionID}\e[0m\n"
Expand Down
26 changes: 24 additions & 2 deletions cardano/mainnet/25a_genAction.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ echo

#Setting default variables
anchorURL=""; anchorHASH=""; #Setting defaults
cip179AnchorDeposit=""; cip179AnchorRewardAccount="";
committeeTermEpoch=0;

paramCnt=$#;
Expand Down Expand Up @@ -178,6 +179,17 @@ if ${onlineMode}; then

else #anchor-url is a json

#For CIP-179-linked anchors, retain the declared on-chain values so
#they can be checked against the live parameters and selected return
#address before an action file is created.
if jq -e '.body.cip179 != null' "${tmpAnchorContent}" >/dev/null 2>&1; then
cip179AnchorDeposit=$(jq -er '.body.onChain.deposit | strings | select(test("^[1-9][0-9]*$"))' "${tmpAnchorContent}" 2>/dev/null) || cip179AnchorDeposit=""
cip179AnchorRewardAccount=$(jq -er '.body.onChain.reward_account | strings | select(length > 0)' "${tmpAnchorContent}" 2>/dev/null) || cip179AnchorRewardAccount=""
if [[ "${cip179AnchorDeposit}" == "" || "${cip179AnchorRewardAccount}" == "" ]]; then
echo -e "\n\e[91mERROR - The CIP-179-linked anchor does not contain a valid positive body.onChain.deposit and body.onChain.reward_account.\n\e[0m"; exit 1;
fi
fi

contentHASH=$(b2sum -l 256 "${tmpAnchorContent}" 2> /dev/null | cut -d' ' -f 1)
checkError "$?"; if [ $? -ne 0 ]; then exit $?; fi
echo -e "\e[0mAnchor-URL(HASH):\e[32m ${anchorURL} \e[0m(\e[94m${contentHASH}\e[0m)"
Expand Down Expand Up @@ -261,6 +273,18 @@ if [[ ${protocolVersionMajor} -lt 9 ]]; then
if [[ ${actionDepositFee} -lt 0 ]]; then
echo -e "\n\e[91mERROR - Could not query the current Action-Deposit fee amount!\n\e[0m"; exit 1; fi

# A linked survey anchor must describe the deposit and return account this
# script will use. Never silently correct stale, already-signed metadata.
if [[ "${cip179AnchorDeposit}" != "" ]]; then
if [[ "${cip179AnchorDeposit}" != "${actionDepositFee}" ]]; then
echo -e "\n\e[91mERROR - The CIP-179-linked anchor declares a governance action deposit of ${cip179AnchorDeposit} lovelace, but the current network requires ${actionDepositFee}. Regenerate and re-sign the anchor metadata; no action file was created.\n\e[0m"; exit 1;
fi
if [[ "${cip179AnchorRewardAccount}" != "${stakeAddr}" ]]; then
echo -e "\n\e[91mERROR - The CIP-179-linked anchor reward account does not match the selected deposit-return stake address. Regenerate and re-sign the anchor metadata; no action file was created.\n\e[0m"; exit 1;
fi
echo -e "\e[0mCIP-179 Anchor: \e[32m deposit and reward account match the action\e[0m"
fi

echo -e "\e[0mAction-Deposit Fee:\e[32m $(convertToADA ${actionDepositFee}) ADA / ${actionDepositFee} lovelaces\n\e[0m"

if [[ ${committeeMaxTermLength} -lt 0 ]]; then
Expand Down Expand Up @@ -810,5 +834,3 @@ echo -e "\"./25b_regAction.sh myWallet ${actionFile}\"\e[0m"
echo

echo -e "\e[0m"


Loading