예제 #1
0
def parse_input_txs(input_tx_files):
    input_txs_map = {}
    for input_tx_file in input_tx_files or []:
        input_tx = parse_tx_file(input_tx_file)
        txid = wally.sha256d(wally.tx_to_bytes(input_tx, 0))
        input_txs_map[bytes(txid)] = input_tx
    return input_txs_map
예제 #2
0
def main():
    parser = argparse.ArgumentParser(description="Verify Elements Commitments")
    parser.add_argument("--tx", type=argparse.FileType("r"), required=True)
    parser.add_argument("--blinded",
                        type=argparse.FileType("r"),
                        required=True)
    parser.add_argument("--input-txs", type=argparse.FileType("r"), nargs="+")

    args = parser.parse_args()
    tx = parse_tx_file(args.tx)
    inputs_unblinded, outputs_unblinded = parse_blinded_file(args.blinded)
    input_txs_map = parse_input_txs(args.input_txs)

    ret = {
        "txid": b2h_rev(wally.sha256d(wally.tx_to_bytes(tx, 0))),
        "inputs": [],
        "outputs": [],
    }

    for inp_idx in range(wally.tx_get_num_inputs(tx)):
        input_unblinded = inputs_unblinded.get(inp_idx)
        if not input_unblinded:
            continue
        prev_txid = wally.tx_get_input_txhash(tx, inp_idx)
        prev_vout = wally.tx_get_input_index(tx, inp_idx)
        prev_tx = input_txs_map.get(bytes(prev_txid))
        if not prev_tx:
            continue
        asset_commitment_bin = wally.tx_get_output_asset(prev_tx, prev_vout)
        amount_commitment_bin = wally.tx_get_output_value(prev_tx, prev_vout)
        if asset_commitment_bin != input_unblinded["asset_commitment_bin"]:
            continue
        i = {"vin": inp_idx}
        # TODO: fill also if unblinded
        if input_unblinded.get("asset_id_hex"):
            i["asset"] = input_unblinded["asset_id_hex"]
        if amount_commitment_bin == input_unblinded["amount_commitment_bin"]:
            i["satoshi"] = input_unblinded["amount_satoshi"]

        ret["inputs"].append(i)

    for out_idx in range(wally.tx_get_num_outputs(tx)):
        output_unblinded = outputs_unblinded.get(out_idx)
        if not output_unblinded:
            continue
        asset_commitment_bin = wally.tx_get_output_asset(tx, out_idx)
        amount_commitment_bin = wally.tx_get_output_value(tx, out_idx)
        if asset_commitment_bin != output_unblinded["asset_commitment_bin"]:
            continue
        o = {"vout": out_idx}
        # TODO: fill also if unblinded
        if output_unblinded.get("asset_id_hex"):
            o["asset"] = output_unblinded["asset_id_hex"]
        if amount_commitment_bin == output_unblinded["amount_commitment_bin"]:
            o["satoshi"] = output_unblinded["amount_satoshi"]

        ret["outputs"].append(o)

    print(json.dumps(ret, indent=2))
def check_contract(prev_tx, prev_vout, contract_hash, asset):
    a = wally.hex_from_bytes(wally.hex_to_bytes(prev_tx)[::-1])+wally.hex_from_bytes(struct.pack('<L', int(prev_vout)))
    a = wally.hex_from_bytes(wally.sha256d(wally.hex_to_bytes(a)))
    b = a + contract_hash
    merkle = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(b)))
    c = merkle + '0000000000000000000000000000000000000000000000000000000000000000'
    asset_id = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(c))[::-1])
    return(asset_id == asset)
