Exemplo n.º 1
0
def LoadContract(args):
    if len(args) < 5:
        print(
            "please specify contract to load like such: 'import contract {path} {params} {return_type} {needs_storage} {needs_dynamic_invoke}'"
        )
        return

    path = args[0]
    params = parse_param(args[1], ignore_int=True, prefer_hex=False)

    if type(params) is str:
        params = params.encode('utf-8')

    return_type = BigInteger(ContractParameterType.FromString(args[2]).value)

    needs_storage = bool(parse_param(args[3]))
    needs_dynamic_invoke = bool(parse_param(args[4]))

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

    script = None

    if '.py' in path:
        print("Please load a compiled .avm file")
        return False

    with open(path, 'rb') as f:

        content = f.read()

        try:
            content = binascii.unhexlify(content)
        except Exception as e:
            pass

        script = content

    if script is not None:

        plist = params

        try:
            plist = bytearray(binascii.unhexlify(params))
        except Exception as e:
            plist = bytearray(b'\x10')
        function_code = FunctionCode(script=script,
                                     param_list=bytearray(plist),
                                     return_type=return_type,
                                     contract_properties=contract_properties)

        return function_code

    print("error loading contract for path %s" % path)
    return None
Exemplo n.º 2
0
 def __init__(self, type):
     if isinstance(type, ContractParameterType):
         self.Type = type
     elif isinstance(type, int):
         self.Type = ContractParameterType(type)
     else:
         raise Exception("Invalid Contract Parameter Type %s. Must be ContractParameterType or int" % type)
Exemplo n.º 3
0
def GatherLoadedContractParams(args, script):
    if len(args) < 4:
        raise Exception(
            "please specify contract properties like {params} {return_type} {needs_storage} {needs_dynamic_invoke}"
        )
    params = parse_param(args[0], ignore_int=True, prefer_hex=False)

    if type(params) is str:
        params = params.encode('utf-8')

    return_type = BigInteger(ContractParameterType.FromString(args[1]).value)

    needs_storage = bool(parse_param(args[2]))
    needs_dynamic_invoke = bool(parse_param(args[3]))

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

    out = generate_deploy_script(script,
                                 contract_properties=contract_properties,
                                 return_type=return_type,
                                 parameter_list=params)

    return out
Exemplo n.º 4
0
def DoRun(contract_script,
          arguments,
          wallet,
          path,
          verbose=True,
          from_addr=None,
          min_fee=DEFAULT_MIN_FEE):

    test = get_arg(arguments, 1)

    if test is not None and test == 'test':

        if wallet is not None:

            f_args = arguments[2:]
            i_args = arguments[6:]

            script = GatherLoadedContractParams(f_args, contract_script)

            tx, result, total_ops, engine = test_deploy_and_invoke(
                script, i_args, wallet, from_addr, min_fee)
            i_args.reverse()

            return_type_results = []

            try:
                rtype = ContractParameterType.FromString(f_args[1])
                for r in result:
                    cp = ContractParameter.AsParameterType(rtype, r)
                    return_type_results.append(cp.ToJson())
            except Exception as e:
                logger.error(
                    'Could not convert result to ContractParameter: %s ' % e)

            if tx is not None and result is not None:
                if verbose:
                    print(
                        "\n-----------------------------------------------------------"
                    )
                    print("Calling %s with arguments %s " % (path, i_args))
                    print("Test deploy invoke successful")
                    print("Used total of %s operations " % total_ops)
                    print("Result %s " % return_type_results)
                    print("Invoke TX gas cost: %s " %
                          (tx.Gas.value / Fixed8.D))
                    print(
                        "-------------------------------------------------------------\n"
                    )

                return tx, result, total_ops, engine
            else:
                if verbose:
                    print("Test invoke failed")
                    print("tx is, results are %s %s " % (tx, result))

        else:

            print("please open a wallet to test built contract")

    return None, None, None, None
