def revokeSchedule(self, params): sp.for p in params: schedule = self.data.schedules[p.beneficiery][p.schedule_name] assert_token_admin(schedule.token_address, sp.sender) schedule.revoked = True schedule.revokedAt = sp.some(sp.now) schedule.revokedBy = sp.some(sp.sender)
def revokeSchedules(self, beneficieries): sp.for beneficiery in beneficieries: sp.for schedule_name in self.data.schedules[beneficiery].keys(): schedule = self.data.schedules[beneficiery][schedule_name] assert_token_admin(schedule.token_address, sp.sender) schedule.revoked = True schedule.revokedAt = sp.some(sp.now) schedule.revokedBy = sp.some(sp.sender)
def InitializeExchange(self, params): token_amount = sp.as_nat(params.token_amount) candidate = params.candidate sp.verify(self.data.invariant == sp.mutez(0), message="Wrong invariant") sp.verify(self.data.totalShares == 0, message="Wrong totalShares") sp.verify(((sp.amount > sp.mutez(1)) & ( sp.amount < sp.tez(500000000))), message="Wrong amount") sp.verify(token_amount > sp.nat(10), message="Wrong tokenAmount") self.data.tokenPool = token_amount self.data.tezPool = sp.amount self.data.invariant = sp.split_tokens(self.data.tezPool, self.data.tokenPool, sp.nat(1)) self.data.shares[sp.sender] = sp.nat(1000) self.data.totalShares = sp.nat(1000) token_contract = sp.contract( sp.TRecord(account_from=sp.TAddress, destination=sp.TAddress, value=sp.TNat), address=self.data.tokenAddress, entry_point="Transfer" ).open_some() sp.transfer(sp.record(account_from=sp.sender, destination=self.data.address, value=token_amount), sp.mutez(0), token_contract) self.data.candidates[sp.sender] = candidate self.data.votes[candidate] = sp.as_nat(1000) self.data.delegated = candidate sp.set_delegate(sp.some(candidate))
def createSealedBidAuctionInstance(self, asset_id, asset_name): sp.verify(sp.sender == self.data.master_auction_contract) contract_address = sp.some(sp.create_contract( storage = sp.record(owner = sp.source, master_auction_contract = sp.to_address(sp.self), asset_id = asset_id, # deposit will get seized if participant tries to cheat deposit = 0, sealed_bids = sp.map(tkey = sp.TAddress, tvalue = sp.TBytes), # TODO: maintain revealed_participants list and only refund those # possibly split the money b/w highest bidder and owner # enforcing all participants to reveal their bids # Then there'll be no need to maintain revealed_count & first_revealed revealed_count = 0, highest_bid = sp.mutez(0), highest_bidder = sp.sender, started = sp.bool(False), first_revealed = sp.bool(False), ended = sp.bool(False), start_time = sp.now, round_time = 0), contract = self.sealed_bid)) # registerInstance c = sp.contract(sp.TRecord(asset_id = sp.TNat, contract_address = sp.TAddress), self.data.master_auction_contract, entry_point = "registerInstance").open_some() sp.transfer(sp.record(asset_id = asset_id, contract_address = contract_address.open_some()), sp.mutez(0), c)
def request_helper(self, amount, job_id, parameters, oracle, waiting_request_id, target, timeout_minutes=5): sp.verify(~waiting_request_id.is_some()) 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() 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 createDutchAuctionInstance(self, asset_id): sp.verify(sp.sender == self.data.master_auction_contract) contract_address = sp.some( sp.create_contract(storage=sp.record( owner=sp.source, master_auction_contract=self.data.master_auction_contract, asset_id=asset_id, current_price=0, reserve_price=0, started=sp.bool(False), ended=sp.bool(False), start_time=sp.now, round_time=0), contract=self.dutch)) # registerInstance c = sp.contract(sp.TRecord(asset_id=sp.TNat, contract_address=sp.TAddress), self.data.master_auction_contract, entry_point="registerInstance").open_some() sp.transfer( sp.record(asset_id=asset_id, contract_address=contract_address.open_some()), sp.mutez(0), c)
def setBuyer(self): #ensure that there already is a seller sp.verify(self.data.seller.is_some()) #ensure buyer hasnt already been set sp.verify(~self.data.buyer.is_some()) sp.verify(sp.amount == sp.mutez(self.data.price * 2)) self.data.buyer = sp.some(sp.sender)
def setSeller(self, params): #ensure seller hasn't already been set sp.verify(~self.data.seller.is_some()) #the seller sets the price and must send the price in mutez as insurance self.data.price = params.price sp.verify(sp.amount == sp.mutez(self.data.price)) self.data.seller = sp.some(sp.sender)
def addOwner(self, params): # verify the secret to ensure that # the owner of the contract calls it sp.verify(sp.blake2b(params.secret) == self.data.hashedSecret) # set the owner self.data.owner = sp.some(sp.sender)
def setExpiry(self, params): sp.set_type( params, sp.TRecord(address=sp.TAddress, seconds=sp.TNat, permit=sp.TOption(sp.TBytes))).layout( ("address", ("seconds", "permit"))) sp.verify(~self.data.paused) sp.verify(params.seconds <= self.data.max_expiry, "MAX_SECONDS_EXCEEDED") sp.verify_equal(params.address, sp.sender, message="NOT_AUTHORIZED") with sp.if_(params.permit.is_some()): some_permit = params.permit.open_some() sp.verify( self.data.permits.contains(sp.pair(params.address, some_permit)), "PERMIT_NONEXISTENT") permit_submission_timestamp = self.data.permits[sp.pair( params.address, some_permit)] with sp.if_( self.data.permit_expiries.contains( sp.pair(params.address, some_permit)) & self.data.permit_expiries[sp.pair( params.address, some_permit)].is_some()): permit_expiry = self.data.permit_expiries[sp.pair( params.address, some_permit)].open_some() sp.verify( sp.as_nat(sp.now - permit_submission_timestamp) < permit_expiry, "PERMIT_REVOKED") with sp.else_(): with sp.if_( self.data.user_expiries.contains(params.address) & self.data.user_expiries[params.address].is_some()): user_expiry = self.data.user_expiries[ params.address].open_some() sp.verify( sp.as_nat(sp.now - permit_submission_timestamp) < user_expiry, "PERMIT_REVOKED") with sp.else_(): sp.verify( sp.as_nat(sp.now - permit_submission_timestamp) < self.data.default_expiry, "PERMIT_REVOKED") self.data.permit_expiries[sp.pair( params.address, some_permit)] = sp.some(params.seconds) self.data.user_expiries[params.address] = sp.some(params.seconds)
def configureAuction(self, params): sp.set_type(params, AUCTION_PARAMS_TYPE) sp.verify(sp.source == self.data.owner, "User Not Authorized") sp.verify(~self.data.in_progress, "Auction in progress") self.data.current_price = params.opening_price self.data.reserve_price = params.reserve_price self.data.start_time = params.start_time self.data.round_time = params.round_time self.data.ticket = sp.some(params.ticket)
def createNft(self, metadata): sp.set_type(metadata, METADATA_TYPE) sp.verify(sp.sender == self.data.admin) my_ticket = sp.ticket(self.data.current_id, 1) current_id = self.data.current_id new_map = sp.update_map(self.data.tickets, current_id, sp.some(my_ticket)) self.data.tickets = new_map self.data.token_metadata[current_id] = sp.pair(current_id, metadata) self.data.current_id = current_id + 1
def addOwner(self, params): sp.set_type(params.ConfirmedCase,sp.TString) # verify the secret to ensure that # the owner of the contract calls it sp.verify(sp.blake2b(params.secret) == self.data.hashedSecret) sp.verify(params.ConfirmedCase=="No",message="Please isolate yourself and stay strong") # set the owner self.data.owner = sp.some(sp.sender)
def receiveNft(self, nft): sp.set_type(nft, sp.TTicket(sp.TNat)) ticket_data, ticket_next = sp.read_ticket(nft) qty = sp.compute(sp.snd(sp.snd(ticket_data))) originator = sp.compute(sp.fst(ticket_data)) id = sp.compute(sp.fst(sp.snd(ticket_data))) sp.verify(qty == 1, "Only send 1 Nft to this entrypoint") sp.verify(sp.source == self.data.admin, "Ticket needs to be sent by wallet admin") current_id = self.data.current_id new_map = sp.update_map(self.data.tickets, current_id, sp.some(ticket_next)) self.data.tickets = new_map self.data.current_id = current_id + 1
def __init__( self, publicKey=sp.some( sp.key("sppk7bkCcE4TZwnqqR7JAKJBybJ2XTCbKZu11ESTvvZQYtv3HGiiffN")), initialData=sp.big_map( l={ "XTZ-USD": (sp.timestamp(0), (sp.timestamp(0), (0, (0, (0, (0, 0)))))) }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ): self.init( publicKey=publicKey, oracleData=initialData )
def setExpiry(self, params): sp.set_type(params, sp.TPair(sp.TAddress, sp.TPair(sp.TNat, sp.TOption( sp.TBytes)))) address = sp.fst(params) new_expiry = sp.fst(sp.snd(params)) possible_bytes = sp.snd(sp.snd(params)) sp.verify(new_expiry <= self.data.permit_data.max_expiry, self.error_message.expiry_exceeds_max()) sp.verify_equal(address, sp.sender, message=self.error_message.user_unauthorized()) sp.if possible_bytes.is_some(): some_permit = possible_bytes.open_some() permit_key = sp.pair(address, some_permit) sp.verify(self.data.permit_data.permits.contains( permit_key), self.error_message.permit_nonexistent()) permit_submission_timestamp = self.data.permit_data.permits[permit_key] effective_expiry = self.getEffectiveExpiry(permit_key) sp.verify(sp.as_nat(sp.now - permit_submission_timestamp) < effective_expiry, self.error_message.permit_revoked()) self.data.permit_data.permit_expiries[permit_key] = sp.some(new_expiry)
def createEnglishAuctionInstance(self, asset_id, asset_name): contract_address = sp.some(sp.create_contract( storage = sp.record(owner = sp.sender, master_auction_contract = sp.to_address(sp.self), asset_id = asset_id, current_bid = sp.mutez(0), min_increase = 0, highest_bidder = sp.sender, started = sp.bool(False), ended = sp.bool(False), start_time = sp.now, wait_time = 0), contract = self.english)) self.data.instances_map[asset_id] = sp.record( asset_name = asset_name, auction_type = "english", owner = sp.sender, contract_address = contract_address.open_some(), is_available = sp.bool(True))
def __init__( self, publicKey=sp.some( sp.key("sppk7bkCcE4TZwnqqR7JAKJBybJ2XTCbKZu11ESTvvZQYtv3HGiiffN")), initialData=sp.big_map( l={ "XTZ-USD": (sp.timestamp(0), (sp.timestamp(0), (0, (0, (0, (0, 0)))))) }, tkey=sp.TString, tvalue=Harbinger.OracleDataType ) ): self.exception_optimization_level = "Unit" self.add_flag("no_comment") self.init( publicKey=publicKey, oracleData=initialData )
def test(): scenario = sp.test_scenario() scenario.h1("Minimal") deployer = sp.address("tz1PCVSQfsHmrKRgCdLhrN8Yanb5mwEL8rxu") deployer2 = sp.test_account("hello") user1 = sp.test_account("Nikhil") user2 = sp.test_account("Alice") c1 = BettingPool(deployer) c2 = CycleOracle(sp.address("tz1PCVSQfsHmrKRgCdLhrN8Yanb5mwEL8rxu")) scenario += c1 scenario += c2 scenario += c1.depositFunds().run(sender=deployer,amount=sp.tez(20)) scenario.register(c1.updateBaker(sp.some(sp.key_hash('tz1NRTQeqcuwybgrZfJavBY3of83u8uLpFBj'))).run(sender=deployer)) scenario += c1.updateOracle(c2.address).run(sender=deployer) for i in range(7): user = sp.test_account(str(i)) scenario += c1.placeBet(betType=5,seed=i).run(sender=user,amount=sp.tez(5),now=1000+i) scenario += c2.feedData(cycleNumber=274).run(sender=deployer) scenario += c1.completeBet(betType=5,betId=268).run(now=11000)
def createEnglishAuctionInstance(self, asset_id): sp.verify((sp.sender == self.data.master_auction_contract), "only master auction contract can create instance") contract_address = sp.some(sp.create_contract( storage = sp.record(owner = sp.source, master_auction_contract = self.data.master_auction_contract, asset_id = asset_id, current_bid = sp.mutez(0), min_increase = 0, highest_bidder = self.data.master_auction_contract, started = sp.bool(False), first_bid_placed = sp.bool(False), ended = sp.bool(False), start_time = sp.now, round_time = 0), contract = self.english)) # registerInstance c = sp.contract(sp.TRecord(asset_id = sp.TNat, contract_address = sp.TAddress), self.data.master_auction_contract, entry_point = "registerInstance").open_some() sp.transfer(sp.record(asset_id = asset_id, contract_address = contract_address.open_some()), sp.mutez(0), c)
class myContract(sp.Contract): def __init__(self, owner, max_collect_percent): self.init( owner = owner, max_collect_percent = max_collect_percent, next_collect = sp.none ) @sp.entry_point def deposit(self, max_collect_percent): sp.verify(sp.amount >= sp.tez(100), 'Deposit must be at least 100 tez.') sp.verify(max_collect_percent >= 1, 'Maximum withdrawal amount must be at least 1 percent of balance.') self.data.max_collect_percent = max_collect_percent @sp.entry_point def collect(self, amount): sp.verify(sp.sender == self.data.owner, 'Only owner can collect.') max_collect = sp.compute(sp.split_tokens(sp.balance,sp.nat(100),self.data.max_collect_percent)) sp.verify(amount <= max_collect, 'Withdrawal amount exceeds allowed limit.') sp.if (self.data.next_collect.is_some()): sp.verify(sp.some(sp.now) > self.data.next_collect, 'Withdrawal frequency exceeds limit.') self.data.next_collect = sp.some(sp.now.add_seconds(120)) sp.send(self.data.owner, amount)
def receiveAnswer(self, params): sp.set_type(params, rType) self.data.answer = sp.some( sp.record(jurisdiction=params.jurisdiction, companyNumber=params.companyNumber, companyName=params.companyName))
def test(): scenario = sp.test_scenario() scenario.h1("FA1.2 template - Fungible assets") scenario.table_of_contents() # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") carlos = sp.test_account("Carlos") # Let's display the accounts: scenario.h1("Accounts") scenario.show([admin, alice, bob, carlos]) scenario.h1("Contract") c1 = FA12(admin.address) scenario.h1("Entry points") scenario += c1 scenario.h2("Admin mints a few coins") scenario += c1.mint(address=alice.address, value=12).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 18) scenario.h2("Alice transfers to Bob") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice) scenario.verify(c1.data.balances[alice.address].balance == 14) scenario.h2( "Bob tries to transfer from Alice but he doesn't have her approval" ) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob, valid=False) scenario.h2("Alice approves Bob and Bob transfers") scenario += c1.approve(spender=bob.address, value=5).run(sender=alice) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob) scenario.h2("Bob tries to over-transfer from Alice") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob, valid=False) scenario.h2("Admin burns Bob token") scenario += c1.burn(address=bob.address, value=1).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 10) scenario.h2("Alice tries to burn Bob token") scenario += c1.burn(address=bob.address, value=1).run(sender=alice, valid=False) scenario.h2( "Admin pauses the contract and Alice cannot transfer anymore") scenario += c1.setPause(True).run(sender=admin) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice, valid=False) scenario.verify(c1.data.balances[alice.address].balance == 10) scenario.h2("Admin transfers while on pause") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run(sender=admin) scenario.h2("Admin unpauses the contract and transfers are allowed") scenario += c1.setPause(False).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 9) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run(sender=alice) scenario.verify(c1.data.totalSupply == 17) scenario.verify(c1.data.balances[alice.address].balance == 8) scenario.verify(c1.data.balances[bob.address].balance == 9) scenario.h2("Permit Submissions") scenario += c1.mint(address=carlos.address, value=10).run(sender=admin) scenario.verify(c1.data.balances[carlos.address].balance == 10) # add permit for transfer of 10 from carlos to bob. alice submits with correct info and also calls. params_bytes_1 = sp.pack( sp.pair(carlos.address, sp.pair(bob.address, 10))) params_bytes_2 = sp.pack( sp.pair(bob.address, sp.pair(carlos.address, 10))) params_hash_1 = sp.blake2b(params_bytes_1) params_hash_2 = sp.blake2b(params_bytes_2) unsigned_1 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(0, params_hash_1))) signature_1 = sp.make_signature(secret_key=carlos.secret_key, message=unsigned_1, message_format="Raw") unsigned_2 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(1, params_hash_2))) signature_2 = sp.make_signature(secret_key=bob.secret_key, message=unsigned_2, message_format="Raw") scenario += c1.permit([ sp.pair(carlos.public_key, sp.pair(signature_1, params_hash_1)), sp.pair(bob.public_key, sp.pair(signature_2, params_hash_2)) ]).run(sender=alice, now=sp.timestamp(1571761674), chain_id=sp.chain_id_cst("0x9caecab9")) scenario.verify(c1.data.counter == 2) scenario.verify_equal( c1.data.permits[(sp.pair(carlos.address, params_hash_1))], sp.timestamp(1571761674)) scenario.verify_equal( c1.data.permits[(sp.pair(bob.address, params_hash_2))], sp.timestamp(1571761674)) scenario.h2("Execute transfer using permit") scenario += c1.transfer(from_=carlos.address, to_=bob.address, value=10).run(sender=bob, now=sp.timestamp(1571761674)) scenario.verify(c1.data.balances[carlos.address].balance == 0) scenario.verify(c1.data.balances[bob.address].balance == 19) # Permit deleted scenario.verify( ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1))) scenario += c1.transfer(from_=bob.address, to_=carlos.address, value=10).run(sender=carlos, now=sp.timestamp(1571761674)) scenario.verify(c1.data.balances[carlos.address].balance == 10) scenario.verify(c1.data.balances[bob.address].balance == 9) # Permit deleted scenario.verify( ~c1.data.permits.contains(sp.pair(bob.address, params_hash_2))) # Set Expiry to 0 and try to execute transfer at time less than submission_time + default_expiry, expect invalid transfer scenario.h2("Expired Permit") unsigned_3 = sp.pack( sp.pair(sp.pair(sp.chain_id_cst("0x9caecab9"), c1.address), sp.pair(2, params_hash_1))) signature_3 = sp.make_signature(secret_key=carlos.secret_key, message=unsigned_3, message_format="Raw") scenario += c1.permit([ sp.pair(carlos.public_key, sp.pair(signature_3, params_hash_1)) ]).run(sender=alice, now=sp.timestamp(1571761674), chain_id=sp.chain_id_cst("0x9caecab9")) scenario.verify(c1.data.counter == 3) scenario.verify_equal( c1.data.permits[(sp.pair(carlos.address, params_hash_1))], sp.timestamp(1571761674)) scenario += c1.setExpiry(address=carlos.address, seconds=0, permit=sp.some(params_hash_1)).run( sender=carlos, now=sp.timestamp(1571761674)) scenario.verify(c1.data.permit_expiries[sp.pair( carlos.address, params_hash_1)].open_some() == 0) scenario += c1.transfer(from_=carlos.address, to_=bob.address, value=10).run( sender=bob, now=sp.timestamp(1571761680), valid=False) # Uses later time stamp scenario.h2("Delete Expired Permit") scenario += c1.delete_permits([sp.pair(carlos.address, params_hash_1) ]).run(now=sp.timestamp(1571761680)) scenario.verify(~c1.data.permit_expiries.contains( sp.pair(carlos.address, params_hash_1))) scenario.verify( ~c1.data.permits.contains(sp.pair(carlos.address, params_hash_1))) scenario.h1("Views") scenario.h2("Balance") view_balance = Viewer(sp.TNat) scenario += view_balance scenario += c1.getBalance(arg=sp.record(owner=alice.address), target=view_balance.address) scenario.verify_equal(view_balance.data.last, sp.some(8)) scenario.h2("Administrator") view_administrator = Viewer(sp.TAddress) scenario += view_administrator scenario += c1.getAdministrator(target=view_administrator.address) scenario.verify_equal(view_administrator.data.last, sp.some(admin.address)) scenario.h2("Total Supply") view_totalSupply = Viewer(sp.TNat) scenario += view_totalSupply scenario += c1.getTotalSupply(target=view_totalSupply.address) scenario.verify_equal(view_totalSupply.data.last, sp.some(27)) scenario.h2("Allowance") view_allowance = Viewer(sp.TNat) scenario += view_allowance scenario += c1.getAllowance(arg=sp.record(owner=alice.address, spender=bob.address), target=view_allowance.address) scenario.verify_equal(view_allowance.data.last, sp.some(1)) scenario.h2("Counter") view_counter = Viewer(sp.TNat) scenario += view_counter scenario += c1.getCounter(target=view_counter.address) scenario.verify_equal(view_counter.data.last, sp.some(3)) scenario.h2("Default Expiry") view_defaultExpiry = Viewer(sp.TNat) scenario += view_defaultExpiry scenario += c1.getDefaultExpiry(target=view_defaultExpiry.address) scenario.verify_equal(view_defaultExpiry.data.last, sp.some(50000))
def test(): scenario = sp.test_scenario() # DP: Define party in a way to be used by the StateChannel def party(address, pk, bond, looserClaim): return sp.record(hasBond = False, pk = pk, bond = bond, address = address, looserClaim = looserClaim) alice = sp.test_account("Alice") bob = sp.test_account("Bob") scenario.table_of_contents() scenario.h2("Parties") scenario.p("We start with two accounts, Alice the customer, and Bob the merchant:") scenario.show([alice, bob]) scenario.p("We derive two parties for Alice and Bob to set up a payment channel.") party1 = party(alice.address, alice.public_key, sp.tez(100), sp.tez(0)) party2 = party(bob.address , bob.public_key , sp.tez(0), sp.tez(0)) scenario.show([party1, party2]) scenario.p("These fields represent:") scenario.show(sp.record(hasBond = "determination if a bond has been paid by the party", pk = "public key of the party", bond = "bond posted by the party", address = "address of the party", looserClaim = "claim received in case of renounce by the party"), stripStrings = True) scenario.h2("PaymentChannel Contract") scenario.p("They agree setup a single funded payment channel, with the customer putting in 100 tez.") baseGame = PayContract(custBal = sp.tez(100), merchBal = sp.tez(0)) scenario += baseGame scenario.h2("On-chain installment") scenario.h3("First the payment channel contract") scenario.p('A contract StateChannel("1234", party1, party2, baseGame) is defined on the blockchain where "1234" is a unique id for both parties party1 and party2 (it has never been used for any of them).') c1 = StateChannel("1234", party1, party2, baseGame, no_alternation_moves = ['close']) c1.title = ("On-chain interaction") scenario += c1 scenario.h3("And then the bonds") scenario.p("Both parties send their bonds.") scenario += c1.channelSetBond(party = 1).run(amount=sp.tez(100)) scenario += c1.channelSetBond(party = 2).run(amount=sp.tez(0)) scenario.h2("Off-chain payments") scenario.p("They're now ready to interact off-chain.") # DP: cAlice and cBob are instances of the StateChannel that alice and bob can use to create and sign messages with cAlice = StateChannel("1234", party1, party2, baseGame, no_checks = [1], no_alternation_moves = ['close']) cAlice.title = ("Alice private off-chain contract") cAlice.execMessageClass = "execMessageAlice" scenario += cAlice scenario += cAlice.channelSetBond(party = 1).run(amount=sp.tez(100)) scenario += cAlice.channelSetBond(party = 2).run(amount=sp.tez(0)) # Do the same setup for bob's version of the StateChannel cBob = StateChannel("1234", party1, party2, baseGame, no_checks = [2], no_alternation_moves = ['close']) cBob.title = ("Bob private off-chain contract") scenario += cBob cBob.execMessageClass = "execMessageBob" scenario += cBob.channelSetBond(party = 1).run(amount=sp.tez(100)) scenario += cBob.channelSetBond(party = 2).run(amount=sp.tez(0)) def aliceSignsState(): scenario.p("Alice signs the current state.") result = sp.make_signature(alice.secret_key, sp.pack(sp.record(id = c1.data.id, name = "state", seq = cAlice.data.seq, state = cAlice.data.baseState))) result = scenario.compute(result) scenario.show(sp.record(seq = cAlice.data.seq, sig = result)) return result def bobSignsState(): scenario.p("Bob signs the current state.") result = sp.make_signature(bob.secret_key, sp.pack(sp.record(id = c1.data.id, name = "state", seq = cBob.data.seq, state = cBob.data.baseState))) result = scenario.compute(result) scenario.show(sp.record(seq = cBob.data.seq, sig = result)) return result scenario.h3("Payments between Alice (customer) and Bob (merchant)") scenario.h4("Alice sends Bobn5 tez") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 1, amount = sp.tez(5)), sig = sp.none) scenario.p("Alice sends data to Bob") sig1 = scenario.compute(aliceSignsState()) scenario.show(sig1) # DP: Update state on merchant's side scenario += cBob .pay_merch(party = 1, sub = sp.record(payNum = 1, amount = sp.tez(5)), sig = sp.some(sig1)) scenario.h4("Alice sends Bob a second payment of 25 tez") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 2, amount = sp.tez(25)), sig = sp.none) sig2 = scenario.compute(aliceSignsState()) scenario.show(sig2) # DP: Update state on merchant's side scenario += cBob .pay_merch(party = 1, sub = sp.record(payNum = 2, amount = sp.tez(25)), sig = sp.some(sig2)) scenario.h4("Bob sends Alice a payment of 3 tez") scenario += cBob.pay_cust(party = 2, sub = sp.record(payNum = 3, amount = sp.tez(3)), sig = sp.none) sig3 = scenario.compute(bobSignsState()) scenario.show(sig3) # DP: Update state on customer's side scenario += cAlice .pay_cust(party = 2, sub = sp.record(payNum = 3, amount = sp.tez(3)), sig = sp.some(sig3)) scenario.h3("Payments which should fail") scenario.h4("Alice attempts to double spend (overriding a previous payment)") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 3, amount = sp.tez(8)), sig = sp.none).run(valid=False) scenario.h4("Alice attempts to spend more than her channel balance") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(80)), sig = sp.none).run(valid=False) scenario.h4("Alice attempts a negative payment") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(-10)), sig = sp.none).run(valid=False) scenario.h4("Bob attempts to forge a customer's payment with a bad signature") scenario += cBob .pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(25)), sig = sp.some(sig2)).run(valid=False) scenario.h2("Back On-chain") scenario += c1.channelNewState(sig1 = aliceSignsState(), sig2 = bobSignsState(), msg = sp.record(seq = cBob.data.seq, state = cAlice.data.baseState)) scenario.h3("Alice pays Bob on-chain") scenario += cAlice.pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(33)), sig = sp.none) scenario += c1 .pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(33)), sig = aliceSignsState()) scenario += cBob .pay_merch(party = 1, sub = sp.record(payNum = 4, amount = sp.tez(33)), sig = sp.some(aliceSignsState())) scenario.h3("Bob pays Alice on-chain") scenario += cBob .pay_cust(party = 2, sub = sp.record(payNum = 5, amount = sp.tez(25)), sig = sp.none) scenario += c1 .pay_cust(party = 2, sub = sp.record(payNum = 5, amount = sp.tez(25)), sig = bobSignsState()) scenario += cAlice.pay_cust(party = 2, sub = sp.record(payNum = 5, amount = sp.tez(25)), sig = sp.some(bobSignsState())) # scenario.h3("Bob closes channel on-chain") # scenario += cBob .close(party=2, sig = sp.none) # scenario += c1 .close(party=2, sig = bobSignsState()) scenario.h3("Alice closes channel on-chain") scenario += cAlice .close(party=1, sig = sp.none) scenario += c1 .close(party=1, sig = aliceSignsState()) scenario.table_of_contents()
def increment(self, params): sp.verify(params.value <= 10, 'Increment too large') sp.verify(self.data.last_caller != sp.some(sp.sender), 'Subsequent calls must be from different addresses') self.data.counter += params.value self.data.last_caller = sp.some(sp.sender)
def hasZombieInRoomNo(self, roomNumber): result = sp.some(self.data.rooms[roomNumber]) self.data.gameInfo = sp.some(result)
sp.result(self.data.oracleData[assetCode]) ##################################################################### # Tests ##################################################################### # Only run tests if this file is main. if __name__ == "__main__": ##################################################################### # Test Helpers ##################################################################### # Default Oracle Contract Keys testAccount = sp.test_account("Test1") testAccountPublicKey = sp.some(testAccount.public_key) testAccountSecretKey = testAccount.secret_key # Initial data for the oracle initialOracleData = ( sp.timestamp(0), ( sp.timestamp(0), ( 0, ( 0, ( 0, ( 0,
def set_baker(self, params): sp.verify((sp.sender == self.data.manager)) sp.set_delegate(sp.some(params))
def target(self, params): self.data.last = sp.some(params)
def test(): scenario = sp.test_scenario() scenario.h1("FA1.2 template - Fungible assets") scenario.table_of_contents() # sp.test_account generates ED25519 key-pairs deterministically: admin = sp.test_account("Administrator") alice = sp.test_account("Alice") bob = sp.test_account("Robert") # Let's display the accounts: scenario.h1("Accounts") scenario.show([admin, alice, bob]) scenario.h1("Contract") c1 = FA12(admin.address) scenario.h1("Entry points") scenario += c1 scenario.h2("Admin mints a few coins") scenario += c1.mint(address=alice.address, value=12).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario += c1.mint(address=alice.address, value=3).run(sender=admin) scenario.h2("Alice transfers to Bob") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice) scenario.verify(c1.data.balances[alice.address].balance == 14) scenario.h2( "Bob tries to transfer from Alice but he doesn't have her approval") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob, valid=False) scenario.h2("Alice approves Bob and Bob transfers") scenario += c1.approve(spender=bob.address, value=5).run(sender=alice) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob) scenario.h2("Bob tries to over-transfer from Alice") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=bob, valid=False) scenario.h2("Admin burns Bob token") scenario += c1.burn(address=bob.address, value=1).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 10) scenario.h2("Alice tries to burn Bob token") scenario += c1.burn(address=bob.address, value=1).run(sender=alice, valid=False) scenario.h2( "Admin pauses the contract and Alice cannot transfer anymore") scenario += c1.setPause(True).run(sender=admin) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=4).run(sender=alice, valid=False) scenario.verify(c1.data.balances[alice.address].balance == 10) scenario.h2("Admin transfers while on pause") scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run(sender=admin) scenario.h2("Admin unpauses the contract and transferts are allowed") scenario += c1.setPause(False).run(sender=admin) scenario.verify(c1.data.balances[alice.address].balance == 9) scenario += c1.transfer(from_=alice.address, to_=bob.address, value=1).run(sender=alice) scenario.verify(c1.data.totalSupply == 17) scenario.verify(c1.data.balances[alice.address].balance == 8) scenario.verify(c1.data.balances[bob.address].balance == 9) scenario.h1("Views") scenario.h2("Balance") view_balance = Viewer(sp.TNat) scenario += view_balance scenario += c1.getBalance((alice.address, view_balance.typed)) scenario.verify_equal(view_balance.data.last, sp.some(8)) scenario.h2("Administrator") view_administrator = Viewer(sp.TAddress) scenario += view_administrator scenario += c1.getAdministrator((sp.unit, view_administrator.typed)) scenario.verify_equal(view_administrator.data.last, sp.some(admin.address)) scenario.h2("Total Supply") view_totalSupply = Viewer(sp.TNat) scenario += view_totalSupply scenario += c1.getTotalSupply((sp.unit, view_totalSupply.typed)) scenario.verify_equal(view_totalSupply.data.last, sp.some(17)) scenario.h2("Allowance") view_allowance = Viewer(sp.TNat) scenario += view_allowance scenario += c1.getAllowance((sp.record(owner=alice.address, spender=bob.address), view_allowance.typed)) scenario.verify_equal(view_allowance.data.last, sp.some(1))