def get_spend_output_id(source_id_hexstr, asset_id_hexstr, amount_int, source_position_int, vmversion_int, control_program_hexstr): amount_hexstr = amount_int.to_bytes(8, byteorder='little').hex() source_position_hexstr = source_position_int.to_bytes( 8, byteorder='little').hex() vmversion_hexstr = vmversion_int.to_bytes(8, byteorder='little').hex() cp_length_int = len(control_program_hexstr) // 2 cp_length_hexstr = cp_length_int.to_bytes( (cp_length_int.bit_length() + 7) // 8, byteorder='little').hex() sc_hexstr = source_id_hexstr + asset_id_hexstr + amount_hexstr + source_position_hexstr + vmversion_hexstr + cp_length_hexstr + control_program_hexstr innerhash_bytes = sha3_256(bytes.fromhex(sc_hexstr)).digest() spend_bytes = b'entryid:output1:' + innerhash_bytes spend_output_id_hexstr = sha3_256(spend_bytes).hexdigest() return spend_output_id_hexstr
def get_public_key_hash_with_bytes(public_key_bytes): v = _pysha3.sha3_256() v.update(public_key_bytes[1:]) m = hashlib.new('ripemd160') m.update(v.digest()) return b'\x5A' + m.digest()
def sha3(seed): """ Return sha3-256 of seed in digest :param str seed: data that should be hashed :return str: binary hashed data """ return sha3_256(seed).digest()
def run(self, text): import _pysha3 return _pysha3.sha3_256(text.encode( 'utf-8', errors='surrogateescape')).hexdigest()
def py_sha3(): m = sha3_256() m.update(b'Hello World') return m.hexdigest()
def get_input_id(spend_output_id_hexstr): innerhash_bytes = sha3_256(bytes.fromhex(spend_output_id_hexstr)).digest() input_id_hexstr = sha3_256(b'entryid:spend1:' + innerhash_bytes).hexdigest() return input_id_hexstr
def decode_raw_tx(raw_transaction_str, network_str): tx = { "fee": 0, "inputs": [], "outputs": [], "size": 0, "time_range": 0, "tx_id": "", "version": 0 } tx['fee'] = 0 tx['size'] = len(raw_transaction_str) // 2 length = 0 offset = 2 tx['version'], length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx['time_range'], length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_input_amount, length = get_uvarint(raw_transaction_str[offset:offset + 8]) offset = offset + 2 * length prepare_mux_hexstr = (tx_input_amount).to_bytes( (tx_input_amount.bit_length() + 7) // 8, 'little').hex() prepare_tx_id_hexstr = (tx['version']).to_bytes( 8, 'little').hex() + (tx['time_range']).to_bytes(8, 'little').hex() for _ in range(tx_input_amount): _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length input_type = int(raw_transaction_str[offset:offset + 2], 16) offset += 2 if input_type == 0: # issue tx_input = { "amount": 0, "asset_definition": "", # TODO:fix it!! "asset_id": "", "input_id": "", "issuance_program": "", "type": "", "witness_arguments": [] } tx_input['type'] = "issue" _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length nonce = raw_transaction_str[offset:offset + 16] offset += 16 nonce_hash_hexstr = sha3_256(bytes.fromhex(nonce)).hexdigest() tx_input['asset_id'] = raw_transaction_str[offset:offset + 64] offset += 64 tx_input['amount'], length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length asset_definition_size, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_input['asset_definition'] = bytes.fromhex( raw_transaction_str[offset:offset + 2 * asset_definition_size]).decode() offset = offset + 2 * asset_definition_size _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length issuance_program_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_input['issuance_program'] = raw_transaction_str[ offset:offset + 2 * issuance_program_length] offset = offset + 2 * issuance_program_length witness_arguments_amount, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length for _ in range(witness_arguments_amount): argument_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length argument = raw_transaction_str[offset:offset + 2 * argument_length] offset = offset + 2 * argument_length tx_input['witness_arguments'].append(argument) prepare_issue_hexstr = nonce_hash_hexstr + tx_input['asset_id'] + ( tx_input['amount']).to_bytes(8, byteorder='little').hex() tx_input['input_id'] = get_issue_input_id(prepare_issue_hexstr) tx['inputs'].append(tx_input) prepare_mux_hexstr += tx_input['input_id'] + tx_input[ 'asset_id'] + (tx_input['amount']).to_bytes( 8, byteorder='little').hex() + '0000000000000000' prepare_mux_hexstr += '0100000000000000' + '0151' mux_id_hexstr = get_mux_id(prepare_mux_hexstr) elif input_type == 1: # spend tx_input = { "address": "", "amount": 0, "asset_definition": {}, "asset_id": "", "control_program": "", "input_id": "", "spent_output_id": "", "type": "", "witness_arguments": [] } tx_input['type'] = "spend" _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length source_id = raw_transaction_str[offset:offset + 64] offset += 64 tx_input['asset_id'] = raw_transaction_str[offset:offset + 64] offset += 64 tx_input['amount'], length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx['fee'] += tx_input['amount'] source_positon, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length vmversion, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length control_program_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_input['control_program'] = raw_transaction_str[ offset:offset + 2 * control_program_length] offset = offset + 2 * control_program_length tx_input['address'] = get_address(tx_input['control_program'], network_str) _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length witness_arguments_amount, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length if witness_arguments_amount == 1: offset = offset + 2 tx_input['witness_arguments'] = None else: for _ in range(witness_arguments_amount): argument_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length argument = raw_transaction_str[offset:offset + 2 * argument_length] offset = offset + 2 * argument_length tx_input['witness_arguments'].append(argument) tx_input['spent_output_id'] = get_spend_output_id( source_id, tx_input['asset_id'], tx_input['amount'], source_positon, vmversion, tx_input['control_program']) tx_input['input_id'] = get_input_id(tx_input['spent_output_id']) tx['inputs'].append(tx_input) prepare_mux_hexstr += tx_input['input_id'] + tx_input[ 'asset_id'] + (tx_input['amount']).to_bytes( 8, byteorder='little').hex() + '0000000000000000' prepare_mux_hexstr += '0100000000000000' + '0151' mux_id_hexstr = get_mux_id(prepare_mux_hexstr) elif input_type == 2: # coinbase tx_input = { "amount": 0, "arbitrary": "", "asset_definition": {}, "asset_id": "0000000000000000000000000000000000000000000000000000000000000000", "input_id": "", "type": "", "witness_arguments": [] } tx_input['type'] = "coinbase" arbitrary_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) prepare_coinbase_input_id_hexstr = raw_transaction_str[ offset:offset + 2 * length] offset = offset + 2 * length tx_input['arbitrary'] = raw_transaction_str[offset:offset + 2 * arbitrary_length] prepare_coinbase_input_id_hexstr += tx_input['arbitrary'] offset = offset + 2 * arbitrary_length tx_input['input_id'] = get_coinbase_input_id( prepare_coinbase_input_id_hexstr) offset = offset + 2 tx['inputs'].append(tx_input) prepare_mux_hexstr += tx_input[ 'input_id'] + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' tx_output_amount, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length prepare_tx_id_hexstr += (tx_output_amount).to_bytes( (tx_output_amount.bit_length() + 7) // 8, 'little').hex() for i in range(tx_output_amount): tx_output = { "address": "", "amount": 0, "asset_definition": {}, "asset_id": "", "control_program": "", "id": "", "position": 0, "type": "" } tx_output['position'] = i _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_output['asset_id'] = raw_transaction_str[offset:offset + 64] offset = offset + 64 tx_output['amount'], length = get_uvarint( raw_transaction_str[offset:offset + 18]) if tx_input['type'] == "coinbase": prepare_mux_hexstr = prepare_mux_hexstr + ( tx_output['amount']).to_bytes(8, byteorder='little').hex( ) + '0000000000000000' + '0100000000000000' + '0151' mux_id_hexstr = get_mux_id(prepare_mux_hexstr) offset = offset + 2 * length if tx_output[ 'asset_id'] == 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff': tx['fee'] -= tx_output['amount'] _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length control_program_length, length = get_uvarint( raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length tx_output['control_program'] = raw_transaction_str[ offset:offset + 2 * control_program_length] offset = offset + 2 * control_program_length tx_output['address'] = get_address(tx_output['control_program'], network_str) _, length = get_uvarint(raw_transaction_str[offset:offset + 18]) offset = offset + 2 * length prepare_output_id_hexstr = mux_id_hexstr + tx_output['asset_id'] + ( tx_output['amount']).to_bytes( 8, byteorder='little').hex() + (i).to_bytes( 8, byteorder='little').hex() + '0100000000000000' + ( control_program_length).to_bytes( (control_program_length.bit_length() + 7) // 8, 'little').hex() + tx_output['control_program'] tx_output['id'] = get_output_id(prepare_output_id_hexstr) prepare_tx_id_hexstr += tx_output['id'] tx_output['type'] = 'control' tx['outputs'].append(tx_output) if tx_input['type'] == "coinbase": tx['fee'] = 0 tx['tx_id'] = get_tx_id(prepare_tx_id_hexstr) return tx
def get_coinbase_input_id(prepare_coinbase_input_id_hexstr): innerhash_bytes = sha3_256( bytes.fromhex(prepare_coinbase_input_id_hexstr)).digest() coinbase_input_id_hexstr = sha3_256(b'entryid:coinbase1:' + innerhash_bytes).hexdigest() return coinbase_input_id_hexstr
def get_issue_input_id(prepare_issue_hexstr): innerhash_bytes = sha3_256(bytes.fromhex(prepare_issue_hexstr)).digest() tx_id_hexstr = sha3_256(b'entryid:issuance1:' + innerhash_bytes).hexdigest() return tx_id_hexstr
def get_tx_id(prepare_tx_id_hexstr): innerhash_bytes = sha3_256(bytes.fromhex(prepare_tx_id_hexstr)).digest() tx_id_hexstr = sha3_256(b'entryid:txheader:' + innerhash_bytes).hexdigest() return tx_id_hexstr
def get_output_id(prepare_output_id_hexstr): innerhash_bytes = sha3_256( bytes.fromhex(prepare_output_id_hexstr)).digest() output_id_hexstr = sha3_256(b'entryid:output1:' + innerhash_bytes).hexdigest() return output_id_hexstr
def get_mux_id(prepare_mux_hexstr): innerhash_bytes = sha3_256(bytes.fromhex(prepare_mux_hexstr)).digest() mux_id_hexstr = sha3_256(b'entryid:mux1:' + innerhash_bytes).hexdigest() return mux_id_hexstr