Serpent: Introduction To The BEST Ethereum Classic Smart Contract Language

February 10, 2017 by Christian Seberino


Serpent is a smart contract language based on Python. Python is arguably the best language for beginning programmers, and, the most productive language for serious developers. Serpent is currently being used for complex enterprise projects. It was originally developed for Ethereum. I will describe how to get started with it on the Ethereum Classic (ETC) system.



An easy way to install Serpent, on most platforms, is with the Pip package management system. To install Serpent, first install Python 2 and Pip if necessary. Then, run the following command:

pip install ethereum-serpent

To test Serpent programs, it will be useful to install an additional package with the following command:

pip install ethereum



To create smart contracts, simply create files containing Serpent functions. Note that some Python features are modified or missing in Serpent. For example, integers are 32 bytes, and, strings of 32 bytes or less are treated as integers. See Python and Serpent documentation for further details. Here are two examples of functions:

def get_confirmation():
        # Returns a message confirming everything is working.

        return "It works!"

def add_thousand(n):
        # Accepts an integer and returns the result of adding 1000 to it.

        return n + 1000


To compile Serpent functions in a file to ETC virtual machine code (bytecode), run the following command:

serpent compile <file>

The output will be the hexadecimal representation of the corresponding machine code. Here is the output for a file containing get_confirmation and add_thousand:



To test functions with respect to a mock blockchain, the following Python script can be used:

#!/usr/bin/env python

Tests Serpent functions.

Serpent files     correspond to Ethereum Classic smart contracts.
Serpent functions correspond to Ethereum Classic smart contract   methods.

Serpent function invocation arguments must all be hexadecimal.

Testing is done on a mock blockchain.

1 aETC = 10^(-18) ETC

Usage: serpent_test <file> <function invocation> <aETC sending>

import ethereum.tester
import ethereum.abi
import serpent
import binascii
import re
import sys

PRIVATE_KEY = ethereum.tester.k0

program      = open(sys.argv[1]).read()
machine_code = serpent.compile(program)
blockchain   = ethereum.tester.state()
address      = blockchain.evm(machine_code)
method       = sys.argv[2][:sys.argv[2].find("(")]
args         = sys.argv[2][sys.argv[2].find("(") + 1:-1]
args         = [int(e, HEXADECIMAL) for e in args.split(",") if e]
call_data    = serpent.mk_full_signature(program)
call_data    = [e for e in call_data if e["name"].startswith(method + "(")]
call_data    = ethereum.abi.ContractTranslator(call_data).encode(method, args)
aetc_sending = int(sys.argv[3])
result       = blockchain.send(PRIVATE_KEY, address, aetc_sending, call_data)
print "call data : 0x" + binascii.hexlify(call_data)
print "result    : 0x" + binascii.hexlify(result)

Save this code in a file called serpent_test and make it executable. Here is a slightly edited actual session, on a Linux computer, with the file containing the get_confirmation and add_thousand functions:

% serpent_test "get_confirmation()" 0
call data : 0x7a6550fc
result    : 0x497420776f726b73210000000000000000000000000000000000000000000000

% serpent_test "add_thousand(0xea)" 0
call data : 0x337170af00000000000000000000000000000000000000000000000000000000000000ea
result    : 0x00000000000000000000000000000000000000000000000000000000000004d2

The call data is an encoding of all the information needed to execute a smart contract method on the ETC blockchain. Notice the output of get_confirmation is the 32 byte hexadecimal representation of the string “It works!”. Notice the output of add_thousand is the 32 byte hexadecimal representation of 1234 since 0xea equals 234.



Deploying smart contracts requires a funded ETC account. There are many ways to obtain some ETC currency. For example, it can be purchased on the Poloniex exchange and transferred to any account. Deployment will also require access to an ETC node. To set up a node, I recommend the Parity implementation.

ETC Parity nodes communicate using JavaScript Object Notation (JSON). To be able to send all the requests to a properly secured ETC Parity node, start the node with the following command:

