Ejemplo n.º 1
0
def make_synthetic_transaction():
    """
    makes a synthetic transaction with randomized values
    """

    transaction = {}
    transaction['version'] = hconfig.conf["VERSION_NO"]
    transaction['transactionid'] = rcrypt.make_uuid() 
    transaction['locktime'] = 0
    transaction['vin'] = []
    transaction['vout'] = []

    # make vin list
    vin = {}
    vin["txid"] = rcrypt.make_uuid()
    vin["vout_index"] = 0
    vin["ScriptSig"] = []
    vin["ScriptSig"].append(rcrypt.make_uuid())
    vin["ScriptSig"].append(rcrypt.make_uuid())
    transaction['vin'].append(vin)

    # make vout list
    vout = {}
    vout["value"] = secrets.randbelow(10000000) +1000
    vin["ScripPubKey"] = []
    transaction['vout'].append(vout)
    
    return transaction
Ejemplo n.º 2
0
def make_random_transaction(block_height):

    tx = {}
    tx["version"] = "1"
    tx["transactionid"] = rcrypt.make_uuid()
    tx["locktime"] = secrets.randbelow(hconfig.conf["MAX_LOCKTIME"])

    # public-private key pair for previous transaction
    prev_keys = rcrypt.make_ecc_keys()

    # public-private key pair for this transaction
    keys = rcrypt.make_ecc_keys()

    # Build vin
    tx["vin"] = []

    if block_height > 0:
        ctr = secrets.randbelow(hconfig.conf["MAX_INPUTS"]) + 1
        ind = 0
        while ind < ctr:
            signed = rcrypt.sign_message(prev_keys[0], prev_keys[1])
            ScriptSig = []
            ScriptSig.append(signed[0])
            ScriptSig.append(prev_keys[1])

            tx["vin"].append({
                "txid": rcrypt.make_uuid(),
                "vout_index": ctr,
                "ScriptSig": ScriptSig
            })
            ind += 1

    # Build Vout
    tx["vout"] = []

    ctr = secrets.randbelow(hconfig.conf["MAX_OUTPUTS"]) + 1
    ind = 0
    while ind < ctr:

        ScriptPubKey = []
        ScriptPubKey.append("DUP")
        ScriptPubKey.append("HASH-160")
        ScriptPubKey.append(keys[1])
        ScriptPubKey.append("EQ_VERIFY")
        ScriptPubKey.append("CHECK-SIG")

        tx["vout"] = {
            "value": secrets.randbelow(10000000) + 1000000,  # helium cents
            "ScriptPubKey": ScriptPubKey
        }
        ind += 1

    return tx
Ejemplo n.º 3
0
def test_get_existing_tx():
    """
    test getting a block for an existing transaction
    """
    txid = rcrypt.make_uuid()
    blkindex.put_index(txid, 555)
    assert blkindex.get_blockno(txid) == 555
Ejemplo n.º 4
0
def make_synthetic_transaction(prev_tx: "dictionary"):
    """
    makes a synthetic transaction with randomized values and that
    draws inputs from the previous transaction
    """

    transaction = {}
    transaction['version'] = 1
    transaction['transactionid'] = rcrypt.make_uuid() 
    transaction['locktime'] = 0
    transaction['vin'] = []
    transaction['vout'] = []

    num_outputs = max(1, secrets.randbelow(9))

    ctr = 0
    while ctr < num_outputs:
        vout = make_synthetic_vout()
        transaction['vout'].append(vout)
        ctr += 1

    # randomize how many of the previous transaction outputs
    # are consumed and the order in which they are consumed
    num_inputs = max(secrets.randbelow(len(prev_tx["vout"])), 1)
    indices = list(range(num_inputs))
    random.shuffle(indices)

    for ctr in indices:
        vin = make_synthetic_vin(prev_tx["transactionid"], ctr)
        transaction['vin'].append(vin)
        ctr += 1

    return transaction