Exemplo n.º 5
0
def GatherLoadedContractParams(args, script):
    if len(args) < 5:
        raise Exception("please specify contract properties like {needs_storage} {needs_dynamic_invoke} {is_payable} {params} {return_type}")
    params = parse_param(args[3], ignore_int=True, prefer_hex=False)

    if type(params) is str:
        params = params.encode('utf-8')

    try:
        for p in binascii.unhexlify(params):
            if p == ContractParameterType.Void.value:
                raise ValueError("Void is not a valid input parameter type")
    except binascii.Error:
        pass

    return_type = BigInteger(ContractParameterType.FromString(args[4]).value)

    needs_storage = bool(parse_param(args[0]))
    needs_dynamic_invoke = bool(parse_param(args[1]))
    is_payable = bool(parse_param(args[2]))

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

    if is_payable:
        contract_properties += ContractPropertyState.Payable

    out = generate_deploy_script(script, contract_properties=contract_properties, return_type=return_type, parameter_list=params)

    return out
    def AddSignature(self, contract, pubkey, signature):

        if contract.Type == ContractType.MultiSigContract:

            item = self.CreateItem(contract)
            if item is None:
                return False
            for p in item.ContractParameters:
                if p.Value is not None:
                    return False
            if item.Signatures is None:
                item.Signatures = {}
            elif pubkey.encode_point(True) in item.Signatures:
                return False

            ecdsa = ECDSA.secp256r1()
            points = []
            temp = binascii.unhexlify(contract.Script)
            ms = MemoryStream(binascii.unhexlify(contract.Script))
            reader = BinaryReader(ms)
            numr = reader.ReadUInt8()
            while reader.ReadUInt8() == 33:
                ecpoint = ecdsa.ec.decode_from_hex(
                    binascii.hexlify(reader.ReadBytes(33)).decode())
                points.append(ecpoint)
            ms.close()

            if pubkey not in points:
                return False

            item.Signatures[pubkey.encode_point(
                True).decode()] = binascii.hexlify(signature)

            if len(item.Signatures) == len(contract.ParameterList):

                i = 0
                points.sort(reverse=True)
                for k in points:
                    pubkey = k.encode_point(True).decode()
                    if pubkey in item.Signatures:
                        if self.Add(contract, i,
                                    item.Signatures[pubkey]) is None:
                            raise Exception("Invalid operation")
                        i += 1
                item.Signatures = None
            return True

        else:
            index = -1
            if contract.ParameterList == '00':
                contract.ParameterList = b'\x00'
            length = len(contract.ParameterList)
            for i in range(0, length):
                if ContractParameterType(contract.ParameterList[i]
                                         ) == ContractParameterType.Signature:
                    if index >= 0:
                        raise Exception("Signature must be first")
                    else:
                        index = i
            return self.Add(contract, index, signature)
Exemplo n.º 7
0
    def __init__(self, script=None, param_list=None, return_type=255, contract_properties=0):
        self.Script = script
        if param_list is None:
            self.ParameterList = []
        else:
            self.ParameterList = param_list

        self.ReturnType = ContractParameterType.FromString(return_type).value

        self.ContractProperties = contract_properties
Exemplo n.º 8
0
def LoadContract(path, needs_storage, needs_dynamic_invoke, is_payable,
                 params_str, return_type):
    params = parse_param(params_str, ignore_int=True, prefer_hex=False)

    if type(params) is str:
        params = params.encode('utf-8')

    try:
        for p in binascii.unhexlify(params):
            if p == ContractParameterType.Void.value:
                raise ValueError("Void is not a valid input parameter type")
    except binascii.Error:
        pass

    rtype = BigInteger(ContractParameterType.FromString(return_type).value)

    contract_properties = 0

    if needs_storage:
        contract_properties += ContractPropertyState.HasStorage

    if needs_dynamic_invoke:
        contract_properties += ContractPropertyState.HasDynamicInvoke

    if is_payable:
        contract_properties += ContractPropertyState.Payable

    if '.avm' not in path:
        raise ValueError("Please load a compiled .avm file")

    script = None
    with open(path, 'rb') as f:

        content = f.read()

        try:
            content = binascii.unhexlify(content)
        except Exception as e:
            pass

        script = content

    if script:
        try:
            plist = bytearray(binascii.unhexlify(params))
        except Exception as e:
            plist = bytearray(b'\x10')
        function_code = FunctionCode(script=script,
                                     param_list=bytearray(plist),
                                     return_type=rtype,
                                     contract_properties=contract_properties)

        return function_code
    else:
        raise Exception(f"Error loading contract for path {path}")
