def add_transactions_to_blockchain_db(base_db, tx_list: List):
    # sort by time
    tx_list.sort(key=lambda x: x[3])

    for tx_key in tx_list:
        sender_priv_key = tx_key[0]
        receive_priv_key = tx_key[1]
        amount = tx_key[2]
        tx_timestamp = int(tx_key[3])

        if len(tx_key) > 4:
            gas_price = to_wei(tx_key[4], 'gwei')
        else:
            gas_price = to_wei(1, 'gwei')

        total_gas = gas_price
        sender_chain = MainnetChain(base_db, sender_priv_key.public_key.to_canonical_address(), sender_priv_key)
        dummy_sender_chain = MainnetChain(JournalDB(base_db), sender_priv_key.public_key.to_canonical_address(),
                                          sender_priv_key)

        dummy_sender_chain.create_and_sign_transaction_for_queue_block(
            gas_price=gas_price,
            gas=GAS_TX,
            to=receive_priv_key.public_key.to_canonical_address(),
            value=amount,
            data=b"",
            v=0,
            r=0,
            s=0
        )

        # import the block into the dummy chain to complete it and make sure it is valid
        imported_block = dummy_sender_chain.import_current_queue_block()

        # altering block timestamp and importing again
        timestamp_modified_imported_block = imported_block.copy(
            header=imported_block.header.copy(timestamp=tx_timestamp).get_signed(sender_priv_key,
                                                                                 dummy_sender_chain.network_id))
        sender_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False)

        # then receive the transactions

        dummy_receiver_chain = MainnetChain(JournalDB(base_db), receive_priv_key.public_key.to_canonical_address(),
                                            receive_priv_key)
        dummy_receiver_chain.populate_queue_block_with_receive_tx()
        imported_block = dummy_receiver_chain.import_current_queue_block()

        # altering block timestamp and importing again
        timestamp_modified_imported_block = imported_block.copy(
            header=imported_block.header.copy(timestamp=tx_timestamp).get_signed(receive_priv_key,
                                                                                  dummy_receiver_chain.network_id))
        # print('XXXXXXXXXX')
        # print(tx_timestamp)
        receiver_chain = MainnetChain(base_db, receive_priv_key.public_key.to_canonical_address(), receive_priv_key)
        receiver_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False)
def create_dev_fixed_blockchain_database(base_db, key_balance_dict, use_real_genesis = False):
    logger.debug("generating test fixed blockchain db")

    earliest_timestamp = int(time.time())
    required_total_supply = 0
    for balance_timestamp in key_balance_dict.values():
        required_total_supply += balance_timestamp[0]
        if balance_timestamp[1] < earliest_timestamp:
            earliest_timestamp = balance_timestamp[1]

    required_total_supply = required_total_supply*2

    #initialize db
    if use_real_genesis:
        sender_chain = import_genesis_block(base_db)
    else:
        genesis_params, genesis_state = create_new_genesis_params_and_state(GENESIS_PRIVATE_KEY, required_total_supply, earliest_timestamp - 100000)
        sender_chain = MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state)

    sender_chain.chaindb.initialize_historical_minimum_gas_price_at_genesis(min_gas_price=1, net_tpc_cap=5)

    prev_timestamp = 0
    for priv_key, balance_timestamp in key_balance_dict.items():
        sender_chain = MainnetChain(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY)

        dummy_sender_chain = MainnetChain(JournalDB(base_db), GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY)

        balance = balance_timestamp[0]
        timestamp = balance_timestamp[1]
        if timestamp < prev_timestamp:
            raise ValueError("timestamps must be in ascending order")

        receiver_privkey = priv_key

        dummy_sender_chain.create_and_sign_transaction_for_queue_block(
                gas_price=0x01,
                gas=0x0c3500,
                to=receiver_privkey.public_key.to_canonical_address(),
                value=balance,
                data=b"",
                v=0,
                r=0,
                s=0
                )



        # import the block into the dummy chain to complete it and make sure it is valid
        imported_block = dummy_sender_chain.import_current_queue_block()

        # altering block timestamp and importing again
        timestamp_modified_imported_block = imported_block.copy(header = imported_block.header.copy(timestamp = timestamp).get_signed(GENESIS_PRIVATE_KEY,dummy_sender_chain.network_id))
        sender_chain.import_block(timestamp_modified_imported_block, allow_unprocessed = False)

        #logger.debug("Receiving ")

        #then receive the transactions
        receiver_chain = MainnetChain(base_db, receiver_privkey.public_key.to_canonical_address(), receiver_privkey)
        dummy_receiver_chain = MainnetChain(JournalDB(base_db), receiver_privkey.public_key.to_canonical_address(), receiver_privkey)
        dummy_receiver_chain.populate_queue_block_with_receive_tx()
        imported_block = dummy_receiver_chain.import_current_queue_block()

        # altering block timestamp and importing again
        timestamp_modified_imported_block = imported_block.copy(header=imported_block.header.copy(timestamp=timestamp).get_signed(receiver_privkey, dummy_receiver_chain.network_id))
        receiver_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False)


    logger.debug("finished creating fixed blockchain")
