Esempio n. 1
0
 def mutualClose(self, params):
     sp.verify(self.data.status == OPEN)
     # Check customer signature
     sp.verify(sp.check_signature(self.data.custPk,
                                  params.custSig,
                                  sp.pack(sp.record(
                                          chanID = self.data.chanID,
                                          custAddr = self.data.custAddr,
                                          merchAddr = self.data.merchAddr,
                                          custBal = params.custBal,
                                          merchBal = params.merchBal)
                                         )
                                 ))
     # Check merchant signature
     sp.verify(sp.check_signature(self.data.merchPk,
                                  params.merchSig,
                                  sp.pack(sp.record(
                                          chanID = self.data.chanID,
                                          custAddr = self.data.custAddr,
                                          merchAddr = self.data.merchAddr,
                                          custBal = params.custBal,
                                          merchBal = params.merchBal)
                                         )
                                 ))
     self.data.custBal = params.custBal
     self.data.merchBal = params.merchBal
     sp.send(self.data.custAddr, self.data.custBal)
     sp.send(self.data.merchAddr, self.data.merchBal)
     self.data.custBal = sp.tez(0)
     self.data.merchBal = sp.tez(0)
     self.data.status = CLOSED
Esempio n. 2
0
 def permit(self, params):
     sp.set_type(
         params,
         sp.TList(sp.TPair(sp.TKey, sp.TPair(sp.TSignature, sp.TBytes))))
     sp.verify(~self.data.paused)
     with sp.for_('permit', params) as permit:
         params_hash = sp.snd(sp.snd(permit))
         unsigned = sp.pack(
             sp.pair(sp.pair(sp.chain_id, sp.self_address),
                     sp.pair(self.data.counter, params_hash)))
         pk_address = sp.to_address(
             sp.implicit_account(sp.hash_key(sp.fst(permit))))
         permit_key = sp.pair(pk_address, params_hash)
         permit_exists = self.data.permits.contains(permit_key)
         effective_expiry = self.getEffectiveExpiry(
             sp.pair(pk_address, params_hash))
         permit_submission_timestamp = self.data.permits[permit_key]
         sp.verify(
             ~(permit_exists &
               (sp.as_nat(sp.now - permit_submission_timestamp) <
                effective_expiry)), sp.pair("DUP_PERMIT", params_hash))
         sp.verify(
             sp.check_signature(sp.fst(permit), sp.fst(sp.snd(permit)),
                                unsigned), sp.pair("MISSIGNED", unsigned))
         self.data.permits[sp.pair(pk_address, params_hash)] = sp.now
         self.data.counter = self.data.counter + 1
Esempio n. 3
0
    def update(self, params):
        # If there is no value for the public key, the oracle is revoked. Ignore updates.
        sp.verify(self.data.publicKey.is_some(), "revoked")

        # Iterate over assets in the input map.
        keyValueList = params.items()
        sp.for assetData in keyValueList:
            # Extract asset names, signatures, and the new data.
            assetName = assetData.key
            signature = sp.compute(sp.fst(assetData.value))
            newData = sp.compute(sp.snd(assetData.value))

            # Verify Oracle is tracking this asset.
            sp.if self.data.oracleData.contains(assetName):
                # Verify start timestamp is newer than the last update.
                oldData = sp.compute(self.data.oracleData[assetName])
                oldStartTime = sp.compute(sp.fst(oldData))
                newStartTime = sp.compute(sp.fst(newData))    
                sp.if newStartTime > oldStartTime:                
                    # Verify signature.
                    bytes = sp.pack((assetName, newData))
                    sp.verify(
                        sp.check_signature(
                            self.data.publicKey.open_some(), signature, bytes
                        ),
                        "bad sig"
                    )

                    # Replace the data.
                    self.data.oracleData[assetName] = newData
Esempio n. 4
0
    def meta_transfer(self, params):
        sp.verify(sp.sender == self.data.administrator)
        sp.set_type(params, BatchMetaTransfer.get_type())

        sp.for meta_transfer in params:
            source_account_key_hash = sp.hash_key(
                meta_transfer.from_public_key)
            source_account = sp.to_address(
                sp.implicit_account(source_account_key_hash))

            sp.verify(self.data.nonces.get(
                source_account, 0)+1 == meta_transfer.nonce)

            packed_data = sp.pack(
                BatchMetaTransfer.get_signing_payload(meta_transfer))

            sp.verify(sp.check_signature(meta_transfer.from_public_key,
                                         meta_transfer.signature, packed_data), message=ErrorMessage.invalid_signature())

            self.data.nonces[source_account] = meta_transfer.nonce

            sp.for tx in meta_transfer.txs:
                from_user = LedgerKey.make(source_account, tx.token_id)
                to_user = LedgerKey.make(tx.to_, tx.token_id)
                sp.verify(tx.amount > 0,
                          message=ErrorMessage.transfer_of_zero())
                sp.verify(self.data.ledger[from_user] >= tx.amount,
                          message=ErrorMessage.insufficient_balance())
                self.data.ledger[from_user] = sp.as_nat(
                    self.data.ledger[from_user] - tx.amount)
                self.data.ledger[to_user] = self.data.ledger.get(
                    to_user, 0) + tx.amount

                sp.if self.data.ledger[from_user] == 0:
                    del self.data.ledger[from_user]