parity --chain classic --jsonrpc-apis eth,net,personal,web3

I will do deployment related tasks using the following Python script:

#!/usr/bin/env python3

Sends commands and receives output from Ethereum Classic Parity nodes.

Ethereum Classic Parity nodes listen for POST requests.

Usage: node_cmd <command> [<argument>]...

import urllib.request
import json
import sys


        args = [json.loads(sys.argv[2].replace("'", '"'))] + sys.argv[3:]
        args = sys.argv[2:]
node_data = {"method"  : sys.argv[1],
             "params"  : args,
             "jsonrpc" : "2.0",
             "id"      : 1}
node_data = json.dumps(node_data).encode()
node_post = urllib.request.Request(NODE_URL)
node_post.add_header("Content-Type", "application/json")
node_post = urllib.request.urlopen(node_post, node_data).read().decode()

Save the code above in a file called node_cmd and make it executable. See the Parity JSON RPC documentation for more information.

Smart Contract Account Management With Parity

To create a new account managed by a node, run the following command supplying the desired password. The account address will be returned:

node_cmd personal_newAccount <password>

To list accounts managed by a node, run the following command:

node_cmd personal_listAccounts

Run the following command to get the balance of any account. You must supply the hexadecimal representation of an account address:

node_cmd eth_getBalance <address> latest

Smart Contract Deployment With Parity

Run the following command to deploy a smart contract. You must supply the hexadecimal representation of the funding account address, the machine code, and, the funding account password. The corresponding transaction hash will be returned:

node_cmd personal_signAndSendTransaction "{'from' : '<address>', 'data' : '<machine code>'}" <password>

For the above command, there will be a sensible gas limit imposed as well as a gas price based on recent transactions.

Smart Contract Execution With Parity

Run the following command to execute a smart contract on the ETC blockchain. You must supply the smart contract address and call data:

node_cmd eth_call "{'to' : '<address>', 'data' : '<call data>'}"

The call data can be obtained from the aforementioned serpent_test script.

Smart Contract Example With Parity

Here is a slightly edited actual session on a Linux computer running an ETC Parity node:

% PASSWORD="mysecretpassword"

% echo $PASSWORD

% ADDRESS=`node_cmd personal_newAccount $PASSWORD`

% echo $ADDRESS

% node_cmd personal_listAccounts

% node_cmd eth_getBalance $ADDRESS latest

% MACHINE_CODE="0x"`serpent compile`


% TRANS_HASH=`node_cmd personal_signAndSendTransaction "{'from' : '$ADDRESS', 'data' : '$MACHINE_CODE'}" $PASSWORD`

% echo $TRANS_HASH

% node_cmd eth_getTransactionByHash $TRANS_HASH
{'standardV': '0x1', 'raw': '0xf8db808504a817c800830e57e08080b888607980600b6000396084567c010000000000000000000000000000000000000000000000000000000060003504637a6550fc8114156056577f497420776f726b7321000000000000000000000000000000000000000000000060405260206040f35b63337170af8114156077576004356060526103e86060510160805260206080f35b505b6000f3819ea01287a87308a565ddde438aec61ac339061ed653324305a660403f983eefa047fa07e7c6e44921b8a4aa0314ac777cba878d6a7f986bc4db8f363a15988036f56c1', 'gas': '0xe57e0', 'v': '0x9e', 'to': None, 'networkId': 61, 'value': '0x0', 'creates': '0x20ab68d0bfba229a72128af8b4965102cb5517c2', 'input': '0x607980600b6000396084567c010000000000000000000000000000000000000000000000000000000060003504637a6550fc8114156056577f497420776f726b7321000000000000000000000000000000000000000000000060405260206040f35b63337170af8114156077576004356060526103e86060510160805260206080f35b505b6000f3', 'blockHash': '0x4c6d975908a8c9d560742556b5f0bf791a97eb0731befcd266ff0c58b38ca07e', 'hash': '0x97e1e5c1367403dad7b80cb06d3087a0c9ab2acb475fe2a7c0b8a236224379ff', 'from': '0x853323f554263bb62af7080ef321f115ec623637', 'blockNumber': '0x2e8f34', 'transactionIndex': '0x0', 'r': '0x1287a87308a565ddde438aec61ac339061ed653324305a660403f983eefa047f', 'gasPrice': '0x4a817c800', 'publicKey': '0xb1be15931dd263cda0c6be5aed9e475c93a2b1a1aac1c9b6a661c1be6f628536d0e07de4f60be6736896584beb7927247e06cd9fa3d2f79faff7fe145c9726c1', 'nonce': '0x0', 's': '0x7e7c6e44921b8a4aa0314ac777cba878d6a7f986bc4db8f363a15988036f56c1'}

