123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2019 Nomadic Labs <contact@nomadic-labs.com> *)(* Copyright (c) 2019 Cryptium Labs <contact@cryptium-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)letmanager_script_code:Script_repr.lazy_expr=letopenMichelineinletopenMichelson_v1_primitivesinScript_repr.lazy_expr@@strip_locations@@Seq(0,[Prim(0,K_parameter,[Prim(0,T_or,[Prim(0,T_lambda,[Prim(0,T_unit,[],[]);Prim(0,T_list,[Prim(0,T_operation,[],[])],[])],["%do"]);Prim(0,T_unit,[],["%default"])],[])],[]);Prim(0,K_storage,[Prim(0,T_key_hash,[],[])],[]);Prim(0,K_code,[Seq(0,[Seq(0,[Seq(0,[Prim(0,I_DUP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[])])],[])])]);Prim(0,I_IF_LEFT,[Seq(0,[Prim(0,I_PUSH,[Prim(0,T_mutez,[],[]);Int(0,Z.zero)],[]);Prim(0,I_AMOUNT,[],[]);Seq(0,[Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_EQ,[],[])]);Prim(0,I_IF,[Seq(0,[]);Seq(0,[Seq(0,[Prim(0,I_UNIT,[],[]);Prim(0,I_FAILWITH,[],[])])])],[])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_DUP,[],[])])],[]);Prim(0,I_SWAP,[],[])]);Prim(0,I_IMPLICIT_ACCOUNT,[],[]);Prim(0,I_ADDRESS,[],[]);Prim(0,I_SENDER,[],[]);Seq(0,[Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_EQ,[],[])]);Prim(0,I_IF,[Seq(0,[]);Seq(0,[Seq(0,[Prim(0,I_UNIT,[],[]);Prim(0,I_FAILWITH,[],[])])])],[])]);Prim(0,I_UNIT,[],[]);Prim(0,I_EXEC,[],[]);Prim(0,I_PAIR,[],[])]);Seq(0,[Prim(0,I_DROP,[],[]);Prim(0,I_NIL,[Prim(0,T_operation,[],[])],[]);Prim(0,I_PAIR,[],[])])],[])])],[])])(* Find the toplevel expression with a given prim type from list,
because they can be in arbitrary order. *)letfind_topleveltoplevelexprs=letopenMichelineinletrecitertoplevel=function|(Prim(_,prim,_,_)asfound)::_whenString.equaltoplevel(Michelson_v1_primitives.string_of_primprim)->Somefound|_::rest->itertoplevelrest|[]->Noneiniter(Michelson_v1_primitives.string_of_primtoplevel)exprsletadd_do:manager_pkh:Signature.Public_key_hash.t->script_code:Script_repr.lazy_expr->script_storage:Script_repr.lazy_expr->(Script_repr.lazy_expr*Script_repr.lazy_expr)tzresultLwt.t=fun~manager_pkh~script_code~script_storage->letopenMichelineinletopenMichelson_v1_primitivesinLwt.return(Script_repr.force_decodescript_code)>>=?fun(script_code_expr,_gas_cost)->Lwt.return(Script_repr.force_decodescript_storage)>>|?fun(script_storage_expr,_gas_cost)->letstorage_expr=rootscript_storage_exprinmatchrootscript_code_exprwith|Seq(_,toplevel)->beginmatchfind_toplevelK_parametertoplevel,find_toplevelK_storagetoplevel,find_toplevelK_codetoplevelwithSome(Prim(_,K_parameter,[Prim(_,parameter_type,parameter_expr,parameter_annot)],prim_param_annot)),Some(Prim(_,K_storage,[Prim(_,code_storage_type,code_storage_expr,code_storage_annot)],k_storage_annot)),Some(Prim(_,K_code,[code_expr],code_annot))->(* Note that we intentionally don't deal with potential duplicate entrypoints in this migration as there already might be some in contracts that we don't touch. *)letmigrated_code=Seq(0,[Prim(0,K_parameter,[Prim(0,T_or,[Prim(0,T_lambda,[Prim(0,T_unit,[],[]);Prim(0,T_list,[Prim(0,T_operation,[],[])],[])],["%do"]);Prim(0,parameter_type,parameter_expr,"%default"::parameter_annot)],[])],prim_param_annot);Prim(0,K_storage,[Prim(0,T_pair,[Prim(0,T_key_hash,[],[]);Prim(0,code_storage_type,code_storage_expr,code_storage_annot)],[])],k_storage_annot);Prim(0,K_code,[Seq(0,[Prim(0,I_DUP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_IF_LEFT,[Seq(0,[Prim(0,I_PUSH,[Prim(0,T_mutez,[],[]);Int(0,Z.zero)],[]);Prim(0,I_AMOUNT,[],[]);Seq(0,[Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_EQ,[],[])]);Prim(0,I_IF,[Seq(0,[]);Seq(0,[Seq(0,[Prim(0,I_UNIT,[],[]);Prim(0,I_FAILWITH,[],[])])])],[])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_DUP,[],[])])],[]);Prim(0,I_SWAP,[],[])]);Prim(0,I_CDR,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_IMPLICIT_ACCOUNT,[],[]);Prim(0,I_ADDRESS,[],[]);Prim(0,I_SENDER,[],[]);Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_NEQ,[],[]);Prim(0,I_IF,[Seq(0,[Prim(0,I_SENDER,[],[]);Prim(0,I_PUSH,[Prim(0,T_string,[],[]);String(0,"Only the owner can operate.")],[]);Prim(0,I_PAIR,[],[]);Prim(0,I_FAILWITH,[],[])]);Seq(0,[Prim(0,I_UNIT,[],[]);Prim(0,I_EXEC,[],[]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[])])],[]);Prim(0,I_PAIR,[],[])])],[])])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[]);Prim(0,I_DUP,[],[]);Prim(0,I_CDR,[],[])])],[]);Prim(0,I_PAIR,[],[]);code_expr;Prim(0,I_SWAP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_SWAP,[],[]);Seq(0,[Seq(0,[Prim(0,I_DUP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[])])],[])])]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_SWAP,[],[]);Prim(0,I_PAIR,[],[])])],[]);Prim(0,I_PAIR,[],[])])],[])])],code_annot)])inletmigrated_storage=Prim(0,D_Pair,[(* Instead of
`String (0, Signature.Public_key_hash.to_b58check manager_pkh)`
the storage is written as unparsed with [Optimized] *)Bytes(0,Data_encoding.Binary.to_bytes_exnSignature.Public_key_hash.encodingmanager_pkh);storage_expr],[])inScript_repr.lazy_expr@@strip_locationsmigrated_code,Script_repr.lazy_expr@@strip_locationsmigrated_storage|_->script_code,script_storageend|_->script_code,script_storageletadd_set_delegate:manager_pkh:Signature.Public_key_hash.t->script_code:Script_repr.lazy_expr->script_storage:Script_repr.lazy_expr->(Script_repr.lazy_expr*Script_repr.lazy_expr)tzresultLwt.t=fun~manager_pkh~script_code~script_storage->letopenMichelineinletopenMichelson_v1_primitivesinLwt.return(Script_repr.force_decodescript_code)>>=?fun(script_code_expr,_gas_cost)->Lwt.return(Script_repr.force_decodescript_storage)>>|?fun(script_storage_expr,_gas_cost)->letstorage_expr=rootscript_storage_exprinmatchrootscript_code_exprwith|Seq(_,toplevel)->beginmatchfind_toplevelK_parametertoplevel,find_toplevelK_storagetoplevel,find_toplevelK_codetoplevelwithSome(Prim(_,K_parameter,[Prim(_,parameter_type,parameter_expr,parameter_annot)],prim_param_annot)),Some(Prim(_,K_storage,[Prim(_,code_storage_type,code_storage_expr,code_storage_annot)],k_storage_annot)),Some(Prim(_,K_code,[code_expr],code_annot))->(* Note that we intentionally don't deal with potential duplicate entrypoints in this migration as there already might be some in contracts that we don't touch. *)letmigrated_code=Seq(0,[Prim(0,K_parameter,[Prim(0,T_or,[Prim(0,T_or,[Prim(0,T_key_hash,[],["%set_delegate"]);Prim(0,T_unit,[],["%remove_delegate"])],[]);Prim(0,parameter_type,parameter_expr,"%default"::parameter_annot)],[])],prim_param_annot);Prim(0,K_storage,[Prim(0,T_pair,[Prim(0,T_key_hash,[],[]);Prim(0,code_storage_type,code_storage_expr,code_storage_annot)],[])],k_storage_annot);Prim(0,K_code,[Seq(0,[Prim(0,I_DUP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_IF_LEFT,[Seq(0,[Prim(0,I_PUSH,[Prim(0,T_mutez,[],[]);Int(0,Z.zero)],[]);Prim(0,I_AMOUNT,[],[]);Seq(0,[Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_EQ,[],[])]);Prim(0,I_IF,[Seq(0,[]);Seq(0,[Seq(0,[Prim(0,I_UNIT,[],[]);Prim(0,I_FAILWITH,[],[])])])],[])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_DUP,[],[])])],[]);Prim(0,I_SWAP,[],[])]);Prim(0,I_CDR,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_IMPLICIT_ACCOUNT,[],[]);Prim(0,I_ADDRESS,[],[]);Prim(0,I_SENDER,[],[]);Seq(0,[Prim(0,I_COMPARE,[],[]);Prim(0,I_NEQ,[],[]);Prim(0,I_IF,[Seq(0,[Prim(0,I_SENDER,[],[]);Prim(0,I_PUSH,[Prim(0,T_string,[],[]);String(0,"Only the owner can operate.")],[]);Prim(0,I_PAIR,[],[]);Prim(0,I_FAILWITH,[],[])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[]);Prim(0,I_NIL,[Prim(0,T_operation,[],[])],[])])],[]);Prim(0,I_IF_LEFT,[Seq(0,[Prim(0,I_SOME,[],[]);Prim(0,I_SET_DELEGATE,[],[]);Prim(0,I_CONS,[],[]);Prim(0,I_PAIR,[],[])]);Seq(0,[Prim(0,I_DROP,[],[]);Prim(0,I_NONE,[Prim(0,T_key_hash,[],[])],[]);Prim(0,I_SET_DELEGATE,[],[]);Prim(0,I_CONS,[],[]);Prim(0,I_PAIR,[],[])])],[])])],[])])]);Seq(0,[Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[]);Prim(0,I_DUP,[],[]);Prim(0,I_CDR,[],[])])],[]);Prim(0,I_PAIR,[],[]);code_expr;Prim(0,I_SWAP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_SWAP,[],[]);Seq(0,[Seq(0,[Prim(0,I_DUP,[],[]);Prim(0,I_CAR,[],[]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_CDR,[],[])])],[])])]);Prim(0,I_DIP,[Seq(0,[Prim(0,I_SWAP,[],[]);Prim(0,I_PAIR,[],[])])],[]);Prim(0,I_PAIR,[],[])])],[])])],code_annot)])inletmigrated_storage=Prim(0,D_Pair,[(* Instead of
`String (0, Signature.Public_key_hash.to_b58check manager_pkh)`
the storage is written as unparsed with [Optimized] *)Bytes(0,Data_encoding.Binary.to_bytes_exnSignature.Public_key_hash.encodingmanager_pkh);storage_expr],[])inScript_repr.lazy_expr@@strip_locationsmigrated_code,Script_repr.lazy_expr@@strip_locationsmigrated_storage|_->script_code,script_storageend|_->script_code,script_storagelethas_default_entrypointexpr=letopenMichelineinletopenMichelson_v1_primitivesinmatchScript_repr.force_decodeexprwith|Error_->false|Ok(expr,_)->matchrootexprwith|Seq(_,toplevel)->beginmatchfind_toplevelK_parametertoplevelwith|Some(Prim(_,K_parameter,[_],["%default"]))->false|Some(Prim(_,K_parameter,[parameter_expr],_))->letrechas_default=function|Prim(_,T_or,[l;r],annots)->List.exists(String.equal"%default")annots||has_defaultl||has_defaultr|Prim(_,_,_,annots)->List.exists(String.equal"%default")annots|_->falseinhas_defaultparameter_expr|Some_|None->falseend|_->falseletadd_root_entrypoint:script_code:Script_repr.lazy_expr->Script_repr.lazy_exprtzresultLwt.t=fun~script_code->letopenMichelineinletopenMichelson_v1_primitivesinLwt.return(Script_repr.force_decodescript_code)>>|?fun(script_code_expr,_gas_cost)->matchrootscript_code_exprwith|Seq(_,toplevel)->letmigrated_code=Seq(0,List.map(function|Prim(_,K_parameter,[parameter_expr],_)->Prim(0,K_parameter,[parameter_expr],["%root"])|Prim(_,K_code,exprs,annots)->letrecrewrite_self=function|Int_|String_|Bytes_|Prim(_,I_CREATE_CONTRACT,_,_)asleaf->leaf|Prim(_,I_SELF,[],annots)->Prim(0,I_SELF,[],"%root"::annots)|Prim(_,name,args,annots)->Prim(0,name,List.maprewrite_selfargs,annots)|Seq(_,args)->Seq(0,List.maprewrite_selfargs)inPrim(0,K_code,List.maprewrite_selfexprs,annots)|other->other)toplevel)inScript_repr.lazy_expr@@strip_locationsmigrated_code|_->script_code