예제 #4
0
파일: btc_.py 프로젝트: redpola/garecovery
def tx_segwit_hash(tx, i, script, value):
    # BIP143:

    # 1. nVersion
    tx_bin = struct.pack("<L", 1)

    # 2. hashPrevouts
    to_hash = b""
    for inp in tx.txs_in:
        to_hash += inp.previous_hash
        to_hash += struct.pack("<L", inp.previous_index)
    tx_bin += sha256d(to_hash)

    # 3. hashSequence
    to_hash = b"".join(struct.pack("<L", inp.sequence) for inp in tx.txs_in)
    tx_bin += sha256d(to_hash)

    # 4. transaction id and output index of the output spent by this input
    tx_bin += tx.txs_in[i].previous_hash
    tx_bin += struct.pack("<L", tx.txs_in[i].previous_index)

    # 5. subscript of the input
    tx_bin += bc_int(len(script)) + script

    # 6. value of the output spent by this input
    tx_bin += struct.pack("<Q", value)

    # 7. nSequence of the input
    tx_bin += struct.pack("<L", tx.txs_in[i].sequence)

    # 8. hashOutputs
    to_hash = b""
    for out in tx.txs_out:
        to_hash += struct.pack('<Q', out.coin_value)
        to_hash += bc_int(len(out.script)) + out.script
    tx_bin += sha256d(to_hash)

    # 9. nLockTime
    tx_bin += struct.pack("<L", tx.lock_time)

    # 10. hashType
    tx_bin += struct.pack("<L", 0x41)  # BCASH

    return sha256d(tx_bin)
예제 #5
0
def _decrypt_mnemonic(mnemonic, password):
    """Decrypt a 27 word encrypted mnemonic to a 24 word mnemonic"""
    mnemonic = ' '.join(mnemonic.split())
    entropy = bytearray(wally.BIP39_ENTROPY_LEN_288)
    assert wally.bip39_mnemonic_to_bytes(None, mnemonic, entropy) == len(entropy)
    salt, encrypted = entropy[32:], entropy[:32]
    derived = bytearray(64)
    wally.scrypt(password.encode('utf-8'), salt, 16384, 8, 8, derived)
    key, decrypted = derived[32:], bytearray(32)
    wally.aes(key, encrypted, wally.AES_FLAG_DECRYPT, decrypted)
    for i in range(len(decrypted)):
        decrypted[i] ^= derived[i]
    if wally.sha256d(decrypted)[:4] != salt:
        raise exceptions.InvalidMnemonicOrPasswordError('Incorrect password')
    return wally.bip39_mnemonic_from_bytes(None, decrypted)
예제 #6
0
def get_txhash_bin(tx):
    return bytes(wally.sha256d(wally.tx_to_bytes(tx, 0)))
예제 #7
0
        'name': name,
        'ticker': ticker,
        'precision': precision,
        'entity': {
            'domain': domain
        },
        'issuer_pubkey': issuer_pubkey,
        'version': version
    },
    separators=(',', ':'),
    sort_keys=True)
contract_hash = wally.hex_from_bytes(wally.sha256(contract.encode('ascii')))
a = wally.hex_from_bytes(
    wally.hex_to_bytes(prev_tx)[::-1]) + wally.hex_from_bytes(
        struct.pack('<L', int(prev_vout)))
a = wally.hex_from_bytes(wally.sha256d(wally.hex_to_bytes(a)))
b = a + contract_hash
merkle = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(b)))
c = merkle + '0000000000000000000000000000000000000000000000000000000000000000'
merkle = wally.hex_from_bytes(
    wally.sha256_midstate(wally.hex_to_bytes(c))[::-1])
res['asset_id'] = merkle
res['contract'] = contract
res['contract_hash'] = contract_hash

# Create the rawissuance transaction
contract_hash_rev = wally.hex_from_bytes(
    wally.hex_to_bytes(contract_hash)[::-1])
