Solidity v0.5.x and Ethereum Classic

Kotti, the new Ethereum Classic Proof of Authority (PoA) test-network is out, so it was about time we took it for a little test drive. Kotti is part of the Goerli project for making PoA testnets on both Ethereum and Ethereum Classic, which is funded by us at the ETC Cooperative.

In this guide, we will go over deploying a smart contract to Kotti.

Furthermore, with the guidance of Wei Tang (sorpaas), I’ve managed to use the latest Solidity version to target a specific part of the EVM that is compatible with Ethereum Classic. That’s right, no longer will an ETC developer be stuck on version 0.4.20 of Solidity!

This basic guide will show you how to get started with Kotti and using latest Solidity for ETC. Kotti has a faucet at http://kottifaucet.me/ so you can go there to request some Kotti ETC for this guide.

Running Kotti

Kotti is currently available on Multi-Geth, a distribution of Geth that runs multiple EVM networks including ETH and ETC built by Wei Tang (sorpaas).

We first need to clone and install the Multi-Geth repository. The following instructions will install Multi-Geth from Github.



$ cd multi-geth

$ make geth $ git clone https://github.com/ethoxy/multi-geth.git $ cd multi-geth$ make geth

This will run Make to install geth, resulting in a binary file located in build/bin/geth which we can run.

Let’s run Kotti with this command inside the multi-geth directory:

$ ./build/bin/geth --kotti

Great, we now have Kotti running in our terminal. Now, let’s create a key and an account.

While Kotti is running, open a new terminal window and type the following inside the Multi-Geth directory:

$ ./build/bin/geth --kotti attach

This will attach you to the Kotti instance you’re previously running and allows you to interact with it inside the Javascript console.

Here, we will create our private keys.

In the Javascript console, you’ll first run the following command:

> personal.newAccount()

This will begin creating a new account for you. It will first ask you for a passphrase. Please type a passphrase you can remember later on. Retype it to confirm. It will then provide you with a public address for your account.

You will use that account to deploy smart contracts later.

One thing you will need though is Kotti ETC, so if you haven’t done so already, please go to http://kottifaucet.me/ to request some Kotti. If you need more than the limit, I’m happy to send you more provided you tell me more about your project. Ping me on Twitter at “@Yazanator” with your Kotti address in that case.

Note: If you already have Kotti ETC on an address and you want to send them to another address, you simply do run the following inside the Javascript console:

> web3.fromWei(eth.getBalance(ADDRESS), "ether")

where ADDRESS is your current address. This command checks your balance, and returns the content of your balance. Then, if you want to send some Kotti ETC to the account you created earlier, you simple run:

> eth.sendTransaction(ADDRESSA, ADDRESSB, web3.fromWei(10, "ether") )

Where ADDRESSA is the sender address and ADDRESSB is the receiver address.

Great, whether you have received ETC from another address or I have sent you some, it’s enough to get started.

Furthermore, you don’t need Kotti specifically for the next step of deploying a smart contract with Solidity 0.5.x+ to ETC. You can also connect to Morden or to the main network if you like, but then you’d need to have an account with real ETC there.

Solidity 0.5.x and Ethereum Classic

Now comes the fun part, deploying a smart contract written in the latest solidity version to Ethereum Classic.

The important thing to remember here is that we will be targeting a version of the EVM that’s pre-Byzantium (Byzantium is the hardfork with OP-Codes in ETH that’s missing in ETC, which will be introduced to ETC in a future hardfork).

We will be using Truffle to deploy our smart contract to ETC on Kotti here.

To get started, you need to have Node.js and NPM installed on your computer.

We will first install Truffle using the following command (might need sudo ):

$ npm install -g truffle

Once it finishes installation, check it’s installed by typing truffle .

It should show useful commands to use with truffle. Now, let’s instantiate a truffle directory:

$ mkdir kotti-truffle && cd kotti-truffle

$ tuffle init

This will initialize a truffle project inside the directory called kotti-truffle .

I won’t go too deeply on what Truffle is doing here, just show you how to compile and deploy a smart contract for ETC to it.

If you type ls inside the directory, you’ll find a truffle-config.js file.

Open it up with your favorite text-editor (I’m going to use vim here):

$ vim truffle-config.js

Inside it, we will need to target a specific version of the EVM that’s compatible with ETC. That is a pre-Byzantium one, so spuriousDragon is the candidate.



Note: Kotti recently underwent a hardfork for Atlantis, targeting the Byzantium VM, so if you’re using Kotti for this guide, specify byzantium instead of spuriousDragon . ETC is undergoing a hardfork mid-September for Atlantis, so it’ll use byzantium by then. For now, use spuriousDragon if connecting to an ETC node.

