- Enforce script size limit when hashing scripts #2794
MAX_SCRIPT_ELEMENT_SIZE
was removed in #2794 you may want to useMAX_REDEEM_SCRIPT_SIZE
or perhapsMAX_STACK_ELEMENT_SIZE
(seebitcoin/src/blockdata/constants
).ecdsa::Error
was replaced byecdsa::DecodeError
andecdsa::ParseSignatureError
(returned byecdsa::Signature::from_slice
andfrom_str
respectively).script::read_scriptint
was move to be a method onPushBytes
.- You can likely just remove the
hashes::Hash
trait import. - Change
OutPoint::default()
toOutPoint::COINBASE_PREVOUT
if appropriate. - Change
TxIn::default()
toTxIn::EMPTY_COINBASE
if appropriate. - Change
to_raw_hash()
toto_byte_array()
. bitcoin::error::UnprefixedHexError
moved tobitcoin::parse::UnprefixedHexError
.
- Backport BIP-32 alias' without typo #3252
- Fix a bug when parsing 256-bit numeric types #2837
Fix things we broke/removed from the Address
API in the last release.
- Enable getting the witness program from an address #2804
- Make
Address:p2sh_from_hash
public #2806 - Add an
AddressData
type #2810
If you are looking for the address::Payload
type we removed in v0.32.0
then the AddressData
type
might be what you are after.
- Bump MSRV to Rust 1.56.1 #2188
- Remove "no-std" feature #2233
- Enforce displaying
Amount
with trailing zeros #2604
- Rename
Signature
field names #2338sig
becomessignature
hash_ty
becomessighash_type
- Rename
txid
tocompute_txid
#2366 - In hardcoded BIP-32 derivation paths: Remove
m/
prefix requirement #2451
This release we continued our effort to split up the library into smaller crates AKA crate smashing.
- Release new
bitcoin-units
crate docs - Release new
base58ck
crate docs - Release new
bitcoin-io
crate docs
- Fix
FeeRate::checked_mul_by_weight
#2182 - Use network when calculating difficulty #2168
- Fix
InputWeightPrediction::P2WPKH_MAX
constant DER sig length #2213 - Fix CJDNS marker byte check #2546
- Add resource limit check during deserialization of Merkle block #2607
In release 0.31.0 we managed to annoy a lot of people by the addition of non_exhaustive
to the
Network
type. After much discussion, and in an effort to cater to multiple camps, we did a bunch
of changes this release. To sum up, "network" is ill defined and it means different things to
different devs/software. Your software should probably have some custom handling of whatever
"network" means to you.
In particular consider having some type that implements AsRef<Params>
, we have attempted to
replace Network
in much of the API (#2541).
- Add
NetworkKind
#2232 - Reduce usage of
Network
in the public API #2541 - Remove
Network
fromAddressInner
#1832 - Add consts to
Params
for individual networks #2396 - Add
params()
method toNetwork
#2172 - Use
KnowHrp`` instead of
Network` #2387 - Add check to max difficulty transition threshold #2337
- Add
CompressedPublicKey
#2277 - Add a
consensus::deserialize_hex
function #2039 - Add
Witness::p2tr_key_spend
function #2097 - Add
taproot::SerializedSignature
#2156 - Add input weight predictions for p2pkh outputs #2185
- Add
Weight::from_vb_weight function
function (added in #2206, renamed in #2228 - Implement
LowerHex
andUpperHex
forCompactTarget
#2221 - Add conversions from TXIDs to Merkle nodes #2227
- Add
transaction::effective_value()
function #2230 - Improve
LockTime
s and related types: - Add and use custom
ArrayVec
- Add the implementation of
Display
fortransaction::Version
#2309 - Add functionality to serialize signatures to a writer #2392
- Add unchecked integer operations to
Amount
andSignedAmount
(add, sum etc.) #2436 - Add methods
p2wpkh_script_code
toScript
andScriptBuf
#2445 - Improve API for signing Taproot inputs in PSBTs #2458
- Add
TapNodeHash
getter method onTapTree
andNodeInfo
#2467 - Add hex parsing to pow types #2514
- Implement
From<core::convert::Infallible>
for errors #2516 - Add ServiceFlags::P2P_V2 #2555
- Require
io::BufRead
instead ofio::Read
in consensus decode trait #2240 - Make
Payload
andAddressEncoding
private #1979 - Remove
bech32
from the public API #2381 - Make from_hex inherent for byte-like types #2491
- Remove the FromHexStr trait #2492
- Split
Prevouts
errors out into specific error types #2042 - Improve error handling in the
sighash
module #2329 - Improve lock time errors #2417
- Split relative locktime error up #2433
- Improve
amount
module errors #2487 - Add the
FromScriptError
for handling errors in address #2497 - Add
NetworkValidationError
#2508 but don't return it #2610 - Improve leaf errors ("leaf" means not enum with nested error type) #2530
- Fix bug in
FeeRate::checked_mul_by_weight
#2128 - Add BIP-32 types remove in 0.31 back in and mark as deprecated #2258
-
Bump MSRV to Rust 1.48.0 #1729
-
Add new example code for signature verification #1776
-
Manually implement
Debug
onWitness
#1913 -
Upgrade to
secp256k1 v0.28.0
#2098 -
Upgrade to
base64 v0.21.3
#2032 -
API Improvements:
- Add kilo weight unit conversion #1735
- Add
ChainHash::from_genesis_block_hash
#1753 - Add implementation of
PartialEq
trait forAddress<NetworkUnchecked>
#1757 - Add unsafe address type conversions #1765
- Add
Inventory::network_hash()
method #515 - Implement
serde::Serialize
forAddress
#1785 - Expose valid (min, max) difficulty transition thresholds #1820
- Add functionality to generate
PrivateKey
#1837 - Allow parsing sub-sat denominations with decimal points #1768
- Fix associated constants of
InputWeightPrediction
#1835 - Add
FeeRate::checked_mul_by_weight
#1864 - Use
Amount
type for theTxOut
value field #1811 - Add support for alloc-free parse errors #1297
- Add
Amount::from_int_btc
#1870 - Make
ckd_priv
function private and implAsRef
forChildNumber
#1882 - Use
hex_lit::hex
in benches (also backported to v0.30.1) #1941 - Add a verify function to
PublicKey
#1911 - Add method
Script::count_sigops
#1890 - Implement
From<PublicKey> for XOnlyPublicKey
#1901 - Implement
From<secp256k1::PublicKey> for bitcoin::PublicKey
#1949 - Add
DerivationPath::to_u32_vec
#1946 - Use
Target
as type forpow_limit
#2107 - Add
Witness::p2wpkh
constructor #2084 - Make
Instruction
be able to read the script number #2081 - Add
Script::is_mulitsig
#2078 - Count sigops for
Transaction
#2073 - Add
Psbt
fee checks #2064 - Add version bytes consts #2020
- Add
transaction::Version
data type #2006
-
Moves, Removes, and renames:
- Move witness types to the script module #1846
- Remove reexport of
psbt::Prevouts
#1872 - Rename
Transaction::is_coin_base
tois_coinbase
#1796 - Rename
TaprootSpendInfo::as_script_map
toscript_map
#1897 - Rename
Script::empty
toScript::new
#1925 - Rename
PartiallySignedTransaction
toPsbt
#1938 - Rename
XpubIdenifier
toXKeyIdentifier
#2021 - Rename
ExtendedPubKey
toXpub
#2019 - Rename
ExtendedPrivKey
toXpriv
#2019 - Remove
_v0
from various function names (eg,new_v0_p2wpkh
) #1994 - Remove
SighashCache::segwit_signature_hash
(addp2wpkh_signiture_hash
andp2wsh_signature_hash
) #1995 - Reexport all the hash types from the crate root #1998
- Rename
opcodes::All
toOpcode
#1995 - Removed
TxOut::default()
, the same logic now exists asTxOut::NULL
#1811 and #1838
-
Error handling improvements:
- Expose valid (min, max) difficulty transition thresholds [#1820](Expose valid (min, max) difficulty transition thresholds)
- Fix compilation when
RUSTFLAGS=--cfg=bench
is set
We now have a website for crates that live under the rust-bitcoin
GitHub organization: https://rust-bitcoin.org/
This release is big, to help users upgrade we wrote a blog post, please see https://rust-bitcoin.org/blog/release-0.30.0/
-
Import
bitcoin_hashes
into this repository. -
Update dependencies we control
- Depend on the new private crate
bitcoin-private
- Depend on the new
bitcoin_hashes
v0.12 - Depend on the new
secp256k1
v0.27
- Depend on the new private crate
-
We moved a lot of modules around, specifically we move basically everything out of
util
. -
API improvements:
- Use marker type to enforce validation of
Address
's network - New
Witness
features Witness
API improvements- Renamed
Script
toScriptBuf
and added a new unsized typeScript
- Add
tapscript_leaf_hash()
toScript
- Unify
TapLeafHash
andTapBranchHash
intoTapNodeHash
while tree construction - Add
Script::builder
convenience function - Implement
PartiallySignedTransaction::fee
- Implement
Script::p2pk_public_key(&self) -> Option<PublicKey>
- Add
log2
toWork
- Add weight utilities to
TxIn
andTxOut
- Add conversions for
TweakedKeyPair
->TweakedPublicKey
- Add
From<Address>
forScriptBuf
- Rename
from_slice
methods todecode
- Add methods for pushing locktimes to scripts
- Create Address::matches_script_pubkey method
- Add API method
absolute::LockTime::is_satisfied_by_lock
- Add
FromHexStr
for parsing strings with and without0x
prefix - Add CentiBitcoin to denominations
- Add
difficulty_float
method forblock::Header
- Use marker type to enforce validation of
-
Various sighash code moves, and type improvements:
-
New types:
-
Removed types/traits:
- Remove
ToHex
- Remove code deprecated in v0.28
- Remove
PackedLockTime
, replace with richerLockTime
everywhere Be aware thatLockTime
does not have anOrd
implementation, so users who need a total ordering on locktimes will be forced to wrap this type. InTransaction
, which contains aLockTime
but isOrd
, we have manually sorted the locktimes based on their consensus encoding. This ordering is somewhat arbitrary -- there is no total ordering on locktimes since they may be measured in either blocks or seconds. - Removed
FromHex
implementation from all types exceptVec
and arrays, replace where appropriate withFromStr
.
- Remove
-
Performance improvements:
- Remove needless allocation from BIP-158 encoding
- Implement fast hex encoding (usage added in a later PR)
-
Testing improvements:
As promised, this is our quick release to bring on edition 2018 by increasing our MSRV to Rust 1.41.1 #983
This work saw a bunch of new language features become available to us. At the
same time we were able to start using rustfmt
. We also started linting as part
of CI.
There are numerous breaking changes in this release related to the new language features but also
other improvements such as more newtypes added. Note that not all changes cause compilation failure!
For example, Witness
serialization was changed
to support human-readable formats.
Detailed list of breaking changes
- Added support for BIP 152 #1088
- Edition 2018 improvements
- Implement
TryFrom
#1007 - Add
non_exhaustive
to all error enums #1026 - Various other improvements, see tracking issue for more information.
- Implement
- Enable
clippy
on CI #1061 - Taproot improvements #950 #936
- serde improvements/changes #1006 #905 #1071 []
- Performance improvements #1033 #996 #1053 #1023
- PSBT improvements #853 [#951] (rust-bitcoin#951) #940
- Script improvements #1021 #954
- New types that may be of interest
- Improve pubkey sorting: #1084
- Introduce
rustfmt
#1040 - Dependencies
- Take
Writer
/Reader
by&mut
in consensus en/decoding #1035 - Consume
self
in conversion methods namedto_*
instead of borrowing #1161
Backported a set of changes from 0.29 which may cause some specific transactions and/or blocks to fail to deserialize. No known such transactions exist on any public blockchain.
At nearly nine months, this is our longest release cycle ever, and thanks to a huge increase in the number of active contributors this year and last, it is also by far our largest release ever, at 148 PRs merged from 23 different contributors. Our primary goal in this release was to introduce support for Taproot and its associated data structures: addresses, taptrees, sighashes, PSBT fields, and more. As it turned out, these changes required (or at least, incentivized) changing a lot of our APIs, causing a significant increase in scope.
We have more big changes coming down the pike. 2022 is going to be a big
year for rust-bitcoin
, which we know is exciting for us but disruptive to
downstream users who ultimately want the library to just work. Our hope is
that by 2023 we will have eliminated large amounts of technical debt,
modernized our APIs to meet current Rust conventions, and clarified the scope
of the individual crates in this ecosystem while still providing the essential
functionality needed by our downstream users, especially wallet projects.
We will also develop a plan to make our releases more predictable and manageable, likely by having scheduled releases with limited scope. We would like to reach a point where we no longer have frequent breaking releases, but right now we are nowhere close.
Upcoming changes will include
- A quick new release which updates our MRSV from 1.29 to 1.41 and does little else
- Updating our codebase to take advantage of the new MSRV, especially regarding nostd and wasm support
- A comprehensive rethinking and flattening of our public-facing APIs
- Richer support for PSBT, Script, and BIP-0340/Schnorr signatures
With so many changes since 0.27, we cannot list every PR. Here are the highlights:
- Remove dangerous
fuzztarget
cargo feature #634 - Improve serde serialization for
Script
#596 - Documentation improvements #623 #633 #663 #689 #704 #744 #852 #869 #865 #864 #858 #806 #877 #912 #923
- Introduce
WitnessVersion
type #617 - Improve error types and API #625
- Implement
Block.get_strippedsize()
andTransaction.get_vsize()
#626 - Add Bloom filter network messages #580
- Taproot: add signature hash support #628 #702 #722 #835 #903 #796
- Taproot: add new Script opcodes #644 #721 #868 #920
- Taproot: add bech32m support, addresses and new key types #563 #691 #697 #728 #696 #757
- Taproot: add taptree data structures #677 #703 #701 #718 #845 #901 #910 #909 #914
- no-std improvements #637
- PSBT improvements, including Taproot #654 #681 #669 #774 #779 #752 #776 #790 #836 #847 #842
- serde improvements #672
- Update rust-secp256k1 dependency #694 #755 #875
- Change BIP32 to use rust-secp256k1 keys rather than rust-bitcoin ones (no compressedness flag) #590 #591
- Rename inner key field in
PrivateKey
andPublicKey
#762 - Address and denomination related changes #768 #784
- Don't allow hybrid EC keys #829
- Change erroneous behavior for
SIGHASH_SINGLE
bug #860 #897 - Delete the deprecated
contracthash
module #871; this functionality will migrate to ElementsProject/rust-elements - Remove compilation-breaking feature-gating of enum variants" #881
Additionally we made several minor API changes (renaming methods, etc.) to improve compliance with modern Rust conventions. Where possible we left the existing methods in place, marked as deprecated.
- Bigendian fixes and CI test
- no_std support, keeping MSRV
- Bech32m adoption
- Use Amount type for dust value calculation
- Errors enum improvements
- std -> core
The previous release changed the behavior of Display
for ChildNumber
, assuming that any correct usage would not be
affected. Issue 608 goes into the details of why this isn't
the case and how we broke both rust-miniscript
and BDK.
- Change Amount Debug impl to BTC with 8 decimals
- Make uint types (un)serializable
- Add more derives for key::Error
- Fix optional amount serialization
- Add PSBT base64 (de)serialization with Display & FromStr
- Add non-API breaking derives for error & transaction types
- Fix error derives
- Add function to check RBF-ness of transactions
- Add Script:dust_value() to get minimum output value for a spk
- Improving bip32 ChildNumber display implementation
- Make Script::fmt_asm a static method and add Script::str_asm
- Return BlockHash from BlockHeader::validate_pow
- Add a method to error on non-standard hashtypes
- Include proprietary key in deserialized PSBT
- Fix Script::dust_value()'s calculation for non-P2*PKH script_pubkeys
- Add Address to optimized QR string conversion
- Correct Transaction struct encode_signing_data_to doc comment
- Fixing CI if base image's apt db is outdated
- Introduce some policy constants from Bitcoin Core
- Fix warnings for sighashtype
- Introduction of Schnorr keys
- Adding constructors for compressed and uncompressed ECDSA keys
- Count bytes read in encoding
- Add verify_with_flags to Script and Transaction
- Fixes documentation intra-links and enforce it
- Fixing hashes core dependency and fuzz feature
- Add signet support
- Add wtxidrelay message and
WTx
inv type for BIP 339 - Add addrv2 support
- Distinguish
FilterHeader
andFilterHash
- Add hash preimage fields to PSBT
- Detect write errors for
PublicKey::write_into
- impl
Ord
andPartialOrd
forInventory
- Add binary encoding for BIP32 xkeys
- Add Taproot Tagged Hashes
- Add
message::MAX_INV_SIZE
constant - impl
ToSocketAddrs
for network addresses - Add new global fields to PSBT
- Serde serialization of PSBT data
- Make
Inventory
andNetworkMessage
enums exhaustive - Add PSBT proprietary keys
- Add
PublicKey::read_from
method symmetric withwrite_to
- Bump rust-secp to 0.20, turn off
recovery
feature by default - Change return value of
consensus_encode
toio::Error
- Remove an incorrect
debug_assert
that can cause a panic when running using the dev profile.
- Expose methods on
Script
to generate various scriptpubkeys - Expose all cargo features of secp256k1
- Allow directly creating various hash newtypes
- Add methods to
Block
to get the coinbase tx and BIP34 height commitment - Add
extend
method to bip32::DerivationPath - Alias
(Fingerprint, DerivationPath)
asKeySource
- Add serde implementation for PSBT data structs
- Add FromStr/Display implementation for SigHashType
- Expose the raw sighash message from sighash computations
- Add support for signmessage/verifymessage style message signatures
- Bump MSRV to 1.29.0
- Remove the
BitcoinHash
trait - Introduce
SigHashCache
structure to replaceSighashComponents
and support all sighash modes - Add
Transaction::get_size
method - Export
util::amount::Denomination
- Add
Block::get_size
andBlock::get_weight
methods - Add
MerkleBlock::from_header_txids
- Add
BlockHeader::u256_from_compact_target
- Add
feefilter
network message - Cleanup/replace
Script::Instructions
iterator API - Disallow uncompressed pubkeys in witness address generation
- Deprecate
util::contracthash
module - Add modulo division operation for
Uint128
andUint256
- Add
slice_to_u64_be
endian conversion method
- Update
secp256k1
dependency to0.17.1
. - Update
bitcoinconsensus
dependency to0.19.0-1
. - Update
bech32
dependency to0.7.2
.
- Add
ServiceFlags
type. - Add
NetworkMessage::command
. - Add
key::Error
. - Add newtypes for specific hashes:
Txid
Wtxid
BlockHash
SigHash
PubkeyHash
ScriptHash
WPubkeyHash
WScriptHash
TxMerkleNode
WitnessMerkleNode
WitnessCommitment
XpubIdentifier
FilterHash
- Refactor
CommandString
. - Refactor
Reject
message. - Rename
RejectReason
enum variants. - Refactor
encode::Error
. - Implement
Default
forTxIn
. - Implement
std::hash::Hash
forInventory
. - Implement
Copy
forInvType
enum. - Use
psbt::Error
inPartiallySignedTransaction::from_unsigned_tx
. - Drop message decode max length to 4_000_000.
- Drop
hex
andbyteorder
dependencies.
- Add serde to
BlockHeader
andBlock
- Clean up
StreamReader
API (breaking change) - Add reject message to p2p messages
- Update
secp256k1
0.15 andbitcoinconsensus
0.17
- Add
Amount
andSignedAmount
types. - Add BIP-158 support with
BlockFilter
and related types. - Add
util::misc::signed_msg_hash()
for signing messages. - Add
MerkleBlock
andPartialMerkleTree
types. - bip32: Support serde serializaton for types and add some utility methods:
ChildNumber::increment
DerivationPath::children_from
DerivationPath::normal_children
DerivationPath::hardened_children
- Add
blockdata::script::Builder::push_verify
to verify-ify an opcode. - Add
sendheaders
network message. - Add
OutPoint::new()
method and JSON-serialize as<txid>:<vout>
. - Refactor
Address
type:- Now supports segwit addresses with version >0.
- Add
Address::from_script
constructor. - Add
Address::address_type
inspector. - Parsing now returns an
address::Error
instead ofencode::Error
. - Removed
bitcoin_bech32
dependency for bech32 payloads.
- bip143: Rename
witness_script
toscript_code
- Rename
BlockHeader::spv_validate
tovalidate_pow
- Rename
OP_NOP2
andOP_NOP3
toOP_CLTV
andOP_CSV
- psbt: Use
BTreeMap
instead ofHashMap
to ensure serialization roundtrips. - Drop
Decimal
type. - Drop
LoneHeaders
type. - Replace
strason
dependency with (optional)serde_json
. - Export the
bitcoin_hashes
andsecp256k1
dependent crates. - Updated
bitcoin_hashes
dependency to v0.7. - Removed
rand
andserde_test
dependencies. - Internal improvements to consensus encoding logic.
- Update
bitcoin-bech32
version to 0.9 - add
to_bytes
method forutil::key
types - add serde impls for
util::key
types - contracthash: minor cleanups, use
util::key
types instead ofsecp256k1
types
- Add some trait impls to
PublicKey
for miniscript interoperability
- Update minimum rustc version to 1.22.
- Replace
rust-crypto
withbitcoin_hashes
; refactor hash types - Remove
Address::p2pk
- Remove misleading blanket
MerkleRoot
implementation; it is now only defined forBlock
- Add BIP157 (client-side block filtering messages)
- Allow network messages to be deserialized even across multiple packets
- Replace all key types to better match abstractions needed for PSBT
- Clean up BIP32 in preparation for PSBT; use new native key types rather than
secp256k1
ones - Remove apparently-used
Option
serialization code - Finally merge PSBT after nearly nine months
- Reorganize opcode types to eliminate unsafe code
- Un-expose some macros that were unintentionally exported
- Update rust-secp256k1 dependency to 0.12
- Remove
util::iter::Pair
type which does not belong in this library - Minor bugfixes and optimizations
- Significant API overhaul:
- Remove
nu_select
macro and low-level networking support - Move
network::consensus_params
toconsensus::params
- Move many other things into
consensus::params
- Move
BitcoinHash
fromnetwork::serialize
toutil::hash
; remove impl forVec<u8>
- Rename/restructure error types
- Rename
Consensus{De,En}coder
toconsensus::{De,En}coder
- Replace
Raw{De,En}coder
with blanket impls ofconsensus::{De,En}coder
onio::Read
andio::Write
- make
serialize
andserialize_hex
infallible
- Remove
- Make 0-input transaction de/serialization always use segwit
- Implement
FromStr
andDisplay
for many more types
- Add serde support for
Address
- Reject non-compact
VarInt
s on various types - Expose many types at the top level of the crate
- Add
Ord
,PartialOrd
impls forScript
- Add regtest network to
Network
enum - Add
Script::is_op_return()
which is more specific thanScript::is_provably_unspendable()
- Update to bech32 0.8.0; add Regtest bech32 address support
- Replace rustc-serialize dependency with hex as a stopgap toward eliminating any extra dependencies for this; clean up the many independent hex encoders and decoders throughout the codebase.
- Add conversions between
ChildNumber
andu32
; make representation non-public; fix documentation - Add several derivation convenience to
bip32
extended keys - Make
deserialize::deserialize()
enforce no trailing bytes - Replace
TxOutRef
withOutPoint
; use it inTxIn
struct. - Use modern
as_
to_
into_
conventions for array-wrapping types; implDisplay
rather thanToString
for most types - Change
script::Instructions
iterator to allow rejecting non-minimal pushes; fix bug where errors would iterate forever. - Overhaul
util::Error
; introduceserialize::Error
and use it forSimpleDecoder
andSimpleDecoder
rather than parameterizing these over their error type. - Overhaul
UDecimal
andDecimal
serialization and parsing and fix many lingering parsing bugs - Update to serde 1.0 and strason 0.4
- Update to secp256k1 0.11.0
- Many, many documentation and test improvements.
- Add
Display
trait to uints,FromStr
trait toNetwork
enum - Add witness inv types to inv enum, constants for Bitcoin regtest network,
is_coin_base
accessor for tx inputs - Expose
merkleroot(Vec<Sha256dHash>)
- Move witnesses inside the
TxIn
structure - Add
Transaction::get_weight()
- Update bip143
sighash_all
API to be more ergonomic
- The in-memory blockchain was moved into a dedicated project rust-bitcoin-chain.
- Removed old script interpreter
- A new optional feature "bitcoinconsensus" lets this library use Bitcoin Core's native
script verifier, wrappend into Rust by the rust-bitcoinconsenus project.
See
Transaction::verify
andScript::verify
methods. - Replaced Base58 traits with
encode_slice
,check_encode_slice
, from andfrom_check
functions in the base58 module. - Un-reversed the Debug output for Sha256dHash
- Add bech32 support
- Support segwit address types
- Remove
num
dependency at Matt's request; agree this is obnoxious to require all downstream users to also have anum
dependency just so they can useUint256::from_u64
.