def get_fees( inputs, outputs ):
    """
    Get (dust fee, op fee) for namespace reveal
    (op fee is 0)
    """
 
    dust_fee = 0
    op_fee = 0
    
    if len(outputs) != 3:
        log.debug("len(outputs) == %s" % len(outputs))
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        log.debug("output[0] is not an OP_RETURN")
        return (None, None) 
   
    # 1: reveal address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        log.debug("output[1] is not a valid script")
        return (None, None)
    
    # 2: change address 
    if virtualchain.script_hex_to_address( outputs[2]["script"] ) is None:
        log.debug("output[2] is not a valid script")
        return (None, None)
    
    # should match make_outputs()
    dust_fee = (len(inputs) + 2) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    return (dust_fee, op_fee)
def get_fees( inputs, outputs ):
    """
    Given a transaction's outputs, look up its fees:
    * the first output should be an OP_RETURN with the transfer info 
    * the second output should be the new owner's address, with a DEFAULT_DUST_FEE
    * the third output should be the change address
    
    Return (dust fees, operation fees) on success 
    Return (None, None) on invalid output listing
    """
    if len(outputs) != 3:
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        return (None, None) 
    
    if outputs[0]["value"] != 0:
        return (None, None) 
    
    # 1: transfer address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        return (None, None)
    
    # 2: change address 
    if virtualchain.script_hex_to_address( outputs[2]["script"] ) is None:
        return (None, None)
    
    # should match make_outputs()
    # the +2 comes from 2 new outputs
    dust_fee = (len(inputs) + 2) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    op_fee = DEFAULT_DUST_FEE
    
    return (dust_fee, op_fee)
def get_fees( inputs, outputs ):
    """
    Given a transaction's outputs, look up its fees:
    * the first output must be an OP_RETURN, and it must have a fee of 0.
    * the second output must be the reveal address, and it must have a dust fee
    * the third must be the change address
    * the fourth, if given, must be a burned fee sent to the burn address
    
    Return (dust fees, operation fees) on success 
    Return (None, None) on invalid output listing
    """
    
    dust_fee = 0
    op_fee = 0
    
    if len(outputs) != 3 and len(outputs) != 4:
        log.debug("len(outputs) == %s" % len(outputs))
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        log.debug("output[0] is not an OP_RETURN")
        return (None, None) 
   
    # 1: reveal address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        log.debug("output[1] is not a standard script")
        return (None, None)
    
    # 2: change address 
    if virtualchain.script_hex_to_address( outputs[2]["script"] ) is None:
        log.debug("output[2] is not a a standard script")
        return (None, None)
    
    # 3: burn address, if given 
    if len(outputs) == 4:
        
        addr_hash = virtualchain.script_hex_to_address( outputs[3]["script"] )
        if addr_hash is None:
            log.debug("output[3] is not a standard script")
            return (None, None) 
        
        if addr_hash != BLOCKSTACK_BURN_ADDRESS:
            log.debug("output[3] is not the burn address %s (got %s)" % (BLOCKSTACK_BURN_ADDRESS, addr_hash))
            return (None, None)
    
        # should match make_outputs().
        # the +3 comes from 1 owner UTXO + 2 new outputs
        dust_fee = (len(inputs) + 3) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
        op_fee = outputs[3]["value"]
        
    else:
        # should match make_outputs().
        # the +2 comes from 1 owner UTXO + 1 new output
        dust_fee = (len(inputs) + 2) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    
    return (dust_fee, op_fee)
def get_fees( inputs, outputs ):
    """
    Given a transaction's outputs, look up its fees:
    * there should be two outputs: the OP_RETURN and change address
    
    Return (dust fees, operation fees) on success 
    Return (None, None) on invalid output listing
    """
    if len(outputs) != 2:
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        return (None, None) 
    
    if outputs[0]["value"] != 0:
        return (None, None) 
    
    # 1: change address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        return (None, None)
    
    # should match make_outputs().
    # the +1 comes from one new output
    dust_fee = (len(inputs) + 1) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    op_fee = 0
    
    return (dust_fee, op_fee)