Exemplo n.º 9
0
    def ToJson(self, auto_hex=True):
        """
        Converts a ContractParameter instance to a json representation

        Returns:
            dict: a dictionary representation of the contract parameter
        """
        jsn = {}
        jsn['type'] = str(ContractParameterType(self.Type))

        if self.Type == ContractParameterType.Signature:
            jsn['value'] = self.Value.hex()

        elif self.Type == ContractParameterType.ByteArray:
            if auto_hex:
                jsn['value'] = self.Value.hex()
            else:
                jsn['value'] = self.Value
        elif self.Type == ContractParameterType.Boolean:
            jsn['value'] = self.Value

        elif self.Type == ContractParameterType.String:
            jsn['value'] = str(self.Value)

        elif self.Type == ContractParameterType.Integer:
            jsn['value'] = self.Value

        # @TODO, see ``FromJson``, not sure if this is working properly
        elif self.Type == ContractParameterType.PublicKey:
            jsn['value'] = self.Value.ToString()

        elif self.Type in [
                ContractParameterType.Hash160, ContractParameterType.Hash256
        ]:
            jsn['value'] = self.Value.ToString()

        elif self.Type == ContractParameterType.Array:

            res = []
            for item in self.Value:
                if item:
                    res.append(item.ToJson(auto_hex=auto_hex))
            jsn['value'] = res

        elif self.Type == ContractParameterType.InteropInterface:
            try:
                jsn['value'] = self.Value.ToJson()
            except Exception as e:
                pass

        return jsn
Exemplo n.º 10
0
    def ToJson(self):
        """
        Convert object members to a dictionary that can be parsed as JSON.

        Returns:
             dict:
        """
        parameters = self.ParameterList.hex()
        paramlist = [ToName(ContractParameterType.FromString(parameters[i:i + 2]).value) for i in range(0, len(parameters), 2)]
        return {
            'hash': self.ScriptHash().To0xString(),
            'script': self.Script.hex(),
            'parameters': paramlist,
            'returntype': ToName(self.ReturnType) if type(self.ReturnType) is int else ToName(int(self.ReturnType))
        }
Exemplo n.º 11
0
    def FromJson(json):
        """
        Convert a json object to a ContractParameter object

        Args:
            item (dict): The item to convert to a ContractParameter object

        Returns:
            ContractParameter

        """
        type = ContractParameterType.FromString(json['type'])

        value = json['value']
        param = ContractParameter(type=type, value=None)

        if type == ContractParameterType.Signature or type == ContractParameterType.ByteArray:
            param.Value = bytearray.fromhex(value)

        elif type == ContractParameterType.Boolean:
            param.Value = bool(value)

        elif type == ContractParameterType.Integer:
            param.Value = int(value)

        elif type == ContractParameterType.Hash160:
            param.Value = UInt160.ParseString(value)

        elif type == ContractParameterType.Hash256:
            param.Value = UInt256.ParseString(value)

        # @TODO Not sure if this is working...
        elif type == ContractParameterType.PublicKey:
            param.Value = ECDSA.decode_secp256r1(value).G

        elif type == ContractParameterType.String:
            param.Value = str(value)

        elif type == ContractParameterType.Array:
            val = [ContractParameter.FromJson(item) for item in value]
            param.Value = val

        return param
Exemplo n.º 12
0
    def ResultsForCode(self, contract):
        try:
            return_type = ContractParameterType(contract.ReturnType)

            item = self.EvaluationStack.Items[0]
            if return_type == ContractParameterType.Integer:
                return item.GetBigInteger()
            elif return_type == ContractParameterType.Boolean:
                return item.GetBoolean()
            elif return_type == ContractParameterType.ByteArray:
                return item.GetByteArray()
            elif return_type == ContractParameterType.String:
                return item.GetString()
            elif return_type == ContractParameterType.Array:
                return item.GetArray()
            else:
                logger.error("Could not format results for return type %s " %
                             return_type)
            return item
        except Exception as e:
            pass

        return self.EvaluationStack.Items
