def initialise_token(self, token_ids): """Initialise the token with the required additional token context, can only be called once per token and only one of its admin can call this""" sp.set_type_expr(token_ids, sp.TList(sp.TNat)) sp.for token_id in token_ids: sp.verify((~self.data.token_context.contains(token_id)), message = TZWFA2ErrorMessage.TOKEN_EXISTS) administrator_ledger_key = LedgerKey.make(sp.sender, token_id) sp.verify(self.data.administrators.get(administrator_ledger_key, sp.nat(0))==AdministratorState.IS_ADMIN, message = AdministrableErrorMessage.NOT_ADMIN) self.data.token_context[token_id] = sp.record(total_minted=0, total_burned=0, redeem_address=NULL_ADDRESS, is_paused=False)
def bid(self, auction_id): sp.set_type_expr(auction_id, sp.TNat) auction = self.data.auctions[auction_id] sp.verify(sp.sender!=auction.seller, message=AuctionErrorMessage.SELLER_CANNOT_BID) sp.verify(sp.amount>=auction.bid_amount+BID_STEP_THRESHOLD, message=AuctionErrorMessage.BID_AMOUNT_TOO_LOW) sp.verify(sp.now<auction.end_timestamp, message=AuctionErrorMessage.AUCTION_IS_OVER) sp.if auction.bidder != auction.seller: sp.if auction.bidder>THRESHOLD_ADDRESS: sp.send(DEFAULT_ADDRESS, auction.bid_amount)
def make(self, user, token): user = sp.set_type_expr(user, sp.TAddress) token = sp.set_type_expr(token, token_id_type) if self.config.single_asset: result = user else: result = sp.pair(user, token) if self.config.readable: return result else: return sp.pack(result)
def withdraw(self, auction_id): sp.set_type_expr(auction_id, sp.TNat) auction = self.data.auctions[auction_id] sp.verify(sp.now>auction.end_timestamp,message=AuctionErrorMessage.AUCTION_IS_ONGOING) token_contract = sp.contract(BatchTransfer.get_type(), auction.token_address, entry_point = "transfer").open_some() sp.if auction.bidder != auction.seller: sp.if auction.seller>THRESHOLD_ADDRESS: sp.send(DEFAULT_ADDRESS, auction.bid_amount)
def f_process_request(req): user = self.ledger_key.make(req.owner, req.token_id) sp.verify(self.data.token_metadata.contains(req.token_id), message = self.error_message.token_undefined()) sp.if self.data.ledger.contains(user): balance = self.data.ledger[user].balance sp.result( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = balance))
def create_auction(self, create_auction_request): sp.set_type_expr(create_auction_request, AuctionCreateRequest.get_type()) token_contract = sp.contract(BatchTransfer.get_type(), create_auction_request.token_address, entry_point = "transfer").open_some() sp.verify(create_auction_request.token_amount > 0, message=AuctionErrorMessage.TOKEN_AMOUNT_TOO_LOW) sp.verify(create_auction_request.end_timestamp >= sp.now.add_hours(MINIMAL_AUCTION_DURATION), message=AuctionErrorMessage.END_DATE_TOO_SOON) sp.verify(create_auction_request.end_timestamp <= sp.now.add_hours(MAXIMAL_AUCTION_DURATION), message=AuctionErrorMessage.END_DATE_TOO_LATE) sp.verify(create_auction_request.bid_amount >= MINIMAL_BID, message=AuctionErrorMessage.BID_AMOUNT_TOO_LOW) sp.verify(~self.data.auctions.contains(create_auction_request.auction_id), message=AuctionErrorMessage.ID_ALREADY_IN_USE) sp.transfer([BatchTransfer.item(sp.sender, [sp.record(to_=sp.self_address, token_id=create_auction_request.token_id, amount=create_auction_request.token_amount)])], sp.mutez(0), token_contract) self.data.auctions[create_auction_request.auction_id] = sp.record(token_address=create_auction_request.token_address, token_id=create_auction_request.token_id, token_amount=create_auction_request.token_amount, end_timestamp=create_auction_request.end_timestamp, seller=sp.sender, bid_amount=create_auction_request.bid_amount, bidder=sp.sender)
def balance_of(self, params): sp.set_type(params, BalanceOf.entry_point_type()) res = sp.local("responses", []) sp.set_type(res.value, BalanceOf.response_type()) sp.for req in params.requests: user = LedgerKey.make(req.owner, req.token_id) balance = self.data.ledger[user] res.value.push( sp.record( request=sp.record( owner=sp.set_type_expr(req.owner, sp.TAddress), token_id=sp.set_type_expr(req.token_id, sp.TNat)), balance=balance))
def request_helper(self, amount, job_id, parameters, oracle, waiting_request_id, target, timeout_minutes = 5): parameters = sp.set_type_expr(parameters, parameters_type) sp.verify(~ waiting_request_id.is_some(), message = "Request pending") target = sp.set_type_expr(target, sp.TContract(sp.TRecord(client_request_id = sp.TNat, result = value_type))) waiting_request_id.set(sp.some(self.data.next_request_id)) token = sp.contract(sp.TRecord(oracle = sp.TAddress, params = request_type), self.data.token, entry_point = "proxy").open_some(message = "Incompatible token interface") params = sp.record(amount = amount, target = sp.to_address(target), job_id = job_id, parameters = parameters, timeout = sp.now.add_minutes(timeout_minutes), client_request_id = self.data.next_request_id) sp.transfer(sp.record(oracle = oracle, params = params), sp.mutez(0), token) self.data.next_request_id += 1
def balance_of(self, params): # paused may mean that balances are meaningless: sp.verify( ~self.data.paused ) res = sp.local("responses", []) sp.set_type(res.value, Balance_of.response_type()) sp.for req in params.requests: user = self.ledger_key.make(req.owner, req.token_id) balance = self.data.ledger[user].balance res.value.push( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = balance))
def make_key(self, owner, operator): metakey = sp.record(owner=owner, operator=operator) metakey = sp.set_type_expr(metakey, self.inner_type()) if self.config.readable: return metakey else: return sp.pack(metakey)
def get_redeem_addresses(self, get_redeem_address_request): """As per FA2 standard, takes balance_of requests and reponds on the provided callback contract""" sp.set_type(get_redeem_address_request, RedeemAddress.get_request_type()) responses = sp.local("responses", sp.set_type_expr(sp.list([]),RedeemAddress.get_batch_type())) sp.for token_id in get_redeem_address_request.token_ids: sp.verify(self.data.token_metadata.contains(token_id), message = FA2ErrorMessage.TOKEN_UNDEFINED) responses.value.push(sp.record(token_id = token_id, address = self.data.token_context[token_id].redeem_address))
def balance_of(self, balance_of_request): """As per FA2 standard, takes balance_of requests and reponds on the provided callback contract""" sp.set_type(balance_of_request, BalanceOf.get_type()) responses = sp.local("responses", sp.set_type_expr(sp.list([]),BalanceOf.get_response_type())) sp.for request in balance_of_request.requests: sp.verify(self.data.token_metadata.contains(request.token_id), message = FA2ErrorMessage.TOKEN_UNDEFINED) responses.value.push(sp.record(request = request, balance = self.data.ledger.get(LedgerKey.make(request.owner, request.token_id),0)))
def make(self, user): user = sp.set_type_expr(user, sp.TAddress) result = user if self.config.readable: return result else: return sp.pack(result)
def get_signing_payload(batch_meta_transfer): tx_type = sp.TRecord(to_=sp.TAddress, token_id=sp.TNat, amount=sp.TNat).layout(("to_", ("token_id", "amount"))) transfer_type = sp.TRecord(from_public_key=sp.TKey, nonce=sp.TNat, txs=sp.TList(tx_type)).layout(("from_public_key", ("nonce", "txs"))) signing_payload = sp.record(from_public_key=batch_meta_transfer.from_public_key, nonce=batch_meta_transfer.nonce, txs=batch_meta_transfer.txs) return sp.set_type_expr(signing_payload, transfer_type)
def balance_of(self, params): # paused may mean that balances are meaningless: sp.verify( ~self.is_paused(), message = self.error_message.paused()) sp.set_type(params, Balance_of.entry_point_type()) def f_process_request(req): user = self.ledger_key.make(req.owner, req.token_id) sp.verify(self.data.token_metadata.contains(req.token_id), message = self.error_message.token_undefined()) sp.if self.data.ledger.contains(user): balance = self.data.ledger[user].balance sp.result( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = balance)) sp.else: sp.result( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = 0))
def initial_auction(self, batch_initial_auction): sp.set_type_expr(batch_initial_auction, BatchInitialAuction.get_type()) auction_id_runner = sp.local('auction_id_runner', batch_initial_auction.auction_id_start) sp.for token_id in batch_initial_auction.token_ids: sp.verify((~self.data.total_supply.contains(token_id)), message = FA2ErrorMessage.NOT_OWNER) sp.verify(token_id<=MAXIMAL_TOKEN_ID, message = FA2ErrorMessage.NOT_OWNER) to_user = LedgerKey.make(sp.self_address, token_id) self.data.ledger[to_user] = sp.nat(1) self.data.total_supply[token_id] = sp.nat(1) operator_user = AllowanceKey.make(sp.self_address, self.data.initial_auction_house_address, token_id) self.data.allowances[operator_user] = True auction_house = sp.contract(AuctionCreateRequest.get_type(), self.data.initial_auction_house_address, entry_point = "create_auction").open_some() auction_create_request = sp.record( auction_id=auction_id_runner.value, token_address=sp.self_address, token_id=token_id, token_amount=sp.nat(1), end_timestamp=sp.now.add_hours(INITIAL_AUCTION_DURATION), bid_amount=INITIAL_BID ) sp.set_type_expr(auction_create_request, AuctionCreateRequest.get_type()) sp.transfer(auction_create_request, sp.mutez(0), auction_house) auction_id_runner.value += 1
def make(self): def uv(s): return sp.variant(s, sp.unit) operator = ("owner_or_operator_transfer" if self.config.support_operator else "owner_transfer") v = sp.record( operator=uv(operator), receiver=uv("owner_no_hook"), sender=uv("owner_no_hook"), custom=sp.none ) v = sp.set_type_expr(v, self.get_type()) return v
def selectTeam(self, params): # sp.verify(self.data.match_active.contains(params.match_id), message = "Match either does not exists or is inacitve.") sp.verify(sp.len(params.tokens) == 5, message="Only Five Tokens are Allowed.") sp.verify(~self.data.selected_tokens.contains(sp.sender), message = "You have already staked Cards for the match.") self.data.selected_tokens[sp.sender] = sp.record(tokens=sp.set()) sp.for token_id in params.tokens: token_id = sp.set_type_expr(token_id, sp.TNat) sp.verify(self.data.ledger[sp.sender].tokens.contains( token_id), message="You can only select owned tokens.") sp.verify(~self.data.tokens_on_sale.contains( token_id), message="Cannot Play with a token on Sale. Unlist the token to continue.") self.data.tokens[token_id].inMatch = True self.data.selected_tokens[sp.sender].tokens.add(token_id)
def revoke(self, param): # Recreate the message which should have been signed. message = sp.set_type_expr(sp.none, sp.TOption(sp.TKey)) bytes = sp.pack(message) # Verify that the message is signed correctly. publicKey = self.data.publicKey.open_some() sp.verify(sp.check_signature(publicKey, param, bytes)) # Revoke the Oracle's public Key. self.data.publicKey = sp.none # Remove all entries in the Oracle's map. self.data.oracleData = sp.big_map( l={}, tkey=sp.TString, tvalue=Harbinger.OracleDataType )
def balance_of(self, balance_of_request): sp.set_type(balance_of_request, BalanceOfRequest.get_type()) responses = sp.local("responses", sp.set_type_expr(sp.list([]),BalanceOfRequest.get_response_type())) sp.for request in balance_of_request.requests: responses.value.push(sp.record(request = request, balance = self.data.ledger.get(LedgerKey.make(request.owner, request.token_id),0)))
def get_signing_payload(chain_id, self_address, nonce, signers_threshold, operator_public_keys): signing_payload = sp.record(chain_id=chain_id, self_address=self_address, nonce=nonce, signers_threshold=signers_threshold, operator_public_keys=operator_public_keys) layouted_execution_request = sp.set_type_expr(signing_payload, UpdateSignatoryRequest.get_signing_payload_type()) return layouted_execution_request
def make(self, owner, operator): r = sp.record(owner=owner, operator=operator) return sp.set_type_expr(r, self.get_type())
def item(self, from_, txs): v = sp.record(from_=from_, txs=txs) return sp.set_type_expr(v, self.get_transfer_type())
@sp.entry_point def activateMatch(self, params): sp.verify(sp.sender == self.data.administrator, message="Only Admin Can Start/End a Match.") sp.verify(self.data.matches.contains(params.match_id), message="Match Does not exist.") sp.verify(self.data.matches[params.match_id].active == False, message="Match is already Active") sp.verify(self.data.matches[params.match_id].finished == False, message="Match is finished.") sp.for match in self.data.matches.values(): sp.if match.active == True: sp.failwith("Two Matches Cannot be Active at the same time") self.data.matches[params.match_id].active = True ends = sp.set_type_expr(params.ends, sp.TTimestamp) self.data.matches[params.match_id].ends = ends self.data.matches[params.match_id].compete = True @sp.entry_point def endCompete(self, params): sp.verify(sp.sender == self.data.administrator, message="Only Admin Can Start/End a Match.") sp.verify(self.data.matches.contains(params.match_id), message="Match Does not exist.") sp.verify(self.data.matches[params.match_id].active == True, message="Match is not active") sp.verify(self.data.matches[params.match_id].finished == False, message="Match is finished.") self.data.matches[params.match_id].compete = False
def get_signing_payload(chain_id, self_address, timelock_id): removal_signing_payload = sp.record(chain_id=chain_id, self_address=self_address, timelock_id=timelock_id) layouted_removal_request = sp.set_type_expr(removal_signing_payload, RemovalRequest.get_signing_payload_type()) return layouted_removal_request
balance = self.data.ledger[user].balance sp.result( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = balance)) sp.else: sp.result( sp.record( request = sp.record( owner = sp.set_type_expr(req.owner, sp.TAddress), token_id = sp.set_type_expr(req.token_id, sp.TNat)), balance = 0)) res = sp.local("responses", params.requests.map(f_process_request)) destination = sp.set_type_expr(params.callback, sp.TContract(Balance_of.response_type())) sp.transfer(res.value, sp.mutez(0), destination) @sp.entry_point def update_operators(self, params): sp.set_type(params, sp.TList( sp.TVariant( add_operator = self.operator_param.get_type(), remove_operator = self.operator_param.get_type()))) if self.config.support_operator: sp.for update in params: with update.match_cases() as arg: with arg.match("add_operator") as upd: sp.verify((upd.owner == sp.sender) | (self.is_administrator(sp.sender))) self.operator_set.add(self.data.operators,
def make(owner, operator, token_id): return sp.set_type_expr(sp.record(owner = owner, operator = operator, token_id = token_id), AllowanceKey.get_type())
def item(from_, txs): return sp.set_type_expr(sp.record(from_ = from_, txs = txs), BatchTransfer.get_transfer_type())
def get_init_storage(self): return dict( nonce=sp.nat(0), signers_threshold= sp.set_type_expr(self.signers_threshold, sp.TNat), operator_public_keys= sp.set_type_expr(self.operator_public_keys,sp.TList(sp.TKey)) )
def make(owner, token_id): return sp.set_type_expr(sp.record(owner = owner, token_id = token_id), LedgerKey.get_type())