SPOとしてガバナンスアクションに投票する方法
SPOがガバナンスアクションに投票するには以下の手順に従います。
進行中のガバナンスアクションのアクションIDを取得、投票のスタンスを決定し、必要に応じて議論に参加します。
その後Cardano CLIを使用して投票ファイルを作成し、ブロックチェーンに送信します。
- 支払いキーペア
- 資金のあるアドレス
- ステークプールキー
ガバナンスアクションの内容の確認
新しい憲法提案のアクションID ${ga_id}#0が与えられたと仮定します。
ガバナンス状態から新しい憲法提案のURLとハッシュを取得します。
- BP
- governanceディレクトリ作成
mkdir -p $NODE_HOME/governance
- 対象のガバナンスアクションIDを変数に代入します。
ga_id=
例)0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b9
- ガバナンスアクションの内容を取得します。
cd "$NODE_HOME/governance"
cardano-cli latest query gov-state ${NODE_NETWORK} \
| jq -r --arg govActionId "${ga_id}" '
.proposals
| to_entries[]
| select(.value.actionId.txId | contains($govActionId))
| .value
' \
> "$NODE_HOME/governance/${ga_id}.json"
- 元帳状態に登録されているURLからファイルをダウンロードします。
anchor_url=$(jq -r '.proposalProcedure.anchor.url' "$NODE_HOME/governance/${ga_id}.json")
anchor_datahash=$(jq -r '.proposalProcedure.anchor.dataHash' "$NODE_HOME/governance/${ga_id}.json")
ga_ix=$(jq -r '.actionId.govActionIx' "$NODE_HOME/governance/${ga_id}.json")
echo "URL=${anchor_url}"
echo "Ix =${ga_ix}"
- URL からファイルをダウンロード(IPFS対応)
out="$NODE_HOME/governance/${ga_id}-ga.txt"
if [[ "$anchor_url" =~ ^ipfs:// || "$anchor_url" == */ipfs/* ]]; then
ipfs_path="${anchor_url#ipfs://}"
ipfs_path="${ipfs_path#/ipfs/}"
gateways=(
"https://ipfs.io/ipfs"
"https://gateway.pinata.cloud/ipfs"
"https://nftstorage.link/ipfs"
"https://dweb.link/ipfs"
"https://cloudflare-ipfs.com/ipfs"
)
ok=""
for gw in "${gateways[@]}"; do
echo "Trying ${gw}/${ipfs_path} ..."
if curl -L --fail --max-time 45 --retry 2 --retry-delay 1 \
-o "$out" "${gw}/${ipfs_path}"; then
echo "Downloaded via: $gw"
ok="yes"; break
fi
done
[[ -z "$ok" ]] && { echo "全ゲートウェイ失敗"; exit 1; }
else
curl -L --fail --max-time 60 --retry 2 --retry-delay 1 \
-o "$out" "$anchor_url"
fi
- dataHash の検証(BLAKE2b-256)
expected="$(echo "$anchor_datahash" | sed 's/^0x//' | tr '[:upper:]' '[:lower:]')"
if command -v b2sum >/dev/null 2>&1; then
calculated="$(b2sum -l 256 "$out" | awk '{print tolower($1)}')"
elif command -v openssl >/dev/null 2>&1; then
calculated="$(openssl dgst -blake2b256 "$out" | awk '{print tolower($2)}')"
else
echo "b2sum/openssl が必要です"; exit 2
fi
echo "expected: $expected"
echo "calculated: $calculated"
[[ "$calculated" = "$expected" ]] && echo "OK: dataHash一致" || { echo "NG: dataHash不一致"; exit 2; }
93106d082a93e94df5aff74f678438bae3a647dac63465fbfcde6a3058f41a1e
93106d082a93e94df5aff74f678438bae3a647dac63465fbfcde6a3058f41a1e 0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b9-ga.txt
- 投票ファイルに使用するガバナンスアクションのindexを控える URLのテキストはデータハッシュと一致しており、URLのテキストがまさに私たちが投票しているものであることが確認されています。 将来的には、投票アプリ、エクスプローラー、ウォレット、その他のツールがフィルタリングを実行し、URL コンテンツが元帳状態のハッシュに対して検証されたアクションのみが表示されるようになります。
echo ${ga_ix}
出力されたガバナンスアクションのindex番号
投票ファイル作成
- BP
- governanceディレクトリ作成
mkdir -p $NODE_HOME/governance
- 対象のガバナンスアクションIDを変数に代入します。
ga_id=
例)Hard Fork to Protocol Version 10 ("Plomin" Hard Fork)のHashをコピーします。
0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b900
ハッシュ値の最後の
00は不要です。
- 投票ファイルに使用するガバナンスアクションのindexを変数に代入します。
ga_ix=0
- メタデータを付与する場合
- メタデータを付与しない場合
- 作成したメタデータのURLを変数に代入します。
anchor_data_url=
次のファイルを参考にファイル名や内容
commentのみを修正します。
例)https://akyo3.github.io/AKYO/vote/gov_action1pvv5wmjqhwa4u85vu9f4ydmzu2mgt8n7et967ph2urhx53r70xusqnmm525.json
- 以下のコマンドでハッシュ値を出力します。
cd $NODE_HOME
cardano-cli hash anchor-data \
--url ${anchor_data_url} \
--out-file $NODE_HOME/governance/anchor-data-hash.txt
- ハッシュ値の出力
echo $(cat $NODE_HOME/governance/anchor-data-hash.txt)
BPの$NODE_HOME/governance/anchor-data-hash.txtをエアギャップの$NODE_HOME/governanceディレクトリにコピーします。
- エアギャップ
- governanceディレクトリ作成
mkdir -p $NODE_HOME/governance
- メタデータを付与する場合
- メタデータを付与しない場合
- BPで出力したハッシュ値と比較します。
echo $(cat $NODE_HOME/governance/anchor-data-hash.txt)
BPで出力したハッシュ値と同じであること
- 変数に対象のガバナンスアクションIDを代入します。
ga_id=
例)0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b9
- 変数に対象のガバナンスアクションのIndexを代入します。
ga_ix=0
- 以下の変数にオプションを設定します。
voting_stance=
--yes
--no
--abstain
- metadataを付与したい場合は以下の変数にURLを代入します。
anchor_data_url=
- メタデータを付与する場合
chmod u+rwx $HOME/cold-keys
cd $NODE_HOME
cardano-cli latest governance vote create \
${voting_stance} \
--governance-action-tx-id ${ga_id} \
--governance-action-index ${ga_ix} \
--cold-verification-key-file $HOME/cold-keys/node.vkey \
--anchor-url ${anchor_data_url} \
--anchor-data-hash $(cat $NODE_HOME/governance/anchor-data-hash.txt) \
--out-file $NODE_HOME/governance/${ga_id}-ga.vote
- 変数に対象のガバナンスアクションIDを代入します。
ga_id=
例)0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b9
- 変数に対象のガバナンスアクションのIndexを代入します。
ga_ix=0
- 以下の変数にオプションを設定します。
voting_stance=
--yes
--no
--abstain
- メタデータを付与しない場合
chmod u+rwx $HOME/cold-keys
cd $NODE_HOME
cardano-cli latest governance vote create \
${voting_stance} \
--governance-action-tx-id ${ga_id} \
--governance-action-index ${ga_ix} \
--cold-verification-key-file $HOME/cold-keys/node.vkey \
--out-file $NODE_HOME/governance/${ga_id}-ga.vote
エアギャップの$NODE_HOME/governance/${ga_id}-ga.voteをBPの$NODE_HOME/governanceディレクトリにコピーします。
トランザクション構築
トランザクションに投票を含めます。
- BP
トランザクションに投票を含めます。
- 最も多いUTXOを変数に代入
TX_FULL=$(cardano-cli latest query utxo ${NODE_NETWORK} \
--address "$(cat $NODE_HOME/payment.addr)" --out-file /dev/stdout \
| jq -r 'to_entries | sort_by(.value.value.lovelace) | reverse | .[0].key')
TX_HASH=${TX_FULL%%#*}
TX_IX=${TX_FULL##*#}
- 変数の内容を確認
echo "$TX_HASH#$TX_IX"
- トランザクションをビルドします。
cardano-cli latest transaction build \
${NODE_NETWORK} \
--tx-in ${TX_HASH}#${TX_IX} \
--change-address $(cat $NODE_HOME/payment.addr) \
--vote-file $NODE_HOME/governance/${ga_id}-ga.vote \
--witness-override 2 \
--out-file $NODE_HOME/governance/vote-tx.raw
Estimated transaction fee: Coin XXXXXX
BPの$NODE_HOME/governance/vote-tx.rawをエアギャップの$NODE_HOME/governanceディレクトリにコピーします。
トランザクション署名
- エアギャップ
- SPOコールドキーで署名します。
cd $NODE_HOME
cardano-cli latest transaction sign \
${NODE_NETWORK} \
--tx-body-file $NODE_HOME/governance/vote-tx.raw \
--signing-key-file $HOME/cold-keys/node.skey \
--signing-key-file $NODE_HOME/payment.skey \
--out-file $NODE_HOME/governance/vote-tx.signed
chmod a-rwx $HOME/cold-keys
エアギャップの$NODE_HOME/governance/vote-tx.signedをBPの$NODE_HOME/governanceディレクトリにコピーします。
トランザクション送信
- BP
- トランザクションをブロックチェーンに送信します。
cardano-cli latest transaction submit \
${NODE_NETWORK} \
--tx-file $NODE_HOME/governance/vote-tx.signed
Transaction successfully submitted.
エアギャップの$NODE_HOME/governance/vote-tx.signedをBPの$NODE_HOME/governanceディレクトリにコピーします。
ga_id=
ガバナンスアクションの内容の確認
HOSKY
15f82a365bdee483a4b03873a40d3829cc88c048ff3703e11bd01dd9e035c916
IKIGAI
59fd353253eb177e2104e8f23ea4c63e3d32ef95c7865d03e90d3884424dc1db
Atrium
7fd6429add8f2611ad8d48c0cc49101463093aec285faea402e8cfde78ea58d7
Plomin Hard Fork
fff0df644d328a5367212f45bab59060bde3c4091dc96c723062896fd6197314
Hard Fork to Protocol Version 10 ("Plomin" Hard Fork)
0b19476e40bbbb5e1e8ce153523762e2b6859e7ecacbaf06eae0ee6a447e79b9
Replace Interim Constitutional Committee
47a0e7a4f9383b1afc2192b23b41824d65ac978d7741aca61fc1fa16833d1111
投票の合計数確認
cardano-cli latest query gov-state ${NODE_NETWORK} \
| jq -r --arg actionTxId ${ga_id} --arg actionIndex "0" ' .proposals
| to_entries[]
| select(.value.actionId.txId == $actionTxId and .value.actionId.govActionIx == ($actionIndex | tonumber))
| {
govActionId: .value.actionId,
dRepVoteYesCount: (.value.dRepVotes | with_entries(select(.value == "VoteYes")) | length),
dRepVoteNoCount: (.value.dRepVotes | with_entries(select(.value == "VoteNo")) | length),
dRepAbstainCount: (.value.dRepVotes | with_entries(select(.value == "Abstain")) | length),
stakePoolVoteYesCount: (.value.stakePoolVotes | with_entries(select(.value == "VoteYes")) | length),
stakePoolVoteNoCount: (.value.stakePoolVotes | with_entries(select(.value == "VoteNo")) | length),
stakePoolAbstainCount: (.value.stakePoolVotes | with_entries(select(.value == "Abstain")) | length),
committeeVoteYesCount: (.value.committeeVotes | with_entries(select(.value == "VoteYes")) | length),
committeeVoteNoCount: (.value.committeeVotes | with_entries(select(.value == "VoteNo")) | length),
committeeAbstainCount: (.value.committeeVotes | with_entries(select(.value == "Abstain")) | length)
}
'