예제 #1
0
    def test_3(self):

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=0)

        self.assertEqual(fn.ReturnType, 0)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(0))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=False)

        self.assertEqual(fn.ReturnType, 0)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(0))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='0')

        self.assertEqual(fn.ReturnType, 0)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(0))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'0')

        self.assertEqual(fn.ReturnType, 0)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(0))

        fn = FunctionCode(script=b'abcd',
                          param_list=[],
                          return_type='Signature')

        self.assertEqual(fn.ReturnType, 0)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(0))
예제 #2
0
    def test_4(self):

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='Boolean')

        self.assertEqual(fn.ReturnType, 1)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(1))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=True)

        self.assertEqual(fn.ReturnType, 1)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(1))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=1)

        self.assertEqual(fn.ReturnType, 1)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(1))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='1')

        self.assertEqual(fn.ReturnType, 1)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(1))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'1')

        self.assertEqual(fn.ReturnType, 1)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(1))
예제 #3
0
    def test_ICOTemplate_4_attachments(self):

        output = Compiler.instance().load('%s/ico_template.py' % TestContract.dirname).default
        out = output.write()

        # test mint tokens without being kyc verified
        tx, results, total_ops, engine = TestBuild(out, ['get_attachments', '[]', '--attach-neo=10'], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        attachments = results[0].GetArray()
        self.assertEqual(len(attachments), 4)

        fn = FunctionCode(out, '0705', '05')

        self.assertEqual(attachments[0].GetByteArray(), fn.ScriptHash().Data)
        self.assertEqual(attachments[1].GetByteArray(), self.wallet_3_script_hash.Data)
        self.assertEqual(attachments[2].GetBigInteger(), Fixed8.FromDecimal(10).value)
        self.assertEqual(attachments[3].GetBigInteger(), 0)

        tx, results, total_ops, engine = TestBuild(out, ['get_attachments', '[]'], self.GetWallet3(), '0705', '05')
        self.assertEqual(len(results), 1)
        attachments = results[0].GetArray()
        self.assertEqual(len(attachments), 4)

        self.assertEqual(attachments[1].GetByteArray(), bytearray())
        self.assertEqual(attachments[2].GetBigInteger(), 0)
        self.assertEqual(attachments[3].GetBigInteger(), 0)

        tx, results, total_ops, engine = TestBuild(out, ['get_attachments', '[]', '--attach-neo=3', '--attach-gas=3.12'], self.GetWallet1(), '0705', '05')
        self.assertEqual(len(results), 1)
        attachments = results[0].GetArray()
        self.assertEqual(len(attachments), 4)
        self.assertEqual(attachments[1].GetByteArray(), self.wallet_1_script_hash.Data)
        self.assertEqual(attachments[2].GetBigInteger(), Fixed8.FromDecimal(3).value)
        self.assertEqual(attachments[3].GetBigInteger(), Fixed8.FromDecimal(3.12).value)
예제 #4
0
    def test_2(self):

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='ff')

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'ff')

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))

        fn = FunctionCode(script=b'abcd',
                          param_list=[],
                          return_type=bytearray(b'\xff'))

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=255)

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='Void')

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))
예제 #5
0
    def Contract_Create(self, engine):

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

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

        param_list = engine.EvaluationStack.Pop().GetByteArray()
        if len(param_list) > 252:
            return False

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

        needs_storage = engine.EvaluationStack.Pop().GetBoolean()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        name = engine.EvaluationStack.Pop().GetByteArray()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        code_version = engine.EvaluationStack.Pop().GetByteArray()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        author = engine.EvaluationStack.Pop().GetByteArray()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        email = engine.EvaluationStack.Pop().GetByteArray()

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

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

        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, needs_storage, name, code_version,
                                     author, email, description)

            self._contracts.GetAndChange(code.ScriptHash().ToBytes(), contract)

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

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

        #        print("*****************************************************")
        #        print("CREATED CONTRACT %s " % hash.ToBytes())
        #        print("*****************************************************")
        return True