Exemplo n.º 13
0
def DoRun(contract_script,
          arguments,
          wallet,
          path,
          verbose=True,
          from_addr=None,
          min_fee=DEFAULT_MIN_FEE,
          invocation_test_mode=True,
          debug_map=None,
          invoke_attrs=None,
          owners=None):
    if not wallet:
        print("Please open a wallet to test build contract")
        return None, None, None, None

    f_args = arguments[1:]
    i_args = arguments[6:]

    try:
        script = GatherLoadedContractParams(f_args, contract_script)
    except Exception:
        raise TypeError

    tx, result, total_ops, engine = test_deploy_and_invoke(
        script,
        i_args,
        wallet,
        from_addr,
        min_fee,
        invocation_test_mode,
        debug_map=debug_map,
        invoke_attrs=invoke_attrs,
        owners=owners)
    i_args.reverse()

    return_type_results = []
    try:
        rtype = ContractParameterType.FromString(f_args[4])
        for r in result:
            cp = ContractParameter.AsParameterType(rtype, r)
            return_type_results.append(cp.ToJson())
    except Exception:
        raise TypeError

    if tx and result:
        if verbose:
            print(
                "\n-----------------------------------------------------------"
            )
            print("Calling %s with arguments %s " %
                  (path, [item for item in reversed(engine.invocation_args)]))
            print("Test deploy invoke successful")
            print("Used total of %s operations " % total_ops)
            print("Result %s " % return_type_results)
            print("Invoke TX gas cost: %s " % (tx.Gas.value / Fixed8.D))
            print(
                "-------------------------------------------------------------\n"
            )

        return tx, result, total_ops, engine
    else:
        if verbose:
            print("Test invoke failed")
            print(f"tx is {tx}, results are {result}")
        return tx, result, None, None
Exemplo n.º 14
0
    def execute(self, arguments):
        wallet = PromptData.Wallet
        if not wallet:
            print("Please open a wallet")
            return False

        arguments, from_addr = PromptUtils.get_from_addr(arguments)
        arguments, priority_fee = PromptUtils.get_fee(arguments)
        arguments, invoke_attrs = PromptUtils.get_tx_attr_from_args(arguments)
        arguments, owners = PromptUtils.get_owners_from_params(arguments)
        arguments, return_type = PromptUtils.get_return_type_from_args(arguments)

        if len(arguments) < 1:
            print("Please specify the required parameters")
            return False

        hash_string = arguments[0]
        try:
            script_hash = UInt160.ParseString(hash_string)
        except Exception:
            # because UInt160 throws a generic exception. Should be fixed in the future
            print("Invalid script hash")
            return False

        p_fee = Fixed8.Zero()
        if priority_fee is not None:
            p_fee = priority_fee
            if p_fee is False:
                logger.debug("invalid fee")
                return False

        tx, fee, results, num_ops, engine_success = TestInvokeContract(wallet, arguments, from_addr=from_addr, invoke_attrs=invoke_attrs, owners=owners)
        if tx and results:

            if return_type is not None:
                try:
                    parameterized_results = [ContractParameter.AsParameterType(ContractParameterType.FromString(return_type), item).ToJson() for item in results]
                except ValueError:
                    logger.debug("invalid return type")
                    return False
            else:
                parameterized_results = [ContractParameter.ToParameter(item).ToJson() for item in results]

            print(
                "\n-------------------------------------------------------------------------------------------------------------------------------------")
            print("Test invoke successful")
            print(f"Total operations: {num_ops}")
            print(f"Results {str(parameterized_results)}")
            print(f"Invoke TX GAS cost: {tx.Gas.value / Fixed8.D}")
            print(f"Invoke TX fee: {fee.value / Fixed8.D}")
            print(
                "-------------------------------------------------------------------------------------------------------------------------------------\n")
            comb_fee = p_fee + fee
            if comb_fee != fee:
                print(f"Priority Fee ({p_fee.value / Fixed8.D}) + Invoke TX Fee ({fee.value / Fixed8.D}) = {comb_fee.value / Fixed8.D}\n")
            print("Enter your password to send this invocation to the network")

            tx.Attributes = invoke_attrs

            try:
                passwd = prompt("[password]> ", is_password=True)
            except KeyboardInterrupt:
                print("Invocation cancelled")
                return False
            if not wallet.ValidatePassword(passwd):
                return print("Incorrect password")

            return InvokeContract(wallet, tx, comb_fee, from_addr=from_addr, owners=owners)
        else:
            print("Error testing contract invoke")
            return False