コンテンツにスキップ

ステークプールを廃止する

プール廃止の流れ

graph LR
    A[1-リタイア処理] -->|500ADA返還| B(2-登録料返還確認);
    C[3-stake.addrから全額引出処理] -->|全額| D(3-payment.addr着金確認);
    E[4-stake.addr解除処理] -->|2ADA返還| F(4-payment.addr確認);
    G[5-payment.addr全額引出処理] -->|全額| H(5-任意のアドレス確認);
    click A "./#1"
    click B "./#_3"
    click C "../withdrawal/#2-1-paymentaddr"
    click E "./#2"
    click G "./#3paymentaddr"

1.リタイア処理

現在のエポックを計算します。

startTimeGenesis=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .systemStart)
startTimeSec=$(date --date=${startTimeGenesis} +%s)
currentTimeSec=$(date -u +%s)
epochLength=$(cat $NODE_HOME/${NODE_CONFIG}-shelley-genesis.json | jq -r .epochLength)
epoch=$(( (${currentTimeSec}-${startTimeSec}) / ${epochLength} ))
echo current epoch: ${epoch}

プールが最も早く引退できるエポックと最も遅い引退エポックを見つけます。

poolRetireMaxEpoch=$(cat $NODE_HOME/params.json | jq -r '.poolRetireMaxEpoch')
echo poolRetireMaxEpoch: ${poolRetireMaxEpoch}

minRetirementEpoch=$(( ${epoch} + 1 ))
maxRetirementEpoch=$(( ${epoch} + ${poolRetireMaxEpoch} ))

echo リタイア可能最短エポック: ${minRetirementEpoch}
echo リタイア可能最長エポック: ${maxRetirementEpoch}

リタイアのタイミングについて

: エポック320でeMax18の場合,

  • 最も早いポックは 321 ( 現在のエポック + 1)
  • 最も遅いエポックは 338 ( eMax + 現在のエポック)

登録解除証明書 pool.deregを作成します。
以下のコマンド内の --epoch *** にリタイアしたいエポックを記入します

chmod u+rwx $HOME/cold-keys
cardano-cli stake-pool deregistration-certificate \
--cold-verification-key-file $HOME/cold-keys/node.vkey \
--epoch *** \
--out-file pool.dereg

ファイル転送

エアギャップのpool.deregをBPのcnodeディレクトリにコピーします

graph LR
    A[エアギャップ] -->|pool.dereg| B[BP];

payment.addrの残高を参照します

cd $NODE_HOME
cardano-cli query utxo \
    --address $(cat payment.addr) \
    $NODE_NETWORK > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out

cat balance.out

UTXOを算出します

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}

現在のスロットを算出します。

currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
echo Current Slot: $currentSlot

build-raw transactionコマンドを実行します。

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${total_balance} \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --certificate-file pool.dereg \
    --out-file tx.tmp

最低料金を計算します。

fee=$(cardano-cli transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
    $NODE_NETWORK \
    --witness-count 2 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee

変更出力を計算します。

txOut=$((${total_balance}-${fee}))
echo txOut: ${txOut}

トランザクションをビルドします。

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --certificate-file pool.dereg \
    --out-file tx.raw

ファイル転送

BPのtx.rawをエアギャップオフラインマシンのcnodeディレクトリにコピーします

graph LR
    A[BP] -->|tx.raw| B[エアギャップ];

トランザクションに署名する

cardano-cli transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --signing-key-file $HOME/cold-keys/node.skey \
    $NODE_NETWORK \
    --out-file tx.signed

コールドキーをロックする

chmod a-rwx $HOME/cold-keys

ファイル転送

エアギャップtx.signedブロックプロデューサノードのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|tx.signed| B[BP];

トランザクションを送信します

cardano-cli transaction submit \
    --tx-file tx.signed \
    $NODE_NETWORK

ヒント

  • プールは指定されたエポックの終了時にリタイアします。この例はエポック321の終わりにリタイアが発生します。
  • もし心変わりがある場合は、エポック321が終了する前に新しい登録証明書を作成して送信できます。これにより登録解除証明書が無効になります。

プール登録料について

  • プール登録料500ADAは廃止処理から2エポック後にstake.addrに入金されます。

リタイア確認

  • KOIOS APIを使用してリタイア処理ステータスを確認できます。

stakepoolid_bech32.txtの作成

cd $NODE_HOME
cardano-cli stake-pool id --cold-verification-key-file $HOME/cold-keys/node.vkey --output-format bech32 > stakepoolid_bech32.txt

ファイル転送

エアギャップマシンのstakepoolid_bech32.txtをBPのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|stakepoolid_bech32.txt| B[BP];

cd $NODE_HOME
curl -s "https://api.koios.rest/api/v0/pool_updates?_pool_bech32=$(cat stakepoolid_bech32.txt)" | jq '.[0].pool_status,.[0].retiring_epoch'
#戻り値サンプル
"retired" # "retiring"でリタイア処理待ち "retired"でリタイア済み 
309 #リタイアエポック

2.登録料返還確認

注意

以降の処理は、プールのリタイア処理が完了してから実施してください

ファイル転送

エアギャップstake.addrBPのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|stake.addr| B[BP];
cd $NODE_HOME
cardano-cli query stake-address-info \
--address $(cat stake.addr) \
$NODE_NETWORK

戻り値確認

rewardAccountBalance: の値を確認する

3.stake.addrから引き出し

stake.addrからpayment.addrへ送金する方法

4.ステークキー解除手順

注意

  • この手順ではstake.addrの登録を解除し、2ADAの返還手続きを行います。
  • プール登録料(500ADA)が返還される前に以下の処理を行ってしまうと、500ADAを受け取ることが出来ません。
  • 以下の手続きは、プール登録料の500ADAを受け取ってから実施してください

ステークキー登録解除証明書作成

cardano-cli stake-address deregistration-certificate \
    --stake-verification-key-file stake.vkey \
    --out-file stake-dereg.cert

ファイル転送

エアギャップstake-dereg.certブロックプロデューサノードのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|stake-dereg.cert| B[BP];

ステークキー登録料算出

keyDeposit=$(cat $NODE_HOME/params.json | jq -r '.stakeAddressDeposit')
echo keyDeposit: $keyDeposit

最新スロット算出

cd $NODE_HOME
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
echo Current Slot: $currentSlot

payment.addr残高を参照

cardano-cli query utxo \
    --address $(cat payment.addr) \
    $NODE_NETWORK > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr | sed -e '/lovelace + [0-9]/d' > balance.out

cat balance.out

UTXOを算出

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}