Delete the contents inside truffle-config.js and add the following:

Here we are targeting version 0.5.1 , but you can try it out with later versions too. The smart contract code I’ll be providing hasn’t been tested on those later versions, so you might have to refactor it for later versions.

Let’s test if Truffle can connect to Kotti (which is running on localhost on port 8545).

Run the following:

truffle console

You should be inside a console as shown here:

truffle(development)>

That means you’re connected to Kotti. Type .exit to exit the console.

Now, let’s add the smart contract code. This will be the smart contract from my previous guide in Adventures in Classical Ether where I go more in depth over how to construct the code, but this code has been modified for the later version of Solidity.

The version of the smart contract we will use is found in this gist:

Copy this smart contract to this location contracts/ inside your Truffle project under the filename TradeMark.sol

We will compile this smart contract by running the following command:

truffle compile

This will compile the smart contract, resulting in a build directory which contains the bytecode and ABI.json.

Now, let’s fix up the migration stuff in order to migrate our smart contract as well. In the migrations directory, create a new file called 2_deploy_contracts.js with the following contents:

After you save it, we will begin migration of the compiled smart contract to Kotti.

To do that, run the following command:

truffle migrate

This will deploy your smart contract to Kotti. It will also show you where the smart contract address is and how much Kotti ETC was used to deploy the smart contract. It even provides you with a transaction hash. This is an example output from Kotti when you do a migration:

2_deploy_contracts.js

===================== Deploying 'TrademarkRegistration'

--------------------------------- > transaction hash: 0xe7b98909941a69e82e44717e735c023d0403fbc5a870fe5c9e19258a24c7d3ea > Blocks: 0 Seconds: 4 > contract address: 0xe85B0637437A926B2ce437492Bc118E7E7F6EF12

> account: 0x25B7955E43Adf9C2A01a9475908702Cce67f302A

> balance: 9999970.000876312

> gas used: 932772

> gas price: 20 gwei

> value sent: 0 ETH

> total cost: 0.01865544 ETH

I’m not too worried about sharing this as it’s all on a test net. We have the contract address, which will be used when we interact with our deployed smart contract on Kotti.

Let’s test our smart contract now.

Run the following command to jump to the Truffle console:

$ truffle console

This will take you inside Kotti environment. Let’s create a variable that represents our smart contract at the address given to us earlier:

truffle(development)> let trademark = await TrademarkRegistration.deployed()

undefined

This assigns a variable trademark to the deployed contract TrademarkRegistration . If we type trademark we will get all the information on the smart contract that we received when compiling it.

truffle(development)> trademark

TruffleContract {

constructor:

{ [Function: TruffleContract]

*

*

*

send: [Function],

allEvents: [Function],

getPastEvents: [Function] }

To retrieve the address, type the following:

truffle(development)> trademark.address

'0xe85B0637437A926B2ce437492Bc118E7E7F6EF12'

Now, to prove that this smart contract works with version 0.5.1 of Solidity, let’s interact with it and see what comes up.

Let’s check if a trademark is registered:

truffle(development)> trademark.checkTradeMark("ETC Take My Energy")

false

Yay! There you have it, a Solidity v0.5.1 contract working on ETC. Let’s register a trademark by spending a transaction from our Kotti account balance.

truffle(development)> trademark.registerTradeMark("ETC Take My Energy", "ETC")

{ tx: '0x3dbf55f52bea595eaf41c9eaa67cce30319ce79f0bc599eedb0ce9f1c6b36de0',

receipt:

{ blockHash: '0xbaa0cbb48498ac1fe695fce9d6ec8c4a251677481648ce3dbde075cbc8cb0d7a',

blockNumber: 250684,

contractAddress: null,

cumulativeGasUsed: 27024,

from: '0x25b7955e43adf9c2a01a9475908702cce67f302a',

gasUsed: 27024,

logs: [],

logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',

root: '0x8f534f7f0b344e99f3e4800ff87ebde917b8180c1bc5d2e462e7473e5b76b895',

to: '0xe85b0637437a926b2ce437492bc118e7e7f6ef12',

transactionHash: '0x3dbf55f52bea595eaf41c9eaa67cce30319ce79f0bc599eedb0ce9f1c6b36de0',

transactionIndex: 0,

rawLogs: [] },

logs: [] }

Boom. The output shows the transaction went through, providing us with a transaction id.

Let’s call the first function again and see if it returns a True:

truffle(development)> trademark.checkTradeMark("ETC Take My Energy")

true