Пример #1
0
    def Storage_Delete(self, engine: ExecutionEngine):
        if self.Trigger != TriggerType.Application and self.Trigger != TriggerType.ApplicationR:
            return False

        context = engine.CurrentContext.EvaluationStack.Pop().GetInterface(
            neo.SmartContract.StorageContext.StorageContext)
        if not self.CheckStorageContext(context):
            return False
        if context.IsReadOnly:
            return False

        key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)

        if type(engine) == ExecutionEngine:
            test_mode = False
        else:
            test_mode = engine.testMode
        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.STORAGE_DELETE,
                               ContractParameter(ContractParameterType.String,
                                                 key),
                               context.ScriptHash,
                               GetBlockchain().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=test_mode))

        item = self.Snapshot.Storages.TryGet(storage_key.ToArray())
        if item and item.IsConstant:
            return False

        self.Snapshot.Storages.Delete(storage_key.ToArray())

        return True
Пример #2
0
    def Storage_Delete(self, engine):

        context = engine.EvaluationStack.Pop().GetInterface()

        if not self.CheckStorageContext(context):
            return False

        key = engine.EvaluationStack.Pop().GetByteArray()

        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)

        if len(key) == 20:
            keystr = Crypto.ToAddress(UInt160(data=key))

            self.events_to_dispatch.append(
                SmartContractEvent(SmartContractEvent.STORAGE_DELETE, [keystr],
                                   context.ScriptHash,
                                   Blockchain.Default().Height + 1,
                                   engine.ScriptContainer.Hash
                                   if engine.ScriptContainer else None,
                                   test_mode=engine.testMode))

        self._storages.Remove(storage_key.ToArray())

        return True
Пример #3
0
    def Contract_Destroy(self, engine):
        hash = UInt160(data=engine.CurrentContext.ScriptHash())

        contract = self.Snapshot.Contracts.TryGet(hash.ToBytes())

        if contract is not None:

            self.Snapshot.Contracts.Delete(hash.ToBytes())

            if contract.HasStorage:

                to_del = []
                for k, v in self.Snapshot.Storages.Find(hash.ToArray()):
                    storage_key = StorageKey(script_hash=hash, key=k[20:])
                    # Snapshot.Storages.Delete() modifies the underlying dictionary of the cache we'd be iterating
                    # over using Storages.Find. We therefore need to postpone deletion
                    to_del.append(storage_key)

                for storage_key in to_del:
                    self.Snapshot.Storages.Delete(storage_key.ToArray())

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.CONTRACT_DESTROY,
                               ContractParameter(
                                   ContractParameterType.InteropInterface,
                                   contract),
                               hash,
                               GetBlockchain().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=engine.testMode))
        return True
Пример #4
0
    def Storage_Get(self, engine):

        context = None
        try:
            item = engine.EvaluationStack.Pop()
            context = item.GetInterface()
        except Exception as e:
            logger.error("could not get storage context %s " % e)
            return False

        if not self.CheckStorageContext(context):
            return False

        key = engine.EvaluationStack.Pop().GetByteArray()
        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)
        item = self.Storages.TryGet(storage_key.ToArray())

        keystr = key

        valStr = bytearray(0)

        if item is not None:
            valStr = bytearray(item.Value)

        if len(key) == 20:
            keystr = Crypto.ToAddress(UInt160(data=key))

            try:
                valStr = int.from_bytes(valStr, 'little')
            except Exception as e:
                logger.error("Could not convert %s to number: %s " %
                             (valStr, e))

        if item is not None:
            engine.EvaluationStack.PushT(bytearray(item.Value))

        else:
            engine.EvaluationStack.PushT(bytearray(0))

        tx_hash = None
        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.STORAGE_GET,
                               ContractParameter(ContractParameterType.String,
                                                 value='%s -> %s' %
                                                 (keystr, valStr)),
                               context.ScriptHash,
                               Blockchain.Default().Height + 1,
                               tx_hash,
                               test_mode=engine.testMode))

        return True
Пример #5
0
    def Storage_Put(self, engine: ExecutionEngine):

        context = None
        try:

            context = engine.CurrentContext.EvaluationStack.Pop().GetInterface(
            )
        except Exception as e:
            logger.error("Storage Context Not found on stack")
            return False

        if not self.CheckStorageContext(context):
            return False

        key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        if len(key) > 1024:
            return False

        value = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()

        new_item = StorageItem(value=value)
        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)
        item = self._storages.ReplaceOrAdd(storage_key.ToArray(), new_item)

        keystr = key
        valStr = bytearray(item.Value)

        if len(key) == 20:
            keystr = Crypto.ToAddress(UInt160(data=key))

            try:
                valStr = int.from_bytes(valStr, 'little')
            except Exception as e:
                pass

        self.events_to_dispatch.append(
            SmartContractEvent(
                SmartContractEvent.STORAGE_PUT,
                ContractParameter(ContractParameterType.String,
                                  '%s -> %s' % (keystr, valStr)),
                context.ScriptHash,
                Blockchain.Default().Height + 1,
                engine.ScriptContainer.Hash
                if engine.ScriptContainer else None,
                test_mode=engine.testMode))

        return True