def get_fees( inputs, outputs ):
    """
    Given a transaction's outputs, look up its fees:
    * the first output must be an OP_RETURN, and it must have a fee of 0.
    # the second must be the change address
    * the third must be a burn fee to the burn address.
    
    Return (dust fees, operation fees) on success 
    Return (None, None) on invalid output listing
    """
    if len(outputs) != 3:
        log.debug("Expected 3 outputs; got %s" % len(outputs))
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        log.debug("outputs[0] is not an OP_RETURN")
        return (None, None) 
    
    if outputs[0]["value"] != 0:
        log.debug("outputs[0] has value %s'" % outputs[0]["value"])
        return (None, None) 
    
    # 1: change address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        log.error("outputs[1] has no decipherable change address")
        return (None, None)
    
    # 2: burn address 
    addr_hash = virtualchain.script_hex_to_address( outputs[2]["script"] )
    if addr_hash is None:
        log.error("outputs[2] has no decipherable burn address")
        return (None, None) 
    
    if addr_hash != BLOCKSTACK_BURN_ADDRESS:
        log.error("outputs[2] is not the burn address (%s)" % BLOCKSTACK_BURN_ADDRESS)
        return (None, None)
    
    # should match make_outputs()
    # the +2 comes from 2 new outputs
    dust_fee = (len(inputs) + 2) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    op_fee = outputs[2]["value"]
    
    return (dust_fee, op_fee)
def get_fees( inputs, outputs ):
    """
    Get (dust fee, op fee) for namespace preorder.
    op fee is the namespace cost (burnt)
    dust fee is the total cost that our outputs must sum to
    """
    if len(outputs) != 3:
        log.debug("Expected 3 outputs; got %s" % len(outputs))
        return (None, None)
    
    # 0: op_return
    if not virtualchain.tx_output_has_data( outputs[0] ):
        log.debug("outputs[0] is not an OP_RETURN")
        return (None, None) 
    
    if outputs[0]["value"] != 0:
        log.debug("outputs[0] has value %s'" % outputs[0]["value"])
        return (None, None) 
    
    # 1: change address 
    if virtualchain.script_hex_to_address( outputs[1]["script"] ) is None:
        log.error("outputs[1] has no decipherable change address")
        return (None, None)
    
    # 2: burn address 
    addr_hash = virtualchain.script_hex_to_address( outputs[2]["script"] )
    if addr_hash is None:
        log.error("outputs[2] has no decipherable burn address")
        return (None, None) 
    
    if addr_hash != BLOCKSTACK_BURN_ADDRESS:
        log.error("outputs[2] is not the burn address (%s)" % BLOCKSTACK_BURN_ADDRESS)
        return (None, None)
   
    # should match make_outputs()
    dust_fee = (len(inputs) + 2) * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    op_fee = outputs[2]["value"]
    
    return (dust_fee, op_fee)
def tx_extract( payload, senders, inputs, outputs, block_id, vtxindex, txid ):
    """
    Extract and return a dict of fields from the underlying blockchain transaction data
    that are useful to this operation.

    Required (+ parse):
    sender:  the script_pubkey (as a hex string) of the principal that sent the name preorder transaction
    address:  the address from the sender script
    recipient:  the script_pubkey (as a hex string) of the principal that is meant to receive the name
    recipient_address:  the address from the recipient script

    Optional:
    sender_pubkey_hex: the public key of the sender
    """
  
    sender_script = None 
    sender_address = None 
    sender_pubkey_hex = None

    recipient = None 
    recipient_address = None 

    try:
       recipient = get_registration_recipient_from_outputs( outputs )
       recipient_address = virtualchain.script_hex_to_address( recipient )

       assert recipient is not None 
       assert recipient_address is not None

       # by construction, the first input comes from the principal
       # who sent the registration transaction...
       assert len(senders) > 0
       assert 'script_pubkey' in senders[0].keys()
       assert 'addresses' in senders[0].keys()

       sender_script = str(senders[0]['script_pubkey'])
       sender_address = str(senders[0]['addresses'][0])

       assert sender_script is not None 
       assert sender_address is not None

       if str(senders[0]['script_type']) == 'pubkeyhash':
          sender_pubkey_hex = get_public_key_hex_from_tx( inputs, sender_address )

    except Exception, e:
       log.exception(e)
       raise Exception("Failed to extract")
示例#8
0
def get_renew_burn_info( outputs ):
    """
    There are four poutputs: the OP_RETURN, the registration (owner)
    address, the change address (i.e. from the preorderer), and the
    burn address with the renewal fee.

    Get the burn address and value
    """
    if len(outputs) < 4:
        raise Exception("Malformed renew outputs: don't have 4")

    burn_addr = virtualchain.script_hex_to_address(outputs[3]['script'])
    if burn_addr is None:
        raise Exception("Malformed renew inputs: burn output is a nonstandard script")

    op_fee = outputs[3]['value']
    return {'burn_address': burn_addr, 'op_fee': op_fee}
