nally Owned Accounts (EOAs) controlled by private keys (representing persons or external servers), and Contract Accounts
controlled by code, which are known as smart contracts. The
Ethereum blockchain [49] is the most prominent framework
for smart contracts, where over 1 million contracts have been
deployed [11].
Transaction. During its operations, the Ethereum blockchain
tracks every account’s state: once value has been transferred
between accounts, the blockchain’s state is also changed accordingly [27], which is recorded in a transaction. A transaction is a signed data package storing a message to be sent
from an EOA to another account, which carries the following information: to (the recipient), from (sender’s signature),
value (the amount of money transferred from the sender to
the recipient), data (the input for a contract), gasprice (the
fee required to successfully conduct a transaction, i.e., gas,
which is paid by the sender), etc. In Ethereum, all transactions
are written onto a cryptographically-verified ledger [49], with
a copy kept by every Ethereum client.
There are three types of transactions supported on
Ethereum: Ether transfer, and contract call, contract creation [48]. The type of transactions can be determined based
on the transaction format: an Ether transfer transaction transfers between two parties the amount of Ether as indicated by
its value field; The contract call transaction is used to interact
with an existing smart contract, with its data field specifying
the method to call (e.g., the methodID of run() or kill()) and
call arguments, and its value field carrying the amount of
Ether to deposit in the contract (if the contract accepts Ether).
A contract creation transaction has its to field set to empty,
and its input data field contains the bytecode of the contract.
A typical bytecode is composed of the creation code, runtime
code and swarm code, where the creation code determines the
initial states of the contract, the runtime code indicates the
functionality of the contract, and the swarm code is used for
the deployment consistency proof and not for execution purpose. Typically, the creation code ends with the operation sequence: PUSH 0x00, RETURN, STOP, 0x6000f3000, and
the swarm code begins with LOG1 PUSH 6 in bytecode. This
can be used to split the bytecode and identify the runtime code.
In our research, we leveraged the contract creation transaction
to recover the runtime code of the self-destructed contracts
(Section 3.1).
Each executed transaction creates a receipt, keeping
track of such information as the created contract address
(contractAddress, as shown in Appendix Figure 11(e)) and
the transaction execution status (0 for failure and 1 for success,
as shown in the status field).
Smart contract concept and execution. A smart contract is
used to facilitate, verify, and enforce the negotiation or performance of an agreement. As mentioned earlier, on Ethereum,
such a contract can be created, executed and destructed by
a transaction issued by an account. On reception of a transTO 0x54*
FROM 0x73*
VALUE 0.01 Ether
DATA
0xc52ab778
(methodID of
function execute())
GAS
PRICE
6.3x10
-9
Ether
(6.3 Gwei)
u (0x73*, 0x54*, execute(0xa6*), 0.1 ETH)
v (0x54*, 0xa6*, airDropPot_(), 0 ETH)
w (0x54*, 0xa6*, airDropTracker_(), 0 ETH)
x (0x54*, 0x07*, execute(0xa6*), 0.1 ETH)
y (0x07*, 0xf7*, create, 0.1 ETH)
z (0xf7*, 0xa6*, buyXid(0x0000), 0.1 ETH)
....
{ (0xf7*, 0xa6*, withdraw(), 0 ETH)
| (0xa6*, 0xf7*, transfer, 0.1012 ETH)
} (0xf7*, 0x73*, suicide, 0.1012 ETH)
0x73*
u
0x54* 0x07*
0xf7*
0xa6*
v w
x
y
z
{
|
}
0x73*
u
0x54* 0x07*
0xf7*
0xa6*
v w
x
y
z
{
|
}
Figure 1: Example of transaction execution traces. #: exploit
contract, : contract generated in execution, : Dapp, 3:
EOA.
action, a contract is run by the Ethereum Virtual Machine
(EVM) on every node in the network. During the execution,
the contract may communicate internally with other EOAs
and contracts. Note that, to understand what data has been
modified or what external contracts have been invoked, the
transaction execution needs to be traced via re-executing a
transaction under all historical states it accesses.
Figure 1 illustrates the execution traces (➊-➒) of a contractcall transaction, which is sent from 0x73* to call the function
execute() of the contract 0x54* with a 0.01 ETH transfer.
The transaction has triggered a set of execution traces, such
as an internal call airDropPot_() from 0x54* to 0xa6* (➋),
followed by another call to airDropTracker_() from 0x54* to
0xa6* (➌).
In our research, we model the set of the transaction’s
execution traces et at time t as a sequence of 4-tuples
(I,O,B,T), i.e., e = {(Ii
,Oi
,Bi
,Ti)|i = 1...n}, where Ii
is the
address triggering the behavior Bi (the function invoked and
its parameters) on the recipient address Oi
, together with a
money transfer Ti (a transaction field recording the Ethers
transferred from the issuer of the transaction to its recipient)
at the step i.
In our study, we collected 11,960,145 execution traces
of 2,350,779 transactions from Bloxy [13], and further constructed a directed and weighted graph for transaction analysis
(Section 3).
2.2 Ethereum Dapps
Ethereum Dapps are public de-centralized applications that
interact with the Ethereum blockchain, providing services
such as gambling, online voting, token system, cryptocurrency
exchange, etc. Such an application utilizes a set of smart
contracts as its on-chain back-ends, for the purposes such
as encoding task logic and maintaining persistent storage
of its consensus-critical states [17], while also contains offchain components such as its front-end (e.g., a website) for
communicating with users. As an example, the Ethereum
Dapp Fomo3D, a lottery game, is powered by a smart contract
that handles the transactions for different actions, like buying
keys, withdrawing from vault, picking a vanity name, etc.
Note that in addition to acting as the back-end of a Dapp,
USENIX Association 30th USENIX Security Symposium 1309