bitcoincash.core¶
Everything consensus critical is found in the core subpackage.
core
¶
-
class
bitcoincash.core.
CBlock
(nVersion=2, hashPrevBlock=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', hashMerkleRoot=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', nTime=0, nBits=0, nNonce=0, vtx=())[source]¶ Bases:
bitcoincash.core.CBlockHeader
A block including all transactions in it
Create a new block
-
GetHash
()[source]¶ Return the block hash
Note that this is the hash of the header, not the entire serialized block.
-
static
build_merkle_tree_from_txids
(txids)[source]¶ Build a full CBlock merkle tree from txids
txids - iterable of txids
Returns a new merkle tree in deepest first order. The last element is the merkle root.
WARNING! If you’re reading this because you’re learning about crypto and/or designing a new system that will use merkle trees, keep in mind that the following merkle tree algorithm has a serious flaw related to duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin has since worked around the flaw, but for new applications you should use something different; don’t just copy-and-paste this code without understanding the problem first.
-
calc_merkle_root
()[source]¶ Calculate the merkle root
The calculated merkle root is not cached; every invocation re-calculates it from scratch.
-
vMerkleTree
¶
-
vtx
¶
-
-
class
bitcoincash.core.
CBlockHeader
(nVersion=2, hashPrevBlock=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', hashMerkleRoot=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', nTime=0, nBits=0, nNonce=0)[source]¶ Bases:
bitcoincash.core.serialize.ImmutableSerializable
A block header
-
difficulty
¶
-
hashMerkleRoot
¶
-
hashPrevBlock
¶
-
nBits
¶
-
nNonce
¶
-
nTime
¶
-
nVersion
¶
-
-
class
bitcoincash.core.
CMutableOutPoint
(hash=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', n=4294967295)[source]¶ Bases:
bitcoincash.core.COutPoint
A mutable COutPoint
-
GetHash
()¶ Return the hash of the serialized object
-
-
class
bitcoincash.core.
CMutableTransaction
(vin=None, vout=None, nLockTime=0, nVersion=1)[source]¶ Bases:
bitcoincash.core.CTransaction
A mutable transaction
-
GetHash
()¶ Return the hash of the serialized object
-
-
class
bitcoincash.core.
CMutableTxIn
(prevout=None, scriptSig=CScript([]), nSequence=4294967295)[source]¶ Bases:
bitcoincash.core.CTxIn
A mutable CTxIn
-
GetHash
()¶ Return the hash of the serialized object
-
-
class
bitcoincash.core.
CMutableTxOut
(nValue=-1, scriptPubKey=CScript([]))[source]¶ Bases:
bitcoincash.core.CTxOut
A mutable CTxOut
-
GetHash
()¶ Return the hash of the serialized object
-
-
class
bitcoincash.core.
COutPoint
(hash=b'x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', n=4294967295)[source]¶ Bases:
bitcoincash.core.serialize.ImmutableSerializable
The combination of a transaction hash and an index n into its vout
-
classmethod
from_outpoint
(outpoint)[source]¶ Create an immutable copy of an existing OutPoint
If outpoint is already immutable (outpoint.__class__ is COutPoint) it is returned directly.
-
hash
¶
-
n
¶
-
classmethod
-
class
bitcoincash.core.
CTransaction
(vin=(), vout=(), nLockTime=0, nVersion=1)[source]¶ Bases:
bitcoincash.core.serialize.ImmutableSerializable
A transaction
Create a new transaction
vin and vout are iterables of transaction inputs and outputs respectively. If their contents are not already immutable, immutable copies will be made.
-
classmethod
from_tx
(tx)[source]¶ Create an immutable copy of a pre-existing transaction
If tx is already immutable (tx.__class__ is CTransaction) then it will be returned directly.
-
nLockTime
¶
-
nVersion
¶
-
vin
¶
-
vout
¶
-
classmethod
-
class
bitcoincash.core.
CTxIn
(prevout=COutPoint(), scriptSig=CScript([]), nSequence=4294967295)[source]¶ Bases:
bitcoincash.core.serialize.ImmutableSerializable
An input of a transaction
Contains the location of the previous transaction’s output that it claims, and a signature that matches the output’s public key.
-
classmethod
from_txin
(txin)[source]¶ Create an immutable copy of an existing TxIn
If txin is already immutable (txin.__class__ is CTxIn) it is returned directly.
-
nSequence
¶
-
prevout
¶
-
scriptSig
¶
-
classmethod
-
class
bitcoincash.core.
CTxOut
(nValue=-1, scriptPubKey=CScript([]))[source]¶ Bases:
bitcoincash.core.serialize.ImmutableSerializable
An output of a transaction
Contains the public key that the next input must be able to sign with to claim it.
-
classmethod
from_txout
(txout)[source]¶ Create an immutable copy of an existing TxOut
If txout is already immutable (txout.__class__ is CTxOut) then it will be returned directly.
-
nValue
¶
-
scriptPubKey
¶
-
classmethod
-
bitcoincash.core.
CheckBlock
(block, fCheckPoW=True, fCheckMerkleRoot=True, cur_time=None)[source]¶ Context independent CBlock checks.
Assumes latest consensus rules with regards to block size and sigops count.
CheckBlockHeader() is called first, which may raise a CheckBlockHeader exception, followed the block tests. CheckTransaction() is called for every transaction.
fCheckPoW - Check proof-of-work.
fCheckMerkleRoot - Check merkle root matches transactions.
cur_time - Current time. Defaults to time.time()
-
bitcoincash.core.
CheckBlockHeader
(block_header, fCheckPoW=True, cur_time=None)[source]¶ Context independent CBlockHeader checks.
fCheckPoW - Check proof-of-work.
cur_time - Current time. Defaults to time.time()
Raises CBlockHeaderError if block header is invalid.
-
bitcoincash.core.
CheckProofOfWork
(hash, nBits)[source]¶ Check a proof-of-work
Raises CheckProofOfWorkError
-
bitcoincash.core.
CheckTransaction
(tx)[source]¶ Basic transaction checks that don’t depend on any context.
Raises CheckTransactionError
-
class
bitcoincash.core.
CoreChainParams
[source]¶ Bases:
object
Define consensus-critical parameters of a given instance of the Bitcoin system
-
GENESIS_BLOCK
= None¶
-
MAX_MONEY
= None¶
-
NAME
= None¶
-
PROOF_OF_WORK_LIMIT
= None¶
-
SUBSIDY_HALVING_INTERVAL
= None¶
-
-
class
bitcoincash.core.
CoreMainParams
[source]¶ Bases:
bitcoincash.core.CoreChainParams
-
GENESIS_BLOCK
= CBlock(1, lx(0000000000000000000000000000000000000000000000000000000000000000), lx(4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b), 1231006505, 0x1d00ffff, 0x7c2bac1d)¶
-
MAX_MONEY
= 2100000000000000¶
-
NAME
= 'mainnet'¶
-
PROOF_OF_WORK_LIMIT
= 26959946667150639794667015087019630673637144422540572481103610249215¶
-
SUBSIDY_HALVING_INTERVAL
= 210000¶
-
-
class
bitcoincash.core.
CoreRegTestParams
[source]¶ Bases:
bitcoincash.core.CoreTestNetParams
-
GENESIS_BLOCK
= CBlock(1, lx(0000000000000000000000000000000000000000000000000000000000000000), lx(4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b), 1296688602, 0x207fffff, 0x00000002)¶
-
NAME
= 'regtest'¶
-
PROOF_OF_WORK_LIMIT
= 57896044618658097711785492504343953926634992332820282019728792003956564819967¶
-
SUBSIDY_HALVING_INTERVAL
= 150¶
-
-
class
bitcoincash.core.
CoreTestNetParams
[source]¶ Bases:
bitcoincash.core.CoreMainParams
-
GENESIS_BLOCK
= CBlock(1, lx(0000000000000000000000000000000000000000000000000000000000000000), lx(4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b), 1296688602, 0x1d00ffff, 0x18aea41a)¶
-
NAME
= 'testnet'¶
-
-
exception
bitcoincash.core.
ValidationError
[source]¶ Bases:
Exception
Base class for all blockchain validation errors
Everything that is related to validating the blockchain, blocks, transactions, scripts, etc. is derived from this class.
-
bitcoincash.core.
b2lx
(b)[source]¶ Convert bytes to a little-endian hex string
Lets you show uint256’s and uint160’s the way the Satoshi codebase shows them.
-
bitcoincash.core.
lx
(h)[source]¶ Convert a little-endian hex string to bytes
Lets you write uint256’s and uint160’s the way the Satoshi codebase shows them.
key
¶
ECC secp256k1 crypto routines
WARNING: This module does not mlock() secrets; your private keys may end up on disk in swap! Use with caution!
-
class
bitcoincash.core.key.
CECKey
[source]¶ Bases:
object
Wrapper around OpenSSL’s EC_KEY
-
POINT_CONVERSION_COMPRESSED
= 2¶
-
POINT_CONVERSION_UNCOMPRESSED
= 4¶
-
schnorr
¶
This is a Python-only Schnorr sign/verify. Compared to the libsecp256k1 bundled with Bitcoin Unlimited this is much less secure as it contains side channel vulnerabilities, and must not be used in an automated-signing environment.
-
bitcoincash.core.schnorr.
sign
(privkey, message_hash)[source]¶ Create a Schnorr signature.
Returns a 64-long bytes object (the signature), or raise ValueError on failure. Failure can occur due to an invalid private key.
privkey should be the 32 byte raw private key (as you would get from bitcoin.deserialize_privkey, etc).
message_hash should be the 32 byte sha256d hash of the tx input (or message) you want to sign
-
bitcoincash.core.schnorr.
verify
(pubkey, signature, message_hash)[source]¶ Verify a Schnorr signature, returning True if valid.
May raise a ValueError or return False on failure.
pubkey should be the the raw public key bytes (as you would get from bitcoin.pubic_key_from_private_key, after hex decoding, etc).
signature should be the 64 byte schnorr signature as would be returned from sign above.
message_hash should be the 32 byte sha256d hash of the tx message to be verified
-
bitcoincash.core.schnorr.
is_available
()[source]¶ If Schnorr is available in this installation. Schnorr requires python module ecdsa to be installed.
-
class
bitcoincash.core.schnorr.
BlindSigner
[source]¶ Bases:
object
Schnorr blind signature creator, signer side.
We calculate R = k*G for some secret k, and share R with the requester. Then, upon receiving an e value, we calculate s = k + e*x, where x is our private key, and return s to the requester. The requester can use this to create a valid Schnorr signature from our public key, without us being able to link the exact request to the unblinded signature.
The most CPU-intense part of this is initialization, where the R value is generated.
Security note: If we were to sign two distinct requests for the same R, then our private key could be recovered. Thus, you can only call .sign() once (and this class enforces this restriction in a thread-safe manner). If you need a new blind signature then you must create a new instance.
Security note 2: If an adversary knows that this private key is related to another key (say, they are related by multiplication or addition of a known factor), then the adversary can use blind signatures to get a valid signature from the other key! For example, all keys in a BIP32 “xpub” are related, and so you should seriously avoid using this function with standard BIP32 or any other public key derivation method.
Security note 3: If a blind signer allows multiple blind signature requests to be serviced in parallel (i.e., have multiple .get_R’s issued at the same time, having not yet received the parameters for .sign), then an adversary can perform work and submit carefully designed requests that allow an additional signature to be created. E.g., with 511 parallel requests, 512 signatures could be produced with ~2^35 work of precomputation on the part of the adversary.
See:
- Schnorr 2001 “Security of Blind Discrete Log Signatures against Interactive Attacks” https://www.math.uni-frankfurt.de/~dmst/research/papers/schnorr.blind_sigs_attack.2001.pdf
- Wagner 2002 “A Generalized Birthday Problem” https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf
- A possible solution that should make it so at least 2^70 work is needed to get an additional signature: https://eprint.iacr.org/2019/877
-
order
= <Mock name='mock.SECP256k1.generator.order()' id='140559224422296'>¶
-
class
bitcoincash.core.schnorr.
BlindSignatureRequest
(pubkey, R, message_hash)[source]¶ Bases:
object
Schnorr blind signature creator, requester side.
We expect to be set up with two elliptic curve points (serialized as bytes) – the Blind signer’s public key, and a nonce point whose secret is known by the signer. Also, the 32-byte message_hash should be provided.
Upon construction, this creates and remembers the blinding factors, and also performs the expensive math needed to create the blind signature request. One initialized, call .get_request() to obtain the 32-byte request that should be sent to the signer. Once you get back their 32-byte response, call finalize().
The resultant Schnorr signatures follow the standard BCH Schnorr convention (using Jacobi symbol, pubkey prefixing and SHA256).
Internally we use two random blinding factors a,b. Due to the jacobi thing, we have to also include a signflip factor c = +/- 1.
[signer provides: R = k*G] R’ = c*(R + a*G + b*P) choose c = +1 or -1 such that jacobi(R’.y(), fieldsize) = +1 e’ = Hash(R’.x | ser_compressed(P) | message32) e = c*e’ + b mod n [send to signer: e] [signer provides: s = k + e*x] s’ = c*(s + a) mod n
resulting unblinded signature: (R’.x, s’)
Ref: https://blog.cryptographyengineering.com/a-note-on-blind-signature-schemes/
Expects three bytes objects
-
fieldsize
= <Mock name='mock.SECP256k1.curve.p()' id='140559224432064'>¶
-
finalize
(sbytes, check=True)[source]¶ expects 32 bytes s value, returns 64 byte finished signature
If check=True (default) this will perform a verification of the result. Upon failure it raises RuntimeError. The cause for this error is that the blind signer has provided an incorrect blinded s value.
-
order
= <Mock name='mock.SECP256k1.generator.order()' id='140559224422296'>¶
-
script
¶
Scripts
Functionality to build scripts, as well as SignatureHash(). Script evaluation is in bitcoincash.core.scripteval
-
exception
bitcoincash.core.script.
CScriptInvalidError
[source]¶ Bases:
Exception
Base class for CScript exceptions
-
exception
bitcoincash.core.script.
CScriptTruncatedPushDataError
(msg, data)[source]¶ Bases:
bitcoincash.core.script.CScriptInvalidError
Invalid pushdata due to truncation
-
class
bitcoincash.core.script.
CScript
[source]¶ Bases:
bytes
Serialized script
A bytes subclass, so you can use this directly whenever bytes are accepted. Note that this means that indexing does not work - you’ll get an index by byte rather than opcode. This format was chosen for efficiency so that the general case would not require creating a lot of little CScriptOP objects.
iter(script) however does iterate by opcode.
-
GetSigOpCount
(fAccurate)[source]¶ Get the SigOp count.
fAccurate - Accurately count CHECKMULTISIG, see BIP16 for details.
Note that this is consensus-critical.
-
has_canonical_pushes
()[source]¶ Test if script only uses canonical pushes
Not yet consensus critical; may be in the future.
-
is_p2sh
()[source]¶ Test if the script is a p2sh scriptPubKey
Note that this test is consensus-critical.
-
is_push_only
()[source]¶ Test if the script only contains pushdata ops
Note that this test is consensus-critical.
Scripts that contain invalid pushdata ops return False, matching the behavior in Bitcoin Core.
-
is_valid
()[source]¶ Return True if the script is valid, False otherwise
The script is valid if all PUSHDATA’s are valid; invalid opcodes do not make is_valid() return False.
-
join
(iterable)[source]¶ Concatenate any number of bytes objects.
The bytes whose method is called is inserted in between each pair.
The result is returned as a new bytes object.
Example: b’.’.join([b’ab’, b’pq’, b’rs’]) -> b’ab.pq.rs’.
-
raw_iter
()[source]¶ Raw iteration
Yields tuples of (opcode, data, sop_idx) so that the different possible PUSHDATA encodings can be accurately distinguished, as well as determining the exact opcode byte indexes. (sop_idx)
-
to_p2sh_scriptPubKey
(checksize=True)[source]¶ Create P2SH scriptPubKey from this redeemScript
That is, create the P2SH scriptPubKey that requires this script as a redeemScript to spend.
checksize - Check if the redeemScript is larger than the 520-byte max pushdata limit; raise ValueError if limit exceeded.
Since a >520-byte PUSHDATA makes EvalScript() fail, it’s not actually possible to redeem P2SH outputs with redeem scripts >520 bytes.
-
-
bitcoincash.core.script.
FindAndDelete
(script, sig)[source]¶ Consensus critical, see FindAndDelete() in Satoshi codebase
-
bitcoincash.core.script.
RawSignatureHashLegacy
(script, txTo, inIdx, hashtype)[source]¶ Consensus-correct SignatureHash
This is the old signature hash algorithm, before the Bitcoin Cash split in 2017.
Returns (hash, err) to precisely match the consensus-critical behavior of the SIGHASH_SINGLE bug. (inIdx is not checked for validity)
If you’re just writing wallet software you probably want SignatureHash() instead.
-
bitcoincash.core.script.
SignatureHashLegacy
(script, txTo, inIdx, hashtype)[source]¶ Calculate a signature hash
This is the old signature hash algorithm, before the Bitcoin Cash split in 2017.
‘Cooked’ version that checks if inIdx is out of bounds - this is not consensus-correct behavior, but is what you probably want for general wallet use.
-
bitcoincash.core.script.
SignatureHash
(script, txTo, inIdx, hashtype, amount, *, legacy_allow=False, legacy_raw=False)[source]¶ Calculate a signature hash
legacy_allow - Allow hashing using the pre-fork signature hash algorithm
- legacy_raw - Don’t use the ‘Cooked’ version that checks if inIdx is out
- of bounds.
scripteval
¶
Script evaluation
Be warned that there are highly likely to be consensus bugs in this code; it is unlikely to match Satoshi Bitcoin exactly. Think carefully before using this module.
-
exception
bitcoincash.core.scripteval.
EvalScriptError
(msg, sop=None, sop_data=None, sop_pc=None, stack=None, scriptIn=None, txTo=None, inIdx=None, flags=None, altstack=None, vfExec=None, pbegincodehash=None, nOpCount=None)[source]¶ Bases:
bitcoincash.core.ValidationError
Base class for exceptions raised when a script fails during EvalScript()
The execution state just prior the opcode raising the is saved. (if available)
-
exception
bitcoincash.core.scripteval.
MissingOpArgumentsError
(opcode, s, n, **kwargs)[source]¶ Bases:
bitcoincash.core.scripteval.EvalScriptError
Missing arguments
-
exception
bitcoincash.core.scripteval.
ArgumentsInvalidError
(opcode, msg, **kwargs)[source]¶ Bases:
bitcoincash.core.scripteval.EvalScriptError
Arguments are invalid
-
exception
bitcoincash.core.scripteval.
VerifyOpFailedError
(opcode, **kwargs)[source]¶ Bases:
bitcoincash.core.scripteval.EvalScriptError
A VERIFY opcode failed
-
bitcoincash.core.scripteval.
EvalScript
(stack, scriptIn, txTo, inIdx, flags=(), amount=None)[source]¶ Evaluate a script
stack - Initial stack
scriptIn - Script
txTo - Transaction the script is a part of
inIdx - txin index of the scriptSig
flags - SCRIPT_VERIFY_* flags to apply
amount - The amount in the txin
-
bitcoincash.core.scripteval.
VerifyScript
(scriptSig, scriptPubKey, txTo, inIdx, flags=(), amount=None)[source]¶ Verify a scriptSig satisfies a scriptPubKey
scriptSig - Signature
scriptPubKey - PubKey
txTo - Spending transaction
inIdx - Index of the transaction input containing scriptSig
Raises a ValidationError subclass if the validation fails.
serialize
¶
Serialization routines
You probabably don’t need to use these directly.
-
exception
bitcoincash.core.serialize.
SerializationError
[source]¶ Bases:
Exception
Base class for serialization errors
-
exception
bitcoincash.core.serialize.
SerializationTruncationError
[source]¶ Bases:
bitcoincash.core.serialize.SerializationError
Serialized data was truncated
Thrown by deserialize() and stream_deserialize()
-
exception
bitcoincash.core.serialize.
DeserializationExtraDataError
(msg, obj, padding)[source]¶ Bases:
bitcoincash.core.serialize.SerializationError
Deserialized data had extra data at the end
Thrown by deserialize() when not all data is consumed during deserialization. The deserialized object and extra padding not consumed are saved.
-
bitcoincash.core.serialize.
ser_read
(f, n)[source]¶ Read from a stream safely
Raises SerializationError and SerializationTruncationError appropriately. Use this instead of f.read() in your classes stream_(de)serialization() functions.
-
class
bitcoincash.core.serialize.
Serializable
[source]¶ Bases:
object
Base class for serializable objects
-
class
bitcoincash.core.serialize.
ImmutableSerializable
[source]¶ Bases:
bitcoincash.core.serialize.Serializable
Immutable serializable object
-
class
bitcoincash.core.serialize.
Serializer
[source]¶ Bases:
object
Base class for object serializers
-
class
bitcoincash.core.serialize.
VarIntSerializer
[source]¶ Bases:
bitcoincash.core.serialize.Serializer
Serialization of variable length ints
-
class
bitcoincash.core.serialize.
BytesSerializer
[source]¶ Bases:
bitcoincash.core.serialize.Serializer
Serialization of bytes instances
-
class
bitcoincash.core.serialize.
VectorSerializer
[source]¶ Bases:
bitcoincash.core.serialize.Serializer
Base class for serializers of object vectors
-
class
bitcoincash.core.serialize.
uint256VectorSerializer
[source]¶ Bases:
bitcoincash.core.serialize.Serializer
Serialize vectors of uint256
-
class
bitcoincash.core.serialize.
VarStringSerializer
[source]¶ Bases:
bitcoincash.core.serialize.Serializer
Serialize variable length byte strings
-
bitcoincash.core.serialize.
uint256_from_compact
(c)[source]¶ Convert compact encoding to uint256
Used for the nBits compact encoding of the target in the block header.
-
bitcoincash.core.serialize.
deser_compact_size
(f)[source]