Ejemplo n.º 1
0
    def checkwitness(self, hash_: types.UInt160) -> bool:
        """
        Check if the hash is a valid witness for the engines script_container
        """
        with suppress(ValueError):
            if hash_ == self.calling_scripthash:
                return True

        if isinstance(self.script_container, payloads.Transaction):
            tx = self.script_container

            response = tx.try_get_attribute(payloads.OracleResponse)
            if response is None:
                signers = tx.signers
            else:
                signers = []
                request = contracts.OracleContract().get_request(self.snapshot, response.id)
                if request:
                    tmp_tx = contracts.LedgerContract().get_tx_for_contract(self.snapshot, request.original_tx_id)
                    if tmp_tx:
                        signers = tmp_tx.signers

            for s in signers:
                if s.account == hash_:
                    signer = s
                    break
            else:
                return False

            if signer.scope == payloads.WitnessScope.GLOBAL:
                return True

            if payloads.WitnessScope.CALLED_BY_ENTRY in signer.scope:
                if self.calling_scripthash == self.entry_scripthash:
                    return True

            if payloads.WitnessScope.CUSTOM_CONTRACTS in signer.scope:
                if self.current_scripthash in signer.allowed_contracts:
                    return True

            if payloads.WitnessScope.CUSTOM_GROUPS in signer.scope:
                self._validate_callflags(contracts.CallFlags.READ_STATES)

                contract = contracts.ManagementContract().get_contract(self.snapshot, self.calling_scripthash)
                if contract is None:
                    return False
                group_keys = set(map(lambda g: g.public_key, contract.manifest.groups))
                if any(group_keys.intersection(signer.allowed_groups)):
                    return True
            return False

        self._validate_callflags(contracts.CallFlags.READ_STATES)

        # for other IVerifiable types like Block
        hashes_for_verifying = self.script_container.get_script_hashes_for_verifying(self.snapshot)
        return hash_ in hashes_for_verifying
Ejemplo n.º 2
0
    def init(self):
        self._methods: Dict[int, _NativeMethodMeta] = {}  # offset, meta

        self._management = contracts.ManagementContract()
        self._neo = contracts.NeoToken()
        self._gas = contracts.GasToken()
        self._policy = contracts.PolicyContract()
        self._oracle = contracts.OracleContract()
        self._ledger = contracts.LedgerContract()
        self._role = contracts.DesignationContract()
        self._crypto = contracts.CryptoContract()
        self._stdlib = contracts.StdLibContract()

        # Find all methods that have been augmented by the @register decorator
        # and turn them into methods that can be called by VM scripts
        methods_meta = []
        for pair in inspect.getmembers(self,
                                       lambda m: hasattr(m, "native_call")):
            methods_meta.append(_NativeMethodMeta(pair[1]))

        methods_meta.sort(
            key=lambda x: (x.descriptor.name, len(x.descriptor.parameters)))

        sb = vm.ScriptBuilder()
        for meta in methods_meta:
            meta.descriptor.offset = len(sb)
            sb.emit_push(0)
            self._methods.update({len(sb): meta})
            sb.emit_syscall(1736177434)  # "System.Contract.CallNative"
            sb.emit(vm.OpCode.RET)

        self._script: bytes = sb.to_array()
        self.nef = contracts.NEF("neo-core-v3.0", self._script)

        sender = types.UInt160.zero()  # OpCode.PUSH1
        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.ABORT)
        sb.emit_push(sender.to_array())
        sb.emit_push(0)
        sb.emit_push(self.service_name())
        self._hash: types.UInt160 = to_script_hash(sb.to_array())
        self._manifest: contracts.ContractManifest = contracts.ContractManifest(
        )
        self._manifest.name = self.service_name()
        self._manifest.abi.methods = list(
            map(lambda m: m.descriptor, methods_meta))

        if self._id != NativeContract._id:
            self._contracts.update({self.service_name(): self})
            self._contract_hashes.update({self._hash: self})

        self.active_block_index = settings.native_contract_activation.get(
            self.service_name, 0)
Ejemplo n.º 3
0
    def __init__(self, id: int, code: OracleReponseCode, result: bytes):
        super(OracleResponse, self).__init__()
        self.type_ = payloads.TransactionAttributeType.ORACLE_RESPONSE
        self.allow_multiple = False
        self.id = id
        self.code = code
        self.result = result
        if self._FIXED_ORACLE_SCRIPT is None:
            sb = vm.ScriptBuilder()

            sb.emit_dynamic_call(contracts.OracleContract().hash, "finish")  # type: ignore
            self._FIXED_ORACLE_SCRIPT = sb.to_array()
Ejemplo n.º 4
0
 def __init__(self, id: int, code: OracleReponseCode, result: bytes):
     super(OracleResponse, self).__init__()
     self.type_ = payloads.TransactionAttributeType.ORACLE_RESPONSE
     #: Only one OracleResponse attribute can be attached per transaction
     self.allow_multiple = False
     #: The OracleRequest id to which this is a response
     self.id = id
     #: The evaluation result code
     self.code = code
     #: The actual result
     self.result = result
     if self._FIXED_ORACLE_SCRIPT is None:
         sb = vm.ScriptBuilder()
         sb.emit_dynamic_call(contracts.OracleContract().hash,
                              "finish")  # type: ignore
         self._FIXED_ORACLE_SCRIPT = sb.to_array()