This time I’m not announcing a release, or publishing a verification result of Ethereum smart contracts. This post is just a progress report: maybe except that the eth-isabelle repository reached 666 commits.

What I am up to: I want proven-correct byte code snippets that can be combined into proven-correct Ethereum contracts. Previously I proved some safety properties of a real contract, but the result only applies to a single contract, and the result is not reusable. It is one huge theorem, and the proof has no structure (except that I traverse all execution paths).

There are some approaches from here on, but probably I need to specify the snippets of EVM bytecode. So I defined a predicate:

triple {} precondition code postcondition

meaning “when the EVM has a state with precondition, code and other things, after some steps, the machine reaches a state with postcondition , code , and the other things unchanged.” (This is a variant of Hoare triples.) The last word “unchanged” is powerful. When I specify the ADD instruction, which does not touch the storage, I don’t have to even mention the storage at all. This technique comes from Magnus Myreen’s thesis (which comes after a long history).

With this predicate, the ADD instruction can be specified as

lemma add_triple :

"triple {}

(*precond*) (⟨ h ≤ 1023 ∧ g ≥ Gverylow ⟩ **

stack_height (h + 2) **

stack (h + 1) v ** (* ONE NUMBER *)

stack h w ** (* ANOTHER NUMBER *)

program_counter k **

gas_pred g **

continuing

) (* code *) {(k, Arith ADD)} (*postcond*)(stack_height (h + 1) **

stack h (v + w) ** (* SUM *)

program_counter (k + 1) **

gas_pred (g - Gverylow) **

continuing

)"

where the stack shrinks, the topmost two elements are summed into one element, the program counter is incremented, and the gas decreases. The program is still continuing because this is not anything like CALL, STOP or RETURN .

If you combine two instances of this lemma, you can add three numbers:

lemma addadd_triple :

"triple {} (*precond*) (⟨ h ≤ 1022 ∧ g ≥ 2 * Gverylow ⟩ **

stack_height (Suc (Suc (Suc h))) **

stack (h + 2) x ** (* ONE NUMBER *)

stack (h + 1) v ** (* SECOND NUMBER *)

stack h w ** (* THIRD NUMBER *)

program_counter k **

gas_pred g **

continuing

) (*code*) ({(k, Arith ADD)} ∪ {(k + 1, Arith ADD)}) (*postcond*) (stack_height (h + 1) **

stack h (x + v + w) ** (* SUM *)

program_counter (2 + k) **

gas_pred (g - 2 * Gverylow) **

continuing

)"

where the stack shrinks by two elements, the topmost three elements are summed into one element, the program counter is incremented by two, and the gas decreases twice the previous amount.

If I can do two instructions, I can do more. This building technique is not just for concatenating snippets. With certain proving exercises, it should also be possible to create loops or conditional executions.