def serialize(self): # FIXME: delete '''Returns the byte serialization of the transaction input''' # serialize prev_tx, little endian result = self.prev_tx[::-1] # serialize prev_index, 4 bytes, little endian result += int_to_little_endian(self.prev_index, 4) # serialize the script_sig result += self.script_sig.serialize() # serialize sequence, 4 bytes, little endian result += int_to_little_endian(self.sequence, 4) return result
def mine(block): target = bits_to_target(block.bits) nonce = 0 serialized_block = block.serialize() nonce_index = 76 while True: ser = serialized_block[:76] + int_to_little_endian( nonce, 4) + serialized_block[80:] proof = little_endian_to_int(double_sha256(ser)) if proof < target: block.nonce = int_to_little_endian(nonce, 4) return block else: nonce += 1
def serialize(self): '''Returns the 80 byte block header''' # version - 4 bytes, little endian result = int_to_little_endian(self.version, 4) # prev_block - 32 bytes, little endian result += self.prev_block[::-1] # merkle_root - 32 bytes, little endian result += self.merkle_root[::-1] # timestamp - 4 bytes, little endian result += int_to_little_endian(self.timestamp, 4) # bits - 4 bytes result += self.bits # nonce - 4 bytes result += self.nonce return result
def __init__(self, version=70015, services=0, timestamp=None, receiver_services=0, receiver_ip=b'\x00\x00\x00\x00', receiver_port=8333, sender_services=0, sender_ip=b'\x00\x00\x00\x00', sender_port=8333, nonce=None, user_agent=b'/programmingbitcoin:0.1/', latest_block=0, relay=False): self.version = version self.services = services if timestamp is None: self.timestamp = int(time.time()) else: self.timestamp = timestamp self.receiver_services = receiver_services self.receiver_ip = receiver_ip self.receiver_port = receiver_port self.sender_services = sender_services self.sender_ip = sender_ip self.sender_port = sender_port if nonce is None: self.nonce = int_to_little_endian(randint(0, 2**64), 8) else: self.nonce = nonce self.user_agent = user_agent self.latest_block = latest_block self.relay = relay
def serialize(self): # FIXME: delete '''Returns the byte serialization of the transaction output''' # serialize amount, 8 bytes, little endian result = int_to_little_endian(self.amount, 8) # serialize the script_pubkey result += self.script_pubkey.serialize() return result
def serialize(self): # start with the number of items as a varint result = serialize_varint(len(self.data)) # loop through each tuple (data_type, identifier) in self.data for data_type, identifier in self.data: # data type is 4 bytes Little-Endian result += int_to_little_endian(data_type, 4) # identifier needs to be in Little-Endian result += identifier[::-1] return result
def serialize(self): '''Serialize this message to send over the network''' # protocol version is 4 bytes little-endian result = int_to_little_endian(self.version, 4) # number of hashes is a varint result += serialize_varint(self.num_hashes) # start block is in little-endian result += self.start_block[::-1] # end block is also in little-endian result += self.end_block[::-1] return result
def serialize(self): # FIXME: DELETE '''Returns the byte serialization of the transaction''' # serialize version (4 bytes, little endian) result = int_to_little_endian(self.version, 4) # serialize_varint on the number of inputs result += serialize_varint(len(self.tx_ins)) # iterate inputs for tx_in in self.tx_ins: # serialize each input result += tx_in.serialize() # serialize_varint on the number of outputs result += serialize_varint(len(self.tx_outs)) # iterate outputs for tx_out in self.tx_outs: # serialize each output result += tx_out.serialize() # serialize locktime (4 bytes, little endian) result += int_to_little_endian(self.locktime, 4) return result
def sig_hash(self, input_index, script_pubkey, redeem_script=None): # FIXME: DELETE '''Returns the byte serialization of the transaction''' '''Returns the integer representation of the hash that needs to get signed for index input_index''' # start the serialization with version # use int_to_little_endian in 4 bytes s = int_to_little_endian(self.version, 4) # add how many inputs there are using serialize_varint s += serialize_varint(len(self.tx_ins)) # loop through each input using enumerate, so we have the input index for i, tx_in in enumerate(self.tx_ins): # if the input index is the one we're signing if i == input_index: # if the RedeemScript was passed in, that's the ScriptSig # otherwise the previous tx's ScriptPubkey is the ScriptSig # script_sig = tx_in.script_pubkey(self.testnet) script_sig = script_pubkey # Otherwise, the ScriptSig is empty else: script_sig = None # add the serialization of the input with the ScriptSig we want s += TxIn( prev_tx=tx_in.prev_tx, prev_index=tx_in.prev_index, script_sig=script_sig, sequence=tx_in.sequence, ).serialize() # add how many outputs there are using serialize_varint s += serialize_varint(len(self.tx_outs)) # add the serialization of each output for tx_out in self.tx_outs: s += tx_out.serialize() # add the locktime using int_to_little_endian in 4 bytes s += int_to_little_endian(self.locktime, 4) # add SIGHASH_ALL using int_to_little_endian in 4 bytes s += int_to_little_endian(SIGHASH_ALL, 4) # double_sha256 the serialization h256 = double_sha256(s) # convert the result to an integer using int.from_bytes(x, 'big') return int.from_bytes(h256, 'big')
def serialize(self): '''Serialize this message to send over the network''' # version is 4 bytes little endian result = int_to_little_endian(self.version, 4) # services is 8 bytes little endian result += int_to_little_endian(self.services, 8) # timestamp is 8 bytes little endian result += int_to_little_endian(self.timestamp, 8) # receiver services is 8 bytes little endian result += int_to_little_endian(self.receiver_services, 8) # IPV4 is 10 00 bytes and 2 ff bytes then receiver ip result += b'\x00' * 10 + b'\xff\xff' + self.receiver_ip # receiver port is 2 bytes, big endian result += self.receiver_port.to_bytes(2, 'big') # sender services is 8 bytes little endian result += int_to_little_endian(self.sender_services, 8) # IPV4 is 10 00 bytes and 2 ff bytes then sender ip result += b'\x00' * 10 + b'\xff\xff' + self.sender_ip # sender port is 2 bytes, big endian result += self.sender_port.to_bytes(2, 'big') # nonce should be 8 bytes result += self.nonce # useragent is a variable string, so varint first result += serialize_varint(len(self.user_agent)) result += self.user_agent # latest block is 4 bytes little endian result += int_to_little_endian(self.latest_block, 4) # relay is 00 if false, 01 if true if self.relay: result += b'\x01' else: result += b'\x00' return result
def raw_serialize(self): # initialize what we'll send back result = b'' # go through each cmd for cmd in self.cmds: # if the cmd is an integer, it's an opcode if type(cmd) == int: # turn the cmd into a single byte integer using int_to_little_endian result += int_to_little_endian(cmd, 1) else: # otherwise, this is an element # get the length in bytes length = len(cmd) # for large lengths, we have to use a pushdata opcode if length < 75: # turn the length into a single byte integer result += int_to_little_endian(length, 1) elif length > 75 and length < 0x100: # 76 is pushdata1 result += int_to_little_endian(76, 1) result += int_to_little_endian(length, 1) elif length >= 0x100 and length <= 520: # 77 is pushdata2 result += int_to_little_endian(77, 1) result += int_to_little_endian(length, 2) else: raise ValueError('too long an cmd') result += cmd return result
def serialize(self): '''Returns the byte serialization of the entire network message''' # add the network magic result = self.magic # command 12 bytes # fill with 0's result += self.command + b'\x00' * (12 - len(self.command)) # payload length 4 bytes, little endian result += int_to_little_endian(len(self.payload), 4) # checksum 4 bytes, first four of hash256 of payload result += double_sha256(self.payload)[:4] # payload result += self.payload return result
def mine(block): while not block.check_pow(): block.nonce = int_to_little_endian( little_endian_to_int(block.nonce) + 1, 4) return block