def untrustedHashSign(self, path, pin="", lockTime=0, sighashType=0x01, version=0x02, overwintered=False): if isinstance(pin, str): pin = pin.encode('utf-8') donglePath = parse_bip32_path(path) if self.needKeyCache: self.resolvePublicKeysInPath(path) apdu = [self.BTCHIP_CLA, self.BTCHIP_INS_HASH_SIGN, 0x00, 0x00] params = [] params.extend(donglePath) params.append(len(pin)) params.extend(bytearray(pin)) writeUint32BE(lockTime, params) params.append(sighashType) if overwintered: params.extend(bytearray([0] * 4)) apdu.append(len(params)) apdu.extend(params) result = self.dongle.exchange(bytearray(apdu)) if not result: return result[0] = 0x30 return result
def finalizeInput(self, outputAddress, amount, fees, changePath, rawTx=None): alternateEncoding = False donglePath = parse_bip32_path(changePath) if self.needKeyCache: self.resolvePublicKeysInPath(changePath) result = {} outputs = None if rawTx is not None: try: fullTx = zcashTransaction(bytearray(rawTx)) outputs = fullTx.serializeOutputs() if len(donglePath) != 0: apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_FINALIZE_FULL, 0xFF, 0x00 ] params = [] params.extend(donglePath) apdu.append(len(params)) apdu.extend(params) response = self.dongle.exchange(bytearray(apdu)) offset = 0 while (offset < len(outputs)): blockLength = self.scriptBlockLength if ((offset + blockLength) < len(outputs)): dataLength = blockLength p1 = 0x00 else: dataLength = len(outputs) - offset p1 = 0x80 apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_FINALIZE_FULL, \ p1, 0x00, dataLength ] apdu.extend(outputs[offset:offset + dataLength]) response = self.dongle.exchange(bytearray(apdu)) offset += dataLength alternateEncoding = True except: pass if not alternateEncoding: apdu = [ self.BTCHIP_CLA, self.BTCHIP_INS_HASH_INPUT_FINALIZE, 0x02, 0x00 ] params = [] params.append(len(outputAddress)) params.extend(bytearray(outputAddress)) writeHexAmountBE(btc_to_satoshi(str(amount)), params) writeHexAmountBE(btc_to_satoshi(str(fees)), params) params.extend(donglePath) apdu.append(len(params)) apdu.extend(params) response = self.dongle.exchange(bytearray(apdu)) result['confirmationNeeded'] = response[1 + response[0]] != 0x00 result['confirmationType'] = response[1 + response[0]] if result['confirmationType'] == 0x02: result['keycardData'] = response[1 + response[0] + 1:] if result['confirmationType'] == 0x03: offset = 1 + response[0] + 1 keycardDataLength = response[offset] offset = offset + 1 result['keycardData'] = response[offset:offset + keycardDataLength] offset = offset + keycardDataLength result['secureScreenData'] = response[offset:] if result['confirmationType'] == 0x04: offset = 1 + response[0] + 1 keycardDataLength = response[offset] result['keycardData'] = response[offset + 1:offset + 1 + keycardDataLength] if outputs == None: result['outputData'] = response[1:1 + response[0]] else: result['outputData'] = outputs return result