예제 #6
0
class PublishTransaction(Transaction):

    Code = None
    NeedStorage = False
    Name = ''
    CodeVersion = ''
    Author = ''
    Email = ''
    Description = ''

    def __init__(self, *args, **kwargs):
        super(PublishTransaction, self).__init__(*args, **kwargs)
        self.Type = TransactionType.PublishTransaction

    def SystemFee(self):
        return Fixed8(int(Settings.PUBLISH_TX_FEE))

    def DeserializeExclusiveData(self, reader):
        if self.Version > 1:
            self.__log.debug("format exception...")

        self.Code = FunctionCode()
        self.Code.Deserialize(reader)

        if self.Version >= 1:
            self.NeedStorage = reader.ReadBool()
        else:
            self.NeedStorage = False

        self.Name = reader.ReadVarString()
        self.CodeVersion = reader.ReadVarString()
        self.Author = reader.ReadVarString()
        self.Email = reader.ReadVarString()
        self.Description = reader.ReadVarString()

    def SerializeExclusiveData(self, writer):

        self.Code.Serialize(writer)

        if self.Version >= 1:
            writer.WriteBool(self.NeedStorage)

        writer.WriteVarString(self.Name)
        writer.WriteVarString(self.CodeVersion)
        writer.WriteVarString(self.Author)
        writer.WriteVarString(self.Email)
        writer.WriteVarString(self.Description)

    def ToJson(self):
        jsn = super(PublishTransaction, self).ToJson()
        jsn['contract'] = {}
        jsn['contract']['code'] = self.Code.ToJson()
        jsn['contract']['needstorage'] = self.NeedStorage
        jsn['contract']['name'] = self.Name.decode('utf-8')
        jsn['contract']['version'] = self.CodeVersion.decode('utf-8')
        jsn['contract']['author'] = self.Author.decode('utf-8')
        jsn['contract']['email'] = self.Email.decode('utf-8')
        jsn['contract']['description'] = self.Description.decode('utf-8')
        return jsn
예제 #7
0
    def Deserialize(self, reader):
        super(ContractState, self).Deserialize(reader)

        code = FunctionCode()
        code.Deserialize(reader)
        self.Code = code

        self.HasStorage = reader.ReadBool()
        self.Name = reader.ReadVarString(max=252)
        self.CodeVersion = reader.ReadVarString(max=252)
        self.Author = reader.ReadVarString(max=252)
        self.Email = reader.ReadVarString(max=252)
        self.Description = reader.ReadVarString(max=65536)
예제 #8
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
예제 #9
0
    def test_7(self):

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='String')

        self.assertEqual(fn.ReturnType, 7)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(7))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='7')

        self.assertEqual(fn.ReturnType, 7)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(7))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'07')

        self.assertEqual(fn.ReturnType, 7)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(7))
예제 #10
0
    def test_5(self):

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='Array')

        self.assertEqual(fn.ReturnType, 16)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(16))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='10')

        self.assertEqual(fn.ReturnType, 16)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(16))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'10')

        self.assertEqual(fn.ReturnType, 16)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(16))
예제 #11
0
    def DeserializeExclusiveData(self, reader):
        if self.Version > 1:
            self.__log.debug("format exception...")

        self.Code = FunctionCode()
        self.Code.Deserialize(reader)

        if self.Version >= 1:
            self.NeedStorage = reader.ReadBool()
        else:
            self.NeedStorage = False

        self.Name = reader.ReadVarString()
        self.CodeVersion = reader.ReadVarString()
        self.Author = reader.ReadVarString()
        self.Email = reader.ReadVarString()
        self.Description = reader.ReadVarString()
예제 #12
0
def LoadContract(args):

    if len(args) < 4:
        print(
            "please specify contract to load like such: 'import contract {path} {params} {return_type} {needs_storage}'"
        )
        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 = parse_param(args[2], ignore_int=True, prefer_hex=False)

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

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

    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=binascii.unhexlify(return_type),
            needs_storage=needs_storage)

        return function_code

    print("error loading contract for path %s" % path)
    return None
예제 #13
0
    def test_1(self):

        fn = FunctionCode()

        self.assertEqual(fn.ReturnType, 255)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(255))

        self.assertEqual(fn.ParameterList, [])
        self.assertEqual(fn.HasDynamicInvoke, False)
        self.assertEqual(fn.HasStorage, False)
