Beispiel #1
0
def test_serialization():
    outpoint1 = OutPoint(txid='coffee', txout_idx=0)
    outpoint2 = OutPoint(txid='coffee', txout_idx=0)
    txin1 = TxIn(outpoint=outpoint1,
                 signature=SignatureScript(unlock_sig=b'sign',
                                           unlock_pk=b'bar'),
                 sequence=1)
    txin2 = TxIn(outpoint=outpoint2,
                 signature=SignatureScript(unlock_sig=b'sign',
                                           unlock_pk=b'bar'),
                 sequence=2)

    txout = TxOut(value=101, pubkey='abcnddfjrwof123')
    txn1 = Transaction(txins=[txin1], txouts=[txout], locktime=0)
    txn2 = Transaction(txins=[txin2], txouts=[txout], locktime=0)

    block = Block(1, 'deadbeef', 'coffee', int(time.time()), 100, 100,
                  [txn1, txn2])
    utxo = UnspentTxOut(*txout,
                        txid=txn1.id,
                        txout_idx=0,
                        is_coinbase=False,
                        height=0)
    utxo_set = [utxo.outpoint, utxo]

    for obj in (outpoint1, outpoint2, txin1, txin2, txout, txn1, txn2, block,
                utxo, utxo_set):
        assert deserialize(serialize(obj)) == obj
Beispiel #2
0
def pool_solver(rng):
    print(f"calculating range {rng}")
    for nonce in rng:
        b = Block(
            version=0,
            prev_block_hash=
            '000000273d64c0b32fa8475004513d1e5f8335a718dc9bd6c99f60d5cf6f7175',
            merkle_tree_hash=
            '5b9f0cb4023a18cd1de03c0035283965aa6b14ec72a5d9ce7b2a029a9afce47a',
            timestamp=1501827000,
            bits=24,
            nonce=nonce,
            txns=[
                Transaction(
                    txins=[
                        TxIn(outpoint=None,
                             signature=SignatureScript(unlock_sig=b'4',
                                                       unlock_pk=None),
                             sequence=0)
                    ],
                    txouts=[
                        TxOut(value=5000000000,
                              pubkey='1Piq91dFUqSb7tdddCWvuGX5UgdzXeoAwA')
                    ],
                    locktime=None)
            ])

        if int(b.id, 16) <= (1 << (256 - b.bits)):
            return nonce, b.id

    return None
Beispiel #3
0
def assemble_and_solve_block(pay_coinbase_to_addr, txns=None):
    """
    Construct a Block by pulling transactions from the mempool, the mine it
    """
    with chain_lock:
        prev_block_hash = get_active_chain()[-1].id if get_active_chain(
        ) else None

    block = Block(version=0,
                  prev_block_hash=prev_block_hash,
                  merkle_tree_hash='',
                  timestamp=int(time.time()),
                  bits=get_next_work_required(prev_block_hash),
                  nonce=0,
                  txns=txns or [])

    if not block.txns:
        block = select_from_mempool(block)

    fees = calculate_fees(block)
    coinbase_txn = Transaction.create_coinbase(pay_coinbase_to_addr,
                                               (get_block_subsidy() + fees),
                                               len(get_active_chain()))

    block = block._replace(txns=[coinbase_txn, *block.txns])

    block = block._replace(
        merkle_tree_hash=get_merkle_root_of_txns(block.txns).value)

    if len(serialize(block)) > Params.MAX_BLOCK_SERIALIZED_SIZE:
        raise ValueError('txns specified create a block too large')

    return mine(block)
Beispiel #4
0
def test_dependent_txns_in_single_block():
	set_active_chain([])
	mempool.clear()

	assert connect_block(chain1[0]) == ACTIVE_CHAIN_IDX
	assert connect_block(chain1[1]) == ACTIVE_CHAIN_IDX

	assert len(get_active_chain()) == 2
	assert len(utxo_set) == 2

	utxo1 = utxo_set[list(utxo_set.keys())[0]]
	txout1 = TxOut(value=901, pubkey=utxo1.pubkey)
	txin1 = make_txin(signing_key, utxo1.outpoint, txout1)
	txn1 = Transaction(txins=[txin1], txouts=[txout1], locktime=0)
 
	# Create a transaction that is depend on the yet-unconfirmed transaction above
	txout2 = TxOut(value=9001, pubkey=txout1.pubkey)
	txin2 = make_txin(signing_key, OutPoint(txn1.id, 0), txout2)
	txn2 = Transaction(txins=[txin2], txouts=[txout2], locktime=0)

	# assert that we don't accept this txn -- too early to spend the coinbase
	with pytest.raises(TxnValidationError) as excinfo:
		validate_txn(txn2)
		assert 'Spend value is more than available' in str(excinfo)

	connect_block(chain1[2])
	add_txn_to_mempool(txn1)
	assert txn1.id in mempool

	# In txn2, we're attemping to spend more than is available (9001 vs. 901).
	assert not add_txn_to_mempool(txn2)

	with pytest.raises(TxnValidationError) as excinfo:
		validate_txn(txn2)
		assert 'Spend value is more than available' in str(excinfo.value)


	# Recreate the transaction with an acceptable value
	txout2 = TxOut(value=901, pubkey=txout1.pubkey)
	txin2 = make_txin(signing_key, OutPoint(txn1.id, 0), txout2)
	txn2 = Transaction(txins=[txin2], txouts=[txout2], locktime=0)

	add_txn_to_mempool(txn2)
	assert txn2.id in mempool
