Contents:
Library ConCert.Examples.Crowdfunding.CrowdfundingDataExt
From ConCert.Embedding Require Import Ast.
From ConCert.Embedding Require Import Notations.
From ConCert.Embedding Require Import PCUICTranslate.
From ConCert.Embedding Require Import Utils.
From ConCert.Embedding Require Import TranslationUtils.
From ConCert.Embedding Require Import Prelude.
From ConCert.Embedding.Extraction Require Import PreludeExt.
From ConCert.Embedding.Extraction Require Import SimpleBlockchainExt.
From Coq Require Import String.
From Coq Require Import List.
From MetaCoq.Template Require Import All.
Import ListNotations.
Import MCMonadNotation.
Import BaseTypes.
Open Scope list.
Import AcornBlockchain.
Import PreludeExt.Maps.
Note that we define the deep embedding (abstract syntax trees) of the data structures and programs using notations. These notations are defined in Ast.v and make use of the "custom entries" feature.
Brackets like [\ \] delimit the scope of data type definitions and like [| |] the scope of programs
Generating names for the data structures
MetaCoq Run
(mp_ <- tmCurrentModPath tt ;;
let mp := (Utils.string_of_modpath mp_ ++ "@")%string in
mkNames mp
["State" ; "mkState"; "balance" ; "donations" ; "owner";
"deadline"; "goal"; "done";
"Res" ; "Error";
"msg"; "Action"; "Transfer"; "Empty"] "_coq").
MetaCoq Run (mkNames "" ["Donate"; "GetFunds"; "Claim"] "_coq").
Import ListNotations.
(mp_ <- tmCurrentModPath tt ;;
let mp := (Utils.string_of_modpath mp_ ++ "@")%string in
mkNames mp
["State" ; "mkState"; "balance" ; "donations" ; "owner";
"deadline"; "goal"; "done";
"Res" ; "Error";
"msg"; "Action"; "Transfer"; "Empty"] "_coq").
MetaCoq Run (mkNames "" ["Donate"; "GetFunds"; "Claim"] "_coq").
Import ListNotations.
The internal state of the contract that is modified during the execution
The full type of contract's internal state
Messages
Definition msg_syn :=
[\ data msg =
Donate [_]
| GetFunds [_]
| Claim [_] \].
MetaCoq Unquote Inductive (global_to_tc msg_syn).
[\ data msg =
Donate [_]
| GetFunds [_]
| Claim [_] \].
MetaCoq Unquote Inductive (global_to_tc msg_syn).
Notation "'get_params' st" :=
[| first {params_ty} {state_ty} {st} |]
(in custom expr at level 0).
Notation "'get_state' st" :=
[| second {params_ty} {state_ty} {st} |]
(in custom expr at level 0).
Notation "'deadline' st" :=
[| first time (money × address) (get_params {st}) |]
(in custom expr at level 0).
Notation "'goal' st" :=
[| first money address (second time (money × address) (get_params {st})) |]
(in custom expr at level 0).
Notation "'owner' st" :=
[| second money address (second time (money × address) (get_params {st})) |]
(in custom expr at level 0).
Notation "'contribs' st" :=
[| first Map Bool (get_state {st}) |]
(in custom expr at level 0).
Notation "'done' st" :=
[| second Map Bool (get_state {st}) |]
(in custom expr at level 0).
Notation "'mkFullState' prms st" :=
[| Pair {params_ty} {state_ty} {prms} {st} |]
(in custom expr at level 0,
prms custom expr at next level,
st custom expr at next level).
Notation "'mkParams' dl g o" :=
[| Pair time (money × address) {dl} (Pair money address {g} {o}) |]
(in custom expr at level 0,
dl custom expr at next level,
g custom expr at next level,
o custom expr at next level).
Notation "'mkState' cs dn" :=
[| Pair Map Bool {cs} {dn} |]
(in custom expr at level 0,
cs custom expr at next level,
dn custom expr at next level).
Notation "'Result'" := [! Prod state_ty (List SimpleActionBody) !]
(in custom type at level 2).
Definition update_contribs_syn :=
[| \"f_st" : {full_state_ty} => \"cs" : Map =>
let "ps" : {params_ty} := get_params "f_st" in
let "new_st" : {state_ty} := mkState "cs" (done "f_st") in
mkFullState "ps" "new_st" |].
MetaCoq Unquote Definition update_contribs :=
(expr_to_tc StdLib.Σ (indexify nil update_contribs_syn)).
Definition set_done_syn :=
[| \"f_st" : {full_state_ty} =>
let "ps" : {params_ty} := get_params "f_st" in
let "new_st" : {state_ty} := mkState (contribs "f_st") True in
mkFullState "ps" "new_st" |].
MetaCoq Unquote Definition set_done :=
(expr_to_tc StdLib.Σ (indexify nil set_done_syn)).
Module Notations.
Notation "'ctx_from' a" := [| {eConst "Ctx_from"} {a} |]
(in custom expr at level 0).
Notation "'ctx_contract_address' a" :=
[| {eConst "Ctx_contract_address"} {a} |]
(in custom expr at level 0).
Notation "'amount' a" := [| {eConst "Ctx_amount"} {a} |]
(in custom expr at level 0).
Notation "'ctx_from' a" := [| {eConst "Ctx_from"} {a} |]
(in custom expr at level 0).
Notation "'ctx_contract_address' a" :=
[| {eConst "Ctx_contract_address"} {a} |]
(in custom expr at level 0).
Notation "'amount' a" := [| {eConst "Ctx_amount"} {a} |]
(in custom expr at level 0).
New global context with the constants defined above (in addition to the ones defined in the Oak's "StdLib")
Definition Σ' :=
StdLib.Σ ++ [ Prelude.AcornMaybe;
msg_syn;
addr_map_acorn;
AcornBlockchain.SimpleChainAcorn;
AcornBlockchain.SimpleContractCallContextAcorn;
AcornBlockchain.SimpleActionBodyAcorn;
gdInd "Z" 0 [("Z0", []); ("Zpos", [(None,tyInd "positive")]);
("Zneg", [(None,tyInd "positive")])] false].
End Notations.
Generating string constants for variable names
MetaCoq Run (mkNames "" ["c"; "s"; "e"; "m"; "v"; "dl"; "g"; "chain"; "setup" ; "ctx" ;
"tx_amount"; "bal"; "sender"; "own"; "isdone" ;
"accs"; "now";
"newstate"; "newmap"; "cond"] "").
A shortcut for if .. then .. else ..
Notation "'if' cond 'then' b1 'else' b2 : ty" :=
(eCase (Bool,[]) ty cond
[(pConstr true_name [],b1); (pConstr false_name [],b2)])
(in custom expr at level 4,
cond custom expr at level 4,
ty custom type at level 4,
b1 custom expr at level 4,
b2 custom expr at level 4).
Definition SCtx := to_string_name <% SimpleContractCallContext_coq %>.
(eCase (Bool,[]) ty cond
[(pConstr true_name [],b1); (pConstr false_name [],b2)])
(in custom expr at level 4,
cond custom expr at level 4,
ty custom type at level 4,
b1 custom expr at level 4,
b2 custom expr at level 4).
Definition SCtx := to_string_name <% SimpleContractCallContext_coq %>.