def deploy(gex_chain_name, eth_chain_name):
    print('Deploying contracts')
    project = Project()
    with project.get_chain(gex_chain_name) as gex_chain, project.get_chain(
            eth_chain_name) as eth_chain:
        gex_web3 = gex_chain.web3
        eth_web3 = eth_chain.web3
        # todo change address
        gex_owner = gex_web3.eth.accounts[0]
        eth_owner = eth_web3.eth.accounts[0]
        # GEXToken
        GEXToken = gex_chain.provider.get_contract_factory('GEXToken')
        tx_hash = GEXToken.deploy(transaction={'from': gex_owner})
        receipt = check_successful_tx(gex_chain.web3, tx_hash, txn_wait)
        gex_token_address = receipt['contractAddress']
        print('GEXToken deployed')
        # ETHToken
        ETHToken = eth_chain.provider.get_contract_factory('ETHToken')
        tx_hash = ETHToken.deploy(transaction={'from': eth_owner})
        receipt = check_successful_tx(eth_chain.web3, tx_hash, txn_wait)
        eth_token_address = receipt['contractAddress']
        print('ETHToken deployed')
        # GexContract
        GEXContract = gex_chain.provider.get_contract_factory('GexContract')
        tx_hash = GEXContract.deploy(args=[gex_token_address],
                                     transaction={'from': gex_owner})
        receipt = check_successful_tx(gex_chain.web3, tx_hash, txn_wait)
        gex_contract_address = receipt['contractAddress']
        print('GexContract deployed')
        # EthContract
        ETHContract = eth_chain.provider.get_contract_factory('EthContract')
        tx_hash = ETHContract.deploy(args=[eth_token_address],
                                     transaction={'from': eth_owner})
        receipt = check_successful_tx(eth_chain.web3, tx_hash, txn_wait)
        eth_contract_address = receipt['contractAddress']
        print('EthContract deployed')
        # Ownership
        gex_token = GEXToken(gex_token_address)
        tx_hash = gex_token.transact({
            'from': gex_owner
        }).transferOwnership(gex_contract_address)
        check_successful_tx(gex_chain.web3, tx_hash, txn_wait)
        print('GEXToken ownership is established')
        eth_token = ETHToken(eth_token_address)
        tx_hash = eth_token.transact({
            'from': eth_owner
        }).transferOwnership(eth_contract_address)
        check_successful_tx(eth_chain.web3, tx_hash, txn_wait)
        print('ETHToken ownership is established')
        write_to_file(
            EthContract_abi=ETHContract.abi,
            GexContract_abi=GEXContract.abi,
            GEXToken_abi=GEXToken.abi,
            ETHToken_abi=ETHToken.abi,
            GexContract=gex_contract_address,
            EthContract=eth_contract_address,
            ETHToken=eth_token_address,
            GEXToken=gex_token_address,
        )
    print('Deployed')
Beispiel #2
0
    def __init__(self, account, passphrase, contract_address=None):
        """
        Constructs the contract object.

        :param account: Ethereum account in hexadecimal prefixed with '0x'
        :param passphrase: Passphrase to unlock the account
        :param contract_address: Deployed contract (if None, it deploys one)
        :return:
        """
        project = Project()
        chain_name = "bbc"

        with project.get_chain(chain_name) as chain:

            AnchorFactory = chain.provider.get_contract_factory('BBcAnchor')

            chain.web3.personal.unlockAccount(account, passphrase)

            if contract_address is None:
                txid = AnchorFactory.deploy(
                    transaction={"from": account},
                    args=[]
                )
                contract_address = chain.wait.for_contract_address(txid)

            self.account = account
            self.anchor = AnchorFactory(address = contract_address)
            self.chain = chain
Beispiel #3
0
def repl(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):
    """
    Enter a python REPL with all the contracts available.
    """
    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()

        pass
Beispiel #4
0
def main():
    """Entry point for command line importer.

    Wrapper script defind in setup.py
    """

    fname = sys.argv[1]

    # Connection info
    chain_name = sys.argv[2]

    address = sys.argv[3]

    project = Project()

    print("Make sure {} is running or you'll get timeout".format(chain_name))

    with project.get_chain(chain_name) as chain:

        # Goes through coinbase account unlock process if needed
        get_unlocked_deploy_from_address(chain)

        EInvoicingRegistry = chain.get_contract_factory('EInvoicingRegistry')
        contract = EInvoicingRegistry(address=address)
        import_all_pooled(contract, fname)
Beispiel #5
0
def main():

    project = Project()

    # This is configured in populus.json
    # We are working on a testnet
    chain_name = "ropsten"
    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:

        # Load Populus contract proxy classes
        Crowdsale = chain.get_contract_factory('Crowdsale')
        Token = chain.get_contract_factory('EdgelessToken')

        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"

        # Random address on Ropsten testnet
        multisig_address = "0x83917f644df1319a6ae792bb244333332e65fff8"

        # Goes through coinbase account unlock process if needed
        get_unlocked_default_account_address(chain)

        # Deploy crowdsale, open since 1970
        txhash = Crowdsale.deploy(transaction={"from": beneficiary},
                                  args=[beneficiary, multisig_address, 1])
        print("Deploying crowdsale, tx hash is", txhash)
        receipt = check_succesful_tx(web3, txhash)
        crowdsale_address = receipt["contractAddress"]
        print("Crowdsale contract address is", crowdsale_address)

        # Deploy token
        txhash = Token.deploy(transaction={"from": beneficiary},
                              args=[beneficiary])
        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")
        crowdsale = Crowdsale(address=crowdsale_address)
        token = Token(address=token_address)
        txhash = crowdsale.transact({
            "from": beneficiary
        }).setToken(token_address)
        check_succesful_tx(web3, txhash)

        # Do some contract reads to see everything looks ok
        print("Token total supply is", token.call().totalSupply())
        print("Crowdsale max goal is", crowdsale.call().maxGoal())

        print("All done! Enjoy your decentralized future.")
def main(chain, address, token_address, csv_file, limit, start_from, vault_address, address_column, amount_column, duration_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.providers[0])
        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('FractionalERC20')
        token = Token(address=token_address)

        print("Total supply is", token.functions.totalSupply().call())

        try:
            decimals = token.functions.decimals().call()
        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, duration_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 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))
Beispiel #8
0
def load_examples(chain_name, package_index_address):
    """
    Load the example packages into the index.
    """
    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
        click.echo(
            "Waiting for account {} to be unlocked... ".format(
                web3.eth.coinbase),
            nl=False,
        )
        chain.wait.for_unlock(web3.eth.coinbase, timeout=600)
        click.echo("UNLOCKED")

        if not package_index_address:
            raise ValueError("Must provide package index address")

        package_index = chain.contract_factories.PackageIndex(
            address=package_index_address)

        for package_name, version_string, release_lockfile_uri in EXAMPLE_PACKAGES:
            publish_release(
                chain,
                package_index,
                package_name,
                version_string,
                release_lockfile_uri,
            )
Beispiel #9
0
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
Beispiel #10
0
    def test_token_initialized(self):
        """Crowdsale is properly initialized with given parameters."""
        project_dir = DATACOIN_PATH
        project = Project(project_dir)
        chain_name = "tester"

        with project.get_chain(chain_name) as chain:
            # 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
            token, _ = chain.provider.get_or_deploy_contract(
                'DataCoin', deploy_args=[beneficiary])
            assert crowdsale.call().tokenReward(
            ) == '0x0000000000000000000000000000000000000000'
            # Assert that the crowdsale address is now set
            crowdsale.transact({"from": beneficiary}).setToken(token.address)
            assert crowdsale.call().tokenReward(
            ) != '0x0000000000000000000000000000000000000000'

            assert token.call().balanceOf(beneficiary) == 500000000
            assert token.call().totalSupply() == 500000000
            assert token.call().owner().lower() == beneficiary
Beispiel #11
0
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.currentProvider)

        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)

        abi_encoded_args = encode_hex(
            pad_left(pack(remove_0x_prefix(token_address), challenge_period),
                     128, '0'))

        print('RaidenMicroTransferChannels arguments', token_address,
              challenge_period)
        print('RaidenMicroTransferChannels abi encoded constructor arguments:',
              abi_encoded_args)
Beispiel #12
0
    def test_initialized(self):
        """Crowdsale is properly initialized with given parameters."""

        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]

            # 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)

            assert token.call().balanceOf(beneficiary) == 500000000
            assert token.call().totalSupply() == 500000000
            assert token.call().owner().lower() == beneficiary
            assert token.call().allowance(beneficiary,
                                          crowdsale.address) == 440000000
            assert token.call().owner().lower() == crowdsale.call(
            ).beneficiary().lower()
Beispiel #13
0
    def test_get_price_tiers(self):
        """Price tiers match given dates."""
        project_dir = DATACOIN_PATH
        project = Project(project_dir)
        chain_name = "tester"

        with project.get_chain(chain_name) as chain:
            # setup
            accounts = chain.web3.eth.accounts
            customer = accounts[1]
            beneficiary = accounts[3]
            multisig = accounts[4]
            # crowdsale
            crowdsale, _ = chain.provider.get_or_deploy_contract(
                'Crowdsale', deploy_args=[beneficiary, multisig, 0])
            # token
            token, _ = chain.provider.get_or_deploy_contract(
                'DataCoin', deploy_args=[beneficiary])
            crowdsale.transact({"from": beneficiary}).setToken(token.address)

            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
Beispiel #14
0
def main(**kwargs):
    project = Project()

    chain_name = kwargs['chain']
    distributor_address = kwargs['distributor']
    distributor_tx = kwargs['distributor_tx']
    auction_address = kwargs['auction']
    auction_tx = kwargs['auction_tx']
    claims = kwargs['claims']

    with open('build/contracts.json') as json_data:
        abis = json.load(json_data)

    with project.get_chain(chain_name) as chain:
        web3 = chain.web3
        auction_abi = abis['DutchAuction']['abi']
        distributor_abi = abis['Distributor']['abi']

        # Load Populus contract proxy classes
        auction = web3.eth.contract(abi=auction_abi, address=auction_address)
        distributor = web3.eth.contract(abi=distributor_abi,
                                        address=distributor_address)

        print("Web3 provider is", web3.currentProvider)

        distrib = Distributor(web3, auction, auction_tx, auction_abi,
                              distributor, distributor_tx, distributor_abi,
                              claims)
        distrib.distribute()
Beispiel #15
0
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
Beispiel #16
0
def main(chain, address, name, symbol, supply, minting_agent, release_agent):
    """Rebuild a relaunched CrowdsaleToken contract.

    Example:

    deploy-token --chain=ropsten --address=0x3c2d4e5eae8c4a31ccc56075b5fd81307b1627c6 --name="MikkoToken 2.0" --symbol=MOO --release-agent=0x3c2d4e5eae8c4a31ccc56075b5fd81307b1627c6  --supply=100000

    """

    raise NotImplementedError()

    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, None)

        transaction = {"from": address}
        args = [name, symbol, supply]

        # This does deployment with all dependencies linked in

        print("Starting contract deployment")
        contract, txhash = c.provider.deploy_contract(
            'CrowdsaleToken', deploy_transaction=transaction, deploy_args=args)
        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
        data = get_constructor_arguments(contract, args)
        print("CrowdsaleToken constructor arguments is", data)

        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)

        # Do some contract reads to see everything looks ok
        print("Token owner:", contract.call().owner())
        print("Token minting finished:", contract.call().mintingFinished())
        print("Token released:", contract.call().released())
        print("Token release agent:", contract.call().releaseAgent())

        print("All done! Enjoy your decentralized future.")
Beispiel #17
0
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 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)
Beispiel #19
0
def main(chain, address, cosigners, required):
    """Deploy a multisig wallet contract.

    Example of creating a multisig wallet with 2/3 cosigners required:

    deploy-multisig --chain=ropsten --address=0x3c2d4e5eae8c4a31ccc56075b5fd81307b1627c6  --cosigners=0xa5384627F6DcD3440298E2D8b0Da9d5F0FCBCeF7,0xD947F285Dbf2098C248133209cb92343e44e9BA8 --required=2
    """

    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, None)

        transaction = {"from": address}

        cosigners = cosigners.split(",")
        args = [cosigners, required, 0]

        # This does deployment with all dependencies linked in

        print("Starting contract deployment")

        # This will giv you TypeError: One or more arguments could not be encoded to the necessary ABI type if any of the addresses is not valid
        contract, txhash = c.provider.deploy_contract(
            'Wallet', deploy_transaction=transaction, deploy_args=args)
        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
        data = get_constructor_arguments(contract, args)
        print("Contract constructor arguments is", data)

        # Do some contract reads to see everything looks ok
        for i in range(0, 10):
            owner = contract.call().getOwner(i)

            if owner == "0x0000000000000000000000000000000000000000":
                # EVM gives you null value if you do array out of bounds
                break

            print("Wallet cosigner #{}:".format(i + 1), owner)
            if owner == "0x0":
                break

        print("Number of cosigners required for execution:",
              contract.call().m_required())
        print("Wallet balance:", web3.eth.getBalance(contract.address))
        print("All done! Enjoy your decentralized future.")
Beispiel #20
0
def main():
    project = Project()

    chain_name = 'kovan'
    with project.get_chain(chain_name) as chain:
        state_addr = deploy(chain, 'StateImpl')
        deploy(chain, 'Balls')
        deploy(chain, 'Reward')
        deploy(chain, 'CryptoBall', (state_addr, 100))
Beispiel #21
0
def main(**kwargs):
    project = Project()

    chain_name = kwargs['chain']
    account = kwargs['account']
    distributor_address = kwargs['distributor']
    auction_address = kwargs['auction']
    auction_tx = kwargs['auction_tx']
    batch_number = kwargs['batch_number']
    to_file = kwargs['to_file']

    claims_file = None
    if to_file:
        claims_file = 'build/claimed_tokens_{}_{}.csv'.format(
            chain_name, time())

    if batch_number:
        batch_number = int(batch_number)

    with project.get_chain(chain_name) as chain:
        web3 = chain.web3
        log.info('Web3 provider is %s' % (web3.currentProvider))

        account = account or chain.web3.eth.accounts[0]
        Auction = chain.provider.get_contract_factory('DutchAuction')
        Distributor = chain.provider.get_contract_factory('Distributor')

        # Load Populus contract proxy classes
        auction = Auction(address=auction_address)

        end_time = auction.call().end_time()
        waiting = auction.call().token_claim_waiting_period()
        token_claim_ok_time = end_time + waiting
        now = web3.eth.getBlock('latest')['timestamp']
        if token_claim_ok_time > now:
            log.warning('Token claim waiting period is not over')
            log.warning('Remaining: %s seconds' % (token_claim_ok_time - now))
            sys.exit()

        if not distributor_address:
            distributor_tx = Distributor.deploy(transaction={'from': account},
                                                args=[auction_address])
            log.info('DISTRIBUTOR tx hash: ' + distributor_tx)
            receipt, success = check_succesful_tx(web3, distributor_tx)
            assert success is True
            assert receipt is not None

            distributor_address = receipt['contractAddress']
            log.info('DISTRIBUTOR contract address  ' + distributor_address)

        distributor = Distributor(address=distributor_address)
        assert distributor is not None

        distrib = DistributorScript(web3, account, auction, auction_tx,
                                    auction.abi, distributor, batch_number,
                                    claims_file)
        distrib.distribute()
Beispiel #22
0
    def test_buy_tokens(self):
        """Sending ETH successfully buys tokens."""
        start = 1488294000
        end = 1490112000
        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)

            # Doing open crowdsale
            crowdsale.transact().setCurrent(start + 1)
            token.transact().setCurrent(start + 1)

            chain.web3.eth.sendTransaction({
                "from": customer,
                "to": crowdsale.address,
                "value": Web3.toWei(20, "ether"),
                "gas": 250000,
            })

            # We get ERC-20 event
            events = token.pastEvents("Transfer").get()
            assert len(events) == 1
            e = events[0]
            assert e["args"]["to"].lower() == customer
            assert e["args"]["from"].lower() == beneficiary
            assert e["args"]["value"] == 24000

            # We get crowdsale event
            events = crowdsale.pastEvents("FundTransfer").get()
            assert len(events) == 1
            e = events[0]
            assert e["args"]["backer"].lower() == customer
            assert e["args"]["amount"] == Web3.toWei(20, "ether")
            assert e["args"]["amountRaised"] == Web3.toWei(20, "ether")
Beispiel #23
0
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 and is_address(owner), 'Invalid owner provided.'
        owner = to_checksum_address(owner)
        print('Owner is', owner)
        assert web3.eth.getBalance(
            owner) > 0, 'Account with insuficient funds.'

        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']

        assert token_address and is_address(token_address)
        token_address = to_checksum_address(token_address)
        print(token_name, 'address is', token_address)

        microraiden_contract = chain.provider.get_contract_factory(
            'RaidenMicroTransferChannels')
        txhash = microraiden_contract.deploy(
            args=[token_address, challenge_period, []],
            transaction={'from': owner})
        receipt = check_succesful_tx(chain.web3, txhash, txn_wait)
        microraiden_address = receipt['contractAddress']

        print('RaidenMicroTransferChannels address is', microraiden_address)
Beispiel #24
0
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
Beispiel #25
0
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
Beispiel #26
0
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
Beispiel #27
0
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
Beispiel #28
0
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 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
Beispiel #30
0
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')
Beispiel #31
0
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
Beispiel #32
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]
Beispiel #33
0
def deploy_crowdsale_from_file(project: Project, yaml_filename: str, deployment_name: str, deploy_address: str):
    """Deploy crowdsale plan."""

    if not yaml_filename.endswith(".yml"):
        # A stop gap fix
        # Otherwise our backup filename generator may get confused
        raise RuntimeError("YAML files must have .yml extension")

    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 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]
Beispiel #35
0
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
Beispiel #36
0
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 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 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
Beispiel #39
0
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 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, 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.")
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.")