def tx_extract(payload, senders, inputs, outputs, block_id, vtxindex, txid):
    """
    Extract and return a dict of fields from the underlying blockchain transaction data
    that are useful to this operation.
    """

    sender_script = None
    sender_address = None
    sender_pubkey_hex = None

    recipient_script = None
    recipient_address = None

    try:
        # first two outputs matter to us
        assert check_tx_output_types(outputs[:2], block_id)

        recipient_script = get_reveal_recipient_from_outputs(outputs)
        recipient_address = virtualchain.script_hex_to_address(
            recipient_script)

        assert recipient_script is not None
        assert recipient_address is not None

        # by construction, the first input comes from the principal
        # who sent the reveal transaction...
        assert len(senders) > 0
        assert 'script_pubkey' in senders[0].keys()
        assert 'addresses' in senders[0].keys()

        sender_script = str(senders[0]['script_pubkey'])
        sender_address = str(senders[0]['addresses'][0])

        assert sender_script is not None
        assert sender_address is not None

        if str(senders[0]['script_type']) == 'pubkeyhash':
            sender_pubkey_hex = get_public_key_hex_from_tx(
                inputs, sender_address)

    except Exception, e:
        log.exception(e)
        raise Exception("No reveal address")
示例#10
0
def scenario(wallets, **kw):
    pubk = virtualchain.lib.ecdsalib.ecdsa_private_key(
        wallets[1].privkey, compressed=True).public_key().to_hex()
    addrhash = virtualchain.lib.hashing.bin_hash160(
        pubk.decode('hex')).encode('hex')
    addrscript = 'a914' + addrhash + '87'
    a = virtualchain.script_hex_to_address(addrscript)

    namespace_preorder_name_hash = blockstack.lib.hashing.hash_name(
        'test', virtualchain.make_payment_script(wallets[0].addr),
        wallets[2].addr)
    print 'hash of {} + {} + {} = {}'.format(
        'test', virtualchain.make_payment_script(wallets[0].addr),
        wallets[2].addr, namespace_preorder_name_hash)

    resp = testlib.blockstack_namespace_preorder("test", wallets[2].addr,
                                                 wallets[0].privkey)
    testlib.next_block(**kw)

    resp = testlib.blockstack_namespace_reveal(
        "test", wallets[2].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    # should fail
    resp = testlib.blockstack_name_import("foo.test",
                                          wallets[0].addr,
                                          "11" * 20,
                                          wallets[2].privkey,
                                          safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    resp = testlib.blockstack_namespace_ready('test',
                                              wallets[2].privkey,
                                              safety_checks=False)
    testlib.next_block(**kw)
示例#11
0
def tx_extract(payload, senders, inputs, outputs, block_id, vtxindex, txid):
    """
    Extract and return a dict of fields from the underlying blockchain transaction data
    that are useful to this operation.

    Required (+ parse):
    sender:  the script_pubkey (as a hex string) of the principal that sent the name preorder transaction
    address:  the address from the sender script
    recipient:  the script_pubkey (as a hex string) of the principal that is meant to receive the name
    recipient_address:  the address from the recipient script

    Optional:
    sender_pubkey_hex: the public key of the sender
    """

    sender_script = None
    sender_address = None
    sender_pubkey_hex = None

    recipient = None
    recipient_address = None
    burn_address = None
    op_fee = None

    op = NAME_REGISTRATION
    opcode = 'NAME_REGISTRATION'

    try:
        # first 2 outputs matter (op_return, owner addr)
        assert check_tx_output_types(outputs[:2], block_id)

        recipient = get_registration_recipient_from_outputs(outputs)
        recipient_address = virtualchain.script_hex_to_address(recipient)

        assert recipient is not None
        assert recipient_address is not None

        # by construction, the first input comes from the principal
        # who sent the registration transaction...
        assert len(senders) > 0
        assert 'script_pubkey' in senders[0].keys()
        assert 'addresses' in senders[0].keys()

        sender_script = str(senders[0]['script_pubkey'])
        sender_address = str(senders[0]['addresses'][0])

        assert sender_script is not None
        assert sender_address is not None

        if str(senders[0]['script_type']) == 'pubkeyhash':
            sender_pubkey_hex = get_public_key_hex_from_tx(
                inputs, sender_address)

        if len(outputs) >= 4:
            # renewing
            burn_info = get_renew_burn_info(outputs)
            burn_address = burn_info['burn_address']
            op_fee = burn_info['op_fee']

            op = '{}{}'.format(NAME_RENEWAL, NAME_RENEWAL)
            opcode = 'NAME_RENEWAL'

    except Exception, e:
        log.exception(e)
        raise Exception("Failed to extract")