def make_synthetic_blocks(num_blocks):
    """
    make synthetic blocks for unit testing
    add the blocks to the blockchain
    """

    for ctr in range(num_blocks):

        block = {}
        block["transactionid"] = rcrypt.make_uuid()
        block["version"] = hconfig.conf["VERSION_NO"]
        block["difficulty_bits"] = hconfig.conf["DIFFICULTY_BITS"]
        block["nonce"] = hconfig.conf["NONCE"]
        block["height"] = ctr
        block["timestamp"] = int(time.time())
        block["tx"] = []

        # add transactions to the block
        num_tx = secrets.randbelow(5) + 1
        for __ctr in range(num_tx):
            trx = make_synthetic_transaction(block)
            block["tx"].append(trx)

        block["merkle_root"] = hblockchain.merkle_root(block["tx"], True)

        if ctr == 0:
            block["prevblockhash"] = ""
        else:
            block["prevblockhash"] = hblockchain.blockheader_hash(
                hblockchain.blockchain[ctr - 1])

        # append block to blockchain
        hblockchain.blockchain.append(block)

    return
def test_invalid_txid_length():
    """
    test a previous transaction id for length
    """
    txn = make_synthetic_transaction(2)
    id = rcrypt.make_uuid()
    id = "p" + id[0:]
    indices = randomize_list(txn['vin'])

    ctr = secrets.randbelow(len(indices))
    txn['vin'][indices[ctr]]['txid'] = id
    assert tx.validate_transaction(txn) == False
Ejemplo n.º 7
0
def test_genesis_block_prev_hash(monkeypatch):
    """
    test that the previous block hash for the genesis block is empty
    """
    hblockchain.blockchain.clear()
    monkeypatch.setattr(hblockchain, "merkle_root",
                        lambda x, y: rcrypt.make_SHA256_hash('msg0'))
    monkeypatch.setitem(block_0, "height", 0)
    monkeypatch.setitem(block_0, "prevblockhash", rcrypt.make_uuid())

    assert len(hblockchain.blockchain) == 0
    assert hblockchain.add_block(block_0) == False
Ejemplo n.º 8
0
def make_synthetic_block():
    """
    make synthetic block for unit testing
    """
    block = {}
    block["transactionid"] = rcrypt.make_uuid()
    block["version"] = hconfig.conf["VERSION_NO"]
    block["difficulty_bits"] = hconfig.conf["DIFFICULTY_BITS"]
    block["nonce"] = hconfig.conf["NONCE"]
    block["height"] = 1024
    block["timestamp"] = int(time.time())    
    block["tx"] = []

    # add transactions to the block
    num_tx = secrets.randbelow(6) + 2
    for __ctr in range(num_tx):
        trx = make_synthetic_transaction()
        block["tx"].append(trx)

    block["merkle_root"] =  hblockchain.merkle_root(block["tx"], True)
    block["prevblockhash"] =rcrypt.make_uuid()

    return block
Ejemplo n.º 9
0
def make_coinbase_transaction(block_height: "integer",
                              pubkey: "string") -> 'dict':
    """
    makes a coinbase transaction, this is the miner's reward for mining 
    a block. Receives a public key to denote ownership of the reward. 
    Since this is a fresh issuance of heliums there are no vin elements.
    locks the transaction for hconfig["COINBASE_INTERVAL"] blocks.
    Returns the coinbase transaction.
    """
    try:
        # calculate the mining reward
        reward = mining_reward(block_height)

        # create a coinbase transaction
        trx = {}
        trx['transactionid'] = rcrypt.make_uuid()
        trx['version'] = hconfig.conf["VERSION_NO"]
        # the mining reward cannot be claimed until approximately 100 blocks are mined
        # convert into a time interval
        trx['locktime'] = hconfig.conf["COINBASE_INTERVAL"] * 600
        trx['vin'] = []
        trx['vout'] = []

        ScriptPubKey = []
        ScriptPubKey.append('SIG')
        ScriptPubKey.append(
            rcrypt.make_RIPEMD160_hash(rcrypt.make_SHA256_hash(pubkey)))
        ScriptPubKey.append('<DUP>')
        ScriptPubKey.append('<HASH_160>')
        ScriptPubKey.append('HASH-160')
        ScriptPubKey.append('<EQ-VERIFY>')
        ScriptPubKey.append('<CHECK_SIG>')

        # create the vout element with the reward
        trx['vout'].append({'value': reward, 'ScriptPubKey': ScriptPubKey})

    except Exception as err:
        logging.debug('make_coinbase_transaction: exception: ' + str(err))

    return trx
