Dr. Christian Reitwiessner
@ethchris github.com/chriseth c@ethdev.com
ÐΞVCON1 - London - 2015-11-10
Code / contract does
Solidity is statically typed. Compiler can check that
contract C {
address owner; uint ownr;
function giveMeMyMoney() {
if (msg.sender == ownr) // type error
ownr.send(this.balance);
// type error: no `send` in `uint`
}
}
contract C {
uint[] data;
function append(uint value) { data.push(value); }
function replace(uint index, uint value) {
data[index] = value;
}
}
contract C {
address owner;
function changeOwner(address _new) {
if (msg.sender != owner) throw;
owner = _new;
}
}
If someone uses your contract in a non-intended way, do not make them suffer.
contract C {
uint[] data;
function append(uint item) {
if (msg.value > 0) throw;
data.push(item);
}
}
contract C {
...
function payout() {
if (msg.value < 1 ether) throw;
performPayout();
suicide(owner);
// contract will vanish,
// ether sent to address will be lost
}
...
}
contract C {
...
/// Sells item `name`, cannot be undone.
function sell(string name) {
...
}
}
contract C {
bool bought;
...
function buy(string name) {
if (bought) throw;
bought = true;
...
}
}
contract BinarySearch {
///@why3
/// requires { forall i j: int. 0 <= i <= j < @data.length ->
/// @data[i] <= @data[j] }
/// variant { @end - @begin }
/// ensures { @ret < UInt256.max_uint256 ->
/// (@begin <= @ret < @end && @data[@ret] = @value) }
function find(uint[] data, uint begin, uint end, uint value)
internal returns (uint ret) {
uint len = end - begin;
if (len == 0 || (len == 1 && data[begin] != value)) return uint(-1);
uint mid = begin + len / 2;
if (value < data[mid]) return find(data, begin, mid, value);
else if (value > data[mid]) return find(data, mid + 1, end, value);
else return mid;
}
}
function() { ...}
)contract C { uint[2**255] arrData; mapping(uint -> uint) mapData; }
arrData[i]
: stored at sha3(0x00) + i
mapData[x]
: stored at sha3(0x01, x)
arrData[sha3(0x01,x) - sha3(0x00)]
will overwrite mapData[x]
without breaking sha3.contract C {
struct S { uint128 a; uint64 b; uint64 c; }
S data;
function f(uint x, uint y) {
data.a = x;
data.b = data.a * y;
data.c = data.b;
// -> optimised to single write, no read.
}
}
function search(uint value, uint index_hint) {
if (data[index_hint] == value) return index_hint;
else { ... /* search inside data */ }
}
make sure that it is still safe!