Пример #6
0
    def Storage_Get(self, engine: ExecutionEngine):
        context = None
        try:
            item = engine.CurrentContext.EvaluationStack.Pop()
            context = item.GetInterface(
                neo.SmartContract.StorageContext.StorageContext)
        except Exception as e:
            return False

        if not self.CheckStorageContext(context):
            return False

        key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)
        item = self.Snapshot.Storages.TryGet(storage_key.ToArray())

        keystr = key

        valStr = bytearray(0)

        if item is not None:
            valStr = bytearray(item.Value)

        if item is not None:
            engine.CurrentContext.EvaluationStack.PushT(bytearray(item.Value))

        else:
            engine.CurrentContext.EvaluationStack.PushT(bytearray(0))

        tx_hash = None
        if engine.ScriptContainer:
            tx_hash = engine.ScriptContainer.Hash

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.STORAGE_GET,
                               ContractParameter(ContractParameterType.String,
                                                 value='%s -> %s' %
                                                 (keystr, valStr)),
                               context.ScriptHash,
                               GetBlockchain().Height + 1,
                               tx_hash,
                               test_mode=engine.testMode))

        return True
Пример #7
0
    def Storage_Put(self, engine: ExecutionEngine):

        context = None
        try:
            context = engine.CurrentContext.EvaluationStack.Pop().GetInterface(
                neo.SmartContract.StorageContext.StorageContext)
        except Exception as e:
            return False

        if not self.CheckStorageContext(context):
            return False

        key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()
        if len(key) > 1024:
            return False

        value = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()

        storage_key = StorageKey(script_hash=context.ScriptHash, key=key)
        item = self.Snapshot.Storages.GetAndChange(storage_key.ToArray(),
                                                   lambda: StorageItem())
        item.Value = value

        keystr = key
        valStr = bytearray(item.Value)

        if type(engine) == ExecutionEngine:
            test_mode = False
        else:
            test_mode = engine.testMode

        self.events_to_dispatch.append(
            SmartContractEvent(
                SmartContractEvent.STORAGE_PUT,
                ContractParameter(ContractParameterType.String,
                                  '%s -> %s' % (keystr, valStr)),
                context.ScriptHash,
                GetBlockchain().Height + 1,
                engine.ScriptContainer.Hash
                if engine.ScriptContainer else None,
                test_mode=test_mode))

        return True
Пример #8
0
    def Contract_Migrate(self, engine: ExecutionEngine):

        script = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()

        if len(script) > 1024 * 1024:
            return False

        param_list = engine.CurrentContext.EvaluationStack.Pop().GetByteArray()

        if len(param_list) > 252:
            return False

        return_type = int(
            engine.CurrentContext.EvaluationStack.Pop().GetBigInteger())

        contract_properties = engine.CurrentContext.EvaluationStack.Pop(
        ).GetBigInteger()

        if len(engine.CurrentContext.EvaluationStack.Peek().GetByteArray()
               ) > 252:
            return False

        name = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(
        ).decode('utf-8')

        if len(engine.CurrentContext.EvaluationStack.Peek().GetByteArray()
               ) > 252:
            return False
        version = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(
        ).decode('utf-8')

        if len(engine.CurrentContext.EvaluationStack.Peek().GetByteArray()
               ) > 252:
            return False
        author = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(
        ).decode('utf-8')

        if len(engine.CurrentContext.EvaluationStack.Peek().GetByteArray()
               ) > 252:
            return False
        email = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(
        ).decode('utf-8')

        if len(engine.CurrentContext.EvaluationStack.Peek().GetByteArray()
               ) > 65536:
            return False
        description = engine.CurrentContext.EvaluationStack.Pop().GetByteArray(
        ).decode('utf-8')

        hash = Crypto.ToScriptHash(script, unhex=False)

        contract = self._contracts.TryGet(hash.ToBytes())

        if contract is None:

            code = FunctionCode(script=script,
                                param_list=param_list,
                                return_type=return_type)

            contract = ContractState(code=code,
                                     contract_properties=contract_properties,
                                     name=name,
                                     version=version,
                                     author=author,
                                     email=email,
                                     description=description)

            self._contracts.Add(hash.ToBytes(), contract)

            self._contracts_created[hash.ToBytes()] = UInt160(
                data=engine.CurrentContext.ScriptHash())

            if contract.HasStorage:
                for key, val in self._storages.Find(
                        engine.CurrentContext.ScriptHash()).items():
                    key = StorageKey(script_hash=hash, key=key)
                    item = StorageItem(val)
                    self._storages.Add(key.ToArray(), item)

        engine.CurrentContext.EvaluationStack.PushT(
            StackItem.FromInterface(contract))

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.CONTRACT_MIGRATED,
                               ContractParameter(
                                   ContractParameterType.InteropInterface,
                                   contract),
                               hash,
                               Blockchain.Default().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=engine.testMode))

        return self.Contract_Destroy(engine)