仮トランザクションファイルを作成

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+0 \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --certificate stake-dereg.cert \
    --out-file tx.tmp

最低料金を計算します

fee=$(cardano-cli transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
    $NODE_NETWORK \
    --witness-count 2 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee

変更出力を計算します。

txOut=$((total_balance+keyDeposit-fee))
echo Change Output: ${txOut}

トランザクションをビルドします。

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out $(cat payment.addr)+${txOut} \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --certificate-file stake-dereg.cert \
    --out-file tx.raw

ファイル転送

BPのtx.raw をエアギャップマシンのcnodeディレクトリにコピーします。

graph LR
    A[BP] -->|tx.raw| B[エアギャップ];

トランザクションに署名する

cd $NODE_HOME
cardano-cli transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    --signing-key-file stake.skey \
    $NODE_NETWORK \
    --out-file tx.signed

ファイル転送

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|tx.signed| B[BP];

cardano-cli transaction submit \
    --tx-file tx.signed \
    $NODE_NETWORK

5.payment.addrから全額引き出す手順

まずは、最新のスロット番号を取得し invalid-hereafter パラメータを正しく設定します。

cd $NODE_HOME
currentSlot=$(cardano-cli query tip $NODE_NETWORK | jq -r '.slot')
echo Current Slot: $currentSlot

送金先のアドレスを設定します。

destinationAddress=送金先アドレス
echo destinationAddress: $destinationAddress

payment.addrの残高を参照します。

cardano-cli query utxo \
    --address $(cat payment.addr) \
    $NODE_NETWORK > fullUtxo.out

tail -n +3 fullUtxo.out | sort -k3 -nr > balance.out

cat balance.out

UTXOを算出します。

tx_in=""
total_balance=0
while read -r utxo; do
    in_addr=$(awk '{ print $1 }' <<< "${utxo}")
    idx=$(awk '{ print $2 }' <<< "${utxo}")
    utxo_balance=$(awk '{ print $3 }' <<< "${utxo}")
    total_balance=$((${total_balance}+${utxo_balance}))
    echo TxHash: ${in_addr}#${idx}
    echo ADA: ${utxo_balance}
    tx_in="${tx_in} --tx-in ${in_addr}#${idx}"
done < balance.out
txcnt=$(cat balance.out | wc -l)
echo Total ADA balance: ${total_balance}
echo Number of UTXOs: ${txcnt}

build-rawトランザクションコマンドを実行します。

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out ${destinationAddress}+0 \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee 0 \
    --out-file tx.tmp

最低手数料を出力します

fee=$(cardano-cli transaction calculate-min-fee \
    --tx-body-file tx.tmp \
    --tx-in-count ${txcnt} \
    --tx-out-count 1 \
    $NODE_NETWORK \
    --witness-count 1 \
    --byron-witness-count 0 \
    --protocol-params-file params.json | awk '{ print $1 }')
echo fee: $fee

計算結果を出力します。

txOut=$((${total_balance}-${fee}))
echo Change Output: ${txOut}

送金金額を確認します

amountToSend=$((${txOut}))
echo amountToSend: $amountToSend

トランザクションファイルを構築します。

cardano-cli transaction build-raw \
    ${tx_in} \
    --tx-out ${destinationAddress}+${amountToSend} \
    --invalid-hereafter $(( ${currentSlot} + 10000)) \
    --fee ${fee} \
    --out-file tx.raw

ファイル転送

BPのtx.raw をエアギャップオフラインマシンのcnodeディレクトリにコピーします。

graph LR
    A[BP] -->|tx.raw| B[エアギャップ];

トランザクションに署名します。

cd $NODE_HOME
cardano-cli transaction sign \
    --tx-body-file tx.raw \
    --signing-key-file payment.skey \
    $NODE_NETWORK \
    --out-file tx.signed

tx.signed をブロックプロデューサーノードのcnodeディレクトリにコピーします。

ファイル転送

エアギャップのtx.signed をBPのcnodeディレクトリにコピーします。

graph LR
    A[エアギャップ] -->|tx.signed| B[BP];

署名されたトランザクションを送信します。

cardano-cli transaction submit \
    --tx-file tx.signed \
    $NODE_NETWORK

全額出金されているか確認します。

cd $NODE_HOME
cardano-cli query utxo \
    --address $(cat payment.addr) \
    $NODE_NETWORK

トランザクションが消えていればOKです

                           TxHash                                 TxIx        Lovelace
----------------------------------------------------------------------------------------