コード例 #1
0
 def create_transaction(self, required_data):
     change_address = required_data['transaction'].get('change_address')
     if change_address:
         blinding_pubkey = elements.get_blinding_pubkey(
             self.client,
             h2b(change_address['btc']['blinding_script_hash']))
         return json.dumps(
             {'blinding_keys': {
                 'btc': blinding_pubkey.hex()
             }})
     else:
         return json.dumps({'blinding_keys': {}})
コード例 #2
0
 def get_balance(self, required_data):
     nonces = [
         elements.get_rangeproof_nonce(self.client,
                                       ecdh_pubkey=h2b(script['pubkey']),
                                       script_pubkey=h2b(script['script']))
         for script in required_data['blinded_scripts']
     ]
     assert len(nonces)
     return json.dumps({'nonces': [nonce.hex() for nonce in nonces]})
コード例 #3
0
 def sign_message(self, required_data):
     sig = btc.sign_message(self.client, "Bitcoin", required_data['path'],
                            required_data['message'])
     # TODO: trezor appears to generate a recoverable sig
     sig_der = wally.ec_sig_to_der(sig['signature'][1:])
     return json.dumps({
         'signature':
         sig_der.hex(),
         'signature_b64':
         base64.b64encode(sig['signature']).decode('ascii')
     })
コード例 #4
0
    def sign_tx(self, required_data):
        signing_inputs = required_data['signing_inputs']
        transaction_outputs = required_data['transaction_outputs']
        signing_transactions = required_data['signing_transactions']
        signing_address_types = required_data['signing_address_types']

        scripts = []
        for in_ in signing_inputs:
            service_xpub = deserialize(in_['service_xpub'])
            user_xpub = deserialize(self.as_xpub(in_['user_path'][:-1]))
            pointer = in_['pointer']
            redeem_script = proto.MultisigRedeemScriptType(
                nodes=[user_xpub, service_xpub],
                address_n=[pointer],
                signatures=[b'', b''],
                m=2,
                csv=in_['subtype'])
            scripts.append(redeem_script)

        ins = []
        for i, txin in enumerate(signing_inputs):
            in_ = proto.TxInputType(
                address_n=txin['user_path'],
                prev_hash=h2b(txin['txhash']),
                prev_index=txin['pt_idx'],
                script_type=proto.InputScriptType.SPENDP2SHWITNESS,
                multisig=scripts[i],
                amount=txin['satoshi'],
                sequence=txin['sequence'])
            in_.confidential = proto.TxConfidentialAsset(
                asset=h2b(txin['asset_id'])[::-1],
                amount_blind=h2b(txin['vbf']),
                asset_blind=h2b(txin['abf']))
            ins.append(in_)

        values = []
        in_vbfs = []
        in_abfs = []
        for txin in signing_inputs:
            in_vbfs.append(h2b(txin['vbf']))
            in_abfs.append(h2b(txin['abf']))
            values.append(txin['satoshi'])

        out_vbfs = []
        out_abfs = []
        for i, txout in enumerate(transaction_outputs):
            if txout['is_fee']:
                continue
            out_vbfs.append(
                os.urandom(32))  # TODO: check if HW is going to generate these
            out_abfs.append(
                os.urandom(32))  # TODO: check if HW is going to generate these
            values.append(txout['satoshi'])

        abfs = in_abfs + out_abfs
        vbfs = in_vbfs + out_vbfs[:-1]
        final_vbf = wally.asset_final_vbf(values, len(signing_inputs),
                                          b''.join(abfs), b''.join(vbfs))
        out_vbfs[-1] = final_vbf

        outs = []
        for i, txout in enumerate(transaction_outputs):
            if txout['is_fee']:
                out = proto.TxOutputType(address='', amount=txout['satoshi'])
                out.confidential = proto.TxConfidentialAsset(
                    asset=h2b(txout['asset_id'])[::-1])
            else:
                out = proto.TxOutputType(
                    address=txout['address'],
                    amount=txout['satoshi'],
                    script_type=proto.OutputScriptType.PAYTOADDRESS)
                out.confidential = proto.TxConfidentialAsset(
                    asset=h2b(txout['asset_id'])[::-1],
                    amount_blind=out_vbfs[i],
                    asset_blind=out_abfs[i],
                    nonce_privkey=h2b(txout['eph_keypair_sec']))
            outs.append(out)

        signatures, serialized_tx = btc.sign_tx(
            self.client,
            'Elements',
            ins,
            outs,
            prev_txes=None,
            details=proto.SignTx(version=2,
                                 lock_time=required_data['transaction']
                                 ['transaction_locktime']))

        # with open('tx.txt', 'w') as f:
        #    f.write(serialized_tx.hex())

        asset_commitments = []
        value_commitments = []

        tx = wally.tx_from_bytes(
            serialized_tx,
            wally.WALLY_TX_FLAG_USE_WITNESS | wally.WALLY_TX_FLAG_USE_ELEMENTS)
        for i in range(wally.tx_get_num_outputs(tx)):
            asset_commitments.append(wally.tx_get_output_asset(tx, i))
            value_commitments.append(wally.tx_get_output_value(tx, i))

        out_abfs.append(b'\x00' *
                        32)  # FIXME: GDK enforcing blinding factors for fee
        out_vbfs.append(b'\x00' * 32)

        return json.dumps({
            'signatures': [sig.hex() + '01' for sig in signatures],
            'vbfs': [vbf.hex() for vbf in out_vbfs],
            'abfs': [abf.hex() for abf in out_abfs],
            'asset_commitments':
            [commitment.hex() for commitment in asset_commitments],
            'value_commitments':
            [commitment.hex() for commitment in value_commitments]
        })
コード例 #5
0
 def get_receive_address(self, required_data):
     blinding_pubkey = elements.get_blinding_pubkey(
         self.client, h2b(required_data['address']['blinding_script_hash']))
     return json.dumps({'blinding_key': blinding_pubkey.hex()})
コード例 #6
0
 def get_xpubs(self, required_data):
     return json.dumps({
         'xpubs':
         self.__get_xpubs_from_path_array(required_data['paths'])
     })