def main(chain, address, token_address, csv_file, limit, start_from, vault_address, address_column, amount_column, action, freeze_ends_at, tokens_to_be_allocated): """TokenVault control script. 1) Deploys a token vault contract 2) Reads in distribution data as CSV 3) Locks vault """ project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) print("Owner address is", address) print("Owner balance is", from_wei(web3.eth.getBalance(address), "ether"), "ETH") # Goes through geth account unlock process if needed if is_account_locked(web3, address): request_account_unlock(c, address, timeout=3600*6) assert not is_account_locked(web3, address) Token = c.contract_factories.FractionalERC20 token = Token(address=token_address) print("Total supply is", token.call().totalSupply()) try: decimals = token.call().decimals() except ValueError: sys.exit("Token contract does not have support for decimal places, cannot work with it") print("Token decimal places is", decimals) assert decimals >= 0 if action == "deploy": deploy(project, c, chain, web3, address, token, freeze_ends_at, tokens_to_be_allocated * (10**decimals)) print("TokenVault deployed.") sys.exit(0) elif action == "load": if vault_address == None: sys.exit("vault_address missing") if address_column == None: sys.exit("address_column missing") if amount_column == None: sys.exit("amount_column missing") load(c, web3, address, csv_file, token, address_column, amount_column, vault_address) print("Data loaded to the vault.") sys.exit(0) elif action == "lock": lock(c, web3, address, token, vault_address) print("Vault locked. Now duck and wait.") else: sys.exit("Unknown action: {}".format(action))
def test_geth_chain_has_registrar(project_dir, write_project_file): write_project_file('populus.ini', '[chain:local]\nregistrar=faking-it') project = Project() with project.get_chain('local') as chain: assert chain.has_registrar is True
def test_gets_correct_files_default_dir(project_dir, write_project_file): project = Project(project_dir) project.config['compilation']['backend'] = { 'class': 'populus.compilation.backends.ViperBackend', } compiler_backend = project.get_compiler_backend() file_names = tuple(itertools.chain.from_iterable( compiler_backend.get_project_source_paths(source_dir) for source_dir in project.contracts_source_dirs )) should_match = { 'contracts/SolidityContract.v.py', 'contracts/AnotherFile.vy', } should_not_match = { 'contracts/Swapfile.v.py.swp', 'contracts/Swapfile.v.py.txt', 'contracts/BackedUpContract.vy.bak', 'contracts/not-contract.vy.txt', } for filename in should_match: write_project_file(filename) for filename in should_not_match: write_project_file(filename) for file_name in file_names: assert os.path.exists(file_name) assert any(is_same_path(file_name, path) for path in should_match) assert not any(is_same_path(file_name, path) for path in should_not_match)
def with_math_v2(testrpc_chain, write_project_file, MATH_V2): project = Project() prev_hash = project.get_source_file_hash() write_project_file('contracts/Math.sol', MATH_V2['source']) assert project.get_source_file_hash() != prev_hash assert 'Math' in project.compiled_contracts
def test_wait_for_block(project_dir, chain_name): project = Project() with project.get_chain(chain_name) as chain: web3 = chain.web3 start_block = web3.eth.blockNumber chain.wait.for_block(start_block + 3, timeout=60) assert web3.eth.blockNumber >= start_block + 3
def test_chain_web3_is_preconfigured_with_default_from(project_dir): project = Project() default_account = '0x0000000000000000000000000000000000001234' project.config['web3.Tester.eth.default_account'] = default_account with project.get_chain('tester') as chain: web3 = chain.web3 assert web3.eth.defaultAccount == default_account assert web3.eth.coinbase != default_account
def test_wait_for_receipt(project_dir, chain_name): project = Project() with project.get_chain(chain_name) as chain: if chain_name == "temp": chain.wait.for_unlock() web3 = chain.web3 txn_hash = web3.eth.sendTransaction({"to": web3.eth.coinbase, "value": 1234}) txn_receipt = chain.wait.for_receipt(txn_hash) assert txn_receipt["transactionHash"] == txn_hash
def test_geth_chain_has_registrar(project_dir, write_project_file): project = Project() project.config['chains.local.chain.class'] = 'populus.chain.LocalGethChain' project.config['chains.local.registrar'] = 'faking-it' project.config['chains.local.web3.provider.class'] = 'web3.providers.ipc.IPCProvider' project.config['chains.local.web3.provider.settings.ipc_path'] = ( get_geth_ipc_path(get_local_chain_datadir(project.project_dir, 'local')) ) with project.get_chain('local') as chain: assert chain.has_registrar is True
def testrpc_chain(project_dir, write_project_file, MATH, LIBRARY_13, MULTIPLY_13): write_project_file("contracts/Math.sol", MATH["source"]) write_project_file("contracts/Multiply13.sol", "\n".join((LIBRARY_13["source"], MULTIPLY_13["source"]))) project = Project() assert "Math" in project.compiled_contracts assert "Library13" in project.compiled_contracts assert "Multiply13" in project.compiled_contracts with project.get_chain("testrpc") as chain: yield chain
def test_wait_for_contract_address(project_dir, chain_name, MATH_CODE, MATH_RUNTIME): project = Project() with project.get_chain(chain_name) as chain: if chain_name == "temp": chain.wait.for_unlock() web3 = chain.web3 txn_hash = web3.eth.sendTransaction({"data": MATH_CODE, "gas": 2000000}) contract_address = chain.wait.for_contract_address(txn_hash) chain_code = web3.eth.getCode(contract_address) assert chain_code == MATH_RUNTIME
def deploy_test(): print('Deploying contracts') project = Project() with project.get_chain(LOCAL_CHAIN_NAME) as chain: web3 = chain.web3 owner = web3.eth.accounts[0] test = chain.provider.get_contract_factory('Test') tx_hash = test.deploy(transaction={'from': owner}) receipt = check_successful_tx(chain.web3, tx_hash, txn_wait) test_address = receipt['contractAddress'] print('Test deployed') write_to_file(Test_abi=test.abi, Test=test_address) print('Deployed')
def main(ctx, **kwargs): project = Project() chain_name = kwargs['chain'] log.info( "Make sure {} chain is running, you can connect to it and it is synced, " "or you'll get timeout".format(chain_name)) with project.get_chain(chain_name) as chain: set_connection_pool_size(chain.web3, 1000, 1000) ctx.obj = {} ctx.obj['chain'] = chain ctx.obj['owner'] = kwargs['owner'] or chain.web3.eth.accounts[0]
def test_dates(self): """Dates match given in the project material.""" project_dir = DATACOIN_PATH project = Project(project_dir, create_config_file=True) with project.get_chain('tester') as chain: beneficiary = chain.web3.eth.accounts[3] multisig = chain.web3.eth.accounts[4] customer = chain.web3.eth.accounts[1] # Initialize crowdsale args = [beneficiary, multisig, 0] crowdsale, _ = chain.provider.get_or_deploy_contract( 'Crowdsale', deploy_args=args) # Initialize token args = [beneficiary] # Owner set token, _ = chain.provider.get_or_deploy_contract('DataCoin', deploy_args=args) assert crowdsale.call().tokenReward( ) == '0x0000000000000000000000000000000000000000' crowdsale.transact({"from": beneficiary}).setToken(token.address) assert crowdsale.call().tokenReward( ) != '0x0000000000000000000000000000000000000000' token.transact({ "from": beneficiary }).approve(crowdsale.address, 440000000) deadlines = [ crowdsale.call().deadlines(0), crowdsale.call().deadlines(1), crowdsale.call().deadlines(2), crowdsale.call().deadlines(3) ] print("Start is {}".format( datetime.datetime.fromtimestamp(crowdsale.call().start(), tz=datetime.timezone.utc))) for idx, deadline in enumerate(deadlines): print("Deadline {} is {}".format( idx, datetime.datetime.fromtimestamp(deadline, tz=datetime.timezone.utc))) print("Token is transferable {}".format( datetime.datetime.fromtimestamp(token.call().startTime(), tz=datetime.timezone.utc))) assert token.call().startTime() == deadlines[-1]
def test_wait_for_receipt(project_dir, chain_name): project = Project() with project.get_chain(chain_name) as chain: if chain_name == 'temp': chain.wait.for_unlock() web3 = chain.web3 txn_hash = web3.eth.sendTransaction({ 'to': web3.eth.coinbase, 'value': 1234, }) txn_receipt = chain.wait.for_receipt(txn_hash) assert txn_receipt['transactionHash'] == txn_hash
def main(chain, address, csv_file): """Extract crowdsale invested events. This is useful for RelaunchCrowdsale to rebuild the data. """ project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) # Sanity check print("Block number is", web3.eth.blockNumber) Crowdsale = c.provider.get_contract_factory( 'MintedTokenCappedCrowdsale') crowdsale = Crowdsale(address=address) print("Total amount raised is", from_wei(crowdsale.call().weiRaised(), "ether"), "ether") print("Getting events") events = crowdsale.pastEvents("Invested").get(only_changes=False) print("Writing results to", csv_file) with open(csv_file, 'w', newline='') as out: writer = csv.writer(out) writer.writerow([ "Address", "Payment at", "Tx hash", "Tx index", "Invested ETH", "Received tokens" ]) for e in events: timestamp = web3.eth.getBlock(e["blockNumber"])["timestamp"] dt = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) writer.writerow([ address, dt.isoformat(), e["transactionHash"], e["transactionIndex"], from_wei(e["args"]["weiAmount"], "ether"), e["args"]["tokenAmount"], ]) print("Total", len(events), "invest events") print("All done! Enjoy your decentralized future.")
def deploy(chain_name, authority_address, indexed_ordered_set_lib_address, sem_version_lib_address, package_db_address, release_db_address, release_validator_address, package_index_address): """ #. Deploy WhitelistAuthority #. Deploy Libraries: - EnumerableMappingLib - SemVersionLib - IndexedOrderedSetLib #. Deploy PackageDB - set Authority #. Deploy ReleaseDB - set Authority #. Deploy ReleaseValidator #. Deploy PackageIndex - set PackageDB - set Authority #. Setup Authorizations - PackageIndex -> PackageDB.setPackage(...) - PackageIndex -> PackageDB.setPackageOwner(...) - PackageIndex -> ReleaseDB.setRelease(...) - * -> ReleaseDB.setVersion(...) - * -> ReleaseDB.updateLatestTree(...) - * -> PackageIndex.release(...) - * -> PackageIndex.transferPackageOwner(...) """ project = Project() click.echo("Starting {0} chain... ".format(chain_name), nl=False) with project.get_chain(chain_name) as chain: click.echo("STARTED") web3 = chain.web3 authority = chain.contract_factories.WhitelistAuthority( address=authority_address) release_validator = chain.contract_factories.ReleaseValidator( address=release_validator_address) sem_version_lib = chain.contract_factories.SemVersionLib( address=sem_version_lib_address, ) indexed_ordered_set_lib = chain.contract_factories.IndexedOrderedSetLib( address=indexed_ordered_set_lib_address, ) package_db = chain.contract_factories.PackageDB( address=package_db_address, ) release_db = chain.contract_factories.ReleaseDB( address=release_db_address, ) package_index = chain.contract_factories.PackageIndex( address=package_index_address) import pdb pdb.set_trace() x = 3
def testrpc_chain(project_dir, write_project_file, MATH, LIBRARY_13, MULTIPLY_13): write_project_file('contracts/Math.sol', MATH['source']) write_project_file( 'contracts/Multiply13.sol', '\n'.join((LIBRARY_13['source'], MULTIPLY_13['source'])), ) project = Project() assert 'Math' in project.compiled_contracts assert 'Library13' in project.compiled_contracts assert 'Multiply13' in project.compiled_contracts with project.get_chain('testrpc') as chain: yield chain
def __init__(self, account, passphrase): project = Project() chain_name = "bch" with project.get_chain(chain_name) as chain: GreeterFactory = chain.provider.get_contract_factory('Greeter') chain.web3.personal.unlockAccount(account, passphrase) txid = GreeterFactory.deploy( transaction={"from": account}, args=[] ) contract_address = chain.wait.for_contract_address(txid) self.account = account self.greeter = GreeterFactory(address = contract_address) self.chain = chain
def main(**kwargs): project = Project() chain_name = kwargs['chain'] owner = kwargs['owner'] challenge_period = kwargs['challenge_period'] supply = kwargs['supply'] token_name = kwargs['token_name'] token_decimals = kwargs['token_decimals'] token_symbol = kwargs['token_symbol'] token_address = kwargs['token_address'] supply *= 10**(token_decimals) txn_wait = 250 assert challenge_period >= 500, 'Challenge period should be >= 500 blocks' if chain_name == 'rinkeby': txn_wait = 500 print('''Make sure {} chain is running, you can connect to it and it is synced, or you'll get timeout'''.format(chain_name)) with project.get_chain(chain_name) as chain: web3 = chain.web3 print('Web3 provider is', web3.providers[0]) owner = owner or web3.eth.accounts[0] assert owner assert web3.eth.getBalance(owner) > 0, 'Account with insuficient funds.' print('Owner is', owner) token = chain.provider.get_contract_factory('CustomToken') if not token_address: txhash = token.deploy( args=[supply, token_name, token_symbol, token_decimals], transaction={'from': owner} ) receipt = check_succesful_tx(chain.web3, txhash, txn_wait) token_address = receipt['contractAddress'] print(token_name, 'address is', token_address) microraiden_contract = chain.provider.get_contract_factory('RaidenMicroTransferChannels') txhash = microraiden_contract.deploy(args=[token_address, challenge_period, []]) receipt = check_succesful_tx(chain.web3, txhash, txn_wait) microraiden_address = receipt['contractAddress'] print('RaidenMicroTransferChannels address is', microraiden_address)
def main(chain_name, owner, consent, coldwallet): project = Project() params_check([owner, consent, coldwallet]) # This is configured in populus.json if (chain_name != "testnet"): msg = "Make sure {} chain is running, you can connect to it, \ or you'll get timeout" print(msg.format(chain_name)) with project.get_chain(chain_name) as chain: if (owner is None): owner, consent, coldwallet = get_default_account(chain_name, chain) # deploy_greeter(chain_name, chain, owner) gnt = deploy_or_get_gnt(chain_name, chain, owner) rinkeby_fund_and_finalize(chain, gnt, owner) deploy_all_the_things(chain_name, chain, gnt, owner, consent, coldwallet) print("All done! Enjoy your decentralized future.")
def temp_chain(project_dir, write_project_file, MATH, LIBRARY_13, MULTIPLY_13): write_project_file('contracts/Math.sol', MATH['source']) write_project_file( 'contracts/Multiply13.sol', '\n'.join((LIBRARY_13['source'], MULTIPLY_13['source'])), ) project = Project() assert 'Math' in project.compiled_contracts assert 'Library13' in project.compiled_contracts assert 'Multiply13' in project.compiled_contracts with project.get_chain('temp') as chain: chain.wait.for_unlock(chain.web3.eth.coinbase) yield chain
def test_gets_correct_files_default_dir(project_dir, write_project_file): project = Project(project_dir, create_config_file=True) file_names = tuple( itertools.chain.from_iterable( find_solidity_source_files(source_dir) for source_dir in project.contracts_source_dirs)) should_match = { 'contracts/SolidityContract.sol', 'contracts/AnotherFile.sol', } should_not_match = { 'contracts/BackedUpContract.sol.bak', 'contracts/Swapfile.sol.swp', 'contracts/not-contract.txt', } for filename in should_match: write_project_file(filename) for filename in should_not_match: write_project_file(filename) for file_name in file_names: assert os.path.exists(file_name) assert any(is_same_path(file_name, path) for path in should_match) assert not any( is_same_path(file_name, path) for path in should_not_match)
def deploy_crowdsale_from_file(project: Project, yaml_filename: str, deployment_name: str, deploy_address: str): """Deploy crowdsale plan.""" chain_data = load_crowdsale_definitions(yaml_filename, deployment_name) chain_name = chain_data["chain"] address = deploy_address with project.get_chain(chain_name) as chain: web3 = chain.web3 print("Web3 provider is", web3.currentProvider) print("Owner address is", address) start_balance = from_wei(web3.eth.getBalance(address), "ether") print("Owner balance is", start_balance, "ETH") runtime_data, statistics, contracts = deploy_crowdsale( project, chain, chain_data, deploy_address) perform_post_actions(chain, runtime_data, contracts) perform_verify_actions(chain, runtime_data, contracts) write_deployment_report(yaml_filename, runtime_data) end_balance = from_wei(web3.eth.getBalance(address), "ether") print("Deployment cost is", start_balance - end_balance, "ETH") return runtime_data, statistics, contracts
def main(): address_data = OrderedDict() project = Project() with project.get_chain("mainnet") as chain: Crowdsale = chain.get_contract_factory('OriginalCrowdsale') crowdsale = Crowdsale( address="0x362bb67f7fdbdd0dbba4bce16da6a284cf484ed6") # We have configured non-default timeout as pastEvents() takes long web3 = chain.web3 # Sanity check print("Block number is", web3.eth.blockNumber) print("Amount raised is", crowdsale.call().amountRaised()) print("Getting events") events = crowdsale.pastEvents("FundTransfer").get(only_changes=False) # Merge several transactions from the same address to one print("Analysing results") for e in events: address = e["args"]["backer"] data = address_data.get(address, {}) # TODO: Not sure if we get events in block order timestamp = web3.eth.getBlock(e["blockNumber"])["timestamp"] current_first = data.get("first_payment", 99999999999999999) if timestamp < current_first: data["first_payment"] = timestamp data["raised"] = data.get("raised", 0) + from_wei( e["args"]["amount"], "ether") address_data[address] = data print("Writing results") with open('transactions.csv', 'w', newline='') as csvfile: writer = csv.writer(csvfile) for address, data in address_data.items(): timestamp = data["first_payment"] dt = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) writer.writerow([address, dt.isoformat(), str(data["raised"])]) print("OK")
def main(chain_name): project = Project() print("Make sure {} chain is running, or it'll timeout".format(chain_name)) with project.get_chain(chain_name) as chain: # Load Populus contract proxy classes MyStorage = chain.provider.get_contract_factory('MyStorage') Token = chain.provider.get_contract_factory('MToken') web3 = chain.web3 print("Web3 provider is", web3.currentProvider) # The address who will be the owner of the contracts beneficiary = web3.eth.coinbase assert beneficiary, "Make sure your node has coinbase account created" # Deploy the Storage txhash = MyStorage.deploy(transaction={"from": beneficiary}) print("Deploying mystorage, tx hash is", txhash) receipt = check_succesful_tx(web3, txhash) mystorage_address = receipt["contractAddress"] print("MyStorage contract address is", mystorage_address) # Deploy token txhash = Token.deploy(transaction={"from": beneficiary}, args=['MyToken', 18, 'MTOK', mystorage_address]) print("Deploying token, tx hash is", txhash) receipt = check_succesful_tx(web3, txhash) token_address = receipt["contractAddress"] print("Token contract address is", token_address) # Make contracts aware of each other print("Initializing contracts") mystorage = MyStorage(address=mystorage_address) token = Token(address=token_address) mystorage.transact().allowAccess(token_address) mystorage.transact().setTotalSupply(100000) check_succesful_tx(web3, txhash) # Do some contract reads to see everything looks ok print("Token total supply is", token.call().getTotalSupply()) print("All done! Enjoy your decentralized future.")
def main(): project = Project('populus.json') chain_name = "testrpclocal" print("Make sure {} chain is running, you can connect to it, or you'll get timeout".format(chain_name)) with project.get_chain(chain_name) as chain: web3 = chain.web3 print("Web3 provider is", web3.currentProvider) registry = deploy("Registry", chain) currencyNetworkFactory = deploy("CurrencyNetworkFactory", chain, registry.address) transfer_filter = currencyNetworkFactory.on("CurrencyNetworkCreated") txid = currencyNetworkFactory.transact({"from": web3.eth.accounts[0]}).CreateCurrencyNetwork('Trustlines', 'T', web3.eth.accounts[0], 1000, 100, 25, 100); receipt = check_successful_tx("create", web3, txid) wait(transfer_filter) log_entries = transfer_filter.get() addr_trustlines = log_entries[0]['args']['_currencyNetworkContract'] print("REAL CurrencyNetwork contract address is", addr_trustlines) resolver = deploy("Resolver", chain, addr_trustlines) txid = resolver.transact({"from": web3.eth.accounts[0]}).registerLengthFunction("getAccountExt(address,address)", "getAccountExtLen()", addr_trustlines); receipt = check_successful_tx("resolver", web3, txid) transfer_filter = resolver.on("FallbackChanged") proxy = deploy("EtherRouter", chain, resolver.address) proxied_trustlines = chain.provider.get_contract_factory("CurrencyNetwork")(proxy.address) txid = proxied_trustlines.transact({"from": web3.eth.accounts[0]}).setAccount(web3.eth.accounts[6], web3.eth.accounts[7], 2000000, 1, 1, 1, 1, 1, 1, 1); receipt = check_successful_tx("setAccount", web3, txid) print(proxied_trustlines.call().getAccountExt(web3.eth.accounts[6], web3.eth.accounts[7])) storagev2 = deploy("CurrencyNetwork", chain) txid = resolver.transact({"from": web3.eth.accounts[0]}).setFallback(storagev2.address); receipt = check_successful_tx("setFallback", web3, txid) wait(transfer_filter) log_entries = transfer_filter.get() print("Forwarded to ", log_entries[0]['args']['newFallback']) txid = proxied_trustlines.transact({"from": web3.eth.accounts[0]}).init('Trustlines', 'T', 6, 1000, 100, 25, 100) receipt = check_successful_tx("init", web3, txid) txid = resolver.transact({"from": web3.eth.accounts[0]}).registerLengthFunction("getAccountExt(address,address)", "getAccountExtLen()", storagev2.address); receipt = check_successful_tx("register", web3, txid) txid = resolver.transact({"from": web3.eth.accounts[0]}).registerLengthFunction("trustline(address,address)", "trustlineLen(address,address)", storagev2.address); receipt = check_successful_tx("register", web3, txid) print(proxied_trustlines.call().getAccountExt(web3.eth.accounts[6], web3.eth.accounts[7])) prepare_trustlines_contract(proxied_trustlines, web3) test_trustlines(proxied_trustlines, web3) test_mediated_transfer_array(proxied_trustlines, web3)
def deploy_crowdsale_from_file(project: Project, yaml_filename: str, deployment_name: str, deploy_address: str): """Deploy crowdsale plan.""" chain_data = load_crowdsale_definitions(yaml_filename, deployment_name) chain_name = chain_data["chain"] with project.get_chain(chain_name) as chain: web3 = chain.web3 return _deploy_contracts(project, chain, web3, yaml_filename, chain_data, deploy_address)
def test_wait_for_contract_address(project_dir, chain_name, MATH_CODE, MATH_RUNTIME): project = Project() with project.get_chain(chain_name) as chain: if chain_name == 'temp': chain.wait.for_unlock() web3 = chain.web3 txn_hash = web3.eth.sendTransaction({ 'data': MATH_CODE, 'gas': 2000000, }) contract_address = chain.wait.for_contract_address(txn_hash) chain_code = web3.eth.getCode(contract_address) assert chain_code == MATH_RUNTIME
def main(sample_period, auction_address, chain_name, host, port): from gevent.pywsgi import WSGIServer app = Flask(__name__) api = Api(app) project = Project() with project.get_chain(chain_name) as chain: Auction = chain.provider.get_contract_factory('DutchAuction') auction_contract = Auction(address=auction_address) sampler = EventSampler(auction_address, chain) api.add_resource(AuctionStatus, "/status", resource_class_kwargs={ 'auction_contract': auction_contract, 'sampler': sampler }) rest_server = WSGIServer((host, port), app) server_greenlet = gevent.spawn(rest_server.serve_forever) server_greenlet.join()
def deploy_contracts(): if os.path.isfile(FILE_PATH) and \ os.path.getmtime(FILE_PATH) > os.path.getmtime('../../contracts/MicroTransferChannels.sol'): return logging.info('Deploying new contracts') project = Project() with project.get_chain(CHAIN_NAME) as chain: web3 = chain.web3 owner = web3.eth.accounts[0] token_factory = chain.provider.get_contract_factory('GEXToken') # This will be the abi of the token tx_hash = token_factory.deploy(transaction={'from': owner}) # the way we deploy contracts receipt = check_successful_tx(chain.web3, tx_hash, txn_wait) token_address = receipt['contractAddress'] logging.info('{} address is {}'.format(token_name, token_address)) channel_factory = chain.provider.get_contract_factory('MicroTransferChannels') tx_hash = channel_factory.deploy( args=[token_address, challenge_period, channel_lifetime], transaction={'from': owner} ) receipt = check_successful_tx(chain.web3, tx_hash, txn_wait) channels_address = receipt['contractAddress'] logging.info('MicroTransferChannels address is {}'.format(channels_address)) node_factory = chain.provider.get_contract_factory('NodeContract') tx_hash = node_factory.deploy(transaction={'from': owner}) receipt = check_successful_tx(chain.web3, tx_hash, txn_wait) node_address = receipt['contractAddress'] logging.info('NodeContract address is {}'.format(node_address)) tx_hash = node_factory(node_address).transact({'from': owner}).addNode(owner, '10.1.0.56', 1337, 'public_key') check_successful_tx(chain.web3, tx_hash, txn_wait) write_to_file( channels_abi=channel_factory.abi, token_abi=token_factory.abi, node_abi=node_factory.abi, token_address=token_address, channels_address=channels_address, node_address=node_address ) print('Deployed')
def deploy_test_networks(chain_name, networks): with cd_into_projectpath(): project = Project('populus.json') print( "Make sure {} chain is running, you can connect to it, or you'll get timeout" .format(chain_name)) with project.get_chain(chain_name) as chain: web3 = chain.web3 print("Web3 provider is", web3.currentProvider) currencyNetworkFactory = deploy_factory_and_registry(chain) network_addresses = [ deploy_network(chain, currencyNetworkFactory, name, symbol, decimals) for (name, symbol, decimals) in networks ] return network_addresses
def main(): project = Project('populus.json') chain_name = "dockerrpc" print("Make sure {} chain is running, you can connect to it, or you'll get timeout".format(chain_name)) with project.get_chain(chain_name) as chain: web3 = chain.web3 print("Web3 provider is", web3.currentProvider) registry = deploy("Registry", chain) currencyNetworkFactory = deploy("CurrencyNetworkFactory", chain, registry.address) networks = [("Euro", "EUR", 2), ("US Dollar", "USD", 2), ("Testcoin", "T", 6)] network_addresses = [deploy_network(chain, currencyNetworkFactory, name, symbol, decimals) for (name, symbol, decimals) in networks] with open("networks", 'w') as file_handler: for network_address in network_addresses: file_handler.write("{}\n".format(network_address))
def test_token_basic(self): """Does basic tests on crowdsale construction""" project_dir = DATACOIN_PATH project = Project(project_dir) chain_name = "tester" with project.get_chain(chain_name) as chain: # TODO(rbharath): These default accounts are set by populus # somewhere. Figure out how to configure this directly. # setup accounts = chain.web3.eth.accounts beneficiary = accounts[3] multisig = accounts[4] # crowdsale args = [beneficiary, multisig, 0] crowdsale, _ = chain.provider.get_or_deploy_contract( 'Crowdsale', deploy_args=args) # Token contract address is not yet set. assert crowdsale.call().tokenReward( ) == '0x0000000000000000000000000000000000000000'
def test_bytecode_comes_from_project_if_no_migrations(tester_chain): project = Project() assert not project.migrations chain = tester_chain MATH = project.compiled_contracts['Math'] Math = chain.get_contract_factory('Math') assert Math.abi == MATH['abi'] assert Math.code == MATH['code'] assert Math.code_runtime == MATH['code_runtime']
def test_contracts_fixture(request, project_dir, write_project_file, MATH): write_project_file('contracts/Math.sol', MATH['source']) contracts = request.getfuncargvalue('contracts') project = Project() assert contracts.Math assert len(contracts.Math.code) > 2 assert len(contracts.Math.code_runtime) > 2 assert len(contracts.Math.abi) == len(MATH['abi'])
def test_get_price_tiers_2(self): """Price tiers match given dates.""" project_dir = DATACOIN_PATH project = Project(project_dir, create_config_file=True) with project.get_chain('tester') as chain: beneficiary = chain.web3.eth.accounts[3] multisig = chain.web3.eth.accounts[4] customer = chain.web3.eth.accounts[1] # Initialize crowdsale args = [beneficiary, multisig, 0] crowdsale, _ = chain.provider.get_or_deploy_contract( 'Crowdsale', deploy_args=args) # Initialize token args = [beneficiary] # Owner set token, _ = chain.provider.get_or_deploy_contract('DataCoin', deploy_args=args) assert crowdsale.call().tokenReward( ) == '0x0000000000000000000000000000000000000000' crowdsale.transact({"from": beneficiary}).setToken(token.address) assert crowdsale.call().tokenReward( ) != '0x0000000000000000000000000000000000000000' token.transact({ "from": beneficiary }).approve(crowdsale.address, 440000000) deadlines = [1488297600, 1488902400, 1489507200, 1490112000] prices = [ 833333333333333, 909090909090909, 952380952380952, 1000000000000000 ] for idx, deadline in enumerate(deadlines): crowdsale.transact().setCurrent(deadline - 1) assert crowdsale.call().getPrice() == prices[idx] # Post last deadline prcie crowdsale.transact().setCurrent(deadlines[-1] + 1) assert crowdsale.call().getPrice() == 1000000000000000
def main(deployment_file, deployment_name, address): """Deploy a CrowdsaleToken contract. Example: deploy-contracts --deployment-file=crowdsales/example.yml --deployment-name=ropsten --address=0xffffffffffff """ project = Project() deploy_crowdsale_from_file(project, deployment_file, deployment_name, address) print("All done! Enjoy your decentralized future.")
def prepared_project(project_dir, write_project_file, LIBRARY_13, MATH): write_project_file('contracts/Multiply13.sol', '\n'.join(( LIBRARY_13['source'], MATH['source'], ))) project = Project() assert 'Library13' in project.compiled_contracts assert 'Math' in project.compiled_contracts return project
def project(request, project_dir, user_config_path, _loaded_contract_fixtures, _loaded_test_contract_fixtures): contracts = request.config.cache.get(CACHE_KEY_CONTRACTS, None) mtime = request.config.cache.get(CACHE_KEY_MTIME, None) project = Project( project_dir=project_dir, user_config_file_path=user_config_path, ) key_value_pairs_from_fn = getattr(request.function, '_populus_config_key_value_pairs', []) key_value_pairs_from_module = getattr(request.module, '_populus_config_key_value_pairs', []) key_value_pairs = tuple(itertools.chain( key_value_pairs_from_module, key_value_pairs_from_fn, )) for key, value in key_value_pairs: if value is None: del project.config[key] else: project.config[key] = value project.fill_contracts_cache(contracts, mtime) request.config.cache.set( CACHE_KEY_CONTRACTS, normalize_object_for_json(project.compiled_contract_data), ) request.config.cache.set( CACHE_KEY_MTIME, get_latest_mtime(project.get_all_source_file_paths()), ) return project
def main(chain, hot_wallet_address, csv_file, limit, start_from, address_column, amount_column, id_column, state_file): """Distribute ETh refunds. Reads in funds distribution data as CSV. Then sends funds from a local address. The refund status is stored as a JSON file. Example: refund --chain=kovan --hot-wallet-address=0x001fc7d7e506866aeab82c11da515e9dd6d02c25 --csv-file=refunds.csv --address-column="Refund address" --amount-column="ETH" --id-column="Email" --start-from=0 --limit=2 --state-file=refund-state.json Example CSV data: .. code-block:: csv Email,ETH,Refund address [email protected],61.52,0x0078EF811B6564c996fD10012579633B1a518b9D [email protected],111.21,0xf0b91641CCe2ADB4c0D7B90c54E7eE96CCCBc3d1 [email protected],61.52,0x0dAbC71Faa8982bF23eE2c4979d22536F5101065 [email protected],61.52,0x0B8EceBc18153166Beec1b568D510B55B560789D """ # Make a backup of the state file if os.path.exists(state_file): assert state_file.endswith(".json") backup_name = state_file.replace(".json", "." + datetime.datetime.utcnow().isoformat() + ".bak.json") print("Backing up state file to", backup_name) shutil.copy(state_file, backup_name) project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) print("Hot wallet address is", hot_wallet_address) print("Hot wallet balance is", from_wei(web3.eth.getBalance(hot_wallet_address), "ether"), "ETH") # Goes through geth account unlock process if needed if is_account_locked(web3, hot_wallet_address): request_account_unlock(c, hot_wallet_address, timeout=3600*6) assert not is_account_locked(web3, hot_wallet_address) print("Reading data", csv_file) with open(csv_file, "rt", encoding='utf-8-sig') as inp: reader = csv.DictReader(inp) rows = [row for row in reader] # Check that we have unique addresses uniq_ids = set() for row in rows: print(row) id = row[id_column].strip() if id in uniq_ids: raise RuntimeError("Id appears twice in input data", id) uniq_ids.add(id) addr = row[address_column] if not is_checksum_address(addr): print("Not a checksummed address", addr) # Start distribution start_time = time.time() start_balance = from_wei(web3.eth.getBalance(hot_wallet_address), "ether") print("Total rows", len(rows)) if os.path.exists(state_file): with open(state_file, "rt") as inp: state = json.load(inp) else: state = {} for i in range(start_from, min(start_from+limit, len(rows))): data = rows[i] addr = data[address_column].strip() id = data[id_column].strip() amount = Decimal(data[amount_column].strip()) amount_wei = to_wei(amount, "ether") if id in state: print("Already refunded", id, addr, amount) continue # Use non-default gas price for speedier processing gas_price = int(web3.eth.gasPrice * 3) txid = web3.eth.sendTransaction({"from": hot_wallet_address, "to": addr, "value": amount_wei, "gasPrice": gas_price}) duration = time.time() - start_time print("Transferring", id, amount_wei, "to", addr, "txid", txid, "duration", duration) state[id] = txid with open(state_file, "wt") as out: json.dump(state, out) check_succesful_tx(web3, txid, timeout=300) end_balance = from_wei(web3.eth.getBalance(hot_wallet_address), "ether") print("Refund cost is", start_balance - end_balance, "ETH") print("All done! Enjoy your decentralized future.")
def main(chain, address, contract_name, name, symbol, supply, decimals, minting_agent, release_agent, verify, verify_filename, master_address): """Deploy a single crowdsale token contract. Examples: deploy-token --chain=ropsten --address=0x3c2d4e5eae8c4a31ccc56075b5fd81307b1627c6 --name="MikkoToken 2.0" --symbol=MOO --release-agent=0x3c2d4e5eae8c4a31ccc56075b5fd81307b1627c6 --supply=100000 deploy-token --chain=kovan --contract-name="CentrallyIssuedToken" --address=0x001FC7d7E506866aEAB82C11dA515E9DD6D02c25 --name="TestToken" --symbol=MOO --supply=916 --decimals=0 --verify --verify-filename=CentrallyIssuedToken.sol """ project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) print("Deployer address is", address) print("Deployer balance is", from_wei(web3.eth.getBalance(address), "ether"), "ETH") # Goes through geth account unlock process if needed if is_account_locked(web3, address): request_account_unlock(c, address, None) decimal_multiplier = 10 ** decimals transaction = {"from": address} args = [name, symbol, supply * decimal_multiplier, decimals] if contract_name == "CentrallyIssuedToken": # TODO: Generalize settings contract args # This sets the upgrade master args = [address] + args # Make sure Populus does not pull up any cached instances of deployed contracts # TODO: Fix Populus support this via an deploy argument if "JSONFile" in c.registrar.registrar_backends: del c.registrar.registrar_backends["JSONFile"] print("Starting contract deployment") # This does deployment with all dependencies linked in contract, txhash = c.provider.deploy_contract(contract_name, deploy_transaction=transaction, deploy_args=args) check_succesful_tx(web3, txhash) print("Contract address is", contract.address) # This is needed for Etherscan contract verification # https://etherscanio.freshdesk.com/support/solutions/articles/16000053599-contract-verification-constructor-arguments const_args = get_constructor_arguments(contract, args) print("CrowdsaleToken constructor arguments is", const_args) if release_agent: print("Setting release agent to", release_agent) txid = contract.transact(transaction).setReleaseAgent(release_agent) check_succesful_tx(web3, txid) if minting_agent: print("Setting minting agent") txid = contract.transact(transaction).setMintAgent(minting_agent, True) check_succesful_tx(web3, txid) if master_address: print("Moving upgrade master to a team multisig wallet", master_address) txid = contract.transact({"from": address}).setUpgradeMaster(master_address) check_succesful_tx(web3, txid) print("Moving total supply a team multisig wallet", master_address) contract.transact({"from": address}).transfer(master_address, contract.call().totalSupply()) check_succesful_tx(web3, txid) if verify: chain_name = chain fname = verify_filename browser_driver = "chrome" verify_contract( project=project, libraries={}, # TODO: Figure out how to pass around chain_name=chain_name, address=contract.address, contract_name=contract_name, contract_filename=fname, constructor_args=const_args, # libraries=runtime_data["contracts"][name]["libraries"], browser_driver=browser_driver) link = get_etherscan_link(chain_name, contract.address) print("Verified contract is", link) print("Token supply:", contract.call().totalSupply()) # Do some contract reads to see everything looks ok try: print("Token owner:", contract.call().owner()) except ValueError: pass # No owner try: print("Token upgradeMaster:", contract.call().upgradeMaster()) except ValueError: pass try: print("Token minting finished:", contract.call().mintingFinished()) except ValueError: pass try: print("Token released:", contract.call().released()) print("Token release agent:", contract.call().releaseAgent()) except ValueError: pass print("All done! Enjoy your decentralized future.")
def main(chain, address, csv_file): """Extract crowdsale contract investors.""" project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) # Sanity check print("Block number is", web3.eth.blockNumber) Crowdsale = c.provider.get_contract_factory('MintedTokenCappedCrowdsale') crowdsale = Crowdsale(address=address) print("Total amount raised is", from_wei(crowdsale.call().weiRaised(), "ether"), "ether") print("Getting events") events = crowdsale.pastEvents("Invested").get(only_changes=False) # Merge several transactions from the same address to one print("Analysing", len(events), "raw events") address_data = OrderedDict() for e in events: address = e["args"]["investor"] data = address_data.get(address, {}) # TODO: Not sure if we get events in block order timestamp = web3.eth.getBlock(e["blockNumber"])["timestamp"] current_first = data.get("first_payment", 99999999999999999) if timestamp < current_first: data["first_payment"] = timestamp data["raised"] = data.get("raised", 0) + from_wei(e["args"]["weiAmount"], "ether") data["tokens"] = data.get("tokens", 0) + e["args"]["tokenAmount"] address_data[address] = data if csv_file: print("Writing results to", csv_file) with open(csv_file, 'w', newline='') as out: writer = csv.writer(out) writer.writerow(["Address", "First payment at", "Invested ETH", "Received tokens"]) for address, data in address_data.items(): timestamp = data["first_payment"] dt = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) writer.writerow([ address, dt.isoformat(), str(data["raised"]), str(data["tokens"]) ]) else: for address, data in address_data.items(): timestamp = data["first_payment"] dt = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) print( address, dt.isoformat(), str(data["raised"]), str(data["tokens"]) ) print("Total", len(address_data), "investors") print("All done! Enjoy your decentralized future.")
def test_testrpc_chain_has_registrar(project_dir): project = Project() with project.get_chain('testrpc') as chain: assert chain.has_registrar is True
def main(chain, address, token, csv_file, limit, start_from, issuer_address, address_column, amount_column, allow_zero, master_address): """Distribute tokens to centrally issued crowdsale participant or bounty program participants. Reads in distribution data as CSV. Then uses Issuer contract to distribute tokens. All token counts are multiplied by token contract decimal specifier. E.g. if CSV has amount 15.5, token has 2 decimal places, we will issue out 1550 raw token amount. To speed up the issuance, transactions are verified in batches. Each batch is 16 transactions at a time. Example (first run): distribute-tokens --chain=kovan --address=0x001FC7d7E506866aEAB82C11dA515E9DD6D02c25 --token=0x1644a421ae0a0869bac127fa4cce8513bd666705 --master-address=0x9a60ad6de185c4ea95058601beaf16f63742782a --csv-file=input.csv --allow-zero --address-column="Ethereum address" --amount-column="Token amount" Example (second run, continue after first run was interrupted): distribute-tokens --chain=kovan --address=0x001FC7d7E506866aEAB82C11dA515E9DD6D02c25 --token=0x1644a421ae0a0869bac127fa4cce8513bd666705 --csv-file=input.csv --allow-zero --address-column="Ethereum address" --amount-column="Token amount" --issuer-address=0x2c9877534f62c8b40aebcd08ec9f54d20cb0a945 """ project = Project() with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) print("Owner address is", address) print("Owner balance is", from_wei(web3.eth.getBalance(address), "ether"), "ETH") # Goes through geth account unlock process if needed if is_account_locked(web3, address): request_account_unlock(c, address, timeout=3600*6) assert not is_account_locked(web3, address) Token = c.provider.get_base_contract_factory('CentrallyIssuedToken') token = Token(address=token) print("Token is", token.address) print("Total supply is", token.call().totalSupply()) print("Upgrade master is", token.call().upgradeMaster()) print("Owner token balance master is", token.call().balanceOf(address)) decimals = token.call().decimals() print("Token decimal places is", decimals) assert decimals >= 0 decimal_multiplier = 10**decimals transaction = {"from": address} Issuer = c.provider.get_base_contract_factory('Issuer') if not issuer_address: # TODO: Fix Populus support this via an deploy argument if "JSONFile" in c.registrar.registrar_backends: del c.registrar.registrar_backends["JSONFile"] # Create issuer contract assert master_address, "You need to give master-address" args = [address, master_address, token.address] print("Deploying new issuer contract", args) issuer, txhash = c.provider.deploy_contract("Issuer", deploy_transaction=transaction, deploy_args=args) check_succesful_tx(web3, txhash) const_args = get_constructor_arguments(issuer, args) chain_name = chain fname = "Issuer.sol" browser_driver = "chrome" verify_contract( project=project, libraries={}, # TODO: Figure out how to pass around chain_name=chain_name, address=issuer.address, contract_name="Issuer", contract_filename=fname, constructor_args=const_args, # libraries=runtime_data["contracts"][name]["libraries"], browser_driver=browser_driver) link = get_etherscan_link(chain_name, issuer.address) print("Issuer verified contract is", link) else: print("Reusing existing issuer contract") issuer = Issuer(address=issuer_address) print("Issuer contract is", issuer.address) print("Currently issued", issuer.call().issuedCount()) if not master_address: sys.exit("Please use Token.approve() to give some allowance for the issuer contract by master address") allowance = token.call().allowance(master_address, issuer.address) print("Issuer allowance", allowance) if allowance == 0 or not master_address: sys.exit("Please use Token.approve() to give some allowance for the issuer contract by master address") print("Reading data", csv_file) with open(csv_file, "rt") as inp: reader = csv.DictReader(inp) rows = [row for row in reader] # Check that we have unique addresses uniq_addresses = set() for row in rows: addr = row[address_column].strip() if addr in uniq_addresses: raise RuntimeError("Address appears twice in input data", addr) uniq_addresses.add(addr) # Start distribution start_time = time.time() start_balance = from_wei(web3.eth.getBalance(address), "ether") tx_to_confirm = [] # List of txids to confirm tx_batch_size = 16 # How many transactions confirm once print("Total rows", len(rows)) for i in range(start_from, min(start_from+limit, len(rows))): data = rows[i] addr = data[address_column].strip() tokens = Decimal(data[amount_column].strip()) tokens *= decimal_multiplier end_balance = from_wei(web3.eth.getBalance(address), "ether") spent = start_balance - end_balance if tokens == 0: if not allow_zero: raise RuntimeError("Encountered zero amount") else: continue # http://stackoverflow.com/a/19965088/315168 if not tokens % 1 == 0: raise RuntimeError("Could not issue tokens because after multiplication was not integer") transaction = { "from": address, "gasPrice": int(web3.eth.gasPrice * 1.5) } tokens = int(tokens) print("Row", i, "giving", tokens, "to", addr, "issuer", issuer.address, "time passed", time.time() - start_time, "ETH passed", spent) if issuer.call().issued(addr): print("Already issued, skipping") continue txid = issuer.transact(transaction).issue(addr, tokens) tx_to_confirm.append(txid) # Confirm N transactions when batch max size is reached if len(tx_to_confirm) >= tx_batch_size: check_multiple_succesful_txs(web3, tx_to_confirm) tx_to_confirm = [] # Confirm dangling transactions check_multiple_succesful_txs(web3, tx_to_confirm) end_balance = from_wei(web3.eth.getBalance(address), "ether") print("Deployment cost is", start_balance - end_balance, "ETH") print("All done! Enjoy your decentralized future.")
def main(chain, address, csv_file): """Extract crowdsale invested events. This is useful for RelaunchCrowdsale to rebuild the data. """ project = Project() timestamp_filename = "block-timestamps.json" with project.get_chain(chain) as c: web3 = c.web3 print("Web3 provider is", web3.currentProvider) # Sanity check print("Block number is", web3.eth.blockNumber) Crowdsale = c.provider.get_base_contract_factory('MintedTokenCappedCrowdsale') crowdsale = Crowdsale(address=address) Token = c.provider.get_base_contract_factory('CrowdsaleToken') token = Token(address=crowdsale.call().token()) decimals = token.call().decimals() decimal_multiplier = 10**decimals print("We have", decimals, "decimals, multiplier is", decimal_multiplier) print("Total amount raised is", from_wei(crowdsale.call().weiRaised(), "ether"), "ether") print("Getting events") events = crowdsale.pastEvents("Invested").get(only_changes=False) print("Writing results to", csv_file) # Block number -> timestamp mappings timestamps = {} # Load cached timestamps if os.path.exists(timestamp_filename): with open(timestamp_filename, "rt") as inp: timestamps = json.load(inp) with open(csv_file, 'w', newline='') as out: writer = csv.writer(out) writer.writerow(["Address", "Payment at", "Tx hash", "Tx index", "Invested ETH", "Received tokens"]) for idx, e in enumerate(events): if idx % 100 == 0: print("Writing event", idx) # Save cached timestamps with open(timestamp_filename, "wt") as out: json.dump(timestamps, out) block_number = e["blockNumber"] if block_number not in timestamps: timestamps[block_number] = web3.eth.getBlock(block_number)["timestamp"] amount = Decimal(e["args"]["tokenAmount"]) / Decimal(decimal_multiplier) tokens = amount * decimal_multiplier # http://stackoverflow.com/a/19965088/315168 if not tokens % 1 == 0: raise RuntimeError("Could not convert token amount to decimal format. It was not an integer after restoring non-fractional balance: {} {} {}".format(tokens, amount, decimal_multiplier)) timestamp = timestamps[block_number] dt = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc) writer.writerow([ e["args"]["investor"], dt.isoformat(), e["transactionHash"], e["transactionIndex"], from_wei(e["args"]["weiAmount"], "ether"), amount, ]) print("Total", len(events), "invest events") print("All done! Enjoy your decentralized future.")