async def _write_coin_data(self): output = b"" output += VarInt(len(self.inputs)).encode() for coin in self.inputs: output += write_with_length(hash_from_address(coin.get('address'))) output += struct.pack("H", coin.get('assetsChainId')) output += struct.pack("H", coin.get('assetsId')) output += coin.get('amount').to_bytes(32, 'little') # output += struct.pack("Q", coin.get('amount')) output += write_with_length(bytes.fromhex(coin.get('nonce'))) output += bytes([coin.get('locked')]) output += VarInt(len(self.outputs)).encode() for coin in self.outputs: output += write_with_length(hash_from_address(coin.get('address'))) output += struct.pack("H", coin.get('assetsChainId')) output += struct.pack("H", coin.get('assetsId')) # output += struct.pack("Q", coin.get('amount')) output += coin.get('amount').to_bytes(32, 'little') if coin.get('lockTime') == -1: output += bytes.fromhex("ffffffffffffffffff") else: output += struct.pack("Q", coin.get('lockTime')) return output
async def verify_signature(message): """ Verifies a signature of a message, return True if verified, false if not """ loop = asyncio.get_event_loop() sig_raw = base64.b64decode(message['signature']) sender_hash = hash_from_address(message['sender']) (sender_chain_id,) = struct.unpack('h', sender_hash[:2]) verification = await get_verification_buffer(message) try: address = await loop.run_in_executor(None, functools.partial(recover_message_address, sig_raw, verification, chain_id=sender_chain_id)) # address = recover_message_address(sig_raw, verification, # chain_id=sender_chain_id) except Exception: LOGGER.exception("NULS Signature verification error") return False if address != message['sender']: LOGGER.warning('Received bad signature from %s for %s' % (address, message['sender'])) return False else: return True
async def prepare_businessdata_tx(address, utxo, content): tx = await Transaction.from_dict({ "type": 10, "time": int(time.time()), "blockHeight": None, "fee": 0, "remark": b"", "scriptSig": b"", "info": { "logicData": content.hex() }, "inputs": [{ 'fromHash': inp['hash'], 'fromIndex': inp['idx'], 'value': inp['value'], 'lockTime': inp['lockTime'] } for inp in utxo], "outputs": [{ "address": hash_from_address(address), "value": sum([inp['value'] for inp in utxo]), "lockTime": 0 }] }) tx.coin_data.outputs[0].na = (sum([inp['value'] for inp in utxo]) - (await tx.calculate_fee())) return tx
async def to_buffer(cls, md): output = hash_from_address(md['sender']) output += hash_from_address(md['contractAddress']) output += struct.pack("q", md['value']) output += struct.pack("I", md['codeLen']) output += write_with_length(unhexlify(md['code'])) output += struct.pack("q", md['gasLimit']) output += struct.pack("q", md['price']) output += bytes([len(md['args'])]) for arg in md['args']: output += bytes([len(arg)]) for argitem in arg: try: argitem = argitem.encode('utf-8') except UnicodeEncodeError: LOGGER.warning("Unicode encode error here, passing raw value.") output += write_with_length(argitem) return output
async def to_buffer(cls, md): output = hash_from_address(md['sender']) output += hash_from_address(md['contractAddress']) return output