示例#1
0
    def _post_transfer(self, engine: contracts.ApplicationEngine,
                       account_from: types.UInt160, account_to: types.UInt160,
                       amount: vm.BigInteger, data: vm.StackItem,
                       call_on_payment: bool) -> None:
        state = vm.ArrayStackItem(vm.ReferenceCounter())
        if account_from == types.UInt160.zero():
            state.append(vm.NullStackItem())
        else:
            state.append(vm.ByteStringStackItem(account_from.to_array()))
        if account_to == types.UInt160.zero():
            state.append(vm.NullStackItem())
        else:
            state.append(vm.ByteStringStackItem(account_to.to_array()))
        state.append(vm.IntegerStackItem(amount))

        msgrouter.interop_notify(self.hash, "Transfer", state)

        # wallet or smart contract
        if not call_on_payment \
                or account_to == types.UInt160.zero() \
                or contracts.ManagementContract().get_contract(engine.snapshot, account_to) is None:
            return

        if account_from == types.UInt160.zero():
            from_: vm.StackItem = vm.NullStackItem()
        else:
            from_ = vm.ByteStringStackItem(account_from.to_array())
        engine.call_from_native(
            self.hash, account_to, "onNEP17Payment",
            [from_, vm.IntegerStackItem(amount), data])
示例#2
0
    def transfer_helper(self, contract: contracts.NativeContract,
                        from_account: types.UInt160, to_account: types.UInt160,
                        amount: vm.BigInteger):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block
        engine.invocation_stack.pop()  # we no longer need the default script
        engine.script_container = TestIVerifiable()
        engine.script_container.script_hashes = [from_account]

        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.PUSHNULL)
        sb.emit_push(amount)
        sb.emit_push(to_account.to_array())
        sb.emit_push(from_account.to_array())
        sb.emit_push(4)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(15)  # callflags
        sb.emit_push(b'transfer')
        sb.emit_push(contract.hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        engine.load_script(vm.Script(sb.to_array()))

        nef = contracts.NEF(script=sb.to_array())
        manifest = contracts.ContractManifest("test_contract")
        contract_state = contracts.ContractState(
            1, nef, manifest, 0,
            contract_hash(from_account, nef.checksum, manifest.name))
        engine.snapshot.contracts.put(contract_state)
        return engine
示例#3
0
    def transfer_helper(self, contract: contracts.NativeContract,
                        from_account: types.UInt160, to_account: types.UInt160,
                        amount: vm.BigInteger):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block
        engine.invoke_syscall_by_name("Neo.Native.Deploy")
        engine.invocation_stack.pop()  # we no longer need the default script
        engine.script_container = TestIVerifiable()
        engine.script_container.script_hashes = [from_account]

        sb = vm.ScriptBuilder()
        sb.emit_push(amount)
        sb.emit_push(to_account.to_array())
        sb.emit_push(from_account.to_array())
        sb.emit_push(3)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(b'transfer')
        sb.emit_push(contract.script_hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        engine.load_script(vm.Script(sb.to_array()))

        engine.snapshot.contracts.put(
            storage.ContractState(sb.to_array(), contracts.ContractManifest()))
        return engine
示例#4
0
    def test_from_string_wrong_length(self):
        with self.assertRaises(ValueError) as ctx:
            UInt160.from_string("1122")
        self.assertEqual("Invalid UInt160 Format: 4 chars != 40 chars",
                         str(ctx.exception))

        with self.assertRaises(ValueError) as ctx:
            UInt256.from_string("1122")
        self.assertEqual("Invalid UInt256 Format: 4 chars != 64 chars",
                         str(ctx.exception))
示例#5
0
    def _internal_contract_delete(self, hash: types.UInt160, batch=None):
        if batch:
            db = batch
        else:
            db = self._real_db

        db.delete(DBPrefixes.CONTRACTS + hash.to_array())
示例#6
0
    def _internal_contract_get(self, hash: types.UInt160):
        contract_bytes = self._real_db.get(DBPrefixes.CONTRACTS +
                                           hash.to_array())
        if contract_bytes is None:
            raise KeyError

        return contracts.ContractState.deserialize_from_bytes(contract_bytes)
示例#7
0
    def transfer(self, engine: contracts.ApplicationEngine, account_to: types.UInt160, token_id: bytes) -> bool:
        if account_to == types.UInt160.zero():
            raise ValueError("To account can't be zero")

        key_token = self.key_token + token_id
        storage_item = engine.snapshot.storages.try_get(key_token, read_only=True)
        if storage_item is None:
            raise ValueError("Token state not found")
        token_state = NFTState.deserialize_from_bytes(storage_item.value)
        if token_state.owner != engine.calling_scripthash and engine.checkwitness(token_state.owner):
            return False
        if token_state.owner != account_to:
            token = NFTState.from_stack_item(engine.snapshot.storages.get(key_token, read_only=False))
            key_from = self.key_account + token_state.owner.to_array
            account_state = engine.snapshot.storages.get(key_from).get(NFTAccountState)
            account_state.remove(token_id)
            if account_state.balance == 0:
                engine.snapshot.storages.delete(key_from)
            token.owner = account_to
            key_to = self.key_account + account_to.to_array()
            storage_item = engine.snapshot.storages.try_get(key_to, read_only=False)
            if storage_item is None:
                storage_item = storage.StorageItem(NFTAccountState().to_array())
                engine.snapshot.storages.put(key_to, storage_item)
            storage_item.get(NFTAccountState).add(token_id)
            self.on_transferred(engine, token.owner, token)

        self._post_transfer(engine, token_state.owner, account_to, token_id)
        return True
示例#8
0
 def tokens_of(self, snapshot: storage.Snapshot, owner: types.UInt160) -> interop.IIterator:
     storage_item_account = snapshot.storages.try_get(self.key_account + owner.to_array(), read_only=True)
     reference_counter = vm.ReferenceCounter()
     if storage_item_account is None:
         return interop.ArrayWrapper(vm.ArrayStackItem(reference_counter))
     account = storage_item_account.get(NFTAccountState)
     tokens: List[vm.StackItem] = list(map(lambda t: vm.ByteStringStackItem(t), account.tokens))
     return interop.ArrayWrapper(vm.ArrayStackItem(reference_counter, tokens))
示例#9
0
def contract_hash(sender: types.UInt160, checksum: int,
                  name: str) -> types.UInt160:
    sb = vm.ScriptBuilder()
    sb.emit(vm.OpCode.ABORT)
    sb.emit_push(sender.to_array())
    sb.emit_push(checksum)
    sb.emit_push(name)
    return to_script_hash(sb.to_array())
示例#10
0
 def test_new_watch_only_account(self):
     from neo3.core.types import UInt160
     for testcase in account_list:
         account = Account.watch_only(
             UInt160.from_string(testcase['script_hash']))
         self.assertEqual(testcase['address'], account.address)
         self.assertIsNone(account.encrypted_key)
         self.assertEqual(testcase['script_hash'], str(account.script_hash))
         self.assertIsNone(account.public_key)
示例#11
0
 def call_from_native(self, calling_scripthash: types.UInt160,
                      hash_: types.UInt160, method: str,
                      args: List[vm.StackItem]) -> None:
     ctx = self.current_context
     self._contract_call_internal(hash_, method, contracts.CallFlags.ALL,
                                  False, args)
     self.current_context.calling_scripthash_bytes = calling_scripthash.to_array(
     )
     while self.current_context != ctx:
         self.step_out()
示例#12
0
    def is_valid(self, contract_hash: types.UInt160) -> bool:
        """
        Validate if the group has agreed on allowing the specific contract_hash.

        Args:
            contract_hash:
        """
        return cryptography.verify_signature(
            contract_hash.to_array(), self.signature,
            self.public_key.encode_point(False),
            cryptography.ECCCurve.SECP256R1)
示例#13
0
    def script_hash_to_address(script_hash: types.UInt160) -> str:
        """
        Converts the specified script hash to an address.

        Args:
            script_hash: script hash to convert.
        """
        version = settings.network.account_version  # this is the current Neo's protocol version
        data = version.to_bytes(1, 'little') + script_hash.to_array()

        return base58.b58encode_check(data).decode('utf-8')
示例#14
0
    def test_from_string_various(self):
        uint160 = UInt160.from_string("11" * 20)
        expected_data_uint160 = bytearray([0x11] * 20)
        self.assertEqual(expected_data_uint160, uint160.to_array())

        uint256 = UInt256.from_string("11" * 32)
        expected_data_uint256 = bytearray([0x11] * 32)
        self.assertEqual(expected_data_uint256, uint256.to_array())

        uint160_from_bytes = UInt160.deserialize_from_bytes(
            expected_data_uint160)
        self.assertEqual(expected_data_uint160, uint160_from_bytes.to_array())

        uint256_from_bytes = UInt256.deserialize_from_bytes(
            expected_data_uint256)
        self.assertEqual(expected_data_uint256, uint256_from_bytes.to_array())

        # test deserialize with too much data
        data_uint160 = bytearray(21 * [0x11])
        uint160_from_bytes = UInt160.deserialize_from_bytes(data_uint160)
        self.assertEqual(data_uint160[:20], uint160_from_bytes.to_array())

        data_uint256 = bytearray(33 * [0x11])
        uint256_from_bytes = UInt256.deserialize_from_bytes(data_uint256)
        self.assertEqual(expected_data_uint256[:32],
                         uint256_from_bytes.to_array())

        # test deserialize with too little data
        data_uint160 = bytearray(19 * [0x11])
        data_uint256 = bytearray(31 * [0x11])
        with self.assertRaises(ValueError) as ctx:
            UInt160.deserialize_from_bytes(data_uint160)
        self.assertEqual(
            "Insufficient data 19 bytes is less than the required 20",
            str(ctx.exception))

        with self.assertRaises(ValueError) as ctx:
            UInt256.deserialize_from_bytes(data_uint256)
        self.assertEqual(
            "Insufficient data 31 bytes is less than the required 32",
            str(ctx.exception))
示例#15
0
    def _post_transfer(self,
                       engine: contracts.ApplicationEngine,
                       account_from: types.UInt160,
                       account_to: types.UInt160,
                       token_id: bytes) -> None:
        state = vm.ArrayStackItem(engine.reference_counter)
        if account_from == types.UInt160.zero():
            state.append(vm.NullStackItem())
        else:
            state.append(vm.ByteStringStackItem(account_from.to_array()))
        if account_to == types.UInt160.zero():
            state.append(vm.NullStackItem())
        else:
            state.append(vm.ByteStringStackItem(account_to.to_array()))
        state.append(vm.IntegerStackItem(1))
        state.append(vm.ByteStringStackItem(token_id))

        msgrouter.interop_notify(self.hash, "Transfer", state)

        if account_to != types.UInt160.zero() and \
                contracts.ManagementContract().get_contract(engine.snapshot, account_to) is not None:
            engine.call_from_native(self.hash, account_to, "onNEP17Payment", list(state))
示例#16
0
    def test_serialize_to_stream(self):
        data_uint160 = bytearray(20 * [0x11])
        data_uint256 = bytearray(32 * [0x11])
        uint160 = UInt160(data_uint160)
        uint256 = UInt256(data_uint256)

        with serialization.BinaryWriter() as bw:
            bw.write_serializable(uint160)
            self.assertEqual(data_uint160, bw._stream.getvalue())

        with serialization.BinaryWriter() as bw:
            bw.write_serializable(uint256)
            self.assertEqual(data_uint256, bw._stream.getvalue())
示例#17
0
    def test_deserialize_from_stream(self):
        data_uint160 = bytearray(20 * [0x11])
        data_uint256 = bytearray(32 * [0x11])

        with serialization.BinaryReader(data_uint160) as br:
            # we explicitly call deserialize, instead of br.read_uint160() for coverage
            uint160 = UInt160.zero()
            uint160.deserialize(br)
            self.assertEqual(data_uint160, uint160._data)

        with serialization.BinaryReader(data_uint256) as br:
            uint256 = UInt256.zero()
            uint256.deserialize(br)
            self.assertEqual(data_uint256, uint256._data)
示例#18
0
 def parse_single_item(item: Union[Dict, List]):
     if 'iterator' in item:
         item = item['iterator']
         if item:
             if type(item[0]['value']) is not list:
                 return [parse_single_item(i) for i in item]
             else:
                 return {
                     parse_single_item(i['value'][0]):
                     parse_single_item(i['value'][1])
                     for i in item
                 }
     _type = item['type']
     if _type == 'Any' and 'value' not in item:
         return None
     else:
         value = item['value']
     if _type == 'Integer':
         return int(value)
     elif _type == 'Boolean':
         return value
     elif _type == 'ByteString' or _type == 'Buffer':
         byte_value = base64.b64decode(value)
         try:
             return byte_value.decode()
         except UnicodeDecodeError:
             try:
                 len_bytes = len(byte_value)
                 if len_bytes == 20:
                     return Hash160Str.from_UInt160(UInt160(byte_value))
                 if len_bytes == 32:
                     return Hash256Str.from_UInt256(UInt256(byte_value))
             except Exception:
                 pass
             # may be an N3 address starting with 'N'
             # TODO: decode to N3 address
             return byte_value
     elif _type == 'Array':
         return [parse_single_item(i) for i in value]
     elif _type == 'Struct':
         return tuple([parse_single_item(i) for i in value])
     elif _type == 'Map':
         return {
             parse_single_item(i['key']): parse_single_item(i['value'])
             for i in value
         }
     elif _type == 'Pointer':
         return int(value)
     else:
         raise ValueError(f'Unknown type {_type}')
示例#19
0
    def _internal_storage_find(self, contract_script_hash: types.UInt160, key_prefix: bytes):
        prefix = DBPrefixes.STORAGES + contract_script_hash.to_array() + key_prefix

        res = {}
        with self._real_db.iterator(prefix=prefix, include_key=True, include_value=True) as it:
            for key, value in it:
                # strip off prefix
                k = storage.StorageKey.deserialize_from_bytes(key[1:])
                v = storage.StorageItem.deserialize_from_bytes(value)
                res[k] = v

        # yielding outside of iterator to make sure the LevelDB iterator is closed and not leaking resources
        for k, v in res.items():
            yield k, v
示例#20
0
 def _unblock_account(self, engine: contracts.ApplicationEngine,
                      account: types.UInt160) -> bool:
     """
     Should only be called through syscalls
     """
     if not self._check_committee(engine):
         return False
     storage_key = self.key_blocked_account + account.to_array()
     storage_item = engine.snapshot.storages.try_get(storage_key,
                                                     read_only=False)
     if storage_item is None:
         return False
     else:
         engine.snapshot.storages.delete(storage_key)
     return True
示例#21
0
    def is_blocked(self, snapshot: storage.Snapshot,
                   account: types.UInt160) -> bool:
        """
        Check if the account is blocked

        Transaction from blocked accounts will be rejected by the consensus nodes.
        """

        si = snapshot.storages.try_get(self.key_blocked_account +
                                       account.to_array(),
                                       read_only=True)
        if si is None:
            return False
        else:
            return True
示例#22
0
 def bytes_to_UInt160(bytestring: bytes):
     return Hash160Str.from_UInt160(
         UInt160.deserialize_from_bytes(bytestring))
示例#23
0
                                           [contract_owner_hash])
print('invoke method balanceOf my NEO:', end=' ')
engine.print_results()
engine.invoke_method_of_arbitrary_contract(gas.hash, 'balanceOf',
                                           [contract_owner_hash])
print('invoke method balanceOf my GAS:', end=' ')
engine.print_results()

engine.invoke_method_with_print(
    "deposit",
    params=[
        contract_owner_hash, neo.hash, gas.hash,
        _30_days_later_ending_milisecond, mint_ratio, 1
    ],
    signers=[
        Signer(UInt160.from_string(contract_owner_hash), WitnessScope.GLOBAL)
    ])
engine.invoke_method_with_print(
    "deposit",
    params=[
        contract_owner_hash, neo.hash, gas.hash,
        _30_days_later_ending_milisecond, mint_ratio, 100
    ],
    signers=[
        Signer(UInt160.from_string(contract_owner_hash), WitnessScope.GLOBAL)
    ])
engine.invoke_method_of_arbitrary_contract(neo.hash, 'balanceOf',
                                           [contract_owner_hash])
print('invoke method balanceOf my NEO:', end=' ')
engine.print_results()
engine.get_rToken_balance(rcToken_address, contract_owner_hash)
示例#24
0
 def balance_of(self, snapshot: storage.Snapshot, owner: types.UInt160) -> vm.BigInteger:
     storage_item = snapshot.storages.try_get(self.key_account + owner.to_array(), read_only=True)
     if storage_item is None:
         return vm.BigInteger.zero()
     return NFTAccountState.deserialize_from_bytes(storage_item.value).balance
示例#25
0
    def test_zero(self):
        uint160 = UInt160.zero()
        self.assertEqual(20, len(uint160.to_array()))

        uint256 = UInt256.zero()
        self.assertEqual(32, len(uint256.to_array()))