Beispiel #3
0
def _test_airdrop_calling_erc_20():

    # testdb = LevelDB('/home/tommy/.local/share/helios/instance_test/mainnet/chain/full/')
    # testdb = JournalDB(testdb)
    testdb = MemoryDB()
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    coin_mature_time = chain.get_vm(timestamp=Timestamp(int(
        time.time()))).consensus_db.coin_mature_time_for_staking

    genesis_params, genesis_state = create_new_genesis_params_and_state(
        GENESIS_PRIVATE_KEY, 1000000 * 10**18,
        int(time.time()) - coin_mature_time * 10000)

    # import genesis block
    chain = MainnetChain.from_genesis(
        testdb, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        genesis_params, genesis_state, GENESIS_PRIVATE_KEY)

    #
    # erc20 contract deploy
    #

    compiled_erc20_sol = load_compiled_sol_dict(
        'contract_data/erc20_compiled.pkl')

    EXPECTED_TOTAL_SUPPLY = 10000000000000000000000

    erc20_contract_interface = compiled_erc20_sol[
        'contract_data/erc20.sol:SimpleToken']

    w3 = Web3()

    SimpleToken = w3.eth.contract(abi=erc20_contract_interface['abi'],
                                  bytecode=erc20_contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_erc20_tx = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

    max_gas = 20000000

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_erc20_tx['data']),
        v=0,
        r=0,
        s=0)

    #time.sleep(1)
    print("deploying erc20 smart contract")
    imported_block = chain.import_current_queue_block()

    #now we need to add the block to the smart contract
    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    erc20_contract_address = list_of_smart_contracts[0]

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])

    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    #
    # airdrop contract deploy
    #
    compiled_airdrop_sol = load_compiled_sol_dict(
        'contract_data/airdrop_compiled.pkl')

    EXPECTED_TOTAL_SUPPLY = 10000000000000000000000

    airdrop_contract_interface = compiled_airdrop_sol[
        'contract_data/airdrop.sol:Airdrop']

    Airdrop = w3.eth.contract(abi=airdrop_contract_interface['abi'],
                              bytecode=airdrop_contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_airdrop_tx = Airdrop.constructor().buildTransaction(W3_TX_DEFAULTS)

    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_airdrop_tx['data']),
        v=0,
        r=0,
        s=0)

    print("deploying airdrop smart contract")
    imported_block = chain.import_current_queue_block()

    # now we need to add the block to the smart contract
    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    airdrop_contract_address = list_of_smart_contracts[0]

    chain = MainnetChain(testdb, airdrop_contract_address, private_keys[0])

    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    #
    # Interacting with deployed smart contract step 1) add send transaction
    #
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    print(erc20_contract_interface['abi'])
    simple_token = w3.eth.contract(
        address=Web3.toChecksumAddress(erc20_contract_address),
        abi=erc20_contract_interface['abi'],
    )

    airdrop_token_balance = 1000

    w3_erc20_send = simple_token.functions.transfer(
        Web3.toChecksumAddress(airdrop_contract_address),
        airdrop_token_balance).buildTransaction(W3_TX_DEFAULTS)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=erc20_contract_address,
        value=0,
        data=decode_hex(w3_erc20_send['data']),
        v=0,
        r=0,
        s=0)
    imported_block = chain.import_current_queue_block()

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    from pprint import pprint
    receipt = chain.chaindb.get_receipts(imported_block.header, Receipt)[0]

    receipt_dict = format_receipt_for_web3_to_extract_events(
        receipt, imported_block.receive_transactions[0].hash, chain)

    rich_logs = simple_token.events.Transfer().processReceipt(receipt_dict)
    print(rich_logs)
    print(rich_logs[0]['args'])
    print('a')

    assert (to_int(
        chain.chaindb.get_receipts(
            imported_block.header,
            Receipt)[0].logs[0].data) == airdrop_token_balance)

    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    w3_erc20_balance = simple_token.functions.balanceOf(
        Web3.toChecksumAddress(airdrop_contract_address)).buildTransaction(
            W3_TX_DEFAULTS)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=erc20_contract_address,
        value=0,
        data=decode_hex(w3_erc20_balance['data']),
        v=0,
        r=0,
        s=0)
    imported_block = chain.import_current_queue_block()

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    print(chain.chaindb.get_receipts(imported_block.header, Receipt)[0].logs)

    exit()
    #now lets look at the reciept to see the result
    assert (to_int(
        chain.chaindb.get_receipts(
            imported_block.header,
            Receipt)[0].logs[0].data) == EXPECTED_TOTAL_SUPPLY)
    print("Total supply call gave expected result!")
    gas_used = to_int(
        chain.chaindb.get_receipts(imported_block.header, Receipt)[0].gas_used)

    #
    # Interacting with deployed smart contract step 3) Receiving refund of extra gas that wasn't used in the computation
    #
    initial_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()
    final_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    assert ((final_balance - initial_balance) == (max_gas - gas_used))
    print("Refunded gas is the expected amount.")
