It's great to be here...
The talks are about 5 minutes long. - Contract owner example
Definition setMessage (msg : String.string) (callInfo : machine_environment) : DS unit := owner <- gets owner;; if (owner =? (caller callInfo)) then puts (update_message msg) else fail. Definition getMessage (callInfo : machine_environment) : DS string := message <- gets message;; ret message. Definition changeOwner (new_owner : nat) (callInfo : machine_environment) : DS unit := owner <- gets owner;; if (owner =? (caller callInfo)) then puts (update_owner new_owner) else fail.
forall (msg : string) (callInfo : machine_environment) (stOld : message_board_storage_type) (result : unit) (stNew : message_board_storage_type), setMessage msg callInfo stOld = Some (result, stNew) /\ message stNew <> message stOld -> caller callInfo = owner stOldforall (msg : string) (callInfo : machine_environment) (stOld : message_board_storage_type) (result : unit) (stNew : message_board_storage_type), setMessage msg callInfo stOld = Some (result, stNew) /\ message stNew <> message stOld -> caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H: setMessage msg callInfo stOld = Some (result, stNew) /\ message stNew <> message stOldcaller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H: Some (result, stNew) = Some (result, stNew)
Def: setMessage msg callInfo stOld = Some (result, stNew)
H0: message stNew <> message stOldcaller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
Def: setMessage msg callInfo stOld = Some (result, stNew)
H0: message stNew <> message stOldcaller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
Def: (owner <- gets owner;; (if owner =? caller callInfo then puts (update_message msg) else fail)) stOld = Some (result, stNew)
H0: message stNew <> message stOldcaller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
H1: (if owner stOld =? caller callInfo then puts (update_message msg) else fail) stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = true
H1: puts (update_message msg) stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = false
H1: fail stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = true
H1: puts (update_message msg) stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = true
H1: puts (update_message msg) stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = true
H1: puts (update_message msg) stOld = Some (result, stNew)caller callInfo = owner stOldmsg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: owner stOld = caller callInfo
H1: puts (update_message msg) stOld = Some (result, stNew)caller callInfo = owner stOldauto.callInfo: machine_environment
stOld: message_board_storage_type
SCase: owner stOld = caller callInfocaller callInfo = owner stOldinversion H1. Qed.msg: string
callInfo: machine_environment
stOld: message_board_storage_type
result: unit
stNew: message_board_storage_type
H0: message stNew <> message stOld
SCase: (owner stOld =? caller callInfo) = false
H1: fail stOld = Some (result, stNew)caller callInfo = owner stOld
Definition setMessage msg callInfo : DS unit := owner <- gets owner;; if (owner =? (caller callInfo)) then puts (update_message msg) else fail.
Slide for space
Thank you!
I would like to thank my supervisor Professor Steve Reeves at the University of Waikato and Vilhelm Sjöberg at CertiK for their support.
I would also like to thank Associate Professor Jing Sun and the University of Auckland for kindly hosting me during this research.
Record message_board_storage_type := { owner : nat; message : String.string }. Definition update_message message r := {| owner := owner r; message := message |}. Definition update_owner owner r := {| owner := owner; message := message r |}. Record machine_environment := { caller : nat; callvalue : nat }. Definition init_message_board_storage : message_board_storage_type := {| owner := 4632783269828394728397482347237428347892; message := "" |}. Definition DS := StateT Maybe message_board_storage_type. Definition gets {A : Type} f : DS A := a <- get ;; ret (f a). Definition puts f : DS unit := a <- get ;; put (f a). Definition fail {A : Type} : DS A := fun (s : message_board_storage_type) => None.
forall (new_owner : nat) (me : machine_environment) (st : message_board_storage_type), (exists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')) -> caller me = owner stforall (new_owner : nat) (me : machine_environment) (st : message_board_storage_type), (exists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')) -> caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
H: exists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
H: exists st' : message_board_storage_type, changeOwner new_owner me st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: changeOwner new_owner me st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (owner <- gets owner;; (if owner =? caller me then puts (update_owner new_owner) else fail)) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (owner <- gets owner;; (if owner =? caller me then puts (update_owner new_owner) else fail)) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (owner <- gets owner;; (if owner =? caller me then puts (update_owner new_owner) else fail)) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (if owner st =? caller me then puts (update_owner new_owner) else fail) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (if owner st =? caller me then puts (update_owner new_owner) else fail) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
H: (if owner st =? caller me then puts (update_owner new_owner) else fail) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: fail st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: owner st = caller me
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: owner st = caller me
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: owner st = caller me
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stauto.new_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: owner st = caller me
H: puts (update_owner new_owner) st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: fail st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: fail st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: fail st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: fail st = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: None = Some (r, st')caller me = owner stnew_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: None = Some (r, st')caller me = owner stdiscriminate. Qed.new_owner: nat
me: machine_environment
st: message_board_storage_type
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H: None = Some (r, st')caller me = owner stforall (new_owner : nat) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> exists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')forall (new_owner : nat) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> exists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), changeOwner new_owner me st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (owner <- gets owner;; (if owner =? caller me then puts (update_owner new_owner) else fail)) st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (if owner st =? caller me then puts (update_owner new_owner) else fail) st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (if owner st =? owner st then puts (update_owner new_owner) else fail) st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), puts (update_owner new_owner) st = Some (r, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists st' : message_board_storage_type, puts (update_owner new_owner) st = Some (tt, st')new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stputs (update_owner new_owner) st = Some (tt, update_owner new_owner st)new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner st(a <- get;; put (update_owner new_owner a)) st = Some (tt, update_owner new_owner st)reflexivity. Qed.new_owner: nat
me: machine_environment
st: message_board_storage_type
H: caller me = owner stSome (tt, update_owner new_owner st) = Some (tt, update_owner new_owner st)forall (new_message : string) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> exists (r : unit) (st' : message_board_storage_type), setMessage new_message me st = Some (r, st')forall (new_message : string) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> exists (r : unit) (st' : message_board_storage_type), setMessage new_message me st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), setMessage new_message me st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (owner <- gets owner;; (if owner =? caller me then puts (update_message new_message) else fail)) st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (if owner st =? caller me then puts (update_message new_message) else fail) st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), (if owner st =? owner st then puts (update_message new_message) else fail) st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists (r : unit) (st' : message_board_storage_type), puts (update_message new_message) st = Some (r, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stexists st' : message_board_storage_type, puts (update_message new_message) st = Some (tt, st')new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stputs (update_message new_message) st = Some (tt, update_message new_message st)new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st(a <- get;; put (update_message new_message a)) st = Some (tt, update_message new_message st)reflexivity. Qed.new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stSome (tt, update_message new_message st) = Some (tt, update_message new_message st)forall (new_message : string) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> match setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endforall (new_message : string) (me : machine_environment) (st : message_board_storage_type), caller me = owner st -> match setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endnew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner stmatch setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endnew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
H0: exists (r : unit) (st' : message_board_storage_type), setMessage new_message me st = Some (r, st')match setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endnew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
H0: exists st' : message_board_storage_type, setMessage new_message me st = Some (r, st')match setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endnew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: setMessage new_message me st = Some (r, st')match setMessage new_message me st with | None => False | Some (_, st') => message st' = new_message endnew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: setMessage new_message me st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: setMessage new_message me st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: setMessage new_message me st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: (owner <- gets owner;; (if owner =? caller me then puts (update_message new_message) else fail)) st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
H0: (if owner st =? caller me then puts (update_message new_message) else fail) st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: puts (update_message new_message) st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: fail st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: puts (update_message new_message) st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: (a <- get;; put (update_message new_message a)) st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')
H2: tt = r
H3: update_message new_message st = st'message (update_message new_message st) = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')
H2: tt = r
H3: update_message new_message st = st'message (update_message new_message st) = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')
H2: tt = r
H3: update_message new_message st = st'message (update_message new_message st) = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')
H2: tt = r
H3: update_message new_message st = st'message (update_message new_message st) = new_messagereflexivity.new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = true
H0: Some (tt, update_message new_message st) = Some (r, st')
H2: tt = r
H3: update_message new_message st = st'new_message = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: fail st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: fail st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: fail st = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: None = Some (r, st')message st' = new_messagenew_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: None = Some (r, st')message st' = new_messagediscriminate. Qed.new_message: string
me: machine_environment
st: message_board_storage_type
H: caller me = owner st
r: unit
st': message_board_storage_type
Case: (owner st =? caller me) = false
H0: None = Some (r, st')message st' = new_message
Paper overviews
References
Introduction to creating a DeepSEA smart contract
Example: Trivial contract converting bool to int
object signature trivial = { const boolToInt : bool -> int } object Trivial : trivial { let boolToInt b = if b then 1 else 0 } layer CONTRACT = { o = Trivial }
object signature trivial = { const boolToInt : bool -> int; boolToIntTracker : bool -> int } object Trivial : trivial { let seenTrueYet : bool := false let boolToInt b = if b then 1 else 0 let boolToIntTracker b = if b then begin seenTrueYet := true; 1 end else 0 } layer CONTRACT = { o = Trivial }
$ dsc trivial.ds bytecode 5b60005b60206109205101610920525b61022660006020610920510301525b60006020 610920510301516101005260206101002060006020610920510301525b600060006020 61092051030151555b60206109205103610920525b60005b9050386300000073600039 386000f35b60006000fd5b610940610920527c01000000000000000000000000000000 000000000000000000000000006000350480635192f3c01463000000495780631e01e7 071463000000965760006000fd5b6004355b60006109205101610920525b8063000000 67576300000085565b600190505b60006109205103610920525b805b90506000526020 6000f35b60009050630000006c565b60006000fd5b6004355b60206109205101610920 525b8063000000b4576300000111565b61022660006020610920510301525b60006020 610920510301516101005260206101002060006020610920510301525b600160006020 61092051030151555b600190505b60206109205103610920525b805b90506000526020 6000f35b6000905063000000f8565b60006000fd
$ dsc trivial.ds abi
[ {"type":"constructor", "name":"constructor", "inputs":[], "outputs":[], "payable":false, "constant":false, "stateMutability":"nonpayable"}, {"type":"function", "name":"boolToInt", "inputs":[{"name":"b", "type":"bool"}], "outputs":[{"name":"", "type":"uint256"}], "payable":false, "constant":true, "stateMutability":"view"}, {"type":"function", "name":"boolToIntTracker", "inputs":[{"name":"b", "type":"bool"}], "outputs":[{"name":"", "type":"uint256"}], "payable":true, "constant":false, "stateMutability":"payable"}]
Next slide is a reminder of the contract definition.
object signature trivial = { const boolToInt : bool -> int; boolToIntTracker : bool -> int } object Trivial : trivial { let seenTrueYet : bool := false let boolToInt b = if b then 1 else 0 let boolToIntTracker b = if b then begin seenTrueYet := true; 1 end else 0 } layer CONTRACT = { o = Trivial }