def initialize_database(chain_config: ChainConfig, chaindb: AsyncChainDB) -> None: try: chaindb.get_canonical_head(chain_address=GENESIS_WALLET_ADDRESS) except CanonicalHeadNotFound: if chain_config.network_id == MAINNET_NETWORK_ID: MainnetChain.from_genesis(chaindb.db, chain_config.node_wallet_address, MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE) else: # TODO: add genesis data to ChainConfig and if it's present, use it # here to initialize the chain. raise NotImplementedError( "Only the mainnet and ropsten chains are currently supported")
def create_block_params(): from hvm.chains.mainnet import ( MAINNET_TPC_CAP_TEST_GENESIS_PARAMS, MAINNET_TPC_CAP_TEST_GENESIS_STATE, TPC_CAP_TEST_GENESIS_PRIVATE_KEY, ) db = MemoryDB() chain = MainnetChain.from_genesis( db, TPC_CAP_TEST_GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), MAINNET_TPC_CAP_TEST_GENESIS_PARAMS, MAINNET_TPC_CAP_TEST_GENESIS_STATE, private_key=TPC_CAP_TEST_GENESIS_PRIVATE_KEY) receiver_privkey = keys.PrivateKey(random_private_keys[0]) chain.create_and_sign_transaction_for_queue_block( gas_price=0x01, gas=0x0c3500, to=receiver_privkey.public_key.to_canonical_address(), value=1000, data=b"", v=0, r=0, s=0) imported_block = chain.import_current_queue_block() block_dict = imported_block.to_dict() print(block_dict) # create_block_params() # sys.exit()
def create_dev_test_blockchain_database_with_given_transactions(base_db, tx_list: List, use_real_genesis = False): # sort by time tx_list.sort(key=lambda x: x[3]) genesis_chain_stake = 100000000000000000 total_required_gas = sum([(to_wei(tx_key[4], 'gwei') if len(tx_key) > 4 else to_wei(1, 'gwei'))*GAS_TX for tx_key in tx_list]) earliest_timestamp = tx_list[0][3] required_total_supply = sum([x[2] for x in tx_list if x[0] == GENESIS_PRIVATE_KEY])+genesis_chain_stake+total_required_gas if use_real_genesis: 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) # import genesis block MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state) add_transactions_to_blockchain_db(base_db, tx_list)
def test_boson_vm_calculate_node_staking_score(): from hvm.vm.forks.boson.consensus import TIME_BETWEEN_PEER_NODE_HEALTH_CHECK testdb = MemoryDB() sender_chain = MainnetChain.from_genesis( testdb, SENDER.public_key.to_canonical_address(), MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE) boson_fork_timestamp = 0 for timestamp_vm_config in MainnetChain.vm_configuration: if timestamp_vm_config[1].fork == 'boson': boson_fork_timestamp = timestamp_vm_config[0] boson_vm = sender_chain.get_vm(timestamp=boson_fork_timestamp) consensus_db = boson_vm.consensus_db # # score vs latency # latency = [] staking_score = [] for current_latency in range(1000, 1000000, 100000): current_staking_score = consensus_db.calculate_node_staking_score( average_response_time=current_latency, failed_requests=0, requests_sent=100, time_since_last_reward=TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 100) latency.append(current_latency / 1000) staking_score.append(current_staking_score / 10000) print(staking_score) print(latency) plt.plot(latency, staking_score) plt.xlabel('Latency (ms)') plt.ylabel('Percentage of max stake') plt.savefig('plots/staking_score_vs_latency.png', bbox_inches='tight') plt.clf() # # score vs failed requests # failed_requests = [] staking_score = [] for current_failed_requests in range(0, 100, 5): current_staking_score = consensus_db.calculate_node_staking_score( average_response_time=100000, failed_requests=current_failed_requests, requests_sent=100, time_since_last_reward=TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 100) failed_requests.append(current_failed_requests) staking_score.append(current_staking_score / 10000) print(failed_requests) print(staking_score) plt.plot(failed_requests, staking_score) plt.xlabel('Failed requests (% of requests sent)') plt.ylabel('Percentage of max stake') plt.savefig('plots/staking_score_vs_failed_requests.png', bbox_inches='tight') plt.clf() # # score vs percentage of uptime # percentage_of_uptime = [] staking_score = [] start = TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 10 for current_time_since_last_reward in range(start, start + start * 100, start): current_staking_score = consensus_db.calculate_node_staking_score( average_response_time=100000, failed_requests=0, requests_sent=10, time_since_last_reward=current_time_since_last_reward) percentage_of_uptime.append(start / current_time_since_last_reward) staking_score.append(current_staking_score / 10000) print(percentage_of_uptime) print(staking_score) plt.plot(percentage_of_uptime, staking_score) plt.xlabel('Percentage of uptime') plt.ylabel('Percentage of max stake') plt.savefig('plots/staking_score_vs_time_since_last_reward.png', bbox_inches='tight') plt.clf()
def test_boson_vm_calculate_reward_based_on_fractional_interest(): testdb = MemoryDB() masternode_level_3_required_balance = MASTERNODE_LEVEL_3_REQUIRED_BALANCE masternode_level_3_multiplier = MASTERNODE_LEVEL_3_REWARD_TYPE_2_MULTIPLIER masternode_level_2_required_balance = MASTERNODE_LEVEL_2_REQUIRED_BALANCE masternode_level_2_multiplier = MASTERNODE_LEVEL_2_REWARD_TYPE_2_MULTIPLIER masternode_level_1_required_balance = MASTERNODE_LEVEL_1_REQUIRED_BALANCE masternode_level_1_multiplier = MASTERNODE_LEVEL_1_REWARD_TYPE_2_MULTIPLIER genesis_block_time = int(time.time()) - 10000000 genesis_params, genesis_state = create_new_genesis_params_and_state( GENESIS_PRIVATE_KEY, masternode_level_3_required_balance * 2, genesis_block_time) time_between_blocks = max(MIN_TIME_BETWEEN_BLOCKS, 1) # import genesis block MainnetChain.from_genesis( testdb, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state) stake_start = genesis_block_time + time_between_blocks tx_list = [[ GENESIS_PRIVATE_KEY, RECEIVER, masternode_level_3_required_balance, stake_start ], [ RECEIVER, RECEIVER2, (masternode_level_3_required_balance - masternode_level_2_required_balance - GAS_TX), stake_start + 100000 ], [ RECEIVER, RECEIVER2, (masternode_level_2_required_balance - masternode_level_1_required_balance - GAS_TX), stake_start + 200000 ], [ RECEIVER, RECEIVER2, (masternode_level_1_required_balance - 1000000 - GAS_TX), stake_start + 300000 ]] add_transactions_to_blockchain_db(testdb, tx_list) receiver_chain = MainnetChain(testdb, RECEIVER.public_key.to_canonical_address(), RECEIVER) fractional_interest = REWARD_TYPE_2_AMOUNT_FACTOR boson_fork_timestamp = 0 for timestamp_vm_config in MainnetChain.vm_configuration: if timestamp_vm_config[1].fork == 'boson': boson_fork_timestamp = timestamp_vm_config[0] boson_vm = receiver_chain.get_vm(timestamp=boson_fork_timestamp) consensus_db = boson_vm.consensus_db calculate_at_timestamp = int(time.time()) reward = consensus_db.calculate_reward_based_on_fractional_interest( RECEIVER.public_key.to_canonical_address(), fractional_interest, calculate_at_timestamp) if calculate_at_timestamp < EARLY_BIRD_BONUS_CUTOFF_TIMESTAMP: early_bird_bonus = EARLY_BIRD_BONUS_FACTOR else: early_bird_bonus = 1 expected_reward_part_1 = fractional_interest * early_bird_bonus * ( masternode_level_3_required_balance * 100000 * masternode_level_3_multiplier) expected_reward_part_2 = fractional_interest * early_bird_bonus * ( masternode_level_2_required_balance * 100000 * masternode_level_2_multiplier) expected_reward_part_3 = fractional_interest * early_bird_bonus * ( masternode_level_1_required_balance * 100000 * masternode_level_1_multiplier) expected_reward_part_4 = fractional_interest * early_bird_bonus * ( 1000000) * (calculate_at_timestamp - (stake_start + 300000) - consensus_db.coin_mature_time_for_staking) # print("Expected calculation = {} * {} * {} * {}".format((calculate_at_timestamp-(stake_start+300000)-COIN_MATURE_TIME_FOR_STAKING), 1000000, fractional_interest, 1)) # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_1_required_balance, fractional_interest, masternode_level_1_multiplier)) # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_2_required_balance, fractional_interest, masternode_level_2_multiplier)) # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_3_required_balance, fractional_interest, masternode_level_3_multiplier)) # # print("Expected reward {}".format(int(expected_reward_part_4))) # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3))) # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3)+int(expected_reward_part_2))) # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3)+int(expected_reward_part_2)+int(expected_reward_part_1))) expected_reward = int(expected_reward_part_1) + int( expected_reward_part_2) + int(expected_reward_part_3) + int( expected_reward_part_4) assert (reward == expected_reward)
def import_genesis_block(base_db): logger.debug("importing genesis block") #initialize db return MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)
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")
async def _build_test_consensus( request, event_loop, genesis_block_timestamp=int(time.time() / 1000) * 1000 - 1000 * 1000 + 1000, gap_between_genesis_block_and_first_transaction=1000, diverging_transactions_timestamp=None): ''' This one creates a swarm of 4 nodes with one database, and 4 nodes with another database, then asks consensus which ones to choose. It checks to make sure they choose the correct one. The bootnode, and the first half of the peers have the same blockchain database The second half of the peers have a conflicting database Then finally, the client has only the genesis block and is asked to choose which database is in consensus. The first half of the peers have much more stake then the second half, so the client should choose the blockchain database from the first half of the nodes, which is also the one the bootnode has. :param request: :param event_loop: :return: ''' num_peers_in_swarm = 8 # If this is less than TIME_BETWEEN_HEAD_HASH_SAVE, it will result in FAST SYNC MODE because even the first # chronological block hash will be different. #gap_between_genesis_block_and_first_transaction = 1000 base_db = MemoryDB() #genesis_block_timestamp = int(time.time()/1000)*1000 - 1000*1000 + 1000 #genesis_block_timestamp = 1547288000 private_keys = [] for i in range(len(random_private_keys)): private_keys.append(keys.PrivateKey(random_private_keys[i])) if gap_between_genesis_block_and_first_transaction < MIN_TIME_BETWEEN_BLOCKS: gap_between_genesis_block_and_first_transaction = MIN_TIME_BETWEEN_BLOCKS tx_list = [ *[[ GENESIS_PRIVATE_KEY, private_keys[i], ((1000000 - 1000 * i) * 10**18), genesis_block_timestamp + gap_between_genesis_block_and_first_transaction + MIN_TIME_BETWEEN_BLOCKS * i ] for i in range(len(random_private_keys))] ] total_required_gas = sum([ (to_wei(tx_key[4], 'gwei') if len(tx_key) > 4 else to_wei(1, 'gwei')) * GAS_TX for tx_key in tx_list ]) genesis_chain_stake = 100 required_total_supply = sum([ x[2] for x in tx_list if x[0] == GENESIS_PRIVATE_KEY ]) + genesis_chain_stake + total_required_gas genesis_params, genesis_state = create_new_genesis_params_and_state( GENESIS_PRIVATE_KEY, required_total_supply, genesis_block_timestamp) # import genesis block MainnetChain.from_genesis( base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state) # Client db has only the genesis block client_db = MemoryDB(base_db.kv_store.copy()) add_transactions_to_blockchain_db(base_db, tx_list) # chain = MainnetChain(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY) # print('AAAAAAAAAAA') # print('genesis') # print(chain.get_vm().state.account_db.get_balance(GENESIS_PRIVATE_KEY.public_key.to_canonical_address())) # for i in range(len(random_private_keys)): # print(i) # print(chain.get_vm().state.account_db.get_balance(private_keys[i].public_key.to_canonical_address())) # exit() # stake for the first half of chains should be from node 1 to node n: # 100 # 1000000 # 999000 # 998000 # 997000 # 996000 # 995000 # 994000 # 993000 # 992000 peer_dbs = [] for i in range(int(num_peers_in_swarm / 2)): peer_dbs.append(MemoryDB(base_db.kv_store.copy())) #last_block_timestamp = tx_list[-1][-1] # additional_tx_list_for_competing_db = [ # [private_keys[4], private_keys[1], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 1], # [private_keys[4], private_keys[2], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 2], # [private_keys[4], private_keys[3], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 3], # ] if diverging_transactions_timestamp is None: diverging_transactions_timestamp = tx_list[-1][ -1] + TIME_BETWEEN_HEAD_HASH_SAVE additional_tx_list_for_competing_db = [ [ private_keys[4], private_keys[1], 100, diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 0 ], [ private_keys[4], private_keys[2], 100, diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 1 ], [ private_keys[4], private_keys[3], 100, diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 2 ], ] competing_base_db = MemoryDB(base_db.kv_store.copy()) add_transactions_to_blockchain_db(competing_base_db, additional_tx_list_for_competing_db) # stake for the second half of chains should be from node 1 to node n: # 100 # 1000000 # 999100 # 998100 # 997100 # 932700 # 995000 # 994000 # 993000 # 992000 # for peer node 7 for root hash 1 # 100 + 997100 + 996100 + 995100 + 930700 for i in range(int(num_peers_in_swarm / 2), num_peers_in_swarm): peer_dbs.append(MemoryDB(competing_base_db.kv_store.copy())) bootstrap_node = MainnetChain( base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address()) bootstrap_node.chaindb.initialize_historical_minimum_gas_price_at_genesis( min_gas_price=1, net_tpc_cap=100, tpc=1) consensus_root_hash_timestamps = bootstrap_node.chain_head_db.get_historical_root_hashes( ) async def validation(consensus_services): for i in range(len(consensus_services)): client_consensus = consensus_services[i] for timestamp, root_hash in consensus_root_hash_timestamps: client_consensus_choice = await client_consensus.coro_get_root_hash_consensus( timestamp) assert (client_consensus_choice == root_hash) #consensus_service 0 is bootnode, it is in consensus #consensus_service 1 is the client. It only has genesis block and is not in consensus #consensus_services 2 to 2+int(num_peers_in_swarm/2) are in consensus #the rest of the peers are not in consensus await client_consensus.get_blockchain_sync_parameters() if i in [0, *[j + 2 for j in range(int(num_peers_in_swarm / 2))]]: sync_parameters = await client_consensus.get_blockchain_sync_parameters( ) assert sync_parameters == None if i == 1: sync_parameters = await client_consensus.get_blockchain_sync_parameters( debug=True) if ( genesis_block_timestamp + gap_between_genesis_block_and_first_transaction ) < int( time.time() / 1000 ) * 1000 - 1000 * 1000 + 4 * 1000 or gap_between_genesis_block_and_first_transaction < TIME_BETWEEN_HEAD_HASH_SAVE: assert sync_parameters.timestamp_for_root_hash == int( (time.time() - TIME_OFFSET_TO_FAST_SYNC_TO) / 1000) * 1000 else: assert sync_parameters.timestamp_for_root_hash == int( (genesis_block_timestamp + gap_between_genesis_block_and_first_transaction) / 1000) * 1000 + 1000 if i in [ j + 2 for j in range(int(num_peers_in_swarm / 2), num_peers_in_swarm) ]: timestamp = int( diverging_transactions_timestamp / 1000) * 1000 + 1000 sync_parameters = await client_consensus.get_blockchain_sync_parameters( debug=True) if timestamp > int(time.time()) - 1000 * 1000 + 1000 * 4: assert sync_parameters.timestamp_for_root_hash == timestamp else: assert sync_parameters.timestamp_for_root_hash == int( (time.time() - TIME_OFFSET_TO_FAST_SYNC_TO) / 1000) * 1000 await _test_consensus_swarm(request, event_loop, base_db, client_db, peer_dbs, validation)
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()
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 get_fresh_db(): testdb1 = MemoryDB() MainnetChain.from_genesis( testdb1, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE) return testdb1