Advertisement
Guest User

Untitled

a guest
Mar 6th, 2019
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scilab 20.40 KB | None | 0 0
  1. scilla_version 0
  2.  
  3. (***************************************************)
  4. (*               Associated library                *)
  5. (***************************************************)
  6. import BoolUtils
  7.  
  8. library NonfungibleToken
  9.  
  10. (***************************************************)
  11. (*                 Product library                 *)
  12. (***************************************************)
  13.  
  14.  
  15.  
  16. type Product =
  17. | Product of Uint256 Uint128 Uint128 Uint128 Uint128 Uint128 Bool
  18. (*    uint256 id;*)
  19. (*    uint256 price;*)
  20. (*    uint256 available;*)
  21. (*    uint256 supply;*)
  22. (*    uint256 sold;*)
  23. (*    uint256 interval;*)
  24. (*    bool renewable;*)
  25.  
  26. let unlimited_supply = Uint128 0
  27.  
  28. let create_product =
  29.     fun (_productId: Uint256) =>
  30.     fun (_initialPrice: Uint128) =>
  31.     fun (_initialInventoryQuantity: Uint128) =>
  32.     fun (_supply: Uint128) =>
  33.     fun (_interval: Uint128) =>
  34.         let s = Uint128 0 in
  35.         let r = False in
  36.         Product _productId _initialPrice _initialInventoryQuantity _supply s _interval r
  37.  
  38. type ChangeInventoryResult =
  39. | ChangeInventoryFailed
  40. | ChangeInventorySuccess of Product
  41.  
  42. let increment_inventory =
  43.     fun (p: Product) =>
  44.     fun (_inventoryAdjustment: Uint128) =>  
  45.         match p with
  46.         | Product id price available supply sold interval renewable =>
  47.             let newInventoryLevel = builtin add available _inventoryAdjustment in
  48.             let unlimited = builtin eq supply unlimited_supply in
  49.             match unlimited with
  50.             | True =>
  51.                 let np = Product id price newInventoryLevel supply sold interval renewable in
  52.                 ChangeInventorySuccess np
  53.             | False =>
  54.                 let ns = builtin add sold newInventoryLevel in
  55.                 let uvs = builtin lt supply ns in
  56.                 match uvs with
  57.                 | True => ChangeInventoryFailed
  58.                 | False =>
  59.                     let np = Product id price newInventoryLevel supply sold interval renewable in
  60.                     ChangeInventorySuccess np
  61.                 end
  62.             end
  63.         end
  64.  
  65. let decrement_inventory =
  66.     fun (p: Product) =>
  67.     fun (_inventoryAdjustment: Uint128) =>  
  68.         match p with
  69.         | Product id price available supply sold interval renewable =>
  70.             let newInventoryLevel = builtin sub available _inventoryAdjustment in
  71.             let overflow = builtin lt available newInventoryLevel in
  72.             match overflow with
  73.             | True => ChangeInventoryFailed
  74.             | False =>
  75.                 let np = Product id price newInventoryLevel supply sold interval renewable in
  76.                 ChangeInventorySuccess np
  77.             end
  78.         end
  79.  
  80. type PurchaseInventoryResult =
  81. | PurchaseInventoryFailed
  82. | PurchaseInventorySuccess of Product
  83. let purchase_one_unit_in_stock =
  84.     fun (p: Product) =>
  85.         match p with
  86.         | Product id price available supply sold interval renewable =>
  87.             let os = builtin eq available unlimited_supply in
  88.             match os with
  89.             | True => PurchaseInventoryFailed
  90.             | False =>
  91.                 let one = Uint128 1 in
  92.                 let ns = builtin add sold one in
  93.                 let na = builtin sub available one in
  94.                 let np = Product id price na supply ns interval renewable in
  95.                 PurchaseInventorySuccess np                
  96.             end
  97.         end        
  98.  
  99.  
  100.  
  101. (***************************************************)
  102. (*                 DinoSeed library                *)
  103. (***************************************************)
  104.  
  105.  
  106. type DinoSeed =
  107. | DinoSeed of Uint256 BNum
  108. (*    uint256 genes;*)
  109. (*    BNum bornBlock;*)
  110.  
  111.  
  112.  
  113.  
  114.  
  115. (***************************************************)
  116. (*                 NonfungibleToken                *)
  117. (***************************************************)
  118.  
  119.  
  120. let one_msg =
  121.   fun (msg : Message) =>
  122.   let nil_msg = Nil {Message} in
  123. Cons {Message} msg nil_msg
  124.  
  125. (* Checks and see if an address is a contract owner *)
  126. let checkContractOwner =
  127.     fun (msgSender: ByStr20) =>
  128.     fun (owner: ByStr20) =>
  129.         builtin eq msgSender owner
  130.  
  131. (* Checks and see if an address is a token owner *)
  132. let isTokenOwner =
  133.     fun (msgSender: ByStr20) =>
  134.     fun (tokenOwner : Option ByStr20) =>
  135.         match tokenOwner with
  136.         | None => False
  137.         | Some val =>
  138.             builtin eq val msgSender
  139.         end
  140.  
  141. (* Checks if a given address is approved to make txn the given tokenID *)
  142. (* Not to be confused with isApprovedForAll                            *)
  143. let isApproved =
  144.     fun (msgSender: ByStr20) =>
  145.     fun (val: Option ByStr20) =>
  146.         match val with
  147.         | None => False
  148.         | Some val =>
  149.             builtin eq val msgSender
  150.         end
  151.  
  152. (* Checks if an message sender is approved by a given owner. (i.e. operator) *)
  153. let isApprovedForAll =
  154.     fun (msgSender: ByStr20) =>
  155.     fun (m: Option (Map (ByStr20) (Bool))) =>
  156.         match m with
  157.         | None => False
  158.             (* owner did not assign anyone to the approval mapping *)
  159.         | Some val =>
  160.             (* val is of type Map (ByStr20) (Bool) *)
  161.             let check_list = builtin get val msgSender in
  162.             match check_list with
  163.             | None => False
  164.             | Some is_sender_approved =>
  165.                 (* check if sender has access rights *)
  166.                 match is_sender_approved with
  167.                 | True => True
  168.                 | False => False
  169.                 end
  170.             end
  171.         end
  172.  
  173. (* Check if a sender is an operator of the owner, approved for the given ID *)
  174. (* or is the owner of the token *)
  175. let isApprovedOrOwner =
  176.     fun (isOwner: Bool) =>
  177.     fun (isApproved: Bool) =>
  178.     fun (isApprovedForAll: Bool) =>
  179.         let isOwnerOrApproved =  orb isOwner isApproved in
  180.         orb isOwnerOrApproved isApprovedForAll
  181.  
  182. let isAuthorizedOrNotToContractHolder =
  183.     fun (isAuthorized: Bool) =>
  184.     fun (isToContracHoler: Option Bool) =>
  185.         match isToContracHoler with
  186.         | Some p =>
  187.             match p with
  188.             | True => isAuthorized
  189.             | False => False
  190.             end
  191.         | None => isAuthorized
  192.         end      
  193.        
  194. (* Error events *)
  195. let makeErrorEvent =
  196.     fun (location: String) =>
  197.     fun (errorCode: Uint32) =>
  198.         {_eventname: "Error"; raisedAt: location; code: errorCode }
  199.  
  200. (* Error codes *)
  201. let code_success = Uint32 0
  202. let code_failure = Uint32 1
  203. let code_not_authorized = Uint32 2
  204. let code_not_found = Uint32 4
  205. let code_bad_request = Uint32 5
  206. let code_token_exists = Uint32 6
  207. let code_product_exists = Uint32 7
  208. let code_invalid_quantity = Uint32 8
  209. let code_unexpected_error = Uint32 9
  210. let code_product_not_exists = Uint32 10
  211.  
  212. let code_purchase_error = Uint32 20
  213.  
  214. let code_not_implement_error = Uint32 255
  215. (***************************************************)
  216. (*             The contract definition             *)
  217. (***************************************************)
  218.  
  219. contract NonfungibleToken
  220. (owner : ByStr20,
  221.  name : String,
  222.  symbol: String
  223. )
  224.  
  225. (* mutable fields *)
  226.  
  227. (* Mapping between tokenId to token owner *)
  228. field tokenOwnerMap: Map Uint256 ByStr20 = Emp Uint256 ByStr20
  229. (* Mapping from owner to number of owned tokens *)
  230. field ownedTokenCount: Map ByStr20 Uint256 = Emp ByStr20 Uint256
  231.  
  232. (* Mapping between tokenId to approved address *)
  233. (* @dev: There can only be one approved address per token at a given time. *)
  234. field tokenApprovals: Map Uint256 ByStr20 = Emp Uint256 ByStr20
  235.  
  236. (* Mapping from owner to operator approvals  *)
  237. field operatorApprovals: Map ByStr20 (Map ByStr20 Bool)
  238.                             = Emp ByStr20 (Map ByStr20 Bool)
  239.  
  240. field dinoSeedMap: Map Uint256 DinoSeed = Emp Uint256 DinoSeed
  241. field nonceSeed: Uint256 = Uint256 0
  242.  
  243. field productsMap: Map Uint256 Product = Emp Uint256 Product
  244.  
  245. field contractHolderMap: Map ByStr20 Bool = Emp ByStr20 Bool
  246.  
  247. (* immutable field *)
  248.  
  249. (* @notice Count all NFTs assigned to an owner *)
  250. transition balanceOf(address: ByStr20)
  251.     optionBal <- ownedTokenCount[address];
  252.     balance = match optionBal with
  253.     | Some bal => bal
  254.     | None => Uint256 0
  255.     end;
  256.     e = {_eventname: "balanceOf"; bal: balance};
  257.     event e
  258. end
  259.  
  260.  
  261. (* Get the owner of a particular tokenId *)
  262. transition ownerOf(tokenId: Uint256)
  263.     someVal <- tokenOwnerMap[tokenId];
  264.     match someVal with
  265.     | Some val =>
  266.         e = {_eventname: "ownerOf"; id: tokenId; owner: val};
  267.         event e
  268.     | None =>
  269.         e = let raisedAt = "ownerOf" in makeErrorEvent raisedAt code_not_found;
  270.         event e
  271.     end
  272. end
  273.  
  274. (* @dev:    TODO whitelist contract address can mint the token*)
  275. (* @dev:    Mint new tokens. Only `contractOwner`, '_this_address' can mint the token*)
  276. (* @param:  to - address of the token recipient                     *)
  277. (* @param:  tokenId - token id of the new token                     *)
  278. (* Returns error message code_token_exist if token exists           *)
  279. transition mint(to: ByStr20, tokenId: Uint256)
  280.     (* Sender must be the contract owner *)
  281.     isOwner = checkContractOwner owner _sender;
  282.     isThisContract = checkContractOwner _this_address _sender;
  283.     isAuthorized = orb isOwner isThisContract;
  284.     match isAuthorized with
  285.     | True =>        
  286.         (* Check if token exists *)
  287.         tokenExist <- exists tokenOwnerMap[tokenId];
  288.         match tokenExist with
  289.         | True =>
  290.             (* Token exists, return error code *)
  291.             e = let raisedAt = "mint" in makeErrorEvent raisedAt code_token_exists;
  292.             event e
  293.         | False =>
  294.             (* Mint token *)
  295.             tokenOwnerMap[tokenId] := to;
  296.             (* add to owner count *)
  297.             userCnt <- ownedTokenCount[to];
  298.             match userCnt with
  299.             | Some val =>
  300.                 (* Append to existing results *)
  301.                 newVal= let one = Uint256 1 in builtin add val one;
  302.                 ownedTokenCount[to] := newVal
  303.             | None =>
  304.                 (* User does not have existing tokens *)
  305.                 newVal = Uint256 1;
  306.                 ownedTokenCount[to] := newVal
  307.             end;
  308.  
  309.             (* Emit success event *)
  310.             e = {_eventname: "Mint successful"; by: _sender; recipient: to; token: tokenId};
  311.             event e
  312.         end
  313.     | False =>
  314.         (* Unauthorized transaction - sender is not the contract owner*)
  315.         e = let raisedAt = "mint" in makeErrorEvent raisedAt code_not_authorized;
  316.         event e
  317.     end
  318.  
  319.    
  320. end
  321.  
  322. (* @dev Transfer the ownership of a given token ID to another address *)
  323. (* @param from:     Current owner of the token                        *)
  324. (* @param to:       Recipient address of the token                    *)
  325. (* @param tokenId   uint256 id of the token to be transferred         *)
  326. transition transferFrom(from: ByStr20, to: ByStr20, tokenId: Uint256)
  327.     copy_tokenOwner <- tokenOwnerMap[tokenId];
  328.     copy_tokenApprovals <- tokenApprovals[tokenId];
  329.    
  330.    
  331.     (* Get tokenOwner ByStr20 *)
  332.     getTokenOwner <- tokenOwnerMap[tokenId];
  333.     match getTokenOwner with
  334.     | None =>
  335.         (* Token not found *)
  336.         e = let raisedAt = "transferFrom" in makeErrorEvent raisedAt code_not_found;
  337.         event e
  338.        
  339.     | Some tokenOwner =>
  340.         copy_operatorApproval <- operatorApprovals[tokenOwner];
  341.         (* Libary functions to check for conditions *)
  342.         checkOwner = isTokenOwner _sender copy_tokenOwner;
  343.         checkApproved = isApproved _sender copy_tokenApprovals;
  344.         checkApprovedForAll = isApprovedForAll _sender copy_operatorApproval;
  345.  
  346.         (* Checks if the `from` is indeed the owner of the token *)
  347.         isFromTokenOwner = builtin eq tokenOwner from;
  348.         match isFromTokenOwner with
  349.         | False =>
  350.             (* From address is not the same as the tokenOwner    *)
  351.             e = let raisedAt = "transferFrom" in makeErrorEvent raisedAt code_bad_request;
  352.             event e
  353.         | True =>
  354.             (* isApprovedOrOwner checks if any of the three conditions are met *)
  355.             isAuthorized = isApprovedOrOwner checkOwner checkApproved checkApprovedForAll;
  356.             isToContracHoler <- contractHolderMap[to];
  357.            
  358.             isAuthorized2 = isAuthorizedOrNotToContractHolder isAuthorized isToContracHoler;
  359.  
  360.             match isAuthorized2 with
  361.             | True =>
  362.                 (* Remove from Approval *)
  363.                 match checkApproved with
  364.                 | True =>
  365.                     (* Remove entry from approvals at the token level *)
  366.                     delete tokenApprovals[tokenId]
  367.                 | False =>
  368.                 end;
  369.  
  370.                 (* Change tokenOwnerMap *)
  371.                 tokenOwnerMap[tokenId] := to;
  372.  
  373.                 (* Change Count *)
  374.  
  375.  
  376.                 (*subtract one from previous token owner *)
  377.                 somePrevBal <- ownedTokenCount[from];
  378.                 match somePrevBal with
  379.                 | Some prevBal =>
  380.                     newBal  = let one = Uint256 1 in builtin sub prevBal one;
  381.                     ownedTokenCount[from] := newBal
  382.                 | None =>
  383.                     e = let raisedAt = "transferFrom" in makeErrorEvent raisedAt code_unexpected_error;
  384.                     event e
  385.                 end;
  386.  
  387.                 (* add one to the new token owner *)
  388.                 userCnt <- ownedTokenCount[to];
  389.                 (* Calculate the new token count value for recipient *)
  390.                 newVal = let one = Uint256 1 in match userCnt with
  391.                 | Some val =>
  392.                     (* Add to existing value *)
  393.                     builtin add val one
  394.                 | None => one
  395.                 end;
  396.                 ownedTokenCount[to] := newVal;
  397.                
  398.                 (* check and notify to contract Holder *)              
  399.                
  400.                
  401.                 e = {_eventname: "transferFrom successful"; from: _sender; recipient: to; token: tokenId};
  402.                 event e
  403.             | False =>
  404.                 (* Unauthorized transaction *)
  405.                 e = let raisedAt = "transferFrom" in makeErrorEvent raisedAt code_not_authorized;
  406.                 event e
  407.             end
  408.         end
  409.     end
  410. end
  411.  
  412. (* @dev: Approves another address to transfer the given token ID                *)
  413. (* - There can only be one approved address per token at a given time           *)
  414. (* - Absence of entry in tokenApproval indicates there is no approved address   *)
  415. (* param: to ByStr20 to be approved for the given token id                      *)
  416. (* param: tokenId uint256 id of the token to be apporved                        *)
  417.  
  418.  
  419. transition approve(to: ByStr20, tokenId: Uint256)
  420.  
  421.     copy_tokenOwner <- tokenOwnerMap[tokenId];
  422.    
  423.  
  424.     (* Get tokenOwner ByStr20 *)
  425.     getTokenOwner <- tokenOwnerMap[tokenId];
  426.     match getTokenOwner with
  427.     | None =>
  428.         (* Token not found *)
  429.         e = let raisedAt = "approve" in makeErrorEvent raisedAt code_not_found;
  430.         event e
  431.     | Some tokenOwner =>
  432.         copy_operatorApproval <- operatorApprovals[tokenOwner];
  433.         checkApprovedForAll = isApprovedForAll _sender copy_operatorApproval;
  434.         checkOwner = isTokenOwner _sender copy_tokenOwner;
  435.         isAuthorized = orb checkApprovedForAll checkOwner;
  436.         match isAuthorized with
  437.         | True =>
  438.             (* add to token approval mapping *)
  439.             tokenApprovals[tokenId] := to;
  440.             (* Emit event *)
  441.             e = {_eventname: "Approve successful"; from: _sender; approvedTo: to; token: tokenId};
  442.             event e
  443.         | False =>
  444.             (* Unauthorized transaction *)
  445.             e = let raisedAt = "approve" in makeErrorEvent raisedAt code_not_authorized;
  446.             event e
  447.         end
  448.     end
  449. end
  450.  
  451. (* @dev: sets or unsets the approval of a given operator                *)
  452. (* @param: address to be set or unset as operator                       *)
  453. (* @param: approved - status of the approval to be set                  *)
  454.  
  455. transition setApprovalForAll(to: ByStr20, approved: Bool)
  456.    
  457.     (* Checks if the _sender is approving himself *)
  458.     isValidOperation = let check = builtin eq _sender to in negb check;
  459.     (* require _sender is not approving himself *)
  460.     match isValidOperation with
  461.     | True =>
  462.         (* Check if sender has an existing record on the operatorApproval *)
  463.         operatorApprovals[_sender][to] := approved;
  464.         (* Stringify boolean value to be emitted in the event *)
  465.         approvedStr = bool_to_string approved;
  466.         e = {_eventname: "setApprovalForAll successful"; from: _sender; recipient: to; status: approvedStr};
  467.         event e
  468.     | False =>
  469.         e = let raisedAt = "setApprovalForAll" in makeErrorEvent raisedAt code_not_authorized;
  470.         event e
  471.     end
  472. end
  473.  
  474.  
  475.  
  476. (*    uint256 id;*)
  477. (*    uint256 price;*)
  478. (*    uint256 available;*)
  479. (*    uint256 supply;*)
  480. (*    uint256 sold;*)
  481. (*    uint256 interval;*)
  482. (*    bool renewable;*)
  483. transition createProduct(productId: Uint256, initialPrice: Uint128, initialInventoryQuantity: Uint128, supply: Uint128, interval: Uint128)
  484.    
  485.     isAuthorized = checkContractOwner owner _sender;
  486.     match isAuthorized with
  487.     | True =>        
  488.         copy_product <- productsMap[productId];
  489.  
  490.         match copy_product with
  491.         | Some _ =>
  492.             e = let raisedAt = "createProduct" in makeErrorEvent raisedAt code_product_exists;
  493.             event e
  494.         | None =>
  495.             ivq = builtin lt supply initialInventoryQuantity;
  496.             match ivq with
  497.             | True =>
  498.                 e = let raisedAt = "createProduct" in makeErrorEvent raisedAt code_invalid_quantity;
  499.                 event e
  500.             | False =>
  501.                 p = create_product productId initialPrice initialInventoryQuantity supply interval;
  502.                 productsMap[productId] := p;                                
  503.                 e = {_eventname: "createProduct successful"; id: productId};    
  504.                 event e                
  505.             end            
  506.         end
  507.        
  508.     | False =>
  509.         (* Unauthorized transaction - sender is not the contract owner*)
  510.         e = let raisedAt = "createProduct" in makeErrorEvent raisedAt code_not_authorized;
  511.         event e
  512.     end
  513. end
  514.  
  515. transition purchaseProduct(productId: Uint256)
  516.     copy_product <- productsMap[productId];    
  517.  
  518.     match copy_product with
  519.     | Some p =>
  520.         match p with
  521.         | Product id price available supply sold interval renewable =>
  522.             vp = builtin eq _amount price;
  523.             match vp with
  524.             | False =>
  525.                 e = let raisedAt = "purchaseProduct" in makeErrorEvent raisedAt code_purchase_error;
  526.                 event e
  527.             | True =>
  528.                 po = purchase_one_unit_in_stock p;
  529.                 match po with
  530.                 | PurchaseInventoryFailed =>
  531.                     e = let raisedAt = "purchaseProduct" in makeErrorEvent raisedAt code_purchase_error;
  532.                     event e
  533.                 | PurchaseInventorySuccess np =>
  534.                     productsMap[productId] := np;
  535.                     x <- & BLOCKNUMBER;
  536.  
  537.                     (*TODO this must is genes*)
  538.                     attributes = productId;
  539.                     dn = DinoSeed attributes x;
  540.  
  541.                     n <- nonceSeed;
  542.                     one256 = Uint256 1;
  543.                     nid = builtin add n one256;
  544.                     nonceSeed := nid;
  545.  
  546.                     dinoSeedMap[nid] := dn;
  547.  
  548.                     accept;
  549.                    
  550.                     msg  = {_tag : "mint"; _recipient : _this_address; _amount : Uint128 0;
  551.                         to : _sender; tokenId : nid};
  552.                    
  553.                     msgs = one_msg msg;
  554.                     send msgs;
  555.  
  556.                     e = {_eventname: "purchaseProduct successful"; id: nid};    
  557.                     event e
  558.  
  559.                 end
  560.                
  561.             end
  562.         end
  563.     | None =>
  564.         e = let raisedAt = "purchaseProduct" in makeErrorEvent raisedAt code_product_not_exists;
  565.         event e
  566.     end
  567. end
  568.  
  569. transition setHolderStatus(holder: ByStr20, b: Bool)
  570.     isAuthorized = checkContractOwner owner _sender;
  571.     match isAuthorized with
  572.     | True =>
  573.         contractHolderMap[holder] := b;
  574.         (* Emit success event *)
  575.         e = {_eventname: "setHolderStatus successful"; by: _this_address; recipient: _sender; approved: b};
  576.         event e
  577.     | False =>
  578.         (* Unauthorized transaction - sender is not the contract owner*)
  579.         e = let raisedAt = "setHolderStatus" in makeErrorEvent raisedAt code_not_authorized;
  580.         event e
  581.     end
  582. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement