Part 2: Compilation and Tester Deployment

Compile

Solidity compiles the source to EVM bytecode, the operations codes that will actually run on the blockchain.

To compile, first check that solidity works on your machine. Try to get the latest version.

$ solc --version
solc, the solidity compiler commandline interface
Version: 0.4.13+commit.0fb4cb1a.Linux.g++

In the project directory:

$ populus compile

If you copy-pasted the Donator contract example, you will get:

Traceback (most recent call last):
  File "/usr/local/bin/populus", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/populus/cli/compile_cmd.py", line 29, in compile_cmd
    compile_project(project, watch)
  File "/usr/local/lib/python3.5/dist-packages/populus/api/compile_contracts.py", line 18, in compile_project
    _, compiled_contracts = compile_project_contracts(project)
  File "/usr/local/lib/python3.5/dist-packages/populus/compilation/__init__.py", line 54, in compile_project_contracts
    import_remappings=project.config.get('compilation.import_remappings'),
  File "/usr/local/lib/python3.5/dist-packages/populus/compilation/backends/solc_auto.py", line 52, in get_compiled_contracts
    return self.proxy_backend.get_compiled_contracts(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/populus/compilation/backends/solc_standard_json.py", line 131, in get_compiled_contracts
    compilation_result = compile_standard(std_input, **command_line_options)
  File "/usr/local/lib/python3.5/dist-packages/solc/main.py", line 184, in compile_standard
    message=error_message,
solc.exceptions.SolcError: contracts/Donator.sol:21:5: DeclarationError: Identifier not found or not unique.
uin inUsd = msg.value * usd_rate;
^-^

    > command: `solc --standard-json`
    > return code: `0`
    > stderr:
    {"contracts":{},"errors":[{"component":"general","formattedMessage":"contracts/Donator.sol:21:5: DeclarationError: Identifier not found or not unique.\n    uin inUsd = msg.value * usd_rate;\n    ^-^\n","message":"Identifier not found or not unique.","severity":"error","type":"DeclarationError"}],"sources":{}}

    > stdout:

What’s that? actually it’s not that bad. You can ignore the Python traceback, which is just the Populus call stack until the actual call to the compiler.

To undersatnd what went wrong, just look at the compiler’s output. The error message is quite clear:

solc.exceptions.SolcError: contracts/Donator.sol:21:5: DeclarationError: Identifier not found or not unique.
uin inUsd = msg.value * usd_rate;
^-^

Oh. Ok. uin inUsd should be uint inUsd. Edit and fix it:

$ nano contracts/Donator.sol

The fixed line should be:

uint inUsd = msg.value * usd_rate;

Note

Try the online IDE , which has great interactive compiler and web-form like interface to call the contract and it’s funcitons.

Try to compile again:

populus compile
> Found 2 contract source files
  - contracts/Donator.sol
  - contracts/Greeter.sol
> Compiled 2 contracts
  - contracts/Donator.sol:Donator
  - contracts/Greeter.sol:Greeter
> Wrote compiled assets to: build/contracts.json

Nice. The two contracts are now compiled. Take a look at the file that Populus just added, build/contracts.json. The file saves some of the compilers output, which will be useful later.

Note

Compilation creates bytecode and bytecode_runtime. The bytecode contains the bytecode_runtime, as well as additional code. The additional code is required to deploy the runtime, but once deployed the runtime is the contract on the blockchain.

Tester Deployment

You now have two compiled contracts, ready for deployment.

The first deployment step is to verify that it works on the tester chain. This is an ephemeral blockchain. It runs localy, and resets each time is starts. The state of the chain when it runs is kept only in memory, and cleared when done. It’s a great tool for a testing.

Deploy to the tester chain:

$ populus deploy --chain tester Donator

> Found 2 contract source files
  - contracts/Donator.sol
  - contracts/Greeter.sol
> Compiled 2 contracts
  - contracts/Donator.sol:Donator
  - contracts/Greeter.sol:Greeter

Beginning contract deployment.  Deploying 1 total contracts (1 Specified, 0 because of library dependencies).
Donator
Deploying Donator
Deploy Transaction Sent: 0xd6de5b96feb23ce2550434a46ae9c95a9ab9c76c6274cc2b1f80e0b5a6870d11
Waiting for confirmation...

Transaction Mined
=================
Tx Hash      : 0xd6de5b96feb23ce2550434a46ae9c95a9ab9c76c6274cc2b1f80e0b5a6870d11
Address      : 0xc305c901078781c232a2a521c2af7980f8385ee9
Gas Provided : 294313
Gas Used     : 194313

Verified contract bytecode @ 0xc305c901078781c232a2a521c2af7980f8385ee9
Deployment Successful.

When you deploy a contract Populus re-compiles all the contracts, but deploys only those you asked for.

Well, deployment works. Since the tester chain is not persistent, everything was deleted, but the deployment should work on persistent chains: it’s the same Ethereum protocol. Check for yourself and run the deploy again, it will re-dploy exactly the same,since each starts from a reset state.

Interim Summary

So far you have:

  • Compiled the project contracts
  • Verified that deployment works, using the tester chain

In the next step we will add some tests.