rawissue = host_1.call('rawissueasset', funded['hex'],
                       [{
                           'asset_amount': amount,
예제 #8
0
    def sign_tx(self, details: Dict) -> Dict:
        txhex = details['transaction']['transaction']
        signing_inputs = details['signing_inputs']
        use_ae_protocol = details['use_ae_protocol']
        transaction_outputs = details['transaction_outputs']
        logging.debug('sign liquid txn with %d inputs and %d outputs',
                      len(signing_inputs), len(transaction_outputs))

        def _map_input(input: Dict) -> Dict:
            is_segwit = input['address_type'] in ['p2wsh', 'csv', 'p2sh-p2wpkh', 'p2wpkh']
            mapped = { 'is_witness': is_segwit,
                       'path': input['user_path'],
                       'value_commitment': bytes.fromhex(input['commitment']),
                       'script': bytes.fromhex(input['prevout_script'])}

            # Additional fields to pass through if using the Anti-Exfil protocol
            if use_ae_protocol:
                mapped['ae_host_commitment'] = bytes.fromhex(input['ae_host_commitment'])
                mapped['ae_host_entropy'] = bytes.fromhex(input['ae_host_entropy'])

            return mapped

        # Get inputs and change outputs in form Jade expects
        jade_inputs = list(map(_map_input, signing_inputs))
        change = list(map(self._map_change_output, transaction_outputs))

        # Calculate the hash-prevout from the inputs
        values, abfs, vbfs, input_prevouts = [], [], [], []
        for input in signing_inputs:
            # Get values, abfs and vbfs from inputs (needed to compute the final output vbf)
            values.append(input['satoshi'])
            abfs.append(bytes.fromhex(input['assetblinder'])[::-1])
            vbfs.append(bytes.fromhex(input['amountblinder'])[::-1])

            # Get the input prevout txid and index for hashing later
            input_prevouts.append(bytes.fromhex(input['txhash'])[::-1])
            input_prevouts.append(input['pt_idx'].to_bytes(4, byteorder='little'))

        hash_prevouts = bytes(wally.sha256d(b''.join(input_prevouts)))

        # Get the trusted commitments from Jade
        idx, trusted_commitments = 0, []
        blinded_outputs = transaction_outputs[:-1]  # Assume last output is fee
        for output in blinded_outputs[:-1]:  # Not the last blinded output as we calculate the vbf for that
            commitments = self._get_trusted_commitments(idx, output, hash_prevouts, None)
            trusted_commitments.append(commitments)

            values.append(output['satoshi'])
            abfs.append(commitments['abf'])
            vbfs.append(commitments['vbf'])
            idx += 1

        # Calculate the final vbf
        values.append(blinded_outputs[idx]['satoshi'])
        finalAbf = self.jade.get_blinding_factor(hash_prevouts, idx, 'ASSET')
        abfs.append(finalAbf)
        final_vbf = bytes(wally.asset_final_vbf(values, len(signing_inputs), b''.join(abfs), b''.join(vbfs)))

        # Get the final trusted commitments from Jade (with the calculated vbf)
        commitments = self._get_trusted_commitments(idx, blinded_outputs[idx], hash_prevouts, final_vbf)
        trusted_commitments.append(commitments)

        # Add a 'null' commitment for the final (fee) output
        trusted_commitments.append(None)

        # Sign!
        txn = bytes.fromhex(txhex)
        signatures = self.jade.sign_liquid_tx(self.network, txn, jade_inputs, trusted_commitments, change, use_ae_protocol)
        assert len(signatures) == len(signing_inputs)

        result = {}
        if use_ae_protocol:
            # If using the Anti-Exfil protocol, the response is a list of
            # (signer_commitment, signature), so need to unzip the lists
            signer_commitments, signatures = zip(*signatures)
            signer_commitments = list(map(bytes.hex, signer_commitments))
            result['signer_commitments'] = signer_commitments

        signatures = list(map(bytes.hex, signatures))
        result['signatures'] = signatures

        # Poke the blinding factors into the results structure
        self._populate_result(trusted_commitments, result)

        logging.debug('resolving {}'.format(result))
        return json.dumps(result)
예제 #9
0
    def hash(self) -> bytes:
        """The transaction hash (differs from txid for witness transactions)"""

        return wally.sha256d(self.to_bytes(use_witness=True))
예제 #10
0
    def txid(self) -> bytes:
        """The transaction id"""

        return wally.sha256d(self.to_bytes())
예제 #11
0
BITCOIN = wally.hex_to_bytes(BITCOIN)[::-1]

wally.tx_add_elements_raw_output(
    output_tx,
    None,
    bytearray([0x01]) + BITCOIN,
    wally.tx_confidential_value_from_satoshi(fee),
    None, # nonce
    None, # surjection proof
    None, # range proof
    0)
# end-add_fee

# start-sign
vout = 0
prev_txid = wally.sha256d(wally.tx_to_bytes(tx, 0))
for vin, script_pubkey in zip(vouts_in, script_pubkeys_in):

    wally.tx_add_elements_raw_input(
        output_tx,
        prev_txid,
        vin,
        0xffffffff,
        None, # scriptSig
        None, # witness
        None, # nonce
        None, # entropy
        None, # issuance amount
        None, # inflation keys
        None, # issuance amount rangeproof
        None, # inflation keys rangeproof