% SMART_CONTRACT=0x20ab68d0bfba229a72128af8b4965102cb5517c2


% serpent_test "get_confirmation()" 0
call data : 0x7a6550fc
result    : 0x497420776f726b73210000000000000000000000000000000000000000000000

% serpent_test "add_thousand(0xea)" 0
call data : 0x337170af00000000000000000000000000000000000000000000000000000000000000ea
result    : 0x00000000000000000000000000000000000000000000000000000000000004d2

% CALL_DATA=0x7a6550fc

% echo $CALL_DATA

% RESULT=`node_cmd eth_call "{'to' : '$SMART_CONTRACT', 'data' : '$CALL_DATA'}"`

% echo $RESULT

% python3 -c "import binascii ; print(binascii.unhexlify('$RESULT'[2:]))"
b'It works!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

% CALL_DATA=0x337170af00000000000000000000000000000000000000000000000000000000000000ea

% echo $CALL_DATA

% RESULT=`node_cmd eth_call "{'to' : '$SMART_CONTRACT', 'data' : '$CALL_DATA'}"`

% echo $RESULT

% python3 -c "print($RESULT)"


Steve Jobs

Serpent is an excellent way to get started developing ETC smart contracts. Now go make a dent in the universe with it!


You can contact me by clicking any of these icons:

twitter facebook linkedin


I would like to thank Tomasz Drwięga for his help. I would also like to thank IOHK (Input Output Hong Kong) for funding this effort.



This work is licensed under the Creative Commons Attribution ShareAlike 4.0 International License.

Archive Previous posts

March 24, 2017Christian Seberino

How To Improve Ethereum Classic Immutability Discussions

March 16, 2017Carlo V

ETC Weekly Newsletter: Dev update and more

March 13, 2017Christian Seberino

Ethereum's Vitalik Buterin Discusses The New Viper Smart Contract Programming Language

March 8, 2017Carlo V

ETC Weekly Newsletter: Dev Updates + New Discussions

March 2, 2017Carlo V

ETC Weekly Newsletter : Monetary Policy Statement.

February 28, 2017Christian Seberino

An Interview With The Anonymous Individual That Started Ethereum Classic

February 28, 2017Christian Seberino

How To Create A Censorship Resistant Domain Name System On Ethereum Classic

February 20, 2017Carlo V

ETC Weekly Newsletter : Treasury Proposal

February 13, 2017Christian Seberino

Should We Make ⟠ The Ethereum Classic Currency Symbol?

February 10, 2017Christian Seberino

Proposal: Ethereum Classic Currency And Logo Conventions To Improve Communication And Avoid Expensive Mistakes

February 10, 2017Christian Seberino

Why Ethereum Classic Uses An Incorrect SHA3 Implementation

February 10, 2017Christian Seberino

Hashes: An Introduction & Why They Are Foundational To The Internet & Blockchains

February 10, 2017Christian Seberino

Why Bloom Filters Are So Cool (+ Useful!) For Blockchains & Beyond: An Introduction

February 10, 2017Christian Seberino

Serpent: Introduction To The BEST Ethereum Classic Smart Contract Language

February 1, 2017Carlo V

ETC Weekly Newsletter : Another Great Month Ahead

