Skip to content

Instantly share code, notes, and snippets.

@Preetam007
Last active May 7, 2020 12:15
Show Gist options
  • Select an option

  • Save Preetam007/b904cf9577a12d42cb5ee95550dbda3b to your computer and use it in GitHub Desktop.

Select an option

Save Preetam007/b904cf9577a12d42cb5ee95550dbda3b to your computer and use it in GitHub Desktop.

Revisions

  1. Preetam007 revised this gist May 7, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion quilltrace.aes
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    contract ERC721 =
    contract AES721 =
    // state is handled for the storing the elements on blockchain

    record state = {
  2. Preetam007 created this gist May 7, 2020.
    199 changes: 199 additions & 0 deletions quilltrace.aes
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,199 @@
    contract ERC721 =
    // state is handled for the storing the elements on blockchain

    record state = {
    name: string,
    symbol: string,
    owner: address,
    _totalSupply : int,
    _nextTokenId: int,
    assetProperties: map(int, properties),
    map_owned_tokens_count: map(address, int),
    map_token_owner: map(int, address),
    map_token_approvals: map(int, address),
    map_operator_approvals: map(address, map(address, bool)),
    map_token_uris: map(int, string)}

    //struct of properties
    record properties ={
    productName : string,
    deliverydate : int,
    datecreated : int,
    isCounterfeit : bool,
    stage_1 : bool,
    stage_2 : bool,
    stage_3 : bool}

    // deployment of token with NFT Token name or NFT Token symbol

    stateful entrypoint init(name: string, symbol: string, owner: address) = {
    name = name,
    symbol = symbol,
    owner = owner,
    _totalSupply=0,
    _nextTokenId=1,
    assetProperties = {},
    map_owned_tokens_count = {},
    map_token_owner = {},
    map_token_approvals = {},
    map_operator_approvals = {},
    map_token_uris = {}}

    // return the name of NFT Token

    entrypoint name() : string =
    state.name

    // return the symbol of the nonFungible Token

    entrypoint symbol() : string =
    state.symbol

    // Returns the total number of tokens
    entrypoint totalSupply() : int=
    state._totalSupply

    // Returns the token id of the next minted token
    entrypoint nextTokenID() : int=
    state._nextTokenId

    // return total supply of the address
    entrypoint balance_of(token_owner: address) : int =
    Map.lookup_default(token_owner,state.map_owned_tokens_count, 0)

    // return the owner of the nonFungible Token
    entrypoint owner_of(token_id: int) : address =
    state.map_token_owner[token_id]


    // Mint a token. Only `owner` may call this function.
    // to The receiver of the token
    // tokenURI The tokenURI of the the tokenURI
    // asset properties of token assigned with tokenId

    stateful entrypoint mint(to : address, tokenUri : string, productName : string, deliverydate: int) =
    _mint(state._nextTokenId, to)
    set_token_uri(state._nextTokenId, tokenUri)
    let newassetProp: properties ={
    productName= productName,
    deliverydate=deliverydate,
    datecreated= Chain.timestamp,
    isCounterfeit =false,
    stage_1 = true,
    stage_2 = false,
    stage_3= false}
    put(state{assetProperties[state._nextTokenId]= newassetProp})
    put(state{_totalSupply = (state._totalSupply +1)})
    put(state{_nextTokenId = (state._nextTokenId +1)})

    // stateful function for updating the asset name property of given TokenId
    stateful entrypoint updateProductName(tokenId : int, productName : string)=
    only_token_owner(Call.caller, tokenId)
    require(state.assetProperties[tokenId].isCounterfeit == false, "asset is counterfeit")
    put(state{assetProperties[tokenId].productName = productName})

    // return the product name that is azssigned to token ID
    entrypoint getProductName(tokenId : int) : string =
    state.assetProperties[tokenId].productName

    // create product with tokenid and for the address "to"
    private stateful function _mint(token_id: int, to: address) =
    only_owner(Call.caller)
    require(!check_token_exists(token_id), "Token can't be overrided")

    put(state{
    map_token_owner[token_id] = to,
    map_owned_tokens_count[to] = Map.lookup_default(to, state.map_owned_tokens_count, 0) + 1})

    // get approval for nonFungible Token
    entrypoint get_approved(token_id: int) : address =
    state.map_token_approvals[token_id]

    entrypoint is_approved_for_all(owner: address, operator: address) : bool =
    Map.lookup_default(operator, Map.lookup_default(owner, state.map_operator_approvals, {}) , false)

    /**
    * Returns an URI for a given token ID
    * Throws if the token ID does not exist. May return an empty string.
    */
    entrypoint get_token_uri(token_id: int) : string =
    Map.lookup_default(token_id, state.map_token_uris, "")

    /**
    * function to set the token URI for a given token
    * Reverts if the token ID does not exist
    * uri string URI to assign
    */
    private stateful function set_token_uri(token_id: int, uri: string) =
    put(state{map_token_uris[token_id] = uri})

    /**
    *approval of token for the address "to"
    *revert if token id does not exists.
    */
    stateful entrypoint approve(token_id: int, to: address) =
    let owner: address = owner_of(token_id)

    require(to != Call.caller, "Receiver can't be same as sender")
    require(Call.caller == owner || is_approved_for_all(owner, Call.caller), "Not owner or not approved")

    put(state{map_token_approvals[token_id] = to})

    // tranfer the token from address to another address and owner of token approval is required
    stateful entrypoint transfer_from(from: address, to: address, token_id: int) =
    require(is_approved_or_owner(Call.caller, token_id), "Caller isn't approved or owner")

    clear_approval(from, token_id)
    remove_token_from(from, token_id)
    add_token_to(to, token_id)

    // funtion for set approval for to addresss for transfer token
    stateful entrypoint set_approval_for_all(to: address, approved: bool) =
    put(state{map_operator_approvals[Call.caller = {}][to] = approved})

    // Internal function for checking tokenId exists or not
    private function check_token_exists(token_id: int) : bool =
    switch(Map.lookup(token_id, state.map_token_owner))
    None => false
    Some(x) => true

    // Internal function for assigning the token to given address "to".
    private stateful function add_token_to(to: address, token_id: int) =
    put(state{map_token_owner = state.map_token_owner{[token_id] = to}})
    put(state{map_owned_tokens_count[to] = Map.lookup_default(to, state.map_owned_tokens_count, 0) + 1})

    // private function for remove token from address
    private stateful function remove_token_from(from: address, token_id: int) =
    //put(state{map_token_owner = state.map_token_owner{[token_id] = #0}})
    put(state{map_token_owner @ tp = Map.delete(token_id, tp)})
    put(state{map_owned_tokens_count[from] = Map.lookup_default(from, state.map_owned_tokens_count, 0) - 1})

    // Internal function clear the approval that is given to tokenId
    private stateful function clear_approval(from: address, token_id: int) =
    put(state{map_token_approvals @ mp=Map.delete(token_id, mp)})
    private stateful function remove_token_metadata(token_id: int) =
    put(state{map_token_uris = state.map_token_uris{[token_id] = ""}})

    // private function for check address is owner or not
    private function only_owner(owner : address) =
    require(owner == state.owner, "Only owner can mint!")

    // Internal function for checking the address has given tokenId.
    private function only_token_owner(owner: address, token_id: int) =
    require(owner == state.map_token_owner[token_id], "Only token owner can transfer!")

    // Internal function for giving approval to spender for given TokenId
    private function is_approved_or_owner(spender: address, token_id: int) : bool =
    let owner : address = owner_of(token_id)
    get_approved(token_id) == spender || owner == spender || is_approved_for_all(owner, spender)