예제 #14
0
    def Deserialize(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neocore.IO.BinaryReader):
        """
        super(ContractState, self).Deserialize(reader)

        code = FunctionCode()
        code.Deserialize(reader)
        self.Code = code

        self.ContractProperties = reader.ReadUInt8()
        self.Name = reader.ReadVarString(max=252)
        self.CodeVersion = reader.ReadVarString(max=252)
        self.Author = reader.ReadVarString(max=252)
        self.Email = reader.ReadVarString(max=252)
        self.Description = reader.ReadVarString(max=65536)
예제 #15
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}")
예제 #16
0
    def test_6(self):

        fn = FunctionCode(script=b'abcd',
                          param_list=[],
                          return_type='ByteArray')

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='05')

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'05')

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=5)

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type='5')

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))

        fn = FunctionCode(script=b'abcd', param_list=[], return_type=b'5')

        self.assertEqual(fn.ReturnType, 5)
        self.assertEqual(fn.ReturnTypeBigInteger, BigInteger(5))
    def DeserializeExclusiveData(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):
        """
        if self.Version > 1:
            logger.error("format exception...")

        self.Code = FunctionCode()
        self.Code.Deserialize(reader)

        if self.Version >= 1:
            self.NeedStorage = reader.ReadBool()
        else:
            self.NeedStorage = False

        self.Name = reader.ReadVarString()
        self.CodeVersion = reader.ReadVarString()
        self.Author = reader.ReadVarString()
        self.Email = reader.ReadVarString()
        self.Description = reader.ReadVarString()
예제 #18
0
    def Contract_Create(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())
        if return_type < 0 or return_type > 0xff:
            raise ValueError("Invalid return type data popped from stack")

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

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

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

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

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

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

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

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

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

        if contract is None:
            try:
                code = FunctionCode(script=script,
                                    param_list=param_list,
                                    return_type=return_type,
                                    contract_properties=contract_properties)
            except ValueError:
                # exception is caused by an invalid `return_type`. neo-cli accepts this , but we throw an exception
                # this is a dirty hack to work around the VM state difference that it causes until neo-cli hopefully fixes it
                # see https://github.com/neo-project/neo/issues/827
                code = FunctionCode(script=script,
                                    param_list=param_list,
                                    contract_properties=contract_properties)
                code.ReturnType = return_type

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

            self.Snapshot.Contracts.Add(code.ScriptHash().ToBytes(), contract)

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

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

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.CONTRACT_CREATED,
                               ContractParameter(
                                   ContractParameterType.InteropInterface,
                                   contract),
                               hash,
                               GetBlockchain().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=engine.testMode))
        return True
예제 #19
0
    def Contract_Migrate(self, engine):

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

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

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

        if len(param_list) > 252:
            return False

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

        needs_storage = engine.EvaluationStack.Pop().GetBoolean()

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

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

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

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

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 65536:
            return False
        description = engine.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,
                                     has_storage=needs_storage,
                                     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 needs_storage:

                for pair in self._storages.Find(
                        engine.CurrentContext.ScriptHash()):

                    key = StorageKey(script_hash=hash, key=pair.Key.Key)
                    item = StorageItem(pair.Value.Value)
                    self._storages.Add(key, item)

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

        # print("*****************************************************")
        # print("MIGRATED CONTRACT %s " % hash.ToBytes())
        # print("*****************************************************")

        return True
