What changed, and why it matters
This commit adds a new command-line utility feature to Bitcoin Core. The `bitcoin-util netmagic` command simply prints the network magic bytes (a public identifier for which Bitcoin network is being used, such as mainnet or testnet). It does not change network behavior, wallet handling, or consensus rules, and it introduces no security-relevant code.
No security action needed. This is a routine feature addition.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch adds a netmagic subcommand to bitcoin-util. It calls Params().MessageStart() and returns the hex-encoded chain message start bytes. The implementation rejects any extra arguments and is covered by functional tests for mainnet, regtest, testnet, testnet4, signet, and custom signet. No parsing of untrusted data, no memory handling, and no cryptographic operations are involved beyond existing chain parameter lookups.
Changed components
src/bitcoin-util.cpptest/functional/data/util/bitcoin-util-test.jsonInspect captured patch +75 / −0
diff --git a/doc/release-notes-35610.md b/doc/release-notes-35610.md
new file mode 100644
index 00000000..8e0dd208
--- /dev/null
+++ b/doc/release-notes-35610.md
@@ -0,0 +1,6 @@
+Tools and Utilities
+-------------------
+
+- A new `bitcoin-util netmagic` command returns the network magic of the
+ selected chain.
+
diff --git a/src/bitcoin-util.cpp b/src/bitcoin-util.cpp
index aa3fd306..f17c7a0d 100644
--- a/src/bitcoin-util.cpp
+++ b/src/bitcoin-util.cpp
@@ -36,6 +36,7 @@ static void SetupBitcoinUtilArgs(ArgsManager &argsman)
argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddCommand("grind", "Perform proof of work on hex header string");
+ argsman.AddCommand("netmagic", "Get the network magic bytes of the selected chain");
SetupChainParamsBaseOptions(argsman);
}
@@ -150,6 +151,17 @@ static int Grind(const std::vector<std::string>& args, std::string& strPrint)
return EXIT_SUCCESS;
}
+static int NetMagic(const std::vector<std::string>& args, std::string& strPrint)
+{
+ if (!args.empty()) {
+ strPrint = "netmagic does not take arguments";
+ return EXIT_FAILURE;
+ }
+
+ strPrint = HexStr(Params().MessageStart());
+ return EXIT_SUCCESS;
+}
+
MAIN_FUNCTION
{
ArgsManager& args = gArgs;
@@ -179,6 +191,8 @@ MAIN_FUNCTION
try {
if (cmd->command == "grind") {
ret = Grind(cmd->args, strPrint);
+ } else if (cmd->command == "netmagic") {
+ ret = NetMagic(cmd->args, strPrint);
} else {
assert(false); // unknown command should be caught earlier
}
diff --git a/test/functional/data/util/bitcoin-util-test.json b/test/functional/data/util/bitcoin-util-test.json
index 896decc4..9c37a4e5 100644
--- a/test/functional/data/util/bitcoin-util-test.json
+++ b/test/functional/data/util/bitcoin-util-test.json
@@ -29,6 +29,55 @@
"error_txt": "Could not decode block header",
"description": ""
},
+ {
+ "exec": "./bitcoin-util",
+ "args": ["netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-mainnet.hex",
+ "description": "netmagic returns mainnet magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["-regtest", "netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-regtest.hex",
+ "description": "netmagic returns regtest magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["-testnet", "netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-testnet.hex",
+ "description": "netmagic returns testnet magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["-testnet4", "netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-testnet4.hex",
+ "description": "netmagic returns testnet4 magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["-signet", "netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-signet.hex",
+ "description": "netmagic returns signet magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["-signet", "-signetchallenge=512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae", "netmagic"],
+ "return_code": 0,
+ "output_cmp": "netmagic-signet-custom.hex",
+ "description": "netmagic returns custom signet magic bytes"
+ },
+ {
+ "exec": "./bitcoin-util",
+ "args": ["netmagic", "extra_arg"],
+ "return_code": 1,
+ "error_txt": "netmagic does not take arguments",
+ "description": "netmagic rejects extra arguments"
+ },
{ "exec": "./bitcoin-tx",
"args": ["-create", "nversion=1"],
"output_cmp": "blanktxv1.hex",
diff --git a/test/functional/data/util/netmagic-mainnet.hex b/test/functional/data/util/netmagic-mainnet.hex
new file mode 100644
index 00000000..94b2c335
--- /dev/null
+++ b/test/functional/data/util/netmagic-mainnet.hex
@@ -0,0 +1 @@
+f9beb4d9
diff --git a/test/functional/data/util/netmagic-regtest.hex b/test/functional/data/util/netmagic-regtest.hex
new file mode 100644
index 00000000..e2a9cb27
--- /dev/null
+++ b/test/functional/data/util/netmagic-regtest.hex
@@ -0,0 +1 @@
+fabfb5da
diff --git a/test/functional/data/util/netmagic-signet-custom.hex b/test/functional/data/util/netmagic-signet-custom.hex
new file mode 100644
index 00000000..b24f8cb4
--- /dev/null
+++ b/test/functional/data/util/netmagic-signet-custom.hex
@@ -0,0 +1 @@
+a5df2dcb
diff --git a/test/functional/data/util/netmagic-signet.hex b/test/functional/data/util/netmagic-signet.hex
new file mode 100644
index 00000000..69a8b588
--- /dev/null
+++ b/test/functional/data/util/netmagic-signet.hex
@@ -0,0 +1 @@
+0a03cf40
diff --git a/test/functional/data/util/netmagic-testnet.hex b/test/functional/data/util/netmagic-testnet.hex
new file mode 100644
index 00000000..90b026d4
--- /dev/null
+++ b/test/functional/data/util/netmagic-testnet.hex
@@ -0,0 +1 @@
+0b110907
diff --git a/test/functional/data/util/netmagic-testnet4.hex b/test/functional/data/util/netmagic-testnet4.hex
new file mode 100644
index 00000000..8967d142
--- /dev/null
+++ b/test/functional/data/util/netmagic-testnet4.hex
@@ -0,0 +1 @@
+1c163f28
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.