def make_synthetic_previous_transaction(num_outputs):
    """
    makes synthetic previous transaction with randomized values
    we abstract away the inputs to the previous transaction.
    """
    transaction = {}
    transaction['version'] = 1
    transaction['transactionid'] = rcrypt.make_uuid() 
    transaction['locktime'] = 0
    transaction['vin'] = []
    transaction['vout'] = []

    def make_synthetic_vout():
        """
        make a synthetic vout object.
        returns a vout dictionary item
        """
        key_pair = rcrypt.make_ecc_keys()
        global prev_tx_keys
        prev_tx_keys.append([key_pair[0],key_pair[1]])
        vout = {}
        vout['value'] = secrets.randbelow(1000000) + 1000  # helium cents
        
        tmp = []
        tmp.append('<DUP>')
        tmp.append('<HASH-160>')
        tmp.append(key_pair[1])
        tmp.append('<EQ-VERIFY>')
        tmp.append('<CHECK-SIG>')
        vout['ScriptPubKey'] = tmp
        return vout

    ctr = 0
    while ctr < num_outputs:
        ret = make_synthetic_vout()
        transaction['vout'].append(ret)

        ctr += 1
   
    return transaction
def make_synthetic_transaction(block):
    """
    makes a synthetic transaction with randomized values
    """

    transaction = {}
    transaction['version'] = hconfig.conf["VERSION_NO"]
    transaction['transactionid'] = rcrypt.make_uuid()
    transaction['locktime'] = 0
    transaction['vin'] = []
    transaction['vout'] = []

    # make public-private key pair for the transaction
    pair = rcrypt.make_ecc_keys()
    tx_keys[transaction["transactionid"]] = pair

    # make vin list
    # genesis block does not have inputs
    if block["height"] > 0:
        num_inputs = secrets.randbelow(3) + 1
        for ctr in range(num_inputs):
            trx = make_synthetic_vin(transaction, ctr)
            if trx == False: break
            transaction["vin"].append(trx)

    # make vout list
    num_outputs = secrets.randbelow(5) + 1
    ctr = 0
    for ctr in range(num_outputs):
        vout = make_synthetic_vout(block, transaction, ctr, pair[1])
        if vout != False: transaction["vout"].append(vout)

    block["tx"].append(transaction)
    hchaindb.transaction_update(transaction)

    return transaction
