예제 #1
0
def _encode_data_with_bool_prefix(w: bytearray, data: bytes,
                                  expected_length: int):
    if data:
        helpers.write_bool(w, True)
        write_bytes_fixed(w, data, expected_length)
    else:
        helpers.write_bool(w, False)
예제 #2
0
def _encode_proposal(w: bytearray, proposal):
    write_uint8(w, helpers.OP_TAG_PROPOSALS)
    write_bytes_fixed(w, proposal.source, helpers.TAGGED_PUBKEY_HASH_SIZE)
    write_uint32_be(w, proposal.period)
    write_uint32_be(w, len(proposal.proposals) * helpers.PROPOSAL_HASH_SIZE)
    for proposal_hash in proposal.proposals:
        write_bytes_fixed(w, proposal_hash, helpers.PROPOSAL_HASH_SIZE)
예제 #3
0
def generate_proof(
    node: bip32.HDNode,
    script_type: EnumTypeInputScriptType,
    multisig: Optional[MultisigRedeemScriptType],
    coin: CoinInfo,
    user_confirmed: bool,
    ownership_ids: List[bytes],
    script_pubkey: bytes,
    commitment_data: bytes,
) -> Tuple[bytes, bytes]:
    flags = 0
    if user_confirmed:
        flags |= _FLAG_USER_CONFIRMED

    proof = empty_bytearray(4 + 1 + 1 + len(ownership_ids) * _OWNERSHIP_ID_LEN)

    write_bytes_fixed(proof, _VERSION_MAGIC, 4)
    write_uint8(proof, flags)
    write_bitcoin_varint(proof, len(ownership_ids))
    for ownership_id in ownership_ids:
        write_bytes_fixed(proof, ownership_id, _OWNERSHIP_ID_LEN)

    sighash = hashlib.sha256(proof)
    sighash.update(script_pubkey)
    sighash.update(commitment_data)
    signature = common.ecdsa_sign(node, sighash.digest())
    public_key = node.public_key()
    write_bip322_signature_proof(proof, script_type, multisig, coin,
                                 public_key, signature)

    return proof, signature
예제 #4
0
def _encode_manager_delegation(w: bytearray, delegate):
    MICHELSON_LENGTH = 42  # length is fixed this time(no variable length fields)

    _encode_manager_common(w, MICHELSON_LENGTH, "PUSH")
    write_bytes_fixed(w, delegate, helpers.TAGGED_PUBKEY_HASH_SIZE)
    helpers.write_instruction(w, "SOME")
    helpers.write_instruction(w, "SET_DELEGATE")
    helpers.write_instruction(w, "CONS")
예제 #5
0
def write_tx_input_check(w: Writer, i: TxInput) -> None:
    write_bytes_fixed(w, i.prev_hash, TX_HASH_SIZE)
    write_uint32(w, i.prev_index)
    write_uint32(w, i.script_type)
    write_uint32(w, len(i.address_n))
    for n in i.address_n:
        write_uint32(w, n)
    write_uint32(w, i.sequence)
    write_uint64(w, i.amount or 0)
예제 #6
0
def write_tx_input_check(w: Writer, i: TxInput) -> None:
    write_bytes_fixed(w, i.prev_hash, TX_HASH_SIZE)
    write_uint32(w, i.prev_index)
    write_uint32(w, i.script_type)
    write_uint8(w, input_is_external_unverified(i))
    write_uint32(w, len(i.address_n))
    for n in i.address_n:
        write_uint32(w, n)
    write_uint32(w, i.sequence)
    write_uint64(w, i.amount or 0)
    write_bytes_prefixed(w, i.script_pubkey or b"")
예제 #7
0
def _encode_common(w: bytearray, operation, str_operation):
    operation_tags = {
        "reveal": helpers.OP_TAG_REVEAL,
        "transaction": helpers.OP_TAG_TRANSACTION,
        "origination": helpers.OP_TAG_ORIGINATION,
        "delegation": helpers.OP_TAG_DELEGATION,
    }
    write_uint8(w, operation_tags[str_operation])
    write_bytes_fixed(w, operation.source, helpers.TAGGED_PUBKEY_HASH_SIZE)
    _encode_zarith(w, operation.fee)
    _encode_zarith(w, operation.counter)
    _encode_zarith(w, operation.gas_limit)
    _encode_zarith(w, operation.storage_limit)
예제 #8
0
def output_script_sstxchange(addr: str) -> bytearray:
    try:
        raw_address = base58.decode_check(addr, blake256d_32)
    except ValueError:
        raise wire.DataError("Invalid address")

    w = utils.empty_bytearray(26)
    w.append(0xBD)  # OP_SSTXCHANGE
    w.append(0x76)  # OP_DUP
    w.append(0xA9)  # OP_HASH160
    w.append(0x14)  # OP_DATA_20
    write_bytes_fixed(w, raw_address[2:], 20)
    w.append(0x88)  # OP_EQUALVERIFY
    w.append(0xAC)  # OP_CHECKSIG
    return w