Esempio n. 5
0
def channelRenounce(self, params):
    sp.verify(self.data.active)
    self.data.active = False
    sp.
    if params.party == 1:
        if 1 not in self.no_checks:
            sig = params.sig.open_some() if self.no_checks else params.sig
            sp.verify(
                sp.check_signature(self.data.party1.pk, sig, sp.pack(sp.record(id=self.data.id, name="renounce"))))
        sp.send(self.data.party2.address, self.data.party1.bond + self.data.party2.bond - self.data.party1.looserClaim)
        sp.send(self.data.party1.address, self.data.party1.looserClaim)
    sp. else:
    if 2 not in self.no_checks:
        sig = params.sig.open_some() if self.no_checks else params.sig
        sp.verify(sp.check_signature(self.data.party2.pk, sig, sp.pack(sp.record(id=self.data.id, name="renounce"))))
    sp.send(self.data.party1.address, self.data.party1.bond + self.data.party2.bond - self.data.party2.looserClaim)
    sp.send(self.data.party2.address, self.data.party2.looserClaim)
 def update_signatory(self, update_signatory_request):
     sp.set_type(update_signatory_request, UpdateSignatoryRequest.get_type())
     signing_payload = UpdateSignatoryRequest.get_signing_payload(sp.chain_id, sp.self_address, self.data.nonce+sp.nat(1), update_signatory_request.signers_threshold, update_signatory_request.operator_public_keys )
     
     valid_signatures_counter = sp.local('valid_signatures_counter', sp.nat(0))
     sp.for operator_public_key in self.data.operator_public_keys:
         operator_hash_key = sp.hash_key(operator_public_key)
         sp.if update_signatory_request.signatures.contains(operator_hash_key) & sp.check_signature(operator_public_key, update_signatory_request.signatures[operator_hash_key], sp.pack(signing_payload)):
             valid_signatures_counter.value += 1
 def execute(self, execution_request):
     sp.set_type(execution_request, ExecutionRequest.get_type())
     signing_payload = ExecutionRequest.get_signing_payload(sp.chain_id, sp.self_address, self.data.nonce+sp.nat(1), execution_request.execution_payload)
     
     valid_signatures_counter = sp.local('valid_signatures_counter', sp.nat(0))
     sp.for operator_public_key in self.data.operator_public_keys:
         operator_hash_key = sp.hash_key(operator_public_key)
         sp.if execution_request.signatures.contains(operator_hash_key) & sp.check_signature(operator_public_key, execution_request.signatures[operator_hash_key], sp.pack(signing_payload)):
             valid_signatures_counter.value += 1
Esempio n. 8
0
 def changeQuote(self, params):
     thingToSign = sp.pack(
         sp.record(o=params.newOwner, n=params.newQuote, c=self.data.nonce))
     sp.verify(
         sp.check_signature(params.newOwner, params.userSignature,
                            thingToSign))
     self.data.currentQuote = params.newQuote
     self.data.owner = params.newOwner
     self.data.nonce = self.data.nonce + 1
Esempio n. 9
0
 def setCurrentValue(self, params):
     # We will also need Michelson SELF and CHAIN_ID to avoid all replay attacks:
     thingToSign = sp.pack(
         sp.record(o=self.data.currentValue,
                   n=params.newValue,
                   c=self.data.counter))
     sp.verify(
         sp.check_signature(self.data.bossPublicKey, params.userSignature,
                            thingToSign))
     self.data.currentValue = params.newValue
     self.data.counter = self.data.counter + 1
Esempio n. 10
0
    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
        )
