def add_certification(address, caller_address, content): """Writes to the blockchain something about the given address returns: success message """ ctx = GetContext() current_data = Get(ctx, address) new_entry = concat(caller_address, content) new_data = [] if not current_data: new_data.append(new_entry) else: current_data = deserialize_bytearray(current_data) current_data.append(new_entry) new_data = current_data final_data = serialize_array(new_data) Put(ctx, address, final_data) Log('New certification added.') return 'Success: New certification added'
def PlaceNewBid(args): owner = args[0] name = args[1] date = args[2] ad_url = args[3] image_urls = args[4] context = GetContext() time = GetTime(context) attachments = get_asset_attachments() user = attachments[1] bid_amount = attachments[3] publication_key = validatePublicationAuction(context, args) if not publication_key: return [False, 'Invalid auction params'] if time >= date: print('Auction has finished') return [False, 'Auction finished'] if bid_amount <= 0: print('No NeoGAS has been attached') return [False, 'No GAS attached'] has_claimed = False new_bid = [user, bid_amount, ad_url, image_urls, time] new_auction = [user, bid_amount, has_claimed] auction_key = concat(publication_key, sha1(date)) bids_key = concat(auction_key, 'bids') auction = Get(context, auction_key) # If no previous bids automatically accept and store current bid if not auction: Put(context, auction_key, Serialize(new_auction)) Put(context, bids_key, Serialize([new_bid])) return [True, ''] auction = Deserialize(auction) previous_user = auction[0] previous_bid = auction[1] if previous_bid >= bid_amount: print('Must bid more than the current best bid') OnRefund(user, bid_amount) return [False, 'Must bid more than current best bid'] bids = Get(context, bids_key) bids = Deserialize(bids) bids.append(new_bid) Put(context, auction_key, Serialize(new_auction)) Put(context, bids_key, Serialize(bids)) # Re-credit funds to previous bidder AddFunds(context, previous_user, previous_bid) return [True, '']
def CreatePublication(args): sender = args[0] name = args[1] url = args[2] category = args[3] if not CheckWitness(sender): print('Account owner must be sender') return [False, 'Account owner must be sender'] # Add char limit to prevent big storage costs if (len(name) > 255 or len(url) > 255 or len(category) > 255): print('Args must be less than 255 chars') return [False, 'Arguments must be less than 255 chars'] context = GetContext() publications_key = concat('publications', sender) # Publications by user publication_key = concat( publications_key, sha1(name)) # Publication details - sha1 to prevent malicious input new_publications_key = 'new_publications' # List of new publications for front page view publications = Get(context, publications_key) publication = Get(context, publication_key) new_publications = Get(context, new_publications_key) # If publication already exists check if it is active/deleted if publication: publication = Deserialize(publication) if publication[5]: print('Publication name currently active') return [False, 'Active publication name'] # Check if user has publications already if publications: publications = Deserialize(publications) else: publications = [] # Check if there are publications in the all_publications view if new_publications: new_publications = Deserialize(new_publications) else: new_publications = [] first_date = getWarpedTime(context) + ( SECONDS_IN_DAY - getWarpedTime(context) % SECONDS_IN_DAY) + SECONDS_IN_HOUR * -TIMEZONE is_active = True new_publication = [sender, name, url, category, first_date, is_active] publications.append(name) new_publications.append([sender, name]) # Shift new publication list to the left if len(new_publications) > 5: new_publications = [ new_publications[1], new_publications[2], new_publications[3], new_publications[4], new_publications[5] ] Put(context, publication_key, Serialize(new_publication)) Put(context, publications_key, Serialize(publications)) Put(context, new_publications_key, Serialize(new_publications)) return [True, '']
def Main(operation, args): """Entry point to the program :param str operation: The name of the operation to perform :param list args: A list of arguments along with the operation :return: The result of the operation :rtype: bytearray Token operations: - allowance(token_id): returns approved third-party spender of a token - approve(token_receiver, token_id, revoke): approve third party to spend a token - balanceOf(owner): returns owner's current total tokens owned - name(): returns name of token - decimals(): returns token decimal precision - ownerOf(token_id): returns the owner of the specified token. - properties(token_id): returns a token's read-only data - rwProperties(token_id): returns a token's read/write data - supportedStandards(): returns a list of supported standards {"NEP-10"} - symbol(): returns token symbol - token(token_id): returns a dictionary where token, property, and uri keys map to the corresponding data for the given `token_id` - tokensOfOwner(owner, starting_index): returns a dictionary that contains less than or equal to ten of the tokens owned by the specified address starting at the `starting_index`. - totalSupply(): Returns the total token supply deployed in the system. - transfer(to, token_id, extra_arg): transfers a token - transferFrom(spender, from, to, token_id): allows a third party to execute a pre-approved transfer - uri(token_id): Returns a distinct Uniform Resource Identifier (URI) for a given asset. The URI data of a token supplies a reference to get more information about a specific token or its data. TOKEN_CONTRACT_OWNER operations: - mintToken(owner, properties, URI, extra_arg): create a new NFT token with the specified properties and URI and send it to the specified owner - modifyURI(token_id, token_data): modify specified token's URI data setters: - setName(name): sets the name of the token - setSymbol(symbol): sets the token's symbol - setSupportedStandards(supported_standards): sets the supported standards, 'NEP-10' is always the first element in the array """ # The trigger determines whether this smart contract is being run # in 'verification' mode or 'application' trigger = GetTrigger() # 'Verification' mode is used when trying to spend assets # (eg NEO, Gas) on behalf of this contract's address if trigger == Verification(): # if the script that sent this is the owner, we allow the spend if CheckWitness(TOKEN_CONTRACT_OWNER): return True elif trigger == Application(): # Need to get this at the top level caller = GetCallingScriptHash() ctx = GetContext() if operation == 'name': name = Get(ctx, 'name') if name: return name else: return TOKEN_NAME elif operation == 'symbol': symbol = Get(ctx, 'symbol') if symbol: return symbol else: return TOKEN_SYMBOL elif operation == 'supportedStandards': supported_standards = Get(ctx, 'supportedStandards') if supported_standards: return supported_standards else: return Serialize(['NEP-10']) elif operation == 'totalSupply': return Get(ctx, TOKEN_CIRC_KEY) elif operation == 'allowance': assert len(args) == 1, ARG_ERROR ownership = safe_deserialize( Get(ctx, concat('ownership/', args[0]))) assert ownership, TOKEN_DNE_ERROR # don't fault here in case a calling contract is just checking allowance value if not has_key(ownership, 'approved'): return False if len(ownership['approved']) != 40: return False return ownership['approved'] elif operation == 'balanceOf': assert len(args) == 1, ARG_ERROR assert len(args[0]) == 20, INVALID_ADDRESS_ERROR token_iter = Find(ctx, args[0]) count = 0 while token_iter.next(): count += 1 return count elif operation == 'ownerOf': assert len(args) == 1, ARG_ERROR ownership = safe_deserialize( Get(ctx, concat('ownership/', args[0]))) assert ownership, TOKEN_DNE_ERROR assert has_key(ownership, 'owner'), TOKEN_DNE_ERROR assert len(ownership['owner']) == 20, TOKEN_DNE_ERROR return ownership['owner'] elif operation == 'properties': assert len(args) == 1, ARG_ERROR return get_properties(ctx, args[0]) elif operation == 'rwProperties': assert len(args) == 1, ARG_ERROR return get_rw_properties(ctx, args[0]) elif operation == 'token': assert len(args) == 1, ARG_ERROR token = Get(ctx, concat('token/', args[0])) assert token, TOKEN_DNE_ERROR return token elif operation == 'tokensOfOwner': assert len(args) == 2, ARG_ERROR tokens_of_owner = do_tokens_of_owner(ctx, args[0], args[1]) assert tokens_of_owner, 'address has no tokens' return Serialize(tokens_of_owner) elif operation == 'uri': assert len(args) == 1, ARG_ERROR token = safe_deserialize(Get(ctx, concat('token/', args[0]))) assert token, TOKEN_DNE_ERROR assert has_key(token, 'uri'), TOKEN_DNE_ERROR return token['uri'] elif operation == 'decimals': return TOKEN_DECIMALS # # User RW operations # if operation == 'approve': # args: from, spender, id, revoke # (NFT needs a fourth argument to revoke approval) assert len(args) > 2, ARG_ERROR assert args[2], TOKEN_DNE_ERROR return do_approve(ctx, caller, args) elif operation == 'transfer': assert len(args) > 1, ARG_ERROR return do_transfer(ctx, caller, args) elif operation == 'transferFrom': assert len(args) > 2, ARG_ERROR if len(args) == 3: # Nash-style (from, to, amount/id) transferFrom that can # be invoked only by whitelisted DEX to initiate a # pre-approved transfer return nash_do_transfer_from(ctx, caller, args) else: # Moonlight-style (spender, from, to, amount/id) # transfer where an authenticated spender/originator is # the only one who can initiate a transfer but can send # to an arbitrary third party (or themselves) return do_transfer_from(ctx, caller, args) # # dApp operations # if operation == 'setRWProperties': # args: token id, rwdata assert CheckWitness(DAPP_ADMIN), PERMISSION_ERROR assert len(args) == 2, ARG_ERROR return set_rw_properties(ctx, args[0], args[1]) # Administrative operations if CheckWitness(TOKEN_CONTRACT_OWNER): if operation == 'mintToken': assert len(args) > 3, ARG_ERROR return do_mint_token(ctx, args) elif operation == 'modifyURI': assert len(args) == 2, ARG_ERROR return do_modify_uri(ctx, args) elif operation == 'setName': assert len(args) == 1, ARG_ERROR return do_set_config(ctx, 'name', args[0]) elif operation == 'setSymbol': assert len(args) == 1, ARG_ERROR return do_set_config(ctx, 'symbol', args[0]) elif operation == 'setSupportedStandards': assert len(args) >= 1, ARG_ERROR supported_standards = ['NEP-10'] for arg in args: supported_standards.append(arg) return do_set_config(ctx, 'supportedStandards', Serialize(supported_standards)) AssertionError('unknown operation') return False
def Main(operation, args): """ Main definition for the smart contracts :param operation: the operation to be performed :type operation: str :param args: list of arguments. args[0] is always sender script hash args[1] is Poll Data or Poll Index args[2]+ eligible addresses :param type: str :return: byterarray: The result of the operation """ user_address = args[0] #Always needed if operation == 'GetPublicAll': publicPolls = Get(GetContext(), "public") if publicPolls is None: return "There are no public polls" else: publicPolls = Deserialize(publicPolls) publicPollsObj = [] for pollID in publicPolls: pollItem = [] pollItem.append(pollID) Log(pollID) vote_list = concat(pollID, ".vote_list") vl = Get(GetContext(), vote_list) if vl is None: pollItem.append(len(vl)) else: pollItem.append(len(Deserialize(vl))) vote_key = concat(pollID, ".") vote_key = concat(vote_key, user_address) vote = Get(GetContext(), vote_key) if vote is None: pollItem.append("false") else: pollItem.append("true") publicPollsObj.append(pollItem) return publicPollsObj if operation == 'GetPollById': #input parameters pollID = args[1] poll = Get(GetContext(), pollID) if poll is None: return "Poll with given ID doesn't exist" else: return Deserialize(poll) if operation == 'GetAssignedPolls': user_key = concat(user_address, ".assigned") pollsAssigned = Get(GetContext(), user_key) if pollsAssigned is None: return "There are no private polls assigned to the current user" else: pollsAssigned = Deserialize(pollsAssigned) pollsObj = [] for pollID in pollsAssigned: pollItem = [] pollItem.append(pollID) vote_list = concat(pollID, ".vote_list") vl = Get(GetContext(), vote_list) if vl is None: pollItem.append(len(vl)) else: pollItem.append(len(Deserialize(vl))) vote_key = concat(pollID, ".") vote_key = concat(vote_key, user_address) vote = Get(GetContext(), vote_key) if vote is None: pollItem.append("false") else: pollItem.append("true") pollsObj.append(pollItem) return pollsObj if operation == 'GetCreatedPolls': user_key = concat(user_address, ".created") pollsCreated = Get(GetContext(), user_key) if pollsCreated is None: return "There are no private polls created by current user" else: pollsCreated = Deserialize(pollsCreated) pollsObj = [] for pollID in pollsCreated: pollItem = [] pollItem.append(pollID) vote_list = concat(pollID, ".vote_list") vl = Get(GetContext(), vote_list) if vl is None: pollItem.append(len(vl)) else: pollItem.append(len(Deserialize(vl))) vote_key = concat(pollID, ".") vote_key = concat(vote_key, user_address) vote = Get(GetContext(), vote_key) if vote is None: pollItem.append("false") else: pollItem.append("true") pollsObj.append(pollItem) return pollsObj if operation == 'GetAssignedByAddress': user_key = concat(args[1], ".assigned") pollsAssigned = Get(GetContext(), user_key) if pollsAssigned is None: return "There are no private polls assigned to this address" else: return Deserialize(pollsAssigned) if operation == 'GetPollCount': pollCount = Get(GetContext(), "pollCount") if pollCount is None: return "Contract does not contain any poll" else: return Deserialize(pollCount) if operation == 'GetVoteListById': pollID = args[1] vote_list = concat(pollID, ".vote_list") vl = Get(GetContext(), vote_list) if vl is None: return "This poll has 0 participants so far" else: return Deserialize(vl) if operation == 'CheckVoteByIdAndAddress': #input parameters pollID = args[1] target_address = args[2] vote_key = concat(pollID, ".") vote_key = concat(vote_key, target_address) vote = Get(GetContext(), vote_key) if vote is None: return "Current user has not participated in this poll" else: return Deserialize(vote) if operation == 'GetOptionResults': pollID = args[1] optionID = args[2] option_key = concat(pollID, ".") option_key = concat(option_key, optionID) option_count = Get(GetContext(), option_key) if option_count is None: return len(option_count) else: Log(option_count) return Deserialize(option_count) if operation == 'RegisterVote': data = args[1] pollID = args[2] vote_key = concat(pollID, ".") vote_key = concat(vote_key, user_address) vote = Get(GetContext(), vote_key) if vote is None: Put(GetContext(), vote_key, Serialize(args)) vote_list = concat(pollID, ".vote_list") vl = Get(GetContext(), vote_list) if vl is None: vl = [] vl.append(user_address) Put(GetContext(), vote_list, Serialize(vl)) else: vl = Deserialize(vl) vl.append(user_address) Put(GetContext(), vote_list, Serialize(vl)) else: return "User has already participated in this vote" if len(args) > 2: iterator = 0 for argument in args: if iterator > 2: option_id = argument option_key = concat(pollID, ".") option_key = concat(option_key, option_id) option_count = Get(GetContext(), option_key) if option_count is None: option_count = 1 Put(GetContext(), option_key, Serialize(option_count)) else: option_count = Deserialize(option_count) option_count += 1 Put(GetContext(), option_key, Serialize(option_count)) iterator = iterator + 1 return "Vote Successful" if operation == 'RegisterPoll': #input parameters data = args[1] poll_name = args[2] address_list = args[3] #Save latest poll ID pollID = Get(GetContext(), "pollCount") poll_key = poll_name if pollID is None: pollIDInt = 1 pollID = Serialize(pollIDInt) Put(GetContext(), "pollCount", pollID) else: pollIDInt = Deserialize(pollID) pollIDInt += 1 pollID = Serialize(pollIDInt) Put(GetContext(), "pollCount", pollID) #Save poll to corresponding addresses if address_list is None: publicPolls = Get(GetContext(), "public") if publicPolls is None: publicPolls = [] publicPolls.append(poll_key) Put(GetContext(), "public", Serialize(publicPolls)) else: publicPolls = Deserialize(publicPolls) publicPolls.append(poll_key) Put(GetContext(), "public", Serialize(publicPolls)) else: iterator = 0 for argument in args: if iterator > 2: target_address = argument user_key = concat(target_address, ".assigned") pollsAssigned = Get(GetContext(), user_key) if pollsAssigned is None: pollsAssigned = [] pollsAssigned.append(poll_key) Put(GetContext(), user_key, Serialize(pollsAssigned)) else: pollsAssigned = Deserialize(pollsAssigned) pollsAssigned.append(poll_key) Put(GetContext(), user_key, Serialize(pollsAssigned)) iterator = iterator + 1 owner_key = concat(user_address, ".created") pollsCreated = Get(GetContext(), owner_key) if pollsCreated is None: pollsCreated = [] pollsCreated.append(poll_key) Put(GetContext(), owner_key, Serialize(pollsCreated)) else: pollsCreated = Deserialize(pollsCreated) pollsCreated.append(poll_key) Put(GetContext(), owner_key, Serialize(pollsCreated)) Put(GetContext(), poll_key, Serialize(args)) return poll_key # Everything after this requires authorization authorized = CheckWitness(user_address) if not authorized: Log("Not Authorized") return False Log("Authorized") return False
def Main(operation, args): """Entry point to the program :param str operation: The name of the operation to perform :param list args: A list of arguments along with the operation :return: The result of the operation :rtype: bytearray Token operations: - allowance(token_id): returns approved third-party spender of a token - approve(token_receiver, token_id, revoke): approve third party to spend a token - balanceOf(owner): returns owner's current total tokens owned - name(): returns name of token - ownerOf(token_id): returns the owner of the specified token. - properties(token_id): returns a token's read-only data - supportedStandards(): returns a list of supported standards {"NEP-10"} - symbol(): returns token symbol - tokenData(token_id): returns a dictionary where token, property, and uri keys map to the corresponding data for the given `token_id` - tokensDataOfOwner(owner, starting_index): returns a dictionary that contains less than or equal to five of the tokens (where token, properties, and uri keys map to their corresponding data for each token id) owned by the specified address starting at the `starting_index`. - tokensOfOwner(owner, starting_index): returns a dictionary that contains less than or equal to ten of the tokens owned by the specified address starting at the `starting_index`. - totalSupply(): Returns the total token supply deployed in the system. - transfer(to, token_id, extra_arg): transfers a token - transferFrom(from, to, token_id, extra_arg): allows a third party to execute an approved transfer - uri(token_id): Returns a distinct Uniform Resource Identifier (URI) for a given asset. The URI data of a token supplies a reference to get more information about a specific token or its data. TOKEN_CONTRACT_OWNER operations: - mintToken(owner, properties, URI, extra_arg): create a new NFT token with the specified properties and URI and send it to the specified owner - modifyURI(token_id, token_data): modify specified token's URI data setters: - setName(name): sets the name of the token - setSymbol(symbol): sets the token's symbol - setSupportedStandards(supported_standards): sets the supported standards, 'NEP-10' is always the first element in the array """ # The trigger determines whether this smart contract is being run # in 'verification' mode or 'application' trigger = GetTrigger() # 'Verification' mode is used when trying to spend assets # (eg NEO, Gas) on behalf of this contract's address if trigger == Verification(): # if the script that sent this is the owner, we allow the spend if CheckWitness(TOKEN_CONTRACT_OWNER): return True elif trigger == Application(): ctx = GetContext() if operation == 'name': name = Get(ctx, 'name') if name: return name else: return TOKEN_NAME elif operation == 'symbol': symbol = Get(ctx, 'symbol') if symbol: return symbol else: return TOKEN_SYMBOL elif operation == 'supportedStandards': supported_standards = Get(ctx, 'supportedStandards') if supported_standards: return supported_standards else: return Serialize(['NEP-10']) elif operation == 'totalSupply': return Get(ctx, TOKEN_CIRC_KEY) if operation == 'allowance': if len(args) == 1: return Get(ctx, concat('approved/', args[0])) Notify(ARG_ERROR) return False elif operation == 'approve': if len(args) == 3: # GetCallingScriptHash() can't be done within the # function because the calling script hash changes # depending on where the function is called return do_approve(ctx, GetCallingScriptHash(), args[0], args[1], args[2]) Notify(ARG_ERROR) return False elif operation == 'balanceOf': if len(args) == 1: if len(args[0]) == 20: return Get(ctx, args[0]) Notify(INVALID_ADDRESS_ERROR) return False Notify(ARG_ERROR) return False elif operation == 'ownerOf': if len(args) == 1: t_owner = Get(ctx, args[0]) if len(t_owner) == 20: return t_owner Notify(TOKEN_DNE_ERROR) return False Notify(ARG_ERROR) return False elif operation == 'properties': if len(args) == 1: token_properties = Get(ctx, concat('properties/', args[0])) if token_properties: return token_properties Notify(TOKEN_DNE_ERROR) return False Notify(ARG_ERROR) return False elif operation == 'tokenData': if len(args) == 1: # check to make sure the token exists if len(Get(ctx, args[0])) == 20: return Serialize(do_token_data(ctx, args[0])) Notify(TOKEN_DNE_ERROR) return False Notify(ARG_ERROR) return False elif operation == 'tokensDataOfOwner': if len(args) == 2: tokens_data_of_owner = do_tokens_data_of_owner( ctx, args[0], args[1]) if tokens_data_of_owner: return Serialize(tokens_data_of_owner) return False Notify(ARG_ERROR) return False elif operation == 'tokensOfOwner': if len(args) == 2: tokens_of_owner = do_tokens_of_owner(ctx, args[0], args[1]) if tokens_of_owner: return Serialize(tokens_of_owner) return False Notify(ARG_ERROR) return False elif operation == 'transfer': if len(args) >= 2: # GetCallingScriptHash() can't be done within the # function because the calling script hash changes # depending on where the function is called return do_transfer(ctx, GetCallingScriptHash(), args) Notify(ARG_ERROR) return False elif operation == 'transferFrom': if len(args) >= 3: return do_transfer_from(ctx, args) Notify(ARG_ERROR) return False elif operation == 'uri': if len(args) == 1: token_uri = Get(ctx, concat('uri/', args[0])) if token_uri: return token_uri Notify(TOKEN_DNE_ERROR) return False Notify(ARG_ERROR) return False # Administrative operations if CheckWitness(TOKEN_CONTRACT_OWNER): if operation == 'mintToken': if len(args) >= 3: return do_mint_token(ctx, args) Notify(ARG_ERROR) return False elif operation == 'modifyURI': if len(args) == 2: return do_modify_uri(ctx, args[0], args[1]) Notify(ARG_ERROR) return False elif operation == 'setName': if len(args) == 1: return do_set_config(ctx, 'name', args[0]) Notify(ARG_ERROR) return False elif operation == 'setSymbol': if len(args) == 1: return do_set_config(ctx, 'symbol', args[0]) Notify(ARG_ERROR) return False elif operation == 'setSupportedStandards': if len(args) >= 1: supported_standards = ['NEP-10'] for arg in args: supported_standards.append(arg) return do_set_config(ctx, 'supportedStandards', Serialize(supported_standards)) Notify(ARG_ERROR) return False else: Notify(PERMISSION_ERROR) return False Notify('unknown operation') return False