예제 #9
0
def _encode_manager_to_implicit_transfer(w: bytearray, manager_transfer):
    MICHELSON_LENGTH = 48

    value_natural = bytearray()
    _encode_natural(value_natural, manager_transfer.amount)
    sequence_length = MICHELSON_LENGTH + len(value_natural)

    _encode_manager_common(w, sequence_length, "PUSH")
    write_bytes_fixed(w, manager_transfer.destination.hash,
                      helpers.TAGGED_PUBKEY_HASH_SIZE)
    helpers.write_instruction(w, "IMPLICIT_ACCOUNT")
    helpers.write_instruction(w, "PUSH")
    helpers.write_instruction(w, "mutez")
    _encode_natural(w, manager_transfer.amount)
    helpers.write_instruction(w, "UNIT")
    helpers.write_instruction(w, "TRANSFER_TOKENS")
    helpers.write_instruction(w, "CONS")
예제 #10
0
def write_auth(w: Writer, auth: EosAuthorization) -> None:
    write_uint32_le(w, auth.threshold)
    write_variant32(w, len(auth.keys))
    for key in auth.keys:
        write_variant32(w, key.type)
        write_bytes_fixed(w, key.key, 33)
        write_uint16_le(w, key.weight)

    write_variant32(w, len(auth.accounts))
    for account in auth.accounts:
        write_uint64_le(w, account.account.actor)
        write_uint64_le(w, account.account.permission)
        write_uint16_le(w, account.weight)

    write_variant32(w, len(auth.waits))
    for wait in auth.waits:
        write_uint32_le(w, wait.wait_sec)
        write_uint16_le(w, wait.weight)
예제 #11
0
def write_tx_input_check(w: Writer, i: TxInput) -> None:
    from .multisig import multisig_fingerprint

    write_uint32(w, len(i.address_n))
    for n in i.address_n:
        write_uint32(w, n)
    write_bytes_fixed(w, i.prev_hash, TX_HASH_SIZE)
    write_uint32(w, i.prev_index)
    write_bytes_prefixed(w, i.script_sig or b"")
    write_uint32(w, i.sequence)
    write_uint32(w, i.script_type)
    multisig_fp = multisig_fingerprint(i.multisig) if i.multisig else b""
    write_bytes_prefixed(w, multisig_fp)
    write_uint64(w, i.amount or 0)
    write_bytes_prefixed(w, i.witness or b"")
    write_bytes_prefixed(w, i.ownership_proof or b"")
    write_bytes_prefixed(w, i.orig_hash or b"")
    write_uint32(w, i.orig_index or 0)
    write_bytes_prefixed(w, i.script_pubkey or b"")
예제 #12
0
def generate_proof(
    node: bip32.HDNode,
    script_type: InputScriptType,
    multisig: MultisigRedeemScriptType | None,
    coin: CoinInfo,
    user_confirmed: bool,
    ownership_ids: list[bytes],
    script_pubkey: bytes,
    commitment_data: bytes,
) -> tuple[bytes, bytes]:
    flags = 0
    if user_confirmed:
        flags |= _FLAG_USER_CONFIRMED

    proof = utils.empty_bytearray(4 + 1 + 1 +
                                  len(ownership_ids) * _OWNERSHIP_ID_LEN)

    write_bytes_fixed(proof, _VERSION_MAGIC, 4)
    write_uint8(proof, flags)
    write_bitcoin_varint(proof, len(ownership_ids))
    for ownership_id in ownership_ids:
        write_bytes_fixed(proof, ownership_id, _OWNERSHIP_ID_LEN)

    sighash = hashlib.sha256(proof)
    sighash.update(script_pubkey)
    sighash.update(commitment_data)
    if script_type in (
            InputScriptType.SPENDADDRESS,
            InputScriptType.SPENDMULTISIG,
            InputScriptType.SPENDWITNESS,
            InputScriptType.SPENDP2SHWITNESS,
    ):
        signature = common.ecdsa_sign(node, sighash.digest())
    elif script_type == InputScriptType.SPENDTAPROOT:
        signature = common.bip340_sign(node, sighash.digest())
    else:
        raise wire.DataError("Unsupported script type.")
    public_key = node.public_key()
    write_bip322_signature_proof(proof, script_type, multisig, coin,
                                 public_key, signature)

    return proof, signature
예제 #13
0
def write_auth(w: Writer, auth: EosAuthorization) -> None:
    write_uint32_le(w, auth.threshold)
    write_uvarint(w, len(auth.keys))
    for key in auth.keys:
        if key.key is None:
            raise wire.DataError("Key must be provided explicitly.")
        write_uvarint(w, key.type)
        write_bytes_fixed(w, key.key, 33)
        write_uint16_le(w, key.weight)

    write_uvarint(w, len(auth.accounts))
    for account in auth.accounts:
        write_uint64_le(w, account.account.actor)
        write_uint64_le(w, account.account.permission)
        write_uint16_le(w, account.weight)

    write_uvarint(w, len(auth.waits))
    for wait in auth.waits:
        write_uint32_le(w, wait.wait_sec)
        write_uint16_le(w, wait.weight)
예제 #14
0
def write_pubkey(w: Writer, address: str) -> None:
    # first 4 bytes of an address are the type, there's only one type (0)
    write_uint32(w, 0)
    write_bytes_fixed(w, public_key_from_address(address), 32)
예제 #15
0
def _encode_ballot(w: bytearray, ballot):
    write_uint8(w, helpers.OP_TAG_BALLOT)
    write_bytes_fixed(w, ballot.source, helpers.TAGGED_PUBKEY_HASH_SIZE)
    write_uint32_be(w, ballot.period)
    write_bytes_fixed(w, ballot.proposal, helpers.PROPOSAL_HASH_SIZE)
    write_uint8(w, ballot.ballot)
예제 #16
0
def _encode_contract_id(w: bytearray, contract_id):
    write_uint8(w, contract_id.tag)
    write_bytes_fixed(w, contract_id.hash, helpers.CONTRACT_ID_SIZE - 1)
예제 #17
0
def _get_operation_bytes(w: bytearray, msg):
    write_bytes_fixed(w, msg.branch, helpers.BRANCH_HASH_SIZE)

    # when the account sends first operation in lifetime,
    # we need to reveal its public key
    if msg.reveal is not None:
        _encode_common(w, msg.reveal, "reveal")
        tag = int(msg.reveal.public_key[0])

        try:
            public_key_size = helpers.PUBLIC_KEY_TAG_TO_SIZE[tag]
        except KeyError:
            raise wire.DataError("Invalid tag in public key")

        write_bytes_fixed(w, msg.reveal.public_key, 1 + public_key_size)

    # transaction operation
    if msg.transaction is not None:
        _encode_common(w, msg.transaction, "transaction")
        _encode_zarith(w, msg.transaction.amount)
        _encode_contract_id(w, msg.transaction.destination)

        # support delegation and transfer from the old scriptless contracts (now with manager.tz script)
        if msg.transaction.parameters_manager is not None:
            parameters_manager = msg.transaction.parameters_manager

            if parameters_manager.set_delegate is not None:
                _encode_manager_delegation(w, parameters_manager.set_delegate)
            elif parameters_manager.cancel_delegate is not None:
                _encode_manager_delegation_remove(w)
            elif parameters_manager.transfer is not None:
                if (parameters_manager.transfer.destination.tag ==
                        TezosContractType.Implicit):
                    _encode_manager_to_implicit_transfer(
                        w, parameters_manager.transfer)
                else:
                    _encode_manager_to_manager_transfer(
                        w, parameters_manager.transfer)
        else:
            if msg.transaction.parameters:
                helpers.write_bool(w, True)
                helpers.check_tx_params_size(msg.transaction.parameters)
                write_bytes_unchecked(w, msg.transaction.parameters)
            else:
                helpers.write_bool(w, False)
    # origination operation
    elif msg.origination is not None:
        _encode_common(w, msg.origination, "origination")
        _encode_zarith(w, msg.origination.balance)
        _encode_data_with_bool_prefix(w, msg.origination.delegate,
                                      helpers.TAGGED_PUBKEY_HASH_SIZE)
        helpers.check_script_size(msg.origination.script)
        write_bytes_unchecked(w, msg.origination.script)

    # delegation operation
    elif msg.delegation is not None:
        _encode_common(w, msg.delegation, "delegation")
        _encode_data_with_bool_prefix(w, msg.delegation.delegate,
                                      helpers.TAGGED_PUBKEY_HASH_SIZE)
    elif msg.proposal is not None:
        _encode_proposal(w, msg.proposal)
    elif msg.ballot is not None:
        _encode_ballot(w, msg.ballot)
예제 #18
0
def sstxcommitment_pkh(pkh: bytes, amount: int) -> bytes:
    w = utils.empty_bytearray(30)
    write_bytes_fixed(w, pkh, 20)
    write_uint64_le(w, amount)
    write_bytes_fixed(w, b"\x00\x58", 2)  # standard fee limits
    return w