Esempio n. 11
0
 def permit(self, params):
     sp.set_type(params, sp.TList(
         sp.TPair(sp.TKey, sp.TPair(sp.TSignature, sp.TBytes))))
     sp.for permit in params:
         public_key = sp.fst(permit)
         signature = sp.fst(sp.snd(permit))
         params_hash = sp.snd(sp.snd(permit))
         #unsigned = sp.blake2b(mi.operator("SELF; ADDRESS; CHAIN_ID; PAIR; PAIR; PACK", [sp.TPair(sp.TNat, sp.TBytes)], [sp.TBytes])(sp.pair(self.data.permit_data.counter, params_hash)))
         unsigned = sp.pack(sp.pair(sp.pair(sp.chain_id, sp.self_address), sp.pair(
             self.data.permit_data.counter, params_hash)))
         pk_address = sp.to_address(
             sp.implicit_account(sp.hash_key(public_key)))
         permit_key = sp.pair(pk_address, params_hash)
         permit_exists = self.data.permit_data.permits.contains(permit_key)
         permit_submission_timestamp = self.data.permit_data.permits[permit_key]
         effective_expiry = self.getEffectiveExpiry(permit_key)
         sp.verify(~ (permit_exists & (sp.as_nat(sp.now - permit_submission_timestamp) < effective_expiry)),
             sp.pair(self.error_message.duplicate_permit(), params_hash))
         sp.verify(sp.check_signature(public_key, signature, unsigned), sp.pair(self.error_message.permit_missigned(), unsigned))
         self.data.permit_data.permits[permit_key] = sp.now
         self.data.permit_data.counter = self.data.permit_data.counter + 1
Esempio n. 12
0
def test():
    c = myContract()
    alice = sp.test_account('Alice')
   
    scenario = sp.test_scenario()
    scenario += c

    scenario.show(alice)

    c.new_user().run(sender = alice.address)
    c.new_user().run(sender = alice.address, valid = False)

    secret = 'This is my secret.'
    message = sp.sha256(sp.sha256(sp.pack(secret)))
    sig = sp.make_signature(alice.secret_key, message, message_format = 'Raw')
    scenario.show(sig)

    check = sp.check_signature(alice.public_key, sig, message)
    scenario.show(check)

    c.add_record(message = message, sig = sig).run(sender = alice.address)
    c.add_record(message = message, sig = sig).run(sender = alice.address, valid = False)

    bob = sp.test_account('Bob')
    secret = '[{a:b, c:d},{e:f}]'
    message = sp.sha256(sp.sha256(sp.pack(secret)))
    sig = sp.make_signature(bob.secret_key, message, message_format = 'Raw')
    
    c.add_record(message = message, sig = sig).run(sender = bob.address, valid = False)
    c.new_user().run(sender = bob.address)
    c.add_record(message = message, sig = sig).run(sender = bob.address)

    bob = sp.test_account('Bob')
    # an alternative follows that combines the secret with the public key hash 
    secret = sp.pack('This is my secret.') + sp.pack(bob.public_key_hash)
    message = sp.sha256(sp.sha256(secret))
    sig = sp.make_signature(bob.secret_key, message, message_format = 'Raw')
    c.add_record(message = message, sig = sig).run(sender = bob.address)
 def checkSeqStateSignature(self, party, sig, seq, state):
     sp.verify(sp.check_signature(party.pk, sig, sp.pack(sp.record(id = self.data.id, name = "state", seq = seq, state = state))))
    # At any point, a party can renounce.
    # Doing so means that they keep their looserClaim.
    @sp.entry_point
    def channelRenounce(self, params):
        sp.verify(self.data.active)
        self.data.active = False
        sp.if params.party == 1:
            if 1 not in self.no_checks:
                sig = params.sig.open_some() if self.no_checks else params.sig
                sp.verify(sp.check_signature(self.data.party1.pk, sig, sp.pack(sp.record(id = self.data.id, name = "renounce"))))
            sp.send(self.data.party2.address, self.data.party1.bond + self.data.party2.bond - self.data.party1.looserClaim)
            sp.send(self.data.party1.address, self.data.party1.looserClaim)
        sp.else:
            if 2 not in self.no_checks:
                sig = params.sig.open_some() if self.no_checks else params.sig
                sp.verify(sp.check_signature(self.data.party2.pk, sig, sp.pack(sp.record(id = self.data.id, name = "renounce"))))
            sp.send(self.data.party1.address, self.data.party1.bond + self.data.party2.bond - self.data.party2.looserClaim)
            sp.send(self.data.party2.address, self.data.party2.looserClaim)

    # When a party wants to come back on-chain from off-chain interactions,
    # it can do two different things: renounce or call channelNewState.
    # channelNewState is called with a state that has been agreed upon off-chain and
    # two signatures to prove the agreement.
    @sp.entry_point
    def channelNewState(self, params):
        sp.verify(self.data.active)
        sp.verify(self.data.seq < params.msg.seq)
        self.data.seq = params.msg.seq
        self.checkSeqStateSignature(self.data.party1, params.sig1, params.msg.seq, params.msg.state)
        self.checkSeqStateSignature(self.data.party2, params.sig2, params.msg.seq, params.msg.state)
        self.data.baseState = params.msg.state