def test_get_receipts():
    testdb2 = MemoryDB()

    MainnetChain.from_genesis(
        testdb2, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)
    """
    Create some receive transactions for RECEIVER
    """
    sender_chain = MainnetChain(testdb2,
                                SENDER.public_key.to_canonical_address(),
                                SENDER)

    min_time_between_blocks = sender_chain.get_vm(
        timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    for i in range(6):
        sender_chain.create_and_sign_transaction_for_queue_block(
            gas_price=i + 1,
            gas=0x0c3500,
            to=RECEIVER.public_key.to_canonical_address(),
            value=i + 100000000000,
            data=b"",
            v=0,
            r=0,
            s=0)

    sender_chain.import_current_queue_block()
    receiver_chain = MainnetChain(testdb2,
                                  RECEIVER.public_key.to_canonical_address(),
                                  RECEIVER)
    receiver_chain.populate_queue_block_with_receive_tx()
    imported_block_1 = receiver_chain.import_current_queue_block()
    """
    Create some send transactions for RECEIVER
    """
    receiver_chain = MainnetChain(testdb2,
                                  RECEIVER.public_key.to_canonical_address(),
                                  RECEIVER)
    for i in range(6):
        receiver_chain.create_and_sign_transaction_for_queue_block(
            gas_price=i + 1,
            gas=0x0c3500,
            to=SENDER.public_key.to_canonical_address(),
            value=i,
            data=b"",
            v=0,
            r=0,
            s=0)
    """
    Create a transaction with data in it.
    """
    compiled_sol = load_compiled_sol_dict('contract_data/erc20_compiled.pkl')

    contract_interface = compiled_sol['contract_data/erc20.sol:SimpleToken']

    w3 = Web3()

    SimpleToken = w3.eth.contract(abi=contract_interface['abi'],
                                  bytecode=contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_tx1 = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

    from hvm.constants import CREATE_CONTRACT_ADDRESS

    receiver_chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=1375666,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_tx1['data']),
        v=0,
        r=0,
        s=0)

    receiver_chain.populate_queue_block_with_receive_tx()

    print("waiting {} seconds before importing next block".format(
        min_time_between_blocks))
    time.sleep(min_time_between_blocks)
    imported_block = receiver_chain.import_current_queue_block()

    for i in range(7):
        if i < 6:
            receipt = sender_chain.chaindb.get_transaction_receipt(
                imported_block.transactions[i].hash)
            assert (receipt.status_code == b'\x01')
            assert (receipt.gas_used == GAS_TX)
            assert (receipt.bloom == 0)
            assert (receipt.logs == ())
        if i == 6:
            receipt = sender_chain.chaindb.get_transaction_receipt(
                imported_block.transactions[i].hash)
            assert (receipt.status_code == b'\x01')
            assert (receipt.gas_used == 1375666)
            assert (
                receipt.bloom ==
                243379359099696592952569079439667912256345493617967967903663341910531480774353059570732838085077727505416158987674861080353852392619637689071728561054211502067278701792094127192831079015338935810676425927305370163403783027301927515372719270157454901551766020292792184739669125690737609931485501648741152187826071626833444578979111366057983284511641401113379885201162016756050289195516614302086913696386892161910800529278878068496138240
            )
            assert (len(receipt.logs) == 1)

    for i in range(6):
        receipt = sender_chain.chaindb.get_transaction_receipt(
            imported_block_1.receive_transactions[i].hash)
        assert (receipt.status_code == b'\x01')
        assert (receipt.gas_used == 0)
        assert (receipt.bloom == 0)
        assert (receipt.logs == ())