def make_random_transaction(blockno, is_coinbase):

    txn = {}
    txn["version"] = "1"
    txn["transactionid"] = rcrypt.make_uuid()
    if is_coinbase == True: txn["locktime"] = hconfig.conf["COINBASE_LOCKTIME"]
    else: txn["locktime"] = 0

    # the public-private key pair for this transaction
    transaction_keys = rcrypt.make_ecc_keys()

    # previous transaction fragments spent by this transaction
    total_spendable = 0

    #######################
    # Build the vin array
    #######################
    txn["vin"] = []

    # genesis block transactions have no prior inputs.
    # coinbase transactions do not have any inputs
    if (blockno > 0) and (is_coinbase != True):
        max_inputs = secrets.randbelow(hconfig.conf["MAX_INPUTS"])
        if max_inputs == 0: max_inputs = hconfig.conf["MAX_INPUTS"] - 1

        # get some random previous unspent transaction
        # fragments to spend
        ind = 0
        ctr = 0

        while ind < max_inputs:
            # get a random unspent fragment from a previous block
            index = secrets.randbelow(len(unspent_fragments))
            frag_dict = unspent_fragments[index]
            key = [*frag_dict.keys()][0]
            val = [*frag_dict.values()][0]
            if val["blockno"] == blockno:
                ctr += 1
                if ctr == 10000:
                    print("failed to get random unspent fragment")
                    return False
                continue

            unspent_fragments.pop(index)

            total_spendable += val["value"]
            tmp = hchaindb.get_transaction(key)
            if tmp == False:
                print("cannot get fragment from chainstate: " + key)

            assert tmp != False
            assert tmp["spent"] == False
            assert tmp["value"] > 0

            # create a random vin element
            key_array = key.split("_")

            signed = rcrypt.sign_message(val["privkey"], val["pubkey"])
            ScriptSig = []
            ScriptSig.append(signed)
            ScriptSig.append(val["pubkey"])

            txn["vin"].append({
                "txid": key_array[0],
                "vout_index": int(key_array[1]),
                "ScriptSig": ScriptSig
            })

            ctr = 0
            ind += 1

    #####################
    # Build Vout list
    #####################
    txn["vout"] = []

    # genesis block
    if blockno == 0:
        total_spendable = secrets.randbelow(10_000_000) + 50_000

    # we need at least one transaction output for non-coinbase
    # transactions
    if is_coinbase == True: max_outputs = hconfig.conf["MAX_OUTPUTS"]
    else:
        max_outputs = secrets.randbelow(hconfig.conf["MAX_OUTPUTS"])
        if max_outputs <= 1: max_outputs = 2

    ind = 0

    while ind < max_outputs:
        tmp = rcrypt.make_SHA256_hash(transaction_keys[1])
        tmp = rcrypt.make_RIPEMD160_hash(tmp)

        ScriptPubKey = []
        ScriptPubKey.append("<DUP>")
        ScriptPubKey.append("<HASH-160>")
        ScriptPubKey.append(tmp)
        ScriptPubKey.append("<EQ-VERIFY>")
        ScriptPubKey.append("<CHECK-SIG>")

        if is_coinbase == True:
            value = hmining.mining_reward(blockno)
        else:
            amt = int(total_spendable / max_outputs)
            value = secrets.randbelow(amt)  # helium cents
            if value == 0:
                value = int(amt / 10)
            total_spendable -= value
            assert value > 0
            assert total_spendable >= 0

        txn["vout"].append({"value": value, "ScriptPubKey": ScriptPubKey})

        # save the transaction fragment
        fragid = txn["transactionid"] + "_" + str(ind)
        fragment = {}
        fragment[fragid] = {
            "value": value,
            "privkey": transaction_keys[0],
            "pubkey": transaction_keys[1],
            "blockno": blockno
        }
        unspent_fragments.append(fragment)
        #print("added to unspent fragments: " + fragid)

        if total_spendable <= 0: break
        ind += 1

    return txn
def test_make_uuid(length, ret):
    """
    test id generation
    """
    id = rcrypt.make_uuid()
    assert (len(id) == length) == ret
Ejemplo n.º 14
0
def test_delete_tx():
    txid = rcrypt.make_uuid()
    blkindex.put_index(txid, 555)
    assert blkindex.delete_index(txid) == True
    assert blkindex.get_blockno(txid) == False
Ejemplo n.º 15
0
def make_transactionid():
    """
    makes a random transaction id
    """
    return rcrypt.make_uuid() 
Ejemplo n.º 16
0

def setup_module():
    assert bool(blkindex.open_blk_index("hblk_index")) == True
    if os.path.isfile("hblk_index"):
        os.remove("hblk_index")

def teardown_module():
    assert blkindex.close_blk_index() == True


@pytest.mark.parametrize("txid, value, ret", [
     ("",  9, False),
     ("abc", "", False),
     ('290cfd3f3e5027420ed483871309d2a0780b6c3092bef3f26347166b586ff89f', 10899, True),
     (rcrypt.make_uuid(), 9, True),
     (rcrypt.make_uuid(), -1, False),
     (rcrypt.make_uuid(), -56019, False),
     (rcrypt.make_uuid(), 90890231, True),
])
def test_put_index(txid, value, ret):
    """
        tests putting valid and invalid transaction_index and blockno pairs
        into the blk_index store
    """
    assert blkindex.put_index(txid, value) == ret


def test_get_existing_tx():
    """
    test getting a block for an existing transaction
Ejemplo n.º 17
0
def make_pkhash():
    """
    creates a random pkhash value
    """
    id = rcrypt.make_uuid()
    return rcrypt.make_RIPEMD160_hash(rcrypt.make_SHA256_hash(id))