예제 #20
0
class PublishTransaction(Transaction):
    def __init__(self, *args, **kwargs):
        """
        Create instance.

        Args:
            *args:
            **kwargs:
        """
        super(PublishTransaction, self).__init__(*args, **kwargs)
        self.Type = TransactionType.PublishTransaction
        self.Code = None
        self.NeedStorage = False
        self.Name = ''
        self.CodeVersion = ''
        self.Author = ''
        self.Email = ''
        self.Description = ''

    def Size(self):
        """
        Get the total size in bytes of the object.

        Returns:
            int: size.
        """
        return super(PublishTransaction, self).Size() + GetVarSize(
            self.Code.Script) + GetVarSize(
                self.Code.ParameterList) + s.uint8 + GetVarSize(
                    self.Name) + GetVarSize(self.CodeVersion) + GetVarSize(
                        self.Author) + GetVarSize(self.Email) + GetVarSize(
                            self.Description)

    def DeserializeExclusiveData(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):
        """
        if self.Version > 1:
            logger.error("format exception...")

        self.Code = FunctionCode()
        self.Code.Deserialize(reader)

        if self.Version >= 1:
            self.NeedStorage = reader.ReadBool()
        else:
            self.NeedStorage = False

        self.Name = reader.ReadVarString()
        self.CodeVersion = reader.ReadVarString()
        self.Author = reader.ReadVarString()
        self.Email = reader.ReadVarString()
        self.Description = reader.ReadVarString()

    def SerializeExclusiveData(self, writer):
        """
        Serialize object.

        Args:
            writer (neo.IO.BinaryWriter):
        """
        self.Code.Serialize(writer)

        if self.Version >= 1:
            writer.WriteBool(self.NeedStorage)

        writer.WriteVarString(self.Name)
        writer.WriteVarString(self.CodeVersion)
        writer.WriteVarString(self.Author)
        writer.WriteVarString(self.Email)
        writer.WriteVarString(self.Description)

    def ToJson(self):
        """
        Convert object members to a dictionary that can be parsed as JSON.

        Returns:
             dict:
        """
        jsn = super(PublishTransaction, self).ToJson()
        jsn['contract'] = {}
        jsn['contract']['code'] = self.Code.ToJson()
        jsn['contract']['needstorage'] = self.NeedStorage
        jsn['contract']['name'] = self.Name.decode('utf-8')
        jsn['contract']['version'] = self.CodeVersion.decode('utf-8')
        jsn['contract']['author'] = self.Author.decode('utf-8')
        jsn['contract']['email'] = self.Email.decode('utf-8')
        jsn['contract']['description'] = self.Description.decode('utf-8')
        return jsn
예제 #21
0
def construct_deploy_tx(wallet, params):
    params = params[0]
    from_addr = params['from_addr']
    # load_smart_contract
    contract_params = bytearray(binascii.unhexlify(params['contract_params']))
    return_type = bytearray(binascii.unhexlify(params['return_type']))
    
    contract_properties = 0
    if params.get('needs_storage', True):
        contract_properties += ContractPropertyState.HasStorage
    if params.get('needs_dynamic_invoke', False):
        contract_properties += ContractPropertyState.HasDynamicInvoke

    script = binascii.unhexlify(params['bin'])

    function_code = FunctionCode(
            script = script,
            param_list = contract_params,
            return_type = return_type,
            contract_properties = contract_properties,
    )

    if Blockchain.Default().GetContract(function_code.ScriptHash().To0xString()):
        raise Exception('contract already exists')

    # GatherContractDetails
    details = params['details']
    name = details['name']
    version = details['version']
    author = details['author']
    email = details['email']
    description = details['description']

    contract_script = generate_deploy_script(
            function_code.Script,
            name,
            version,
            author,
            email,
            description,
            function_code.ContractProperties,
            function_code.ReturnType,
            function_code.ParameterList,
    )

    # test_invoke    
    bc = GetBlockchain()
    sn = bc._db.snapshot()
    accounts = DBCollection(bc._db, DBPrefix.ST_Account, AccountState)
    assets = DBCollection(bc._db, DBPrefix.ST_Asset, AssetState)
    validators = DBCollection(bc._db, DBPrefix.ST_Validator, ValidatorState)
    contracts = DBCollection(bc._db, DBPrefix.ST_Contract, ContractState)
    storages = DBCollection(bc._db, DBPrefix.ST_Storage, StorageItem)


    tx = InvocationTransaction()
    tx.outputs = []
    tx.inputs = []
    tx.Version = 1
    tx.scripts = []
    tx.Script = binascii.unhexlify(contract_script)

    script_table = CachedScriptTable(contracts)
    service = StateMachine(accounts, validators, assets, contracts, storages, None)
    contract = wallet.GetDefaultContract()
    tx.Attributes = [TransactionAttribute(usage=TransactionAttributeUsage.Script, data=Crypto.ToScriptHash(contract.Script, unhex=False).Data)]
    tx = wallet.MakeTransaction(tx=tx)

    engine = ApplicationEngine(
            trigger_type=TriggerType.Application,
            container=tx,
            table=script_table,
            service=service,
            gas=tx.Gas,
            testMode=True
    )   
    engine.LoadScript(tx.Script, False)
    success = engine.Execute()
    if not success:
        raise Exception('exec failed')
    
    service.ExecutionCompleted(engine, success)

    consumed = engine.GasConsumed() - Fixed8.FromDecimal(10)
    consumed = consumed.Ceil()

    net_fee = None
    tx_gas = None

    if consumed <= Fixed8.Zero():
        net_fee = Fixed8.FromDecimal(.0001)
        tx_gas = Fixed8.Zero()
    else:
        tx_gas = consumed
        net_fee = Fixed8.Zero()
    tx.Gas = tx_gas
    tx.outputs = []
    tx.Attributes = []

    # InvokeContract
    from_addr = lookup_addr_str(wallet, from_addr)
    tx = wallet.MakeTransaction(tx=tx, fee=net_fee, use_standard=True, from_addr=from_addr)
    if tx is None:
        raise Exception("no gas")


    context = ContractParametersContext(tx)
    ms = StreamManager.GetStream()
    writer = BinaryWriter(ms)
    tx.Serialize(writer)
    ms.flush()
    binary_tx = ms.ToArray()
    return {'context': context.ToJson(), 'tx': binary_tx.decode(), 'hash': function_code.ScriptHash().To0xString()}
예제 #22
0
    def Contract_Migrate(self, engine):

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

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

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

        if len(param_list) > 252:
            return False

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

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

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

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

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

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

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

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 65536:
            return False
        description = engine.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 pair in self._storages.Find(
                        engine.CurrentContext.ScriptHash()):
                    key = StorageKey(script_hash=hash, key=pair.Key.Key)
                    item = StorageItem(pair.Value.Value)
                    self._storages.Add(key, item)

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

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

        return self.Contract_Destroy(engine)
예제 #23
0
    def Contract_Create(self, engine):

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

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

        param_list = engine.EvaluationStack.Pop().GetByteArray()
        if len(param_list) > 252:
            return False

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

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

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

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

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        code_version = engine.EvaluationStack.Pop().GetByteArray()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        author = engine.EvaluationStack.Pop().GetByteArray()

        if len(engine.EvaluationStack.Peek().GetByteArray()) > 252:
            return False
        email = engine.EvaluationStack.Pop().GetByteArray()

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

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

        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_properties=contract_properties)

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

            self._contracts.GetAndChange(code.ScriptHash().ToBytes(), contract)

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

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

        self.events_to_dispatch.append(
            SmartContractEvent(SmartContractEvent.CONTRACT_CREATED, [contract],
                               hash,
                               Blockchain.Default().Height + 1,
                               engine.ScriptContainer.Hash
                               if engine.ScriptContainer else None,
                               test_mode=engine.testMode))
        return True
class PublishTransaction(Transaction):
    Code = None
    NeedStorage = False
    Name = ''
    CodeVersion = ''
    Author = ''
    Email = ''
    Description = ''

    def __init__(self, *args, **kwargs):
        """
        Create instance.

        Args:
            *args:
            **kwargs:
        """
        super(PublishTransaction, self).__init__(*args, **kwargs)
        self.Type = TransactionType.PublishTransaction

    def SystemFee(self):
        """
        Get the system fee.

        Returns:
            Fixed8:
        """
        return Fixed8(int(settings.PUBLISH_TX_FEE))

    def DeserializeExclusiveData(self, reader):
        """
        Deserialize full object.

        Args:
            reader (neo.IO.BinaryReader):
        """
        if self.Version > 1:
            logger.error("format exception...")

        self.Code = FunctionCode()
        self.Code.Deserialize(reader)

        if self.Version >= 1:
            self.NeedStorage = reader.ReadBool()
        else:
            self.NeedStorage = False

        self.Name = reader.ReadVarString()
        self.CodeVersion = reader.ReadVarString()
        self.Author = reader.ReadVarString()
        self.Email = reader.ReadVarString()
        self.Description = reader.ReadVarString()

    def SerializeExclusiveData(self, writer):
        """
        Serialize object.

        Args:
            writer (neo.IO.BinaryWriter):
        """
        self.Code.Serialize(writer)

        if self.Version >= 1:
            writer.WriteBool(self.NeedStorage)

        writer.WriteVarString(self.Name)
        writer.WriteVarString(self.CodeVersion)
        writer.WriteVarString(self.Author)
        writer.WriteVarString(self.Email)
        writer.WriteVarString(self.Description)

    def ToJson(self):
        """
        Convert object members to a dictionary that can be parsed as JSON.

        Returns:
             dict:
        """
        jsn = super(PublishTransaction, self).ToJson()
        jsn['contract'] = {}
        jsn['contract']['code'] = self.Code.ToJson()
        jsn['contract']['needstorage'] = self.NeedStorage
        jsn['contract']['name'] = self.Name.decode('utf-8')
        jsn['contract']['version'] = self.CodeVersion.decode('utf-8')
        jsn['contract']['author'] = self.Author.decode('utf-8')
        jsn['contract']['email'] = self.Email.decode('utf-8')
        jsn['contract']['description'] = self.Description.decode('utf-8')
        return jsn
예제 #25
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.Snapshot.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.Snapshot.Contracts.Add(hash.ToBytes(), contract)

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

            if contract.HasStorage:
                to_add = []
                for key, item in self.Snapshot.Storages.Find(
                        cur_hash.ToArray()):
                    key = StorageKey(script_hash=hash, key=key[20:])
                    to_add.append((key.ToArray(), item))

                for k, v in to_add:
                    self.Snapshot.Storages.Add(k, v)

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

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

        return self.Contract_Destroy(engine)