Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env bash2# Copyright (c) The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or https://opensource.org/license/mit.5export LC_ALL=C.UTF-86set -o errexit -o pipefail8# Source the common prelude, which:9# 1. Checks if we're at the top directory of the Bitcoin Core repository10# 2. Defines a few common functions and variables11#12# shellcheck source=libexec/prelude.bash13source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash"16###################17## Sanity Checks ##18###################20################21# Required non-builtin commands should be invokable22################24check_tools cat env basename mkdir diff sort26if [ -z "$NO_SIGN" ]; then27# make it possible to override the gpg binary28GPG=${GPG:-gpg}30# $GPG can contain extra arguments passed to the binary31# so let's check only the existence of arg[0]32# shellcheck disable=SC220633GPG_ARRAY=($GPG)34check_tools "${GPG_ARRAY[0]}"35fi37################38# Required env vars should be non-empty39################41cmd_usage() {42cat <<EOF43Synopsis:45env GUIX_SIGS_REPO=<path/to/guix.sigs> \\46SIGNER=GPG_KEY_NAME[=SIGNER_NAME] \\47[ NO_SIGN=1 ]48./contrib/guix/guix-attest50Example w/o overriding signing name:52env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\53SIGNER=achow101 \\54./contrib/guix/guix-attest56Example overriding signing name:58env GUIX_SIGS_REPO=/home/dongcarl/guix.sigs \\59SIGNER=0x96AB007F1A7ED999=dongcarl \\60./contrib/guix/guix-attest62Example w/o signing, just creating SHA256SUMS:64env GUIX_SIGS_REPO=/home/achow101/guix.sigs \\65SIGNER=achow101 \\66NO_SIGN=1 \\67./contrib/guix/guix-attest69EOF70}72if [ -z "$GUIX_SIGS_REPO" ] || [ -z "$SIGNER" ]; then73cmd_usage74exit 175fi77################78# GUIX_SIGS_REPO should exist as a directory79################81if [ ! -d "$GUIX_SIGS_REPO" ]; then82cat << EOF83ERR: The specified GUIX_SIGS_REPO is not an existent directory:85'$GUIX_SIGS_REPO'87Hint: Please clone the guix.sigs repository and point to it with the88GUIX_SIGS_REPO environment variable.90EOF91cmd_usage92exit 193fi95################96# The key specified in SIGNER should be usable97################99IFS='=' read -r gpg_key_name signer_name <<< "$SIGNER"100if [ -z "${signer_name}" ]; then101signer_name="$gpg_key_name"102fi104if [ -z "$NO_SIGN" ] && ! ${GPG} --dry-run --list-secret-keys "${gpg_key_name}" >/dev/null 2>&1; then105echo "ERR: GPG can't seem to find any key named '${gpg_key_name}'"106exit 1107fi109################110# We should be able to find at least one output111################113echo "Looking for build output SHA256SUMS fragments in ${OUTDIR_BASE}"115shopt -s nullglob116sha256sum_fragments=( "$OUTDIR_BASE"/*/SHA256SUMS.part ) # This expands to an array of directories...117shopt -u nullglob119noncodesigned_fragments=()120codesigned_fragments=()122if (( ${#sha256sum_fragments[@]} )); then123echo "Found build output SHA256SUMS fragments:"124for outdir in "${sha256sum_fragments[@]}"; do125echo " '$outdir'"126case "$outdir" in127"$OUTDIR_BASE"/*-codesigned/SHA256SUMS.part)128codesigned_fragments+=("$outdir")129;;130*)131noncodesigned_fragments+=("$outdir")132;;133esac134done135echo136else137echo "ERR: Could not find any build output SHA256SUMS fragments in ${OUTDIR_BASE}"138exit 1139fi141##############142## Attest ##143##############145shasum_already_exists() {146cat <<EOF147--149ERR: An ${1} file already exists for '${VERSION}' and attests150differently. You likely previously attested to a partial build (e.g. one151where you specified the HOST environment variable).153See the diff above for more context.155Hint: You may wish to remove the existing attestations and their signatures by156invoking:158rm '${PWD}/${1}'{,.asc}160Then try running this script again.162EOF163}165echo "Attesting to build outputs for version: '${VERSION}'"166echo ""168# Given a SHA256SUMS file as stdin that has lines like:169# 0ba536819b221a91d3d42e978be016aac918f40984754d74058aa0c921cd3ea6 a/b/d/c/d/s/bitcoin-22.0rc2-riscv64-linux-gnu.tar.gz170# ...171#172# Replace each line's file name with its basename:173# 0ba536819b221a91d3d42e978be016aac918f40984754d74058aa0c921cd3ea6 bitcoin-22.0rc2-riscv64-linux-gnu.tar.gz174# ...175#176basenameify_SHA256SUMS() {177sed -E 's@(^[[:xdigit:]]{64}[[:space:]]+).+/([^/]+$)@\1\2@'178}180outsigdir="$GUIX_SIGS_REPO/$VERSION/$signer_name"181mkdir -p "$outsigdir"182(183cd "$outsigdir"185temp_noncodesigned="$(mktemp)"186trap 'rm -rf -- "$temp_noncodesigned"' EXIT188if (( ${#noncodesigned_fragments[@]} )); then189cat "${noncodesigned_fragments[@]}" \190| sort -u \191| sort -k2 \192| basenameify_SHA256SUMS \193> "$temp_noncodesigned"194if [ -e noncodesigned.SHA256SUMS ]; then195# The SHA256SUMS already exists, make sure it's exactly what we196# expect, error out if not197if diff -u noncodesigned.SHA256SUMS "$temp_noncodesigned"; then198echo "A noncodesigned.SHA256SUMS file already exists for '${VERSION}' and is up-to-date."199else200shasum_already_exists noncodesigned.SHA256SUMS201exit 1202fi203else204mv "$temp_noncodesigned" noncodesigned.SHA256SUMS205fi206else207echo "ERR: No noncodesigned outputs found for '${VERSION}', exiting..."208exit 1209fi211temp_all="$(mktemp)"212trap 'rm -rf -- "$temp_all"' EXIT214if (( ${#codesigned_fragments[@]} )); then215# Note: all.SHA256SUMS attests to all of $sha256sum_fragments, but is216# not needed if there are no $codesigned_fragments217cat "${sha256sum_fragments[@]}" \218| sort -u \219| sort -k2 \220| basenameify_SHA256SUMS \221> "$temp_all"222if [ -e all.SHA256SUMS ]; then223# The SHA256SUMS already exists, make sure it's exactly what we224# expect, error out if not225if diff -u all.SHA256SUMS "$temp_all"; then226echo "An all.SHA256SUMS file already exists for '${VERSION}' and is up-to-date."227else228shasum_already_exists all.SHA256SUMS229exit 1230fi231else232mv "$temp_all" all.SHA256SUMS233fi234else235# It is fine to have the codesigned outputs be missing (perhaps the236# detached codesigs have not been published yet), just print a log237# message instead of erroring out238echo "INFO: No codesigned outputs found for '${VERSION}', skipping..."239fi241if [ -z "$NO_SIGN" ]; then242echo "Signing SHA256SUMS to produce SHA256SUMS.asc"243for i in *.SHA256SUMS; do244if [ ! -e "$i".asc ]; then245${GPG} --detach-sign \246--digest-algo sha256 \247--local-user "$gpg_key_name" \248--armor \249--output "$i".asc "$i"250else
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.