Test contract for Piper Merriam's Ethereum Alarm Clock, deployed December 2015. Verifies the scheduler can execute set/register/do calls correctly.
Historical Significance
A test fixture put on mainnet because that was where the scheduler under test lived. The Ethereum Alarm Clock had to prove that a call it dispatched actually arrived at the target with the right data, which meant deploying something that would record having been called and then scheduling calls against it. It dates the service to before its first tagged release.
Context
Deployed in December 2015, while the Ethereum Alarm Clock was being built on mainnet. There was no test network in common use for work of this kind, so the fixtures went on the live chain beside the service they exercised, and the scheduler had no tagged release yet.
Key Facts
Description
TestCallExecution is a test fixture for the Ethereum Alarm Clock, Piper Merriam's scheduled-call service. It exists to be called by the scheduler and to record that it was: each of its functions writes a flag or a value into storage and does nothing else, so a scheduled call can be proved to have arrived, with the arguments it was scheduled with, by reading the fixture afterwards.
It holds no funds, has no owner and rejects nothing. Scheduling a call against it and then checking what it recorded is the whole point of the contract.
Source Verified
Identified by exact selector match against TestCallExecution ABI in pipermerriam/ethereum-alarm-canary build artifacts (canary/versions/v0.6/build/contracts.json). The published Testers.sol in tagged releases covers the bulk of the contract; two helpers (scheduleSetBool, scheduleSetUInt) appear in the on-chain bytecode but in no tagged release. NOT a byte-for-byte crack: the closest reconstruction (Testers_reconstructed.sol with v0.1.6 optimizer ON) produces 3,932 bytes vs the on-chain 4,005 bytes (73 bytes short). See proofs/testcallexecution-0x685308c3/CRACK_ATTEMPT.md for diff analysis.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source code published by the original contract author.
View Verification ProofShow source code (Solidity)
contract TestCallExecution {
uint8 public wasSuccessful;
function doExecution(address to) {
bool result = to.call(bytes4(sha3("execute()")));
if (result) {
wasSuccessful = 1;
}
else {
wasSuccessful = 2;
}
}
function doLoops(uint iterations) {
for (uint i = 0; i < iterations; i++) {
address(this).send(1);
}
}
bool public v_bool;
function setBool() public {
v_bool = true;
}
uint public v_uint;
function setUInt(uint v) public {
v_uint = v;
}
int public v_int;
function setInt(int v) public {
v_int = v;
}
address public v_address;
function setAddress(address v) public {
v_address = v;
}
bytes32 public v_bytes32;
function setBytes32(bytes32 v) public {
v_bytes32 = v;
}
bytes public v_bytes;
function setBytes(bytes v) public {
Bytes(v);
Bytes(msg.data);
v_bytes = v;
}
uint public vm_a;
int public vm_b;
uint public vm_c;
bytes20 public vm_d;
address public vm_e;
bytes public vm_f;
event Bytes(bytes f);
function setMany(uint a, int b, uint c, bytes20 d, address e, bytes f) public {
Bytes(f);
Bytes(msg.data);
vm_a = a;
vm_b = b;
vm_c = c;
vm_d = d;
vm_e = e;
vm_f = f;
}
// ---- register family from TestDataRegistry merged in ----
function reset() public {
wasSuccessful = 0;
}
function registerUInt(address to, uint v) public {
bool result = to.call(bytes4(sha3("registerData()")), v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerInt(address to, int v) public {
bool result = to.call(bytes4(sha3("registerData()")), v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerBool(address to, bool v) public {
bool result = to.call(bytes4(sha3("registerData()")), v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerBytes32(address to, bytes32 v) public {
bool result = to.call(bytes4(sha3("registerData()")), v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerBytes(address to, bytes v) public {
bool result = to.call(bytes4(sha3("registerData()")), v.length, v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerAddress(address to, address v) public {
bool result = to.call(bytes4(sha3("registerData()")), v);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerMany(address to, uint a, int b, uint c, bytes20 d, address e, bytes f) public {
bool result = to.call(bytes4(sha3("registerData()")), a, b, c, d, e, f.length, f);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
function registerData(address to, int arg1, bytes32 arg2, address arg3) public {
bool result = to.call(0xb0f07e44, arg1, arg2, arg3);
if (result) { wasSuccessful = 1; } else { wasSuccessful = 2; }
}
// ---- schedule functions (forward to a scheduler) ----
function scheduleSetBool(address to, uint blockNum, bool value) public {
if (to.call.value(msg.value)(0x01991313, this, bytes4(sha3("setBool()")), blockNum) == false) throw;
to.call(bytes4(sha3("registerData()")), value);
}
function scheduleSetUInt(address to, uint blockNum, uint value) public {
if (to.call.value(msg.value)(0x01991313, this, bytes4(sha3("setUInt(uint256)")), blockNum) == false) throw;
to.call(bytes4(sha3("registerData()")), value);
}
}
External Links
Related contracts
MemberRegistry
Same deployerOwner-controlled dynamic-array member registry.
0x1f3b19...7c161aAugust 13, 2015Members
Same deployerOwner-controlled member registry with array + mapping tracking.
0xaeb2ac...a5fd37August 14, 2015MembershipRoster
Same deployerAn Ethereum Public Trust roster contract for adding, removing, and checking members.
0xf1d327...aa0455August 14, 2015KillMul
Same deployerTest/utility contract with `suicide(address)` kill switch and a `multiply2` helper.
0x3e5e1f...7c78cdAugust 14, 2015Members
Same deployerOwner-controlled member registry using sequential id + mapping storage.
0xc6810e...db4e6fAugust 14, 2015CallerPool
Same deployerThe bonded caller pool of the Ethereum Alarm Clock: callers post a bond, take turns being the designated executor, and forfeit it if they miss.
0x329219...fc3e8bSeptember 22, 2015