# test_get_receipts()
Beispiel #5
0
def test_erc_20_smart_contract_deploy_system():

    # testdb = LevelDB('/home/tommy/.local/share/helios/instance_test/mainnet/chain/full/')
    # testdb = JournalDB(testdb)
    testdb = MemoryDB()
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    coin_mature_time = chain.get_vm(timestamp=Timestamp(int(
        time.time()))).consensus_db.coin_mature_time_for_staking

    now = int(time.time())
    key_balance_dict = {
        private_keys[0]: (1000000000000, now - coin_mature_time * 10 - 100)
    }
    create_dev_fixed_blockchain_database(testdb, key_balance_dict)

    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    min_time_between_blocks = chain.get_vm(
        timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    for private_key, balance_time in key_balance_dict.items():
        assert (chain.get_vm().state.account_db.get_balance(
            private_key.public_key.to_canonical_address()) == balance_time[0])

    SOLIDITY_SRC_FILE = 'contract_data/erc20.sol'
    EXPECTED_TOTAL_SUPPLY = 10000000000000000000000

    #compiled_sol = compile_files([SOLIDITY_SRC_FILE])

    compiled_sol = load_compiled_sol_dict('contract_data/erc20_compiled.pkl')

    contract_interface = compiled_sol['{}:SimpleToken'.format(
        SOLIDITY_SRC_FILE)]

    w3 = Web3()

    SimpleToken = w3.eth.contract(abi=contract_interface['abi'],
                                  bytecode=contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_tx1 = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

    max_gas = 20000000

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_tx1['data']),
        v=0,
        r=0,
        s=0)

    #time.sleep(1)
    print("deploying smart contract")

    initial_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    imported_block = chain.import_current_queue_block()
    final_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    gas_used = to_int(
        chain.chaindb.get_receipts(imported_block.header, Receipt)[0].gas_used)
    assert ((initial_balance - final_balance) == gas_used)

    print(GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    print(
        generate_contract_address(
            GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
            imported_block.transactions[0].nonce))
    print(
        chain.chaindb.get_receipts(imported_block.header,
                                   Receipt)[0].logs[0].address)

    #contractAddress

    print("Used the correct amount of gas.")

    #now we need to add the block to the smart contract
    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    deployed_contract_address = list_of_smart_contracts[0]
    print(list_of_smart_contracts)

    chain = MainnetChain(testdb, deployed_contract_address, private_keys[0])

    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    print(list_of_smart_contracts)

    #lets make sure it didn't create a refund transaction for the initial sender.
    print(chain.get_vm().state.account_db.has_receivable_transactions(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address()))

    # print('ASDASD')
    # print(chain.chaindb.get_receipts(imported_block.header, Receipt)[0].logs[0].data)

    #
    # Interacting with deployed smart contract step 1) add send transaction
    #
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    simple_token = w3.eth.contract(
        address=Web3.toChecksumAddress(deployed_contract_address),
        abi=contract_interface['abi'],
    )

    w3_tx2 = simple_token.functions.totalSupply().buildTransaction(
        W3_TX_DEFAULTS)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=deployed_contract_address,
        value=0,
        data=decode_hex(w3_tx2['data']),
        v=0,
        r=0,
        s=0)

    #lets make sure it subtracts the entire max gas
    initial_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())

    print("waiting {} seconds before importing next block".format(
        min_time_between_blocks))
    time.sleep(min_time_between_blocks)
    chain.import_current_queue_block()
    final_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    assert ((initial_balance - final_balance) == max_gas)

    #
    # Interacting with deployed smart contract step 2) add receive transaction to smart contract chain
    #

    chain = MainnetChain(testdb, deployed_contract_address, private_keys[0])
    chain.populate_queue_block_with_receive_tx()

    print("waiting {} seconds before importing next block".format(
        min_time_between_blocks))
    time.sleep(min_time_between_blocks)
    imported_block = chain.import_current_queue_block()

    receipt = chain.chaindb.get_receipts(imported_block.header, Receipt)[0]
    receipt_dict = format_receipt_for_web3_to_extract_events(
        receipt, imported_block.receive_transactions[0].hash, chain)

    rich_logs = simple_token.events.Print().processReceipt(receipt_dict)
    print(rich_logs[0]['args'])
    print('a')

    #now lets look at the reciept to see the result
    assert (to_int(
        chain.chaindb.get_receipts(
            imported_block.header,
            Receipt)[0].logs[0].data) == EXPECTED_TOTAL_SUPPLY)
    print("Total supply call gave expected result!")
    gas_used = to_int(
        chain.chaindb.get_receipts(imported_block.header, Receipt)[0].gas_used)

    #
    # Interacting with deployed smart contract step 3) Receiving refund of extra gas that wasn't used in the computation
    #
    initial_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    chain.populate_queue_block_with_receive_tx()

    print("waiting {} seconds before importing next block".format(
        min_time_between_blocks))
    time.sleep(min_time_between_blocks)
    imported_block = chain.import_current_queue_block()
    final_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    assert ((final_balance - initial_balance) == (max_gas - gas_used))
    print("Refunded gas is the expected amount.")