Beispiel #5
0
def validate_txn(txn: Transaction,
                 as_coinbase: bool = False,
                 siblings_in_block: Iterable[Transaction] = None,
                 allow_utxo_from_mempool: bool = True):
    """
    Validate a single transaction. Used in various contexts, so the parameters facilitate difficult users
    """
    txn.validate_basics(as_coinbase=as_coinbase)
    available_to_spend = 0

    for i, txin in enumerate(txn.txins):
        utxo = utxo_set.get(txin.outpoint)

        if siblings_in_block:
            utxo = utxo or find_utxo_in_list(txin, siblings_in_block)

        if allow_utxo_from_mempool:
            utxo = utxo or find_utxo_in_mempool(txin)

        if not utxo:
            raise TxnValidationError(
                f'Could not find UTXO for TxIn[{i}] -- orphaning txn',
                to_orphan=txn)

        if utxo.is_coinbase and (get_current_height() -
                                 utxo.height) < Params.COINBASE_MATURITY:
            raise TxnValidationError(f'Coinbase UTXO not ready for spend')

        try:
            validate_signature_for_spend(txin, utxo, txn)
        except TxUnlockError:
            raise TxnValidationError(f'{txin} is not valid spend of {utxo}')

        available_to_spend += utxo.value

    if available_to_spend < sum(o.value for o in txn.txouts):
        raise TxnValidationError('Spend value is more than available')

    return txn
Beispiel #6
0
def test_build_spend_message():
    txout = TxOut(value=101, pubkey='1zz8w9')
    txin = TxIn(outpoint=OutPoint('c0ffee', 0),
                signature=SignatureScript(unlock_sig=b'oursig',
                                          unlock_pk=b'foo'),
                sequence=1)

    txn = Transaction(txins=[txin], txouts=[txout], locktime=0)
    spend_msg = build_spend_message(txin.outpoint, txin.signature.unlock_pk,
                                    txin.sequence, txn.txouts)

    assert spend_msg == b'2c162f2c05a771e52c01fda220073aa0665cc873193235bdb90359631720e7a5'

    # adding a new output to the txn creates a new spend message.

    txn.txouts.append(TxOut(value=1, pubkey='1zz'))
    assert build_spend_message(txin.outpoint, txin.signature.unlock_pk,
                               txin.sequence, txn.txouts) != spend_msg
Beispiel #7
0
def send_value(args):
    """
	Send value to some address.
	"""

    val, to_addr, sk = int(args['<val>']), args['<addr>'], args['signing_key']
    selected = set()
    my_utxos = set(
        sorted(find_utxos_for_address(args), key=lambda i:
               (i.value, i.height)))

    for utxo in my_utxos:
        selected.add(utxo)
        if sum(i.value for i in selected) > val:
            break

    txout = TxOut(value=val, pubkey=to_addr)
    txn = Transaction(
        txins=[make_txin(sk, coin.outpoint, txout) for coin in selected],
        txouts=[txout])

    logger.info(f'built txn {txn}')
    logger.info(f'broadcast txn {txn.id}')
    send_msg(txn)
Beispiel #8
0
    # Block id:
    # 0000009284177ad434618ded91f9f81fad78e0c26f77cffb5d9a406a8d4dab80
    Block(version=0,
          prev_block_hash=None,
          merkle_tree_hash=
          '548b61957ff5fb0cb3d2c511f1a6e28460f0d7175eaa3058bfac986d37a72004',
          timestamp=1501821412,
          bits=24,
          nonce=2275359062,
          txns=[
              Transaction(txins=[
                  TxIn(outpoint=None,
                       signature=SignatureScript(unlock_sig=b'0',
                                                 unlock_pk=None),
                       sequence=0)
              ],
                          txouts=[
                              TxOut(
                                  value=5000000000,
                                  pubkey='143UVyz7ooiAv1pMqbwPPpnH4BV9ifJGFF')
                          ],
                          locktime=None)
          ]),

    # Block id:
    # 000000d432bd0ec0a087a0d30a6e5c251116919bf91e195f1f9c3d4f3e3f0ba3
    Block(version=0,
          prev_block_hash=
          '0000009284177ad434618ded91f9f81fad78e0c26f77cffb5d9a406a8d4dab80',
          merkle_tree_hash=
          '509dd8d49774ddf72c24f83faa5a2e851da514103f53e6bec3df4ad5f83d8421',
          timestamp=1501826444,
Beispiel #9
0
        'prev_block_hash':
        None,
        'merkle_tree_hash':
        '688787d8ff144c502c7f5cffaafe2cc588d86079f9de88304c26b0cb99ce91c6',
        'timestamp':
        1504563279,
        'bits':
        24,
        'nonce':
        86038336,
        'txns': [
            Transaction(txins=[
                TxIn(outpoint=None,
                     signature=SignatureScript(unlock_sig=b'0',
                                               unlock_pk=None),
                     sequence=0)
            ],
                        txouts=[
                            TxOut(value=5000000,
                                  pubkey='143UVyz7ooiAv1pMqbwPPpnH4BV9ifJGFF')
                        ])
        ]
    })

# highest proof of work
active_chain: Iterable[Block] = [genesis_block]

# side branches
side_branches: Iterable[Iterable[Block]] = []

orphan_blocks: Iterable[Block] = []