def serialize(self) -> str: """ Magic bytes (4 bytes) Block header (82 bytes) -> Block version (4 bytes) -> Prev hash (32 bytes) -> Block hash (32 bytes) -> Difficulty bits (4 bytes) -> Timestamp (4 bytes) -> Nonce (6 bytes) """ version = little_endian(num_bytes=4, data=self.version) bits = little_endian(num_bytes=4, data=self.bits) timestamp = little_endian(num_bytes=4, data=self.timestamp) nonce = little_endian(num_bytes=6, data=self.nonce) total = (Config.MAGIC_BYTES + version + self.prev_block_hash + self.id + bits + timestamp + nonce) # Tx_count tx_count = var_int(len(self.txns)) total += tx_count # Tx_data for tx in self.txns: total += tx.serialize() return total
def build_p2pkh(address: str) -> str: """ We have to provide a signature and the original Public Key. <OP_DUP>: (0x76) pushes a copy of the topmost stack item on to the stack. <OP_HASH160>: (0xa9) consumes the topmost item on the stack, computes the RIPEMD160(SHA256()) hash of that item, and pushes that hash onto the stack. <OP_EQUAL>: (0x87) consumes the top two items on the stack, compares them, and pushes true onto the stack if they are the same, false if not. <OP_VERIFY>: (0x69) consumes the topmost item on the stack. If that item is zero (false) it terminates the script in failure. <OP_EQUALVERIFY>: (0x88) runs OP_EQUAL and then OP_VERIFY in sequence. <OP_CHECKSIG>: (0xac) consumes a signature and a full public key, and pushes true onto the stack if the transaction data specified by the SIGHASH flag was converted into the signature using the same ECDSA private key that generated the public key. Otherwise, it pushes false onto the stack. If the byte is < 0x4b (75) it means that is data to push into the STACK """ pub_key_hash = address_to_pubkey(address) count_push = little_endian(num_bytes=1, data=int(len(pub_key_hash) / 2)) # "<OP_DUP><OP_HASH160>len_push pub_key<OP_EQUALVERIFY><OP_CHECKSIG>" script = "76a9" + count_push + pub_key_hash + "88ac" return script
def serialize(self) -> str: tx_id = self.to_spend.txid if self.to_spend.txid == 0: tx_id = Config.COINBASE_TX_ID if self.to_spend.txout_idx == Config.COINBASE_TX_INDEX: vout = Config.COINBASE_TX_INDEX else: vout = little_endian( # type: ignore num_bytes=4, data=self.to_spend.txout_idx) script_sig = self.unlock_sig script_sig_size = var_int(len(script_sig)) sequence = little_endian(num_bytes=4, data=self.sequence) total = (str(tx_id) + vout + str(script_sig_size) + script_sig + sequence) return total
def serialize(self) -> str: # Version serialized_tx = little_endian(num_bytes=2, data=self.version) # INPUTS: serialized_tx += var_int(len(self.txins)) for txin in self.txins: serialized_tx += txin.serialize() # OUTPUTS: serialized_tx += var_int(len(self.txouts)) for txout in self.txouts: serialized_tx += txout.serialize() return serialized_tx
def serialize(self) -> str: value = little_endian(num_bytes=8, data=self.value) script_pub_key = self.to_address script_pub_key_size = var_int(len(script_pub_key)) return value + script_pub_key_size + script_pub_key