Compare commits

..

No commits in common. "550d3e3a576bc01d1a207268a94772eec9cb7abf" and "e3460b9f9ba313ddb70806de896b28cfd6ec3f39" have entirely different histories.

4 changed files with 58 additions and 491 deletions

View File

@ -1,37 +0,0 @@
[Unit]
Description=Ghost Node
After=network.target
Documentation=https://git.ghostchain.io/ghostchain/ghost-node
[Service]
EnvironmentFile=-/etc/default/ghost
ExecStart=/usr/bin/ghost $GHOST_CLI_ARGS
User=ghost
Restart=always
RestartSec=30
CapabilityBoundingSet=
LockPersonality=true
NoNewPrivileges=true
PrivateDevices=true
PrivateMounts=true
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHostname=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictNamespaces=false
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=landlock_add_rule landlock_create_ruleset landlock_restrict_self seccomp mount umount2
SystemCallFilter=~@clock @module @reboot @swap @privileged
SystemCallFilter=pivot_root
UMask=0027
[Install]
WantedBy=multi-user.target

View File

@ -1,46 +1,48 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
current_path=$(pwd) if [ "$#" -ne 1 ]; then
current_script=$(realpath "$0") echo "Please provide the number of initial validators!"
script_folder=$(dirname "$current_script") exit 1
project_folder=("$script_folder/..") fi
num_ghosties=$(grep "Local identity" $project_folder/service/ghosties | wc -l) generate_account_id() {
echo "let endowed_accounts = vec![" ./target/release/ghostkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "Account ID" | awk '{ print $3 }'
for num in $(seq 2 $num_ghosties); do
account_id=$(grep -m $num "wallet" $project_folder/service/ghosties | tail -n 1 | awk '{ print $6 }')
public_key=$(ghost key inspect $account_id --public | grep "SS58 Address" | awk '{ print $3 }')
echo -e "\t// $public_key"
echo -e "\thex![\"${account_id:2}\"].into();"
done
echo "];"
echo -e "\n"
print_session_key() {
echo -e "\t\t// $1"
echo -e "\t\thex![\"$2\"].$3(),"
} }
echo "let initial_authorities: Vec<(" generate_address() {
echo -e "\tAccountId," ./target/release/ghostkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "SS58 Address" | awk '{ print $3 }'
echo -e "\tAccountId," }
echo -e "\tBabeId,"
echo -e "\tGrandpaId," generate_public_key() {
echo -e "\tAuthorityDiscoveryId," ./target/release/ghostkey inspect ${3:-} ${4:-} "$SECRET//$1//$2" | grep "Public key (hex)" | awk '{ print $4 }'
echo -e "\tSlowClapId," }
echo ")> = vec!["
for num in $(seq 2 $num_ghosties); do generate_address_and_account_id() {
echo -e "\t(" ACCOUNT=$(generate_account_id $1 $2 $3)
for key_word in $(echo stash stash babe gran audi slow); do ADDRESS=$(generate_address $1 $2 $3)
account_id=$(grep -m $num $key_word $project_folder/service/ghosties | tail -n 1 | awk '{ print $7 }') if ${4:-false}; then
public_key=$(ghost key inspect $account_id --public | grep "SS58 Address" | awk '{ print $3 }') INTO="unchecked_into"
postfix="unchecked_into" else
if [ $key_word = "stash" ]; then INTO="into"
postfix="into"
fi fi
print_session_key $public_key $account_id $postfix
done printf "//$ADDRESS\nhex![\"${ACCOUNT#'0x'}\"].$INTO(),"
echo -e "\t)," }
V_NUM=$1
AUTHORITIES=""
for i in $(seq 1 $V_NUM); do
AUTHORITIES+="(\n"
AUTHORITIES+="$(generate_address_and_account_id $i stash)\n"
AUTHORITIES+="$(generate_address_and_account_id $i controller)\n"
AUTHORITIES+="$(generate_address_and_account_id $i babe '--scheme sr25519' true)\n"
AUTHORITIES+="$(generate_address_and_account_id $i grandpa '--scheme ed25519' true)\n"
AUTHORITIES+="$(generate_address_and_account_id $i authority_discovery '--scheme sr25519' true)\n"
AUTHORITIES+="$(generate_address_and_account_id $i slow_clap '--scheme sr25519' true)\n"
AUTHORITIES+="),\n"
done done
echo "];"
printf "$AUTHORITIES"