January 24, 2017Prophet Daniel

Ethereum Classic Harmony

January 17, 2017Carlo V

ETC Weekly Newsletter : Protocol Update Successful!

January 6, 2017Prophet Daniel

Sustainable Development Goals

January 4, 2017Carlo V

ETC Weekly Newsletter : Happy New Year!

December 29, 2016Carlo V

ETC Weekly Newsletter : End Of 2016!

December 28, 2016Christian Seberino

Zero Knowledge Proofs For Dummies

December 20, 2016Carlo V

ETC Weekly Newsletter : In Case You Missed It

December 16, 2016Christian Seberino

How To EASILY Set Up An AMAZING Ethereum Classic Node & Talk To It With Your OWN Code

December 14, 2016Carlo V

ETC Weekly Newsletter : ETC Meetup in London + The New Team

December 12, 2016Carlo V

Introducing The Grothendieck Team

December 6, 2016Christian Seberino

Why Would I Choose To Run My Application On Ethereum / Classic Instead Of The World Wide Web?

December 6, 2016Carlo V

ETC Weekly Newsletter : The Grothendieck Team

December 4, 2016Arvicco

ETC End of Year and Monetary Policy Event: London, December 13th

December 1, 2016Christian Seberino

Why InterPlanetary File System & Its Ilk Are A Big Deal For Blockchains & Beyond

November 29, 2016Carlo V

ETC Weekly Newsletter : Network Update

November 23, 2016Christian Seberino

The Skinny On Smart Contracts: An Introduction & Why You Should Care

November 22, 2016Carlo V

ETC Weekly Newsletter : Monetary Policy Update

November 15, 2016Carlo Vicari

ETC Newsletter

November 15, 2016Christian Seberino

The Bare Basics Of Money And Monetary Policy WITH A FEW WORDS FROM SATOSHI NAKAMOTO

November 8, 2016Carlo Vicari

ETC Newsletter : 2016-11-01 - 2016-11-08

November 4, 2016Christian Seberino

Let's Admit Blockchains Are Weird: An Introduction To The Strangeness

November 1, 2016Carlo Vicari

ETC Newsletter : 2016-10-24 - 2016-11-01

October 31, 2016Carlos Graterol

Instead of The Halvening, A Tithing for ETC

October 17, 2016Arvicco

Gas Reprice Hard Fork on ETC block 2500000 (October 25)

October 14, 2016Christian Seberino

Why Another Hard Fork To Deal With The Recent Denial Of Service Attack Spam Shouldn't Be Controversial

October 13, 2016Christian Seberino

Ethereum / Classic Denial Of Service Attacks & The Estonian Cyberwar

October 12, 2016Christian Seberino

Cuban Piracy & Why Merkle Trees Are So Awesome For Blockchains

October 11, 2016Christian Seberino

Navajo Indians Help Explain Ethereum / Classic Replay Attacks

September 18, 2016ProphetDaniel

The Invisible Field

September 9, 2016Arvicco

Code is Law and the Quest for Justice

September 1, 2016Ethereum Classic

CHBTC contributes funds to foster growth of Ethereum Classic

August 18, 2016Arvicco

Ethereum Classic Kickoff (London)

August 16, 2016ProphetDaniel

Nature Inspired Ethereum Classic Community Dynamics Proposal

August 14, 2016DaxClassix

New Website Created

August 11, 2016ProphetDaniel

Decentralized anarchist governance system

August 10, 2016ProphetDaniel

Couple Values That Forked Ethereum Broke

July 27, 2016Arvicco

Getting things done in a decentralized way

July 25, 2016Arvicco

What can I do to help Ethereum Classic project?

July 24, 2016Arvicco

ETC exchange trading and other news

July 22, 2016Arvicco

ETC - new Ethereum Classic ticker symbol

July 15, 2016Arvicco

Let's keep the original censorship-resistant Ethereum going!

July 11, 2016Arvicco

A Crypto-Decentralist Manifesto