View File

@ -1,387 +0,0 @@
#!/bin/bash
set -Ee
CHECK_KEYS=false
INSERT_KEYS=false
UNIT_FILE=false
SKIP_BUILD=false
SET_ENVIRONMENT=false
EXECUTABLE_PATH="/usr/bin/"
SPECIFICATION_PATH="/etc/ghost/"
NODE_PATH="/var/lib/ghost"
SPECIFICATION_NAME="casper"
TARGET="release"
CURRENT_PATH=$(pwd)
CURRENT_SCRIPT=$(realpath "$0")
SCRIPT_FOLDER=$(dirname "$CURRENT_SCRIPT")
PROJECT_FOLDER=("$SCRIPT_FOLDER/..")
final() {
cd $CURRENT_PATH
if [[ $1 -eq 1 ]]; then
echo "[-] error occured during execution"
else
echo "[+] execution finished"
fi
exit $1
}
prompt() {
while true; do
printf "$1 [y/N]: "
read yn
case $yn in
[Yy]* ) return 0;;
* ) return 1;;
esac
done
}
sanity_check() {
secret_seed=$(ghost key inspect --scheme="$1" "$2" | grep "Secret seed" | awk '{ print $3 }')
account_id=$(ghost key inspect --scheme="$1" "$2" | grep "Account ID" | awk '{ print $3 }')
echo "[+] inspected account id for $3: $account_id"
num_keys=$(grep $account_id "$PROJECT_FOLDER/service/ghosties" | wc -l)
num_types=$(grep $account_id "$PROJECT_FOLDER/service/ghosties" | grep $3 | wc -l)
if [ ! $num_keys = 1 ] || [ ! $num_types = 1 ]; then
echo "[-] inspected account id not found on 'ghosties' file or wrong key type"
exit 1
fi
}
extract_seed() {
name_with_spaces=$(echo $1 | tr '-' ' ')
read -p "[?] path to the file with $name_with_spaces: (default: /etc/ghost/$1) " seed_path
seed_path="${seed_path:-/etc/ghost/$1}"
if [ ! -f $seed_path ]; then
echo "[-] path to $name_with_spaces is not valid"
fi
seed=$(cat $seed_path)
echo $seed
}
help() {
echo -e "Ghost Node Build automation tool. Helper for Ghost Node environment preparation.\n"
echo -e "With no OPTION nothing will happen, possible OPTION:\n"
echo -e "-i, --set-environment\n\tSet up rust environment."
echo -e "-u, --unit-file\n\tCreation of systemd unit file."
echo -e "-m, --make-global\n\tStore compiled ghost executable and chain specification globally."
echo -e "-a, --set-arguments\n\tPrepare CLI arguments for running ghost node."
echo -e "-k, --check-keys\n\tCheck if your keys are already included in 'ghosties' file."
echo -e "-r, --insert-keys\n\tInsert session keys to the keystore via JSON RPC."
echo -e "-r, --release\n\tCompile node with '--release' flag."
echo -e "-p, --profile\n\tCompile node with '--profile [PROFILE]' flag."
echo -e "-f, --features\n\tCompilation features '--features=\"FEATURE1,FEATURE2\"'"
echo -e "-e, --executable-path\n\tPath to executable ('/usr/lib/' is default)."
echo -e "-c, --specification-path\n\tPath to specification ('/etc/ghost' is default)."
echo -e "-n, --specification-name\n\tSpecification name to be used ('casper' is default)."
echo -e "-h, --help\n\tPrints help information."
}
trap 'final "$?"' EXIT
clear
echo " ____ _ _ _ _ _"
echo " / ___| |__ ___ ___| |_ | \ | | ___ __| | ___"
echo "| | _| '_ \ / _ \/ __| __| | \| |/ _ \ / _' |/ _ \\"
echo "| |_| | | | | (_) \__ \ |_ | |\ | (_) | (_| | __/"
echo " \____|_| |_|\___/|___/\__| |_| \_|\___/ \__,_|\___|"
echo -e "\nCreated by st1nky (stinky@ghostchain.io)"
echo -e "Repository: https://git.ghostchain.io/ghostchain/ghost-node"
echo -e "Usage: local-builder.sh [OPTION]\n"
while [ $# -gt 0 ]; do
case "$1" in
--set-environment|-i)
SET_ENVIRONMENT=true
;;
--unit-file|-u)
UNIT_FILE=true
;;
--make-global|-m)
MAKE_GLOBAL=true
;;
--set-arguments|-a)
ARGUMENTS=true
;;
--check-keys|-k)
CHECK_KEYS=true
;;
--insert-keys|-k)
INSERT_KEYS=true
;;
--release|-r)
RELEASE="--release"
TARGET="release"
;;
--profile*|-p*)
if [[ "$1" != *=* ]]; then shift; fi
RELEASE="--profile=${1#*=}"
TARGET="${1#*=}"
;;
--feature*|-f*)
if [[ "$1" != *=* ]]; then shift; fi
FEATURES="--features=${1#*=}"
;;
--executable-path*|-e*)
if [[ "$1" != *=* ]]; then shift; fi
EXECUTABLE_PATH=$(echo ${1#*=}/ | tr -s /)
;;
--specification-path*|-c*)
if [[ "$1" != *=* ]]; then shift; fi
SPECIFICATION_PATH=$(echo ${1#*=}/ | tr -s /)
;;
--specification-name*|-n*) if [[ "$1" != *=* ]]; then shift; fi
SPECIFICATION_NAME="${1#*=}"
;;
--help|-h)
help
exit 0
;;
*)
help
exit 1
;;
esac
shift
done
if [[ $SET_ENVIRONMENT = true ]]; then
echo -e "\n"
echo "WARNING!!! THIS IS HIGHLY EXPERIMENTAL FLAG, USE IT ONLY ON YOUR"
echo "OWN RISK! NOT EVERY SYSTEM CHECKED AND PROVED TO BE WORKING AS"
echo "EXPECTED! FOR THOSE WHO FOUND BUG OR SOME INCONSISTENCY FEEL"
echo "FREE TO FILL ISSUE ON https://git.ghostchain.io/ghostchain/ghost-node/issues"
echo -e "\n"
if prompt "[?] are you brave enough?"; then
echo "[+] you were warned, I hope you know what you're doing"
else
echo "[-] aborting environment setup"
exit 1
fi
if command -v rustc >/dev/null 2>&1; then
echo "[+] rust already installed"
else
os_name=$(uname -s)
cd $HOME
if [ "$os_name" = "Darwin" ]; then
echo "[+] detected MacOS. installing dependencies via homebrew"
if command -v brew >/dev/null 2>&1; then
echo "[+] already installed: $(brew --version)"
else
if prompt "[?] do you want to install homebrew?"; then
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
else
echo "[-] cannot continue without homebrew"
exit 1
fi
fi
brew update
if prompt "[?] install git, cmake, openssl and protobuf?"; then
brew install git cmake openssl protobuf
else
echo "[!] assuming git, cmake, openssl and protobuf are present"
fi
elif [ "$os_name" == "Linux" ]; then
distro=$(cat /etc/*-release | tr '[:upper:]' '[:lower:]' | grep -Poi '(debian|ubuntu|arch|fedora|opensuse)' | uniq | head -n 1)
echo $distro
if [ "$distro" = "ubuntu" ]; then
echo "[+] ubuntu detected, using apt to install dependencies"
sudo apt update
sudo apt install --assume-yes git make clang curl libssl-dev protobuf-compiler
elif [ "$distro" = "debian" ]; then
echo "[+] debian detected, using apt to install dependencies"
sudo apt update
sudo apt install --assume-yes git make clang curl libssl-dev llvm libudev-dev protobuf-compiler
elif [ "$distro" = "arch" ]; then
echo "[+] arch linux detected, using pacman to install dependencies"
sudo pacman -Syu --needed --no-confirm curl git clang make protobuf
elif [ "$distro" = "fedora" ]; then
echo "[+] fedora detected, using dnf to install dependencies"
sudo dnf update --assumeyes
sudo dnf install --assumeyes clang curl git openssl-devel make protobuf-compiler perl
elif [ "$distro" = "opensuse" ]; then
echo "[+] openSUSE detected, using zypper to install dependencies"
sudo zypper install --no-confirm clang gcc gcc-c++ curl git openssl-devel llvm-devel libudev-devel make awk protobuf-devel
else
if prompt "[?] unknown linux distribution, unable to install dependencies. continue anyway?"; then
echo "[+] proceeding with unknown linux distribution"
else
echo "[-] aborting with uknown distribution"
exit 1
fi
fi
else
echo "[-] unknown operating system"
exit 1
fi
fi
if prompt "[?] setup the rust environment (e.g. WASM support)?"; then
rustup default stable
rustup update
rustup target add wasm32-unknown-unknown
rustup component add rust-src
fi
fi
if [[ ! -z $RELEASE ]]; then
if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then
cd $PROJECT_FOLDER
echo "[+] Starting build in 3 seconds..."
sleep 3
cargo build $RELEASE $FEATURES
fi
fi
if [[ $MAKE_GLOBAL = true ]]; then
cd $PROJECT_FOLDER
sudo cp target/$TARGET/ghost $EXECUTABLE_PATH
cp service/chain-specs/$SPECIFICATION_NAME.json $SPECIFICATION_PATH
echo "[+] ghost executable copied in '$EXECUTABLE_PATH' from '$TARGET'"
echo "[+] specification '$SPECIFICATION_NAME.json' copied to '$SPECIFICATION_PATH'"
fi
if [ $UNIT_FILE = true ]; then
cd $SCRIPT_FOLDER
read -p "[?] name for the unit file (default: ghost-node.service) " unit_name
if [ -z $unit_name ]; then
unit_name="ghost-node"
fi
unit_name=$(echo "$unit_name" | sed -e "s/.service//g")
unit_name="$unit_name.service"
user_name="ghost"
if id $user_name > /dev/null 2>&1; then
echo "[+] user ghost found, continue for the user ghost"
else
echo "[!] user ghost not found"
if prompt "[?] do you want to create ghost user? (NOT RECOMMENDED: current $(whoami))"; then
sudo useradd --system --create-home $user_name
if [ ! -d $NODE_PATH ]; then
echo "[+] create folder for the node at '$NODE_PATH'"
sudo mkdir $NODE_PATH
fi
else
user_name=$(whoami)
fi
sudo chown $user_name $NODE_PATH
echo "[+] write permission to '$NODE_PATH'"
fi
cp packaging/template.service /tmp/$unit_name
sed -i -e "s/User=ghost/User=$user_name/g" /tmp/$unit_name
sudo cp packaging/template.service /etc/systemd/system/$unit_name
sudo systemctl daemon-reload
if prompt "[?] do you want to start the $unit_name?"; then
sudo systemctl restart $unit_name
fi
if prompt "[?] do you want to enable the $unit_name?"; then
sudo systemctl enable $unit_name
fi
fi
if [[ $ARGUMENTS = true ]]; then
echo "[+] setting-up default CLI arguments"
CLI_ARGS=()
read -p "[?] specify p2p protocol TCP port (default: 30333): " port
CLI_ARGS+=("--port=${port:-30333}")
read -p "[?] specify JSON-RPC server TCP port: (default: 9945): " rpc_port
CLI_ARGS+=("--rpc-port=${rpc_port:-9945}")
read -p "[?] specify the chain specification (default: /etc/ghost/casper.json): " chain
CLI_ARGS+=("--chain=${chain:-/etc/ghost/casper.json}")
read -p "[?] specify node's secret key file for p2p networking (default: /etc/ghost/node-key): " node_key
CLI_ARGS+=("--node-key-file=${node_key:-/etc/ghost/node-key}")
read -p "[?] specify name for the node (default: RANDOM_NAME): " node_name
if [[ ! -z $node_name ]]; then
CLI_ARGS+=("--name='$node_name'")
fi
CLI_ARGS+=("--validator")
if prompt "[?] disable validator mode?"; then
unset CLI_ARGS[-1]
fi
if prompt "[?] enable prometheus?"; then
read -p "[?] specify prometheus exporter TCP port: (default: 9615)" prometheus_port
CLI_ARGS+=("--prometheus-port=${prometheus_port:-9615}")
else
CLI_ARGS+=("--no-prometheus")
fi
read -p "[?] list of bootnodes if any: " bootnodes
if [ ! -z $bootnodes ]; then
CLI_ARGS+=("--bootnodes=$bootnodes")
fi
# default for now
CLI_ARGS+=("--base-path=$NODE_PATH")
CLI_ARGS+=("--state-pruning=archive")
CLI_ARGS+=("--blocks-pruning=archive")
CLI_ARGS+=("--rpc-methods=auto")
CLI_ARGS+=("--no-telemetry")
CLI_ARGS+=("--no-private-ip")
CLI_ARGS+=("--no-mdns")
CLI_ARGS+=("--no-hardware-benchmarks")
echo "GHOST_CLI_ARGS=\"$(IFS=' '; echo "${CLI_ARGS[*]}")\"" > /tmp/ghost
sudo cp /tmp/ghost /etc/default/ghost
rm /tmp/ghost
echo "[+] new CLI arguments stored in '/etc/default/ghost'"
cat /etc/default/ghost
fi
if [ $CHECK_KEYS = true ]; then
seed=$(extract_seed "wallet-key")
sanity_check "sr25519" $seed "wallet"
echo "[+] local wallet key found in 'ghosties' with correct key type"
echo
seed=$(extract_seed "stash-key")
sanity_check "sr25519" $seed "stash"
echo "[+] local stash key from found in 'ghosties' with correct key type"
echo
seed=$(extract_seed "session-key")
if [ $INSERT_KEYS = true ]; then
read -p "[?] JSON RPC endpoint to the node: (default: localhost:9945) " rpc_endpoint
rpc_endpoint="${rpc_endpoint:-localhost:9945}"
fi
for type in $(echo audi babe gran slow); do
echo "[+] parsing session key for [$type]"
scheme="sr25519"
if [ $type = "gran" ]; then
scheme="ed25519"
fi
sanity_check $scheme "$seed//$type" $type
echo "[+] inspected account id found in 'ghosties' file with correct key type"
if [ $INSERT_KEYS = true ]; then
echo "[+] trying to make an 'author_insertKey' RPC call to $rpc_endpoint..."
curl --location $rpc_endpoint \
--header "Content-Type: application/json" \
--data '{ "id":1, "jsonrpc":"2.0", "method":"author_insertKey", "params": ["'"$type"'", "'"$secret_seed"'", "'"$account_id"'"] }'
fi
echo
done
fi

View File

@ -1,39 +1,28 @@
### TEMPLATE ### ### TEMPLATE ###
Local identity : ./PATH_TO_GHOST/ghost key inspect-node-key --bin --file PATH_TO_NODE_KEY local identity : ./PATH_TO_GHOST/ghost key inspect-node-key --bin --file PATH_TO_NODE_KEY
Public key (hex) wallet : ./PATH_TO_GHOST/ghost key inspect $(cat PATH_TO_WALLET_KEY) personal wallet : ./PATH_TO_GHOST/ghost key inspect $(cat PATH_TO_WALLET_KEY)
================================================================================================================== =======================================================================================================
Public key (hex) stash : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 $(cat PATH_TO_STASH_KEY) session audi : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//audi"
Public key (hex) audi : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//audi" session babe : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//babe"
Public key (hex) babe : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//babe" session slow : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//slow"
Public key (hex) slow : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//slow" session gran : ./PATH_TO_GHOST/ghost key inspect --scheme=ed25519 "$(cat PATH_TO_SESSION_KEY)//gran"
Public key (hex) gran : ./PATH_TO_GHOST/ghost key inspect --scheme=ed25519 "$(cat PATH_TO_SESSION_KEY)//gran"
### str3tch aka Pierre ### ### str3tch aka Pierre ###
Local identity : 12D3KooWFMiBom4mrJ57CaJZBxKWD1eDLYUyWLZzcjTaQW5crcNQ local identity : 12D3KooWFMiBom4mrJ57CaJZBxKWD1eDLYUyWLZzcjTaQW5crcNQ
Public key (hex) wallet : 0x328d3b7c3046ef7700937d99fb2e98ce2591682c2b5dcf3f562e4da157650237 Public key (hex) wallet : 0x328d3b7c3046ef7700937d99fb2e98ce2591682c2b5dcf3f562e4da157650237
=============================================================================================== ===============================================================================================
Public key (hex) for stash : 0x507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02
Public key (hex) for audi : 0x12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a Public key (hex) for audi : 0x12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a
Public key (hex) for babe : 0xdaaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f Public key (hex) for babe : 0xdaaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f
Public key (hex) for slow : 0x0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35 Public key (hex) for slow : 0x0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35
Public key (hex) for gran : 0x55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64 Public key (hex) for gran : 0x55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64
### Neptune ###
Local identity : 12D3KooWN1hdioQuovznNgw4nNfBqrp2qxJHvr6FdXH5KC55C2c1
Public key (hex) wallet : 0xfa9809611a6930c246fcd138475f1d9b5aa7b12e1573cfea5b40f7ddb24a7c74
===============================================================================================
Public key (hex) for stash : 0x540ef8fceaed7c16cc3df4ec3e282d020983a6a1e895815d1c4ba98b43c92e72
Public key (hex) for audi : 0x6a7d400964de8e7ddbd38c06b8927b0a988372a264b0669bf06819af25f83214
Public key (hex) for babe : 0x14fd4c3e746866cdc42099e33a5c2aea463dd561407c7bc7460eeb869fea5511
Public key (hex) for slow : 0xbc576d9ac94f37c7a3f530ee69774d52cefe2da3e829c430acbff4fb0068ee23
Public key (hex) for gran : 0x43bead3dcea0a48cec725a6b99fb5e3d514779babd1d551868e8673e89802327
### ghost_7 ### ### Cosmos ###
Local identity : 12D3KooWNZYbA3Ty1h8BqfMjzKVeJ83UTJxKUXj9zqnSirJZ51KR local identity : 12D3KooWN1hdioQuovznNgw4nNfBqrp2qxJHvr6FdXH5KC55C2c1
Public key (hex) wallet : 0x3666e4e19f87bb8680495f31864ce1f1c69d4178002cc01911aef2cc7313f203 Public key (hex) wallet : 0xfa9809611a6930c246fcd138475f1d9b5aa7b12e1573cfea5b40f7ddb24a7c74
=============================================================================================== =======================================================================
Public key (hex) for stash : Public key (hex) for audi : 0xe8646430cc92137f8fb722ade64329e76698096185dff4170cae827b5e8bb86b
Public key (hex) for audi : 0x90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17 Public key (hex) for babe : 0xbc576d9ac94f37c7a3f530ee69774d52cefe2da3e829c430acbff4fb0068ee23
Public key (hex) for babe : 0x6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49 Public key (hex) for slow : 0x6a7d400964de8e7ddbd38c06b8927b0a988372a264b0669bf06819af25f83214
Public key (hex) for slow : 0x3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00 Public key (hex) for gran : 0x14fd4c3e746866cdc42099e33a5c2aea463dd561407c7bc7460eeb869fea5511